diff --git a/vlib/v/checker/for.v b/vlib/v/checker/for.v index 9ef3e116b3..2b7f7df590 100644 --- a/vlib/v/checker/for.v +++ b/vlib/v/checker/for.v @@ -156,6 +156,13 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) { node.cond_type = typ node.kind = sym.kind node.val_type = val_type + if node.val_type.has_flag(.generic) { + if c.table.sym(c.unwrap_generic(node.val_type)).kind == .any { + c.add_error_detail('type parameters defined by `next()` method should be bounded by method owner type') + c.error('cannot infer from generic type `${c.table.get_type_name(c.unwrap_generic(node.val_type))}`', + node.vv_pos) + } + } node.scope.update_var_type(node.val_var, val_type) if is_comptime { diff --git a/vlib/v/checker/tests/struct_iter_generic_invalid_infer_err.out b/vlib/v/checker/tests/struct_iter_generic_invalid_infer_err.out new file mode 100644 index 0000000000..8b9d8fa137 --- /dev/null +++ b/vlib/v/checker/tests/struct_iter_generic_invalid_infer_err.out @@ -0,0 +1,8 @@ +vlib/v/checker/tests/struct_iter_generic_invalid_infer_err.vv:25:6: error: cannot infer from generic type `K` + 23 | } + 24 | + 25 | for squared in iter { + | ~~~~~~~ + 26 | println(squared) + 27 | } +Details: type parameters defined by `next()` method should be bounded by method owner type diff --git a/vlib/v/checker/tests/struct_iter_generic_invalid_infer_err.vv b/vlib/v/checker/tests/struct_iter_generic_invalid_infer_err.vv new file mode 100644 index 0000000000..8683a57de0 --- /dev/null +++ b/vlib/v/checker/tests/struct_iter_generic_invalid_infer_err.vv @@ -0,0 +1,28 @@ +module main + +struct SquareIterator { + arr []int +mut: + idx int +} + +fn (mut iter SquareIterator) next[K]() ?K { + if iter.idx >= iter.arr.len { + return none + } + defer { + iter.idx++ + } + return iter.arr[iter.idx] * iter.arr[iter.idx] +} + +fn main() { + nums := [1, 2, 3, 4, 5] + iter := SquareIterator{ + arr: nums + } + + for squared in iter { + println(squared) + } +}