From 89ac2a37c5c2229290d7bba11929d5db2b4c3cdd Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Wed, 5 Jan 2022 00:37:39 +0200 Subject: [PATCH] checker: add error for `for x in t {`, where `t.next()` returns multiple values (Fix #9459). --- vlib/v/checker/for.v | 4 ++++ .../for_in_iterator_returning_multiple_values_err.out | 7 +++++++ .../for_in_iterator_returning_multiple_values_err.vv | 11 +++++++++++ 3 files changed, 22 insertions(+) create mode 100644 vlib/v/checker/tests/for_in_iterator_returning_multiple_values_err.out create mode 100644 vlib/v/checker/tests/for_in_iterator_returning_multiple_values_err.vv diff --git a/vlib/v/checker/for.v b/vlib/v/checker/for.v index 9dc77045db..6365a9ae57 100644 --- a/vlib/v/checker/for.v +++ b/vlib/v/checker/for.v @@ -61,6 +61,10 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) { if !next_fn.return_type.has_flag(.optional) { c.error('iterator method `next()` must return an optional', node.cond.position()) } + return_sym := c.table.sym(next_fn.return_type) + if return_sym.kind == .multi_return { + c.error('iterator method `next()` must not return multiple values', node.cond.position()) + } // the receiver if next_fn.params.len != 1 { c.error('iterator method `next()` must have 0 parameters', node.cond.position()) diff --git a/vlib/v/checker/tests/for_in_iterator_returning_multiple_values_err.out b/vlib/v/checker/tests/for_in_iterator_returning_multiple_values_err.out new file mode 100644 index 0000000000..658b37938a --- /dev/null +++ b/vlib/v/checker/tests/for_in_iterator_returning_multiple_values_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/for_in_iterator_returning_multiple_values_err.vv:8:10: error: iterator method `next()` must not return multiple values + 6 | + 7 | t := TestStruct{} + 8 | for x in t { + | ^ + 9 | println(x) // ('foo', 'bar') + 10 | break diff --git a/vlib/v/checker/tests/for_in_iterator_returning_multiple_values_err.vv b/vlib/v/checker/tests/for_in_iterator_returning_multiple_values_err.vv new file mode 100644 index 0000000000..e5f471b8c6 --- /dev/null +++ b/vlib/v/checker/tests/for_in_iterator_returning_multiple_values_err.vv @@ -0,0 +1,11 @@ +struct TestStruct {} + +fn (t TestStruct) next() ?(string, string) { + return 'foo', 'bar' +} + +t := TestStruct{} +for x in t { + println(x) // ('foo', 'bar') + break +}