1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

ast, cgen: fix generic struct with inconsistent generic types (fix #18254) (#18301)

This commit is contained in:
yuyi 2023-05-30 20:24:54 +08:00 committed by GitHub
parent af05cfcbbc
commit ac6289301c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 7 deletions

View File

@ -222,7 +222,7 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) {
eprintln('INFO: compile with `v -live ${g.pref.path} `, if you want to use the [live] function ${node.name} .') eprintln('INFO: compile with `v -live ${g.pref.path} `, if you want to use the [live] function ${node.name} .')
} }
mut name := g.c_fn_name(node) or { return } mut name := g.c_fn_name(node)
mut type_name := g.typ(g.unwrap_generic(node.return_type)) mut type_name := g.typ(g.unwrap_generic(node.return_type))
if node.return_type.has_flag(.generic) && g.table.sym(node.return_type).kind == .array_fixed { if node.return_type.has_flag(.generic) && g.table.sym(node.return_type).kind == .array_fixed {
@ -432,17 +432,17 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) {
} }
} }
fn (mut g Gen) c_fn_name(node &ast.FnDecl) !string { fn (mut g Gen) c_fn_name(node &ast.FnDecl) string {
mut name := node.name mut name := node.name
if name in ['+', '-', '*', '/', '%', '<', '=='] { if name in ['+', '-', '*', '/', '%', '<', '=='] {
name = util.replace_op(name) name = util.replace_op(name)
} }
if node.is_method { if node.is_method {
unwrapped_rec_sym := g.table.sym(g.unwrap_generic(node.receiver.typ)) unwrapped_rec_typ := g.unwrap_generic(node.receiver.typ)
if unwrapped_rec_sym.kind == .placeholder { name = g.cc_type(unwrapped_rec_typ, false) + '_' + name
return error('none') if g.table.sym(unwrapped_rec_typ).kind == .placeholder {
name = name.replace_each(['[', '_T_', ']', ''])
} }
name = g.cc_type(node.receiver.typ, false) + '_' + name
} }
if node.language == .c { if node.language == .c {
name = util.no_dots(name) name = util.no_dots(name)
@ -605,7 +605,7 @@ fn (mut g Gen) fn_decl_params(params []ast.Param, scope &ast.Scope, is_variadic
typ = g.table.sym(typ).array_info().elem_type.set_flag(.variadic) typ = g.table.sym(typ).array_info().elem_type.set_flag(.variadic)
} }
param_type_sym := g.table.sym(typ) param_type_sym := g.table.sym(typ)
mut param_type_name := g.typ(typ) // util.no_dots(param_type_sym.name) mut param_type_name := g.typ(typ).replace_each(['[', '_T_', ']', ''])
if param_type_sym.kind == .function && !typ.has_flag(.option) { if param_type_sym.kind == .function && !typ.has_flag(.option) {
info := param_type_sym.info as ast.FnType info := param_type_sym.info as ast.FnType
func := info.func func := info.func

View File

@ -0,0 +1,26 @@
pub struct Generic[D] {
pub mut:
field D
}
pub fn (j Generic[D]) foo() D {
return j.field
}
pub fn new_generic[T](field T) Generic[T] {
return Generic[T]{
field: field
}
}
fn test_generic_struct_with_inconsistent_generic_types() {
my_generic1 := new_generic[int](2)
r1 := my_generic1.foo()
println(r1)
assert r1 == 2
my_generic2 := new_generic[string]('hello')
r2 := my_generic2.foo()
println(r2)
assert r2 == 'hello'
}