diff --git a/releasenotes.md b/releasenotes.md index 4053055b5..dc8de1753 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -5,11 +5,12 @@ ### Changes / improvements - Introduce `arg: x` named arguments instead of `.arg = x`, deprecate old style. - Support splat for varargs #1352. +- Allow `var` in lambdas in macros. ### Fixes - Issue where a lambda wasn't correctly registered as external. #1408 - Generic methods were incorrectly registered as functions, leading to naming collisions. #1402 -- Deprecated inline generic types. +- Deprecated inline generic types outside of struct definitions and macros. - Deprecated tuple / triple types. - Converting a slice to a vector/array would copy too little data. - Crash when reading an empty 'manifest.json'. diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 2781ef699..42aa89dbe 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -499,6 +499,7 @@ typedef struct bool attr_nosanitize_memory : 1; bool attr_nosanitize_thread : 1; bool is_lambda : 1; + bool in_macro : 1; union { uint32_t priority; @@ -1762,7 +1763,6 @@ typedef struct unsigned warnings_found; unsigned includes_used; Decl ***locals_list; - bool silence_deprecation; HTable compiler_defines; HTable features; Module std_module; @@ -2079,6 +2079,7 @@ void unit_register_external_symbol(SemaContext *context, Decl *decl); bool unit_add_import(CompilationUnit *unit, Path *path, bool private_import); bool context_set_module_from_filename(ParseContext *context); bool context_set_module(ParseContext *context, Path *path, const char **generic_parameters); +bool context_is_macro(SemaContext *context); // --- Decl functions diff --git a/src/compiler/context.c b/src/compiler/context.c index 2a740be7e..8d01b5300 100644 --- a/src/compiler/context.c +++ b/src/compiler/context.c @@ -112,6 +112,11 @@ bool context_set_module(ParseContext *context, Path *path, const char **generic_ return create_module_or_check_name(context->unit, path, generic_parameters); } +bool context_is_macro(SemaContext *context) +{ + if (context->current_macro != NULL) return true; + return context->call_env.current_function && context->call_env.current_function->func_decl.in_macro; +} void unit_register_external_symbol(SemaContext *context, Decl *decl) { diff --git a/src/compiler/parse_expr.c b/src/compiler/parse_expr.c index 6239cd1ce..0d18af0d4 100644 --- a/src/compiler/parse_expr.c +++ b/src/compiler/parse_expr.c @@ -466,7 +466,7 @@ Expr *parse_vasplat(ParseContext *c) RANGE_EXTEND_PREV(expr); END: // TODO remove in 0.7 - if (lparen && !compiler.context.silence_deprecation) + if (lparen && !compiler.build.silence_deprecation) { if (expr->vasplat_expr.end || expr->vasplat_expr.start) { @@ -517,7 +517,7 @@ bool parse_arg_list(ParseContext *c, Expr ***result, TokenType param_end, bool v CONSUME_OR_RET(TOKEN_EQ, false); ASSIGN_EXPR_OR_RET(expr->named_argument_expr.value, parse_expr(c), false); RANGE_EXTEND_PREV(expr); - if (!compiler.context.silence_deprecation) + if (!compiler.build.silence_deprecation) { SEMA_NOTE(expr, "Named arguments using the '.foo = expr' style are deprecated, please use 'foo: expr' instead."); } @@ -1297,7 +1297,7 @@ static Expr *parse_ct_arg(ParseContext *c, Expr *left) ASSIGN_EXPRID_OR_RET(expr->ct_arg_expr.arg, parse_expr(c), poisoned_expr); CONSUME_OR_RET(is_lparen ? TOKEN_RPAREN : TOKEN_RBRACKET, poisoned_expr); // TODO remove in 0.7 - if (is_lparen && !compiler.context.silence_deprecation) + if (is_lparen && !compiler.build.silence_deprecation) { SEMA_NOTE(expr, "'%s(...)' is deprecated, use '%s[...]' instead.", token_type_to_string(type), token_type_to_string(type)); diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index 8ada930e7..b5a723e16 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -421,7 +421,7 @@ static inline TypeInfo *parse_base_type(ParseContext *c) CONSUME_OR_RET(is_lparen ? TOKEN_RPAREN : TOKEN_RBRACKET, poisoned_type_info); RANGE_EXTEND_PREV(type_info); // TODO remove in 0.7 - if (is_lparen && !compiler.context.silence_deprecation) + if (is_lparen && !compiler.build.silence_deprecation) { SEMA_NOTE(type_info, "'$vatype(...)' is deprecated, use '$vatype[...]' instead."); } diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index e85ec3d0b..aee0fdd5e 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -3788,7 +3788,7 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local) SEMA_ERROR(decl, "Constants need to have an initial value."); return decl_poison(decl); } - if (kind == VARDECL_LOCAL && !context->current_macro) + if (kind == VARDECL_LOCAL && !context_is_macro(context)) { SEMA_ERROR(decl, "Defining a variable using 'var %s = ...' is only allowed inside a macro.", decl->name); return decl_poison(decl); diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 920c3b9ae..c9edeb90d 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -8290,6 +8290,10 @@ static inline bool sema_expr_analyse_lambda(SemaContext *context, Type *target_t } decl->func_decl.lambda_ct_parameters = ct_lambda_parameters; decl->func_decl.is_lambda = true; + if (context_is_macro(context) || !context->call_env.current_function) + { + decl->func_decl.in_macro = true; + } decl->alignment = type_alloca_alignment(decl->type); // We will actually compile this into any module using it (from a macro) by necessity, // so we'll declare it as weak and externally visible. diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index 8ab5fcd36..92d3e5752 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -3123,7 +3123,7 @@ bool sema_analyse_function_body(SemaContext *context, Decl *func) context->call_env = (CallEnv) { .current_function = func, .kind = CALL_ENV_FUNCTION, - .pure = func->func_decl.signature.attrs.is_pure + .pure = func->func_decl.signature.attrs.is_pure, }; context->rtype = prototype->rtype; context->macro_call_depth = 0; diff --git a/src/compiler/sema_types.c b/src/compiler/sema_types.c index b35e4884f..d9a24e90b 100644 --- a/src/compiler/sema_types.c +++ b/src/compiler/sema_types.c @@ -362,9 +362,10 @@ INLINE bool sema_resolve_generic_type(SemaContext *context, TypeInfo *type_info) Decl *type = sema_analyse_parameterized_identifier(context, inner->unresolved.path, inner->unresolved.name, inner->span, type_info->generic.params); if (!decl_ok(type)) return false; type_info->type = type->type; - if (!context->current_macro && !type_info->in_def) + if (!context->current_macro && (context->call_env.kind == CALL_ENV_FUNCTION || context->call_env.kind == CALL_ENV_FUNCTION_STATIC) + && !context->call_env.current_function->func_decl.in_macro) { - if (!compiler.context.silence_deprecation) SEMA_NOTE(type_info, "Direct generic type declarations outside of macros is a deprecated feature, please use 'def' to create an alias."); + if (!compiler.build.silence_deprecation) SEMA_NOTE(type_info, "Direct generic type declarations outside of macros is a deprecated feature, please use 'def' to create an alias."); // TODO, completely disallow // RETURN_SEMA_ERROR(type_info, "Direct generic type declarations are only allowed inside of macros. Use `def` to define an alias for the type instead."); }