mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Splatting optional compile-time macro parameter from inside lambda expression does not work #2532.
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
- Compiler assert when getting a member of a `bitstruct : char @bigendian` #2517.
|
||||
- Add ??? and +++= to list-precedence.
|
||||
- Fix issues with linking when using symbol aliases. #2519
|
||||
- Splatting optional compile-time macro parameter from inside lambda expression does not work #2532.
|
||||
|
||||
### Stdlib changes
|
||||
- Sorting functions correctly took slices by value, but also other types by value. Now, only slices are accepted by value, other containers are always by ref.
|
||||
|
||||
@@ -1778,9 +1778,9 @@ static inline ArrayIndex sema_len_from_expr(Expr *expr)
|
||||
return range_const_len(&expr->slice_expr.range);
|
||||
}
|
||||
|
||||
static Decl *sema_find_splat_arg(Decl *macro, const char *name)
|
||||
static Decl *sema_find_splat_arg(Decl **params, const char *name)
|
||||
{
|
||||
FOREACH(Decl *, decl, macro->func_decl.signature.params)
|
||||
FOREACH(Decl *, decl, params)
|
||||
{
|
||||
if (decl && decl->name == name) return decl;
|
||||
}
|
||||
@@ -1797,19 +1797,31 @@ typedef enum
|
||||
static SplatResult sema_splat_optional_argument(SemaContext *context, Expr *expr)
|
||||
{
|
||||
Decl *macro = context->current_macro;
|
||||
if (!macro) return SPLAT_NONE;
|
||||
Decl **macro_params;
|
||||
if (macro)
|
||||
{
|
||||
macro_params = macro->func_decl.signature.params;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (context->call_env.kind != CALL_ENV_FUNCTION || !context->call_env.current_function->func_decl.in_macro)
|
||||
{
|
||||
return SPLAT_NONE;
|
||||
}
|
||||
macro_params = context->call_env.current_function->func_decl.lambda_ct_parameters;
|
||||
}
|
||||
Decl *candidate = NULL;
|
||||
switch (expr->expr_kind)
|
||||
{
|
||||
case EXPR_UNRESOLVED_IDENTIFIER:
|
||||
if (expr->unresolved_ident_expr.path) break;
|
||||
candidate = sema_find_splat_arg(macro, expr->unresolved_ident_expr.ident);
|
||||
candidate = sema_find_splat_arg(macro_params, expr->unresolved_ident_expr.ident);
|
||||
break;
|
||||
case EXPR_HASH_IDENT:
|
||||
candidate = sema_find_splat_arg(macro, expr->hash_ident_expr.identifier);
|
||||
candidate = sema_find_splat_arg(macro_params, expr->hash_ident_expr.identifier);
|
||||
break;
|
||||
case EXPR_CT_IDENT:
|
||||
candidate = sema_find_splat_arg(macro, expr->ct_ident_expr.identifier);
|
||||
candidate = sema_find_splat_arg(macro_params, expr->ct_ident_expr.identifier);
|
||||
break;
|
||||
default:
|
||||
return SPLAT_NONE;
|
||||
|
||||
31
test/test_suite/lambda/lambda_splat_macro.c3t
Normal file
31
test/test_suite/lambda/lambda_splat_macro.c3t
Normal file
@@ -0,0 +1,31 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
import std;
|
||||
fn int main()
|
||||
{
|
||||
bool x = test1a(true)();
|
||||
return 0;
|
||||
}
|
||||
|
||||
macro test1a(bool $a = ...) => fn bool()
|
||||
{
|
||||
return test1b(...$a);
|
||||
};
|
||||
macro test1b(bool $a = ...) => $defined($a) ??? $a : false;
|
||||
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
define i32 @main() #0 {
|
||||
entry:
|
||||
%x = alloca i8, align 1
|
||||
%0 = call i8 @"test.test1a$lambda1"()
|
||||
store i8 %0, ptr %x, align 1
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
define internal zeroext i8 @"test.test1a$lambda1"() #0 {
|
||||
entry:
|
||||
ret i8 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user