From eb674411c786aac57fef9bf9a0e1d1493e53fbb6 Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 9 Jun 2022 20:36:31 +0800 Subject: [PATCH] checker: fix generic method on aliases receiver type (#14729) --- vlib/v/checker/check_types.v | 2 +- vlib/v/checker/fn.v | 20 +++++++++---------- ...cs_method_on_receiver_aliases_types_test.v | 17 ++++++++++++++++ 3 files changed, 28 insertions(+), 11 deletions(-) create mode 100644 vlib/v/tests/generics_method_on_receiver_aliases_types_test.v diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index 4da2b45059..53398523d4 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -619,7 +619,7 @@ pub fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr mut to_set := ast.void_type // resolve generic struct receiver if node.is_method && param.typ.has_flag(.generic) { - sym := c.table.sym(node.receiver_type) + sym := c.table.final_sym(node.receiver_type) match sym.info { ast.Struct, ast.Interface, ast.SumType { if !isnil(c.table.cur_fn) && c.table.cur_fn.generic_names.len > 0 { // in generic fn diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index 746fa7b013..788d39eee9 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -1193,14 +1193,14 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { method = m has_method = true } else { - if left_sym.kind in [.struct_, .sum_type, .interface_] { + if final_left_sym.kind in [.struct_, .sum_type, .interface_] { mut parent_type := ast.void_type - if left_sym.info is ast.Struct { - parent_type = left_sym.info.parent_type - } else if left_sym.info is ast.SumType { - parent_type = left_sym.info.parent_type - } else if left_sym.info is ast.Interface { - parent_type = left_sym.info.parent_type + if final_left_sym.info is ast.Struct { + parent_type = final_left_sym.info.parent_type + } else if final_left_sym.info is ast.SumType { + parent_type = final_left_sym.info.parent_type + } else if final_left_sym.info is ast.Interface { + parent_type = final_left_sym.info.parent_type } if parent_type != 0 { type_sym := c.table.sym(parent_type) @@ -1214,7 +1214,7 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { if !has_method { has_method = true mut embed_types := []ast.Type{} - method, embed_types = c.table.find_method_from_embeds(left_sym, method_name) or { + method, embed_types = c.table.find_method_from_embeds(final_left_sym, method_name) or { if err.msg() != '' { c.error(err.msg(), node.pos) } @@ -1226,14 +1226,14 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { node.from_embed_types = embed_types } } - if left_sym.kind == .aggregate { + if final_left_sym.kind == .aggregate { // the error message contains the problematic type unknown_method_msg = err.msg() } } if has_method { // x is Bar, x.foo() -> x.foo() - rec_sym := c.table.sym(node.left_type) + rec_sym := c.table.final_sym(node.left_type) rec_is_generic := left_type.has_flag(.generic) mut rec_concrete_types := []ast.Type{} if rec_sym.info is ast.Struct { diff --git a/vlib/v/tests/generics_method_on_receiver_aliases_types_test.v b/vlib/v/tests/generics_method_on_receiver_aliases_types_test.v new file mode 100644 index 0000000000..7f5b022c7e --- /dev/null +++ b/vlib/v/tests/generics_method_on_receiver_aliases_types_test.v @@ -0,0 +1,17 @@ +module main + +struct Container { + value T +} + +fn (c Container) id() int { + return 1 +} + +type Text = Container + +fn test_generic_method_on_receiver_aliases_type() { + t := Text{'test'} + println(t.id()) + assert t.id() == 1 +}