Skip to content

Commit 2f54c48

Browse files
authored
checker: ensure ?Struct is not parsed as ??Struct when param is ?T (fix #25559) (#25564)
1 parent 43c45d9 commit 2f54c48

2 files changed

Lines changed: 47 additions & 1 deletion

File tree

‎vlib/v/checker/check_types.v‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1030,7 +1030,16 @@ fn (mut c Checker) infer_fn_generic_types(func &ast.Fn, mut node ast.CallExpr) {
10301030
arg := node.args[arg_i]
10311031
param_sym := c.table.sym(param.typ)
10321032

1033-
if param.typ.has_flag(.generic) && param_sym.name == gt_name {
1033+
if (param.typ.has_flag(.option) && arg.typ.has_flag(.option))
1034+
|| (param.typ.has_flag(.result) && arg.typ.has_flag(.result)) {
1035+
param_inner := param.typ.clear_option_and_result()
1036+
if param_inner.has_flag(.generic) && c.table.sym(param_inner).name == gt_name {
1037+
typ = arg.typ.clear_option_and_result()
1038+
if param_inner.nr_muls() > 0 && typ.nr_muls() > 0 {
1039+
typ = typ.set_nr_muls(0)
1040+
}
1041+
}
1042+
} else if param.typ.has_flag(.generic) && param_sym.name == gt_name {
10341043
typ = ast.mktyp(arg.typ)
10351044
if typ == ast.nil_type {
10361045
typ = ast.voidptr_type
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
fn unwrap[T](t ?T) T {
2+
return t or { panic('none') }
3+
}
4+
5+
fn unwrap_or[T](t ?T, t_or T) T {
6+
return t or { t_or }
7+
}
8+
9+
struct S1 {
10+
value int
11+
}
12+
13+
struct S2 {}
14+
15+
fn test_unwrap() {
16+
s1 := ?S1{
17+
value: 42
18+
}
19+
assert unwrap(s1).value == 42
20+
21+
// see #25566
22+
s2 := ?S2(S2{})
23+
assert unwrap(s2) == S2{}
24+
}
25+
26+
fn test_unwrap_or() {
27+
s1 := ?S1{
28+
value: 42
29+
}
30+
assert unwrap_or(s1, S1{ value: 12 }).value == 42
31+
32+
s1n := ?S1(none)
33+
assert unwrap_or(s1n, S1{ value: 12 }).value == 12
34+
35+
s2 := ?S2{}
36+
assert unwrap_or(s2, S2{}) == S2{}
37+
}

0 commit comments

Comments
 (0)