checker: fix generic method on aliases receiver type (#14729)
parent
e1360ccf8c
commit
784361f153
|
@ -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
|
||||
|
|
|
@ -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<T>, x.foo() -> x.foo<T>()
|
||||
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 {
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
module main
|
||||
|
||||
struct Container<T> {
|
||||
value T
|
||||
}
|
||||
|
||||
fn (c Container<T>) id() int {
|
||||
return 1
|
||||
}
|
||||
|
||||
type Text = Container<string>
|
||||
|
||||
fn test_generic_method_on_receiver_aliases_type() {
|
||||
t := Text{'test'}
|
||||
println(t.id())
|
||||
assert t.id() == 1
|
||||
}
|
Loading…
Reference in New Issue