From ea86c9d37a5e07f17355132156aa01d0fde5383d Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Fri, 6 Dec 2024 13:09:47 +0100 Subject: [PATCH] Fix of issue where multiple methods were accepted for the same type. Fix of issue where a method was linked to a type alias instead of the underlying type. #1661 --- releasenotes.md | 2 ++ src/compiler/sema_decls.c | 7 ++++--- src/compiler/sema_name_resolution.c | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/releasenotes.md b/releasenotes.md index f6c40601c..fd11aab4f 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -33,6 +33,8 @@ - Enforce single module compilation for static libraries to make constructors run properly. - Crash when using --no-obj without compile-only. #1653 - Do not produce expression locations for windows. +- Issue where multiple methods were accepted for the same type. +- Issue where a method was linked to a type alias instead of the underlying type. ### Stdlib changes - Add `io::MultiReader`, `io::MultiWriter`, and `io::TeeReader` structs. diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 43992b159..1943c92c8 100755 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -1968,8 +1968,8 @@ static inline bool unit_add_method(SemaContext *context, Type *parent_type, Decl // Did we already define it externally? Decl *other = sema_find_extension_method_in_list(unit->local_method_extensions, parent_type, name); - if (!other) sema_find_extension_method_in_list(unit->module->private_method_extensions, parent_type, name); - if (!other) sema_find_extension_method_in_list(compiler.context.method_extensions, parent_type, name); + if (!other) other = sema_find_extension_method_in_list(unit->module->private_method_extensions, parent_type, name); + if (!other) other = sema_find_extension_method_in_list(compiler.context.method_extensions, parent_type, name); if (other) { SEMA_ERROR(method, "This %s is already defined.", method_name_by_decl(method)); @@ -4556,12 +4556,13 @@ bool sema_analyse_method_register(SemaContext *context, Decl *method) if (!sema_resolve_type_info(context, parent_type_info, method->decl_kind == DECL_MACRO ? RESOLVE_TYPE_MACRO_METHOD : RESOLVE_TYPE_FUNC_METHOD)) return false; // Can the type have methods? - Type *parent_type = parent_type_info->type; + Type *parent_type = parent_type_info->type = parent_type_info->type->canonical; if (!type_may_have_method(parent_type)) { RETURN_SEMA_ERROR(parent_type_info, "Methods can not be associated with '%s'", type_to_error_string(parent_type)); } + // We need at least one argument (the parent type) if (!vec_size(method->func_decl.signature.params)) { diff --git a/src/compiler/sema_name_resolution.c b/src/compiler/sema_name_resolution.c index ff278ff2b..17eaa44a6 100644 --- a/src/compiler/sema_name_resolution.c +++ b/src/compiler/sema_name_resolution.c @@ -760,10 +760,11 @@ MOD_FOUND: Decl *sema_find_extension_method_in_list(Decl **extensions, Type *type, const char *method_name) { + ASSERT0(type == type->canonical); FOREACH(Decl *, extension, extensions) { if (extension->name != method_name) continue; - if (type_infoptr(extension->func_decl.type_parent)->type->canonical == type) return extension; + if (typeget(extension->func_decl.type_parent) == type) return extension; } return NULL; }