mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
ast, parser, cgen: fix generic struct init with inconsistent generic types (#17639)
This commit is contained in:
parent
cb7e25e47e
commit
2643d6645f
@ -1714,6 +1714,7 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
|
|||||||
Struct, Interface, SumType {
|
Struct, Interface, SumType {
|
||||||
if sym.info.is_generic {
|
if sym.info.is_generic {
|
||||||
mut nrt := '${sym.name}['
|
mut nrt := '${sym.name}['
|
||||||
|
mut rnrt := '${sym.rname}['
|
||||||
mut t_generic_names := generic_names.clone()
|
mut t_generic_names := generic_names.clone()
|
||||||
mut t_concrete_types := concrete_types.clone()
|
mut t_concrete_types := concrete_types.clone()
|
||||||
if sym.generic_types.len > 0 && sym.generic_types.len == sym.info.generic_types.len
|
if sym.generic_types.len > 0 && sym.generic_types.len == sym.info.generic_types.len
|
||||||
@ -1744,17 +1745,23 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
|
|||||||
{
|
{
|
||||||
gts := t.sym(ct)
|
gts := t.sym(ct)
|
||||||
nrt += gts.name
|
nrt += gts.name
|
||||||
|
rnrt += gts.name
|
||||||
if i != sym.info.generic_types.len - 1 {
|
if i != sym.info.generic_types.len - 1 {
|
||||||
nrt += ', '
|
nrt += ', '
|
||||||
|
rnrt += ', '
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return none
|
return none
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nrt += ']'
|
nrt += ']'
|
||||||
|
rnrt += ']'
|
||||||
mut idx := t.type_idxs[nrt]
|
mut idx := t.type_idxs[nrt]
|
||||||
if idx == 0 {
|
if idx == 0 {
|
||||||
idx = t.add_placeholder_type(nrt, .v)
|
idx = t.type_idxs[rnrt]
|
||||||
|
if idx == 0 {
|
||||||
|
idx = t.add_placeholder_type(nrt, .v)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic)
|
return new_type(idx).derive_add_muls(generic_type).clear_flag(.generic)
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,7 @@ pub mut:
|
|||||||
kind Kind
|
kind Kind
|
||||||
name string // the internal & source name of the type, i.e. `[5]int`.
|
name string // the internal & source name of the type, i.e. `[5]int`.
|
||||||
cname string // the name with no dots for use in the generated C code
|
cname string // the name with no dots for use in the generated C code
|
||||||
|
rname string // the raw name
|
||||||
methods []Fn
|
methods []Fn
|
||||||
generic_types []Type
|
generic_types []Type
|
||||||
mod string
|
mod string
|
||||||
|
@ -983,7 +983,11 @@ fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr) {
|
|||||||
mut concrete_types := []ast.Type{}
|
mut concrete_types := []ast.Type{}
|
||||||
match arg_sym.info {
|
match arg_sym.info {
|
||||||
ast.Struct, ast.Interface, ast.SumType {
|
ast.Struct, ast.Interface, ast.SumType {
|
||||||
generic_types = arg_sym.info.generic_types.clone()
|
if param_type_sym.generic_types.len > 0 {
|
||||||
|
generic_types = param_type_sym.generic_types.clone()
|
||||||
|
} else {
|
||||||
|
generic_types = arg_sym.info.generic_types.clone()
|
||||||
|
}
|
||||||
concrete_types = arg_sym.info.concrete_types.clone()
|
concrete_types = arg_sym.info.concrete_types.clone()
|
||||||
}
|
}
|
||||||
else {}
|
else {}
|
||||||
|
@ -1325,7 +1325,7 @@ fn (mut g Gen) cc_type(typ ast.Type, is_prefix_struct bool) string {
|
|||||||
// TODO: this needs to be removed; cgen shouldn't resolve generic types (job of checker)
|
// TODO: this needs to be removed; cgen shouldn't resolve generic types (job of checker)
|
||||||
match sym.info {
|
match sym.info {
|
||||||
ast.Struct, ast.Interface, ast.SumType {
|
ast.Struct, ast.Interface, ast.SumType {
|
||||||
if sym.info.is_generic {
|
if sym.info.is_generic && sym.generic_types.len == 0 {
|
||||||
mut sgtyps := '_T'
|
mut sgtyps := '_T'
|
||||||
for gt in sym.info.generic_types {
|
for gt in sym.info.generic_types {
|
||||||
gts := g.table.sym(g.unwrap_generic(gt))
|
gts := g.table.sym(g.unwrap_generic(gt))
|
||||||
|
@ -682,6 +682,7 @@ pub fn (mut p Parser) find_type_or_add_placeholder(name string, language ast.Lan
|
|||||||
idx = p.table.register_sym(ast.TypeSymbol{
|
idx = p.table.register_sym(ast.TypeSymbol{
|
||||||
...sym
|
...sym
|
||||||
name: sym_name
|
name: sym_name
|
||||||
|
rname: sym.name
|
||||||
generic_types: p.struct_init_generic_types.clone()
|
generic_types: p.struct_init_generic_types.clone()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
struct MyData[T] {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn myfunc[U](a MyData[U]) string {
|
||||||
|
println(a)
|
||||||
|
return '${a}'
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_generics_struct_init_with_inconsistent_generic_types() {
|
||||||
|
d1 := MyData[int]{}
|
||||||
|
r1 := myfunc(d1)
|
||||||
|
println(r1)
|
||||||
|
assert r1 == 'MyData[int]{}'
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user