diff --git a/releasenotes.md b/releasenotes.md index 84cbf592c..21cc919a8 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -9,6 +9,7 @@ - Fixes issue where single character filenames like 'a.c3' would be rejected. - Better errors when index type doesn't match len() when doing user defined foreach. - Fixes to `to_int` for hexadecimal strings. +- Fixed issue when using a generic type from a generic type. ### Stdlib changes - Allow `to_int` family functions take a base, parsing base 2-10 and 16. diff --git a/src/compiler/ast.c b/src/compiler/ast.c index fe287e673..1348215b1 100644 --- a/src/compiler/ast.c +++ b/src/compiler/ast.c @@ -89,6 +89,12 @@ Decl *decl_new_with_type(const char *name, SourceSpan loc, DeclKind decl_type) return decl; } +const char *decl_safe_name(Decl *decl) +{ + if (!decl) return ""; + if (decl->name) return decl->name; + return decl_to_name(decl); +} const char *decl_to_name(Decl *decl) { const char *name = decl_to_a_name(decl); diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 9b1108024..4fc40af1b 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -1508,6 +1508,7 @@ typedef struct Module_ bool is_c_library : 1; bool is_exported : 1; bool is_generic : 1; + bool is_from_generic : 1; bool no_extprefix : 1; AnalysisStage stage : 6; @@ -2163,6 +2164,7 @@ Decl *decl_new_with_type(const char *name, SourceSpan span, DeclKind decl_type); Decl *decl_new_var(const char *name, SourceSpan span, TypeInfo *type, VarDeclKind kind); Decl *decl_new_generated_var(Type *type, VarDeclKind kind, SourceSpan span); void decl_set_external_name(Decl *decl); +const char *decl_safe_name(Decl *decl); const char *decl_to_name(Decl *decl); const char *decl_to_a_name(Decl *decl); int decl_count_elements(Decl *structlike); diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index d82d9fa97..c835304a7 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -2789,7 +2789,7 @@ static inline bool sema_analyse_func_macro(SemaContext *context, Decl *decl, Att static inline bool sema_analyse_func(SemaContext *context, Decl *decl, bool *erase_decl) { - DEBUG_LOG("----Analysing function %s", decl->name); + DEBUG_LOG(">>> Analyse function [%s] in %s", decl_safe_name(decl), context->unit->file->full_path); bool is_interface_method = decl->func_decl.attr_interface_method; if (!sema_analyse_func_macro(context, decl, is_interface_method ? ATTR_INTERFACE_METHOD : ATTR_FUNC, erase_decl)) return false; @@ -2892,7 +2892,7 @@ static inline bool sema_analyse_func(SemaContext *context, Decl *decl, bool *era if (!sema_analyse_doc_header(decl->func_decl.docs, decl->func_decl.signature.params, NULL, &pure)) return decl_poison(decl); decl->func_decl.signature.attrs.is_pure = pure; if (!sema_set_alloca_alignment(context, decl->type, &decl->alignment)) return false; - DEBUG_LOG("Function analysis done."); + DEBUG_LOG("<<< Function analysis of [%s] successful.", decl_safe_name(decl)); return true; } @@ -3396,9 +3396,10 @@ static Module *module_instantiate_generic(SemaContext *context, Module *module, SEMA_ERROR(param, "Expected a value, not a type."); return NULL; } + TypeInfo *type_info = param->type_expr; + if (!sema_resolve_type_info(context, type_info, RESOLVE_TYPE_DEFAULT)) return false; Decl *decl = decl_new_with_type(param_name, params[i]->span, DECL_TYPEDEF); decl->resolve_status = RESOLVE_DONE; - TypeInfo *type_info = param->type_expr; assert(type_info->resolve_status == RESOLVE_DONE); decl->typedef_decl.type_info = type_info; decl->type->name = decl->name; @@ -3406,9 +3407,9 @@ static Module *module_instantiate_generic(SemaContext *context, Module *module, params_decls[decls++] = decl; } - Module *new_module = compiler_find_or_create_module(path, NULL); new_module->is_generic = false; + new_module->is_from_generic = true; CompilationUnit **units = module->units; VECEACH(units, i) { @@ -3633,7 +3634,14 @@ Decl *sema_analyse_parameterized_identifier(SemaContext *c, Path *decl_path, con if (!sema_append_generate_parameterized_name(c, module, params, false)) return poisoned_decl; if (!instantiated_module) return poisoned_decl; instantiated_module->generic_suffix = scratch_buffer_copy(); - sema_analyze_stage(instantiated_module, c->unit->module->stage - 1); + if (c->unit->module->is_from_generic) + { + sema_analyze_stage(instantiated_module, c->unit->module->stage); + } + else + { + sema_analyze_stage(instantiated_module, c->unit->module->stage - 1); + } } if (global_context.errors_found) return poisoned_decl; Decl *symbol = module_find_symbol(instantiated_module, name); @@ -3770,10 +3778,11 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl) { if (decl->resolve_status == RESOLVE_DONE) return decl_ok(decl); + DEBUG_LOG(">>> Analyse declaration [%s] in %s.", decl_safe_name(decl), context_filename(context)); + SemaContext temp_context; context = context_transform_for_eval(context, &temp_context, decl->unit); - DEBUG_LOG(">>> Analysing %s.", decl->name ? decl->name : ".anon"); if (decl->resolve_status == RESOLVE_RUNNING) { SEMA_ERROR(decl, decl->name @@ -3859,9 +3868,12 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl) decl->resolve_status = RESOLVE_DONE; sema_context_destroy(&temp_context); + DEBUG_LOG("<<< Analysis of [%s] successful.", decl_safe_name(decl)); + return true; FAILED: sema_context_destroy(&temp_context); + DEBUG_LOG("<<< Analysis of [%s] failed.", decl_safe_name(decl)); return decl_poison(decl); } diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 5171d6877..c75e4c68c 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -2547,7 +2547,7 @@ static inline bool sema_expr_analyse_subscript(SemaContext *context, Expr *expr, Type *underlying_type = type_flatten(subscripted->type); Type *current_type = underlying_type; - + assert(current_type == current_type->canonical); int64_t index_value = -1; bool start_from_end = expr->subscript_expr.range.start_from_end; if (start_from_end && (underlying_type->type_kind == TYPE_POINTER || underlying_type->type_kind == TYPE_FLEXIBLE_ARRAY)) diff --git a/src/compiler/sema_internal.h b/src/compiler/sema_internal.h index 8f86f97a4..896591058 100644 --- a/src/compiler/sema_internal.h +++ b/src/compiler/sema_internal.h @@ -31,6 +31,8 @@ extern const char *ct_eval_error; Decl **global_context_acquire_locals_list(void); void generic_context_release_locals_list(Decl **); +const char *context_filename(SemaContext *context); + AstId context_get_defers(SemaContext *context, AstId defer_top, AstId defer_bottom, bool is_success); void context_pop_defers(SemaContext *context, AstId *next); void context_pop_defers_and_replace_ast(SemaContext *context, Ast *ast); diff --git a/src/compiler/semantic_analyser.c b/src/compiler/semantic_analyser.c index 3b7df3cc7..06ff9aa62 100644 --- a/src/compiler/semantic_analyser.c +++ b/src/compiler/semantic_analyser.c @@ -51,6 +51,15 @@ void context_change_scope_with_flags(SemaContext *context, ScopeFlags flags) } } +const char *context_filename(SemaContext *context) +{ + CompilationUnit *unit = context->unit; + if (!unit) return ""; + File *file = unit->file; + if (!file || !file->full_path) return ""; + return file->full_path; +} + void context_change_scope_for_label(SemaContext *context, DeclId label_id) { context_change_scope_with_flags(context, SCOPE_NONE);