mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: fix generic method on aliases receiver type (#14729)
This commit is contained in:
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
|
mut to_set := ast.void_type
|
||||||
// resolve generic struct receiver
|
// resolve generic struct receiver
|
||||||
if node.is_method && param.typ.has_flag(.generic) {
|
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 {
|
match sym.info {
|
||||||
ast.Struct, ast.Interface, ast.SumType {
|
ast.Struct, ast.Interface, ast.SumType {
|
||||||
if !isnil(c.table.cur_fn) && c.table.cur_fn.generic_names.len > 0 { // in generic fn
|
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
|
method = m
|
||||||
has_method = true
|
has_method = true
|
||||||
} else {
|
} 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
|
mut parent_type := ast.void_type
|
||||||
if left_sym.info is ast.Struct {
|
if final_left_sym.info is ast.Struct {
|
||||||
parent_type = left_sym.info.parent_type
|
parent_type = final_left_sym.info.parent_type
|
||||||
} else if left_sym.info is ast.SumType {
|
} else if final_left_sym.info is ast.SumType {
|
||||||
parent_type = left_sym.info.parent_type
|
parent_type = final_left_sym.info.parent_type
|
||||||
} else if left_sym.info is ast.Interface {
|
} else if final_left_sym.info is ast.Interface {
|
||||||
parent_type = left_sym.info.parent_type
|
parent_type = final_left_sym.info.parent_type
|
||||||
}
|
}
|
||||||
if parent_type != 0 {
|
if parent_type != 0 {
|
||||||
type_sym := c.table.sym(parent_type)
|
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 {
|
if !has_method {
|
||||||
has_method = true
|
has_method = true
|
||||||
mut embed_types := []ast.Type{}
|
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() != '' {
|
if err.msg() != '' {
|
||||||
c.error(err.msg(), node.pos)
|
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
|
node.from_embed_types = embed_types
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if left_sym.kind == .aggregate {
|
if final_left_sym.kind == .aggregate {
|
||||||
// the error message contains the problematic type
|
// the error message contains the problematic type
|
||||||
unknown_method_msg = err.msg()
|
unknown_method_msg = err.msg()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if has_method {
|
if has_method {
|
||||||
// x is Bar<T>, x.foo() -> x.foo<T>()
|
// 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)
|
rec_is_generic := left_type.has_flag(.generic)
|
||||||
mut rec_concrete_types := []ast.Type{}
|
mut rec_concrete_types := []ast.Type{}
|
||||||
if rec_sym.info is ast.Struct {
|
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
Block a user