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 {
|
||||
if sym.info.is_generic {
|
||||
mut nrt := '${sym.name}['
|
||||
mut rnrt := '${sym.rname}['
|
||||
mut t_generic_names := generic_names.clone()
|
||||
mut t_concrete_types := concrete_types.clone()
|
||||
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)
|
||||
nrt += gts.name
|
||||
rnrt += gts.name
|
||||
if i != sym.info.generic_types.len - 1 {
|
||||
nrt += ', '
|
||||
rnrt += ', '
|
||||
}
|
||||
} else {
|
||||
return none
|
||||
}
|
||||
}
|
||||
nrt += ']'
|
||||
rnrt += ']'
|
||||
mut idx := t.type_idxs[nrt]
|
||||
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)
|
||||
}
|
||||
|
@ -94,6 +94,7 @@ pub mut:
|
||||
kind Kind
|
||||
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
|
||||
rname string // the raw name
|
||||
methods []Fn
|
||||
generic_types []Type
|
||||
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{}
|
||||
match arg_sym.info {
|
||||
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()
|
||||
}
|
||||
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)
|
||||
match sym.info {
|
||||
ast.Struct, ast.Interface, ast.SumType {
|
||||
if sym.info.is_generic {
|
||||
if sym.info.is_generic && sym.generic_types.len == 0 {
|
||||
mut sgtyps := '_T'
|
||||
for gt in sym.info.generic_types {
|
||||
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{
|
||||
...sym
|
||||
name: sym_name
|
||||
rname: sym.name
|
||||
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…
Reference in New Issue
Block a user