- Inlining location when accessing #foo symbols.

- Improve inlined-at when checking generic code.
This commit is contained in:
Christoffer Lerno
2025-09-04 11:39:48 +02:00
parent cf14787552
commit 29e20ee1be
8 changed files with 53 additions and 23 deletions

View File

@@ -9,6 +9,8 @@
- Confusing error message when type has [] overloaded but not []= #2453
- $defined(x[0] = val) causes an error instead of returning false when a type does not have []= defined #2454
- Returning pointer to index of slice stored in a struct from method taking self incorrectly detected as returning pointer to local variable #2455.
- Inlining location when accessing #foo symbols.
- Improve inlined-at when checking generic code.
### Stdlib changes
- Added generic `InterfaceList` to store a list of values that implement a specific interface

View File

@@ -1604,6 +1604,7 @@ Module *compiler_find_or_create_module(Path *module_name, const char **parameter
// Set up the module.
module = CALLOCS(Module);
module->name = module_name;
module->inlined_at = (InliningSpan) { INVALID_SPAN, NULL };
size_t first = 0;
for (size_t i = module_name->len; i > 0; i--)
{

View File

@@ -166,6 +166,25 @@ struct ConstInitializer_
};
};
typedef union
{
struct
{
FileId file_id;
unsigned char length;
unsigned char col;
uint32_t row;
};
uint64_t a;
} SourceSpan;
static_assert(sizeof(SourceSpan) == 8, "Expected 8 bytes");
typedef struct InliningSpan_
{
SourceSpan span;
struct InliningSpan_ *prev;
} InliningSpan;
typedef struct
{
@@ -211,21 +230,8 @@ typedef struct
const char *full_path;
} File;
typedef union
{
struct
{
FileId file_id;
unsigned char length;
unsigned char col;
uint32_t row;
};
uint64_t a;
} SourceSpan;
static_assert(sizeof(SourceSpan) == 8, "Expected 8 bytes");
typedef struct
{
const char *key;
@@ -1607,6 +1613,7 @@ typedef struct Module_
Decl **tests;
Decl **lambdas_to_evaluate;
const char *generic_suffix;
InliningSpan inlined_at;
} Module;
@@ -1757,11 +1764,7 @@ typedef struct JumpTarget_
AstId defer;
} JumpTarget;
typedef struct InliningSpan_
{
SourceSpan span;
struct InliningSpan_ *prev;
} InliningSpan;
struct SemaContext_
{
@@ -2203,6 +2206,7 @@ Decl **copy_decl_list_macro(Decl **decl_list);
Ast *copy_ast_macro(Ast *source_ast);
Ast *copy_ast_defer(Ast *source_ast);
TypeInfo *copy_type_info_single(TypeInfo *type_info);
InliningSpan *copy_inlining_span(InliningSpan *span);
void init_asm(PlatformTarget *target);
void print_asm_list(PlatformTarget *target);

View File

@@ -1159,3 +1159,11 @@ Decl *copy_decl(CopyStruct *c, Decl *decl)
return copy;
}
InliningSpan *copy_inlining_span(InliningSpan *span)
{
if (!span) return NULL;
InliningSpan *copy_span = MALLOCS(InliningSpan);
copy_span->span = span->span;
copy_span->prev = copy_inlining_span(span->prev);
return copy_span;
}

View File

@@ -41,7 +41,7 @@ Expr *parse_integer(ParseContext *c, Expr *left, SourceSpan lhs_start);
Expr *parse_decl_or_expr(ParseContext *c);
void recover_top_level(ParseContext *c);
Expr *parse_cond(ParseContext *c);
Ast* parse_compound_stmt(ParseContext *c);
Ast *parse_compound_stmt(ParseContext *c);
Ast *parse_short_body(ParseContext *c, TypeInfoId return_type, bool is_regular_fn);
bool parse_attribute(ParseContext *c, Attr **attribute_ref, bool expect_eos);

View File

@@ -48,7 +48,7 @@ static inline bool sema_analyse_distinct(SemaContext *context, Decl *decl, bool
static CompilationUnit *unit_copy(Module *module, CompilationUnit *unit);
static Module *module_instantiate_generic(SemaContext *context, Module *module, Path *path, Expr **params);
static Module *module_instantiate_generic(SemaContext *context, Module *module, Path *path, Expr **params, SourceSpan from_span);
static inline bool sema_analyse_enum_param(SemaContext *context, Decl *param);
static inline bool sema_analyse_enum(SemaContext *context, Decl *decl, bool *erase_decl);
@@ -4851,7 +4851,7 @@ static CompilationUnit *unit_copy(Module *module, CompilationUnit *unit)
return copy;
}
static Module *module_instantiate_generic(SemaContext *context, Module *module, Path *path, Expr **params)
static Module *module_instantiate_generic(SemaContext *context, Module *module, Path *path, Expr **params, SourceSpan from_span)
{
unsigned decls = 0;
Decl* params_decls[MAX_PARAMS];
@@ -4902,6 +4902,7 @@ static Module *module_instantiate_generic(SemaContext *context, Module *module,
new_module->contracts = astid(copy_ast_macro(astptr(module->contracts)));
copy_end();
}
new_module->inlined_at = (InliningSpan) { .span = from_span, .prev = copy_inlining_span(context->inlined_at) };
return new_module;
}
@@ -5159,7 +5160,7 @@ Decl *sema_analyse_parameterized_identifier(SemaContext *c, Path *decl_path, con
path->module = path_string;
path->span = module->name->span;
path->len = scratch_buffer.len;
instantiated_module = module_instantiate_generic(c, module, path, params);
instantiated_module = module_instantiate_generic(c, module, path, params, invocation_span);
if (!instantiated_module) return poisoned_decl;
if (!sema_generate_parameterized_name_to_scratch(c, module, params, false, NULL)) return poisoned_decl;
instantiated_module->generic_suffix = scratch_buffer_copy();

View File

@@ -216,19 +216,22 @@ static Type *defer_iptr_cast(Expr *maybe_pointer);
typedef struct
{
bool in_no_eval;
InliningSpan *old_inlining;
} ContextSwitchState;
static inline ContextSwitchState context_switch_state_push(SemaContext *context, SemaContext *new_context)
{
ContextSwitchState state = { .in_no_eval = new_context->call_env.in_no_eval, };
ContextSwitchState state = { .in_no_eval = new_context->call_env.in_no_eval, .old_inlining = new_context->inlined_at };
new_context->call_env.in_no_eval = context->call_env.in_no_eval;
new_context->inlined_at = context->inlined_at;
return state;
}
static inline void context_switch_stat_pop(SemaContext *swapped, ContextSwitchState state)
{
swapped->call_env.in_no_eval = state.in_no_eval;
swapped->inlined_at = state.old_inlining;
}
Expr *sema_enter_inline_member(Expr *parent, CanonicalType *type)

View File

@@ -592,6 +592,17 @@ void sema_print_inline(SemaContext *context, SourceSpan original)
}
inlined_at = inlined_at->prev;
}
InliningSpan span = context->compilation_unit->module->inlined_at;
if (span.span.a == INVALID_SPAN.a) return;
inlined_at = &span;
while (inlined_at)
{
if (inlined_at->span.a != original.a)
{
sema_note_prev_at(inlined_at->span, "Inlined from here.");
}
inlined_at = inlined_at->prev;
}
}
void sema_error_at(SemaContext *context, SourceSpan span, const char *message, ...)