diff --git a/releasenotes.md b/releasenotes.md index e084e8457..b8eb2f9e4 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -64,6 +64,7 @@ - `@tag` was not allowed to repeat. - Lambdas on the top level were not exported by default. #2428 - `has_tagof` on tagged lambdas returns false #2432 +- Properly add "inlined at" for generic instantiation errors #2382. ### Stdlib changes - Add `==` to `Pair`, `Triple` and TzDateTime. Add print to `Pair` and `Triple`. diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index fefdeba0b..ea46763eb 100755 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -5059,7 +5059,7 @@ static bool sema_generate_parameterized_name_to_scratch(SemaContext *context, Mo return true; } -static bool sema_analyse_generic_module_contracts(SemaContext *c, Module *module, SourceSpan error_span) +static bool sema_analyse_generic_module_contracts(SemaContext *c, Module *module, SourceSpan param_span, SourceSpan invocation_span) { ASSERT(module->contracts); AstId contract = module->contracts; @@ -5071,7 +5071,11 @@ static bool sema_analyse_generic_module_contracts(SemaContext *c, Module *module SemaContext temp_context; if (ast->contract_stmt.kind == CONTRACT_COMMENT) continue; ASSERT_SPAN(ast, ast->contract_stmt.kind == CONTRACT_REQUIRE); + InliningSpan *old_span = c->inlined_at; + InliningSpan new_span = { .prev = old_span, .span = invocation_span }; SemaContext *new_context = context_transform_for_eval(c, &temp_context, module->units[0]); + new_context->inlined_at = &new_span; + FOREACH(Expr *, expr, ast->contract_stmt.contract.decl_exprs->expression_list) { CondResult res = sema_check_comp_time_bool(new_context, expr); @@ -5079,13 +5083,13 @@ static bool sema_analyse_generic_module_contracts(SemaContext *c, Module *module if (res == COND_TRUE) continue; if (ast->contract_stmt.contract.comment) { - sema_error_at(c, error_span, + sema_error_at(c, param_span, "Parameter(s) would violate constraint: %s.", ast->contract_stmt.contract.comment); } else { - sema_error_at(c, error_span, "Parameter(s) failed validation: %s", + sema_error_at(c, param_span, "Parameter(s) failed validation: %s", ast->contract_stmt.contract.expr_string); } FAIL: @@ -5111,7 +5115,7 @@ bool sema_parameterized_type_is_found(SemaContext *context, Path *decl_path, con } Decl *sema_analyse_parameterized_identifier(SemaContext *c, Path *decl_path, const char *name, SourceSpan span, - Expr **params, bool *was_recursive_ref) + Expr **params, bool *was_recursive_ref, SourceSpan invocation_span) { NameResolve name_resolve = { .path = decl_path, @@ -5167,8 +5171,8 @@ Decl *sema_analyse_parameterized_identifier(SemaContext *c, Path *decl_path, con { if (instantiated_module->contracts) { - SourceSpan error_span = extend_span_with_token(params[0]->span, params[parameter_count - 1]->span); - if (!sema_analyse_generic_module_contracts(c, instantiated_module, error_span)) + SourceSpan param_span = extend_span_with_token(params[0]->span, params[parameter_count - 1]->span); + if (!sema_analyse_generic_module_contracts(c, instantiated_module, param_span, invocation_span)) { return poisoned_decl; } diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index fa08bb8fb..54663e4d6 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -3104,13 +3104,14 @@ static bool sema_call_analyse_body_expansion(SemaContext *macro_context, Expr *c } +// Conversion MyEnum.FOO -> MyEnum.ordinal, will change the type. void sema_expr_convert_enum_to_int(Expr *expr) { ASSERT(type_flatten(expr->type)->type_kind == TYPE_ENUM); Type *underlying_type = type_base(expr->type); if (sema_cast_const(expr)) { - ASSERT(expr->const_expr.const_kind == CONST_ENUM); + ASSERT(expr_is_const_enum(expr)); expr_rewrite_const_int(expr, underlying_type, expr->const_expr.enum_val->enum_constant.inner_ordinal); } if (expr->expr_kind == EXPR_ENUM_FROM_ORD) @@ -10084,8 +10085,8 @@ static inline bool sema_expr_analyse_generic_ident(SemaContext *context, Expr *e RETURN_SEMA_ERROR(parent, "Expected an identifier to parameterize."); } Decl *symbol = sema_analyse_parameterized_identifier(context, parent->unresolved_ident_expr.path, - parent->unresolved_ident_expr.ident, parent->span, - expr->generic_ident_expr.parameters, NULL); + parent->unresolved_ident_expr.ident, parent->span, + expr->generic_ident_expr.parameters, NULL, expr->span); if (!decl_ok(symbol)) return false; expr_resolve_ident(expr, symbol); return true; diff --git a/src/compiler/sema_internal.h b/src/compiler/sema_internal.h index 640070c2d..b0909330e 100644 --- a/src/compiler/sema_internal.h +++ b/src/compiler/sema_internal.h @@ -126,7 +126,7 @@ Type *cast_numeric_arithmetic_promotion(Type *type); void cast_to_int_to_max_bit_size(Expr *lhs, Expr *rhs, Type *left_type, Type *right_type); bool sema_decl_if_cond(SemaContext *context, Decl *decl); Decl *sema_analyse_parameterized_identifier(SemaContext *c, Path *decl_path, const char *name, SourceSpan span, - Expr **params, bool *was_recursive_ref); + Expr **params, bool *was_recursive_ref, SourceSpan invocation_span); bool sema_parameterized_type_is_found(SemaContext *context, Path *decl_path, const char *name, SourceSpan span); Type *sema_resolve_type_get_func(Signature *signature, CallABI abi); INLINE bool sema_set_abi_alignment(SemaContext *context, Type *type, AlignSize *result); diff --git a/src/compiler/sema_types.c b/src/compiler/sema_types.c index 1aba5368c..96c96408c 100644 --- a/src/compiler/sema_types.c +++ b/src/compiler/sema_types.c @@ -454,7 +454,7 @@ INLINE bool sema_resolve_generic_type(SemaContext *context, TypeInfo *type_info) } compiler.generic_depth++; Decl *type = sema_analyse_parameterized_identifier(context, inner->unresolved.path, inner->unresolved.name, - inner->span, type_info->generic.params, &was_recursive); + inner->span, type_info->generic.params, &was_recursive, type_info->span); compiler.generic_depth--; if (!decl_ok(type)) return false; if (!sema_analyse_decl(context, type)) return false;