Skip to content

Commit a22a3f7

Browse files
authored
checker: check if next() method infers generic type correctly (fix #23927) (#23932)
1 parent e8c6922 commit a22a3f7

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

vlib/v/checker/for.v

+7
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,13 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) {
156156
node.cond_type = typ
157157
node.kind = sym.kind
158158
node.val_type = val_type
159+
if node.val_type.has_flag(.generic) {
160+
if c.table.sym(c.unwrap_generic(node.val_type)).kind == .any {
161+
c.add_error_detail('type parameters defined by `next()` method should be bounded by method owner type')
162+
c.error('cannot infer from generic type `${c.table.get_type_name(c.unwrap_generic(node.val_type))}`',
163+
node.vv_pos)
164+
}
165+
}
159166
node.scope.update_var_type(node.val_var, val_type)
160167

161168
if is_comptime {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
vlib/v/checker/tests/struct_iter_generic_invalid_infer_err.vv:25:6: error: cannot infer from generic type `K`
2+
23 | }
3+
24 |
4+
25 | for squared in iter {
5+
| ~~~~~~~
6+
26 | println(squared)
7+
27 | }
8+
Details: type parameters defined by `next()` method should be bounded by method owner type
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
module main
2+
3+
struct SquareIterator {
4+
arr []int
5+
mut:
6+
idx int
7+
}
8+
9+
fn (mut iter SquareIterator) next[K]() ?K {
10+
if iter.idx >= iter.arr.len {
11+
return none
12+
}
13+
defer {
14+
iter.idx++
15+
}
16+
return iter.arr[iter.idx] * iter.arr[iter.idx]
17+
}
18+
19+
fn main() {
20+
nums := [1, 2, 3, 4, 5]
21+
iter := SquareIterator{
22+
arr: nums
23+
}
24+
25+
for squared in iter {
26+
println(squared)
27+
}
28+
}

0 commit comments

Comments
 (0)