Skip to content

Commit e93c344

Browse files
authored
checker: fix generic option array arg passing to []T (fix #24423) (#24457)
1 parent 2dd7de4 commit e93c344

2 files changed

Lines changed: 43 additions & 0 deletions

File tree

‎vlib/v/checker/fn.v‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1852,6 +1852,12 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
18521852
c.handle_generic_lambda_arg(node, mut call_arg.expr)
18531853
continue
18541854
}
1855+
// passing []?T to []T
1856+
if !unwrap_typ.has_flag(.variadic) && unwrap_sym.kind == .array
1857+
&& c.table.final_sym(utyp).kind == .array
1858+
&& c.check_basic(c.table.value_type(utyp).clear_flag(.option), c.table.value_type(unwrap_typ)) {
1859+
continue
1860+
}
18551861
c.error('${err.msg()} in argument ${i + 1} to `${fn_name}`', call_arg.pos)
18561862
}
18571863
}
@@ -2607,6 +2613,12 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool)
26072613
continue
26082614
}
26092615
}
2616+
// passing []?T to []T
2617+
if !exp_arg_typ.has_flag(.variadic) && param_typ_sym.kind == .array
2618+
&& c.table.final_sym(got_arg_typ).kind == .array
2619+
&& c.check_basic(c.table.value_type(got_arg_typ).clear_flag(.option), c.table.value_type(exp_arg_typ)) {
2620+
continue
2621+
}
26102622
c.error('${err.msg()} in argument ${i + 1} to `${left_sym.name}.${method_name}`',
26112623
arg.pos)
26122624
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
struct Decoder {}
2+
3+
pub fn decode[T](val string) !T {
4+
mut decoder := Decoder{}
5+
mut result := T{}
6+
decoder.decode_value(mut result)!
7+
return result
8+
}
9+
10+
fn (mut decoder Decoder) decode_value[T](mut val T) ! {
11+
$if T.unaliased_typ is $array {
12+
// checking wrongly. `decode_array` think that `[]?int` is `[]int`
13+
decoder.decode_array(mut val)!
14+
return
15+
} $else $if T.unaliased_typ is $struct {
16+
$for field in T.fields {
17+
decoder.decode_value(mut val.$(field.name))!
18+
}
19+
}
20+
}
21+
22+
fn (mut decoder Decoder) decode_array[T](mut val []T) ! {}
23+
24+
struct Foo {
25+
int []int
26+
oint []?int
27+
}
28+
29+
fn test_main() {
30+
decode[Foo]('')!
31+
}

0 commit comments

Comments
 (0)