Skip to content

Commit 2b43d31

Browse files
authored
checker: fix generics with assign generics struct (fix #7784) (#9889)
1 parent 181b0f1 commit 2b43d31

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

vlib/v/checker/checker.v

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,11 +1632,6 @@ pub fn (mut c Checker) method_call(mut call_expr ast.CallExpr) ast.Type {
16321632
c.error('expected $nr_args arguments, but got $call_expr.args.len', unexpected_arguments_pos)
16331633
return method.return_type
16341634
}
1635-
if method.generic_names.len > 0 && method.return_type.has_flag(.generic) {
1636-
c.check_return_generics_struct(method.return_type, mut call_expr, concrete_types)
1637-
} else {
1638-
call_expr.return_type = method.return_type
1639-
}
16401635
mut exp_arg_typ := ast.Type(0) // type of 1st arg for special builtin methods
16411636
mut param_is_mut := false
16421637
mut no_type_promotion := false
@@ -1761,6 +1756,12 @@ pub fn (mut c Checker) method_call(mut call_expr ast.CallExpr) ast.Type {
17611756
// no type arguments given in call, attempt implicit instantiation
17621757
c.infer_fn_generic_types(method, mut call_expr)
17631758
}
1759+
// resolve return generics struct to concrete type
1760+
if method.generic_names.len > 0 && method.return_type.has_flag(.generic) {
1761+
c.check_return_generics_struct(method.return_type, mut call_expr, call_expr.concrete_types)
1762+
} else {
1763+
call_expr.return_type = method.return_type
1764+
}
17641765
if call_expr.concrete_types.len > 0 && method.return_type != 0 {
17651766
if typ := c.table.resolve_generic_to_concrete(method.return_type, method.generic_names,
17661767
call_expr.concrete_types)
@@ -2127,11 +2128,6 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type {
21272128
call_expr.pos)
21282129
return func.return_type
21292130
}
2130-
if func.generic_names.len > 0 && func.return_type.has_flag(.generic) {
2131-
c.check_return_generics_struct(func.return_type, mut call_expr, concrete_types)
2132-
} else {
2133-
call_expr.return_type = func.return_type
2134-
}
21352131
if func.return_type == ast.void_type && func.ctdefine.len > 0
21362132
&& func.ctdefine !in c.pref.compile_defines {
21372133
call_expr.should_be_skipped = true
@@ -2293,6 +2289,12 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type {
22932289
}
22942290
}
22952291
}
2292+
// resolve return generics struct to concrete type
2293+
if func.generic_names.len > 0 && func.return_type.has_flag(.generic) {
2294+
c.check_return_generics_struct(func.return_type, mut call_expr, call_expr.concrete_types)
2295+
} else {
2296+
call_expr.return_type = func.return_type
2297+
}
22962298
if call_expr.concrete_types.len > 0 && func.return_type != 0 {
22972299
if typ := c.table.resolve_generic_to_concrete(func.return_type, func.generic_names,
22982300
call_expr.concrete_types)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
struct Test<T> {
2+
v T
3+
}
4+
5+
fn get_test<T>(v T) Test<T> {
6+
return Test{
7+
v: v
8+
}
9+
}
10+
11+
fn test_generics_assign_generics_struct() {
12+
x := get_test(1)
13+
println('$x.v')
14+
assert x.v == 1
15+
}

0 commit comments

Comments
 (0)