From bc16c61f6f29c228a9bbc7887e971c77b8fbcacf Mon Sep 17 00:00:00 2001 From: yuyi Date: Sun, 27 Feb 2022 20:23:43 +0800 Subject: [PATCH] parser: check using 'mut' on fn_decl return type (#13610) --- vlib/v/parser/fn.v | 2 ++ vlib/v/parser/parse_type.v | 3 +++ vlib/v/parser/parser.v | 1 + vlib/v/parser/tests/fn_decl_return_type_err_a.out | 7 +++++++ vlib/v/parser/tests/fn_decl_return_type_err_a.vv | 9 +++++++++ vlib/v/parser/tests/fn_decl_return_type_err_b.out | 7 +++++++ vlib/v/parser/tests/fn_decl_return_type_err_b.vv | 9 +++++++++ 7 files changed, 38 insertions(+) create mode 100644 vlib/v/parser/tests/fn_decl_return_type_err_a.out create mode 100644 vlib/v/parser/tests/fn_decl_return_type_err_a.vv create mode 100644 vlib/v/parser/tests/fn_decl_return_type_err_b.out create mode 100644 vlib/v/parser/tests/fn_decl_return_type_err_b.vv diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 4d30f4d57f..26a663342e 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -353,7 +353,9 @@ fn (mut p Parser) fn_decl() ast.FnDecl { same_line := p.tok.line_nr == p.prev_tok.line_nr if (p.tok.kind.is_start_of_type() && (same_line || p.tok.kind != .lsbr)) || (same_line && p.tok.kind == .key_fn) { + p.inside_fn_return = true return_type = p.parse_type() + p.inside_fn_return = false return_type_pos = return_type_pos.extend(p.prev_tok.pos()) } mut type_sym_method_idx := 0 diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index af4b58ca3f..0adbeb8e2f 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -376,6 +376,9 @@ pub fn (mut p Parser) parse_type() ast.Type { p.register_auto_import('sync') } mut nr_muls := 0 + if p.inside_fn_return && p.tok.kind == .key_mut { + p.error_with_pos('cannot use `mut` on fn return type', p.tok.pos()) + } if p.tok.kind == .key_mut || is_shared || is_atomic { nr_muls++ p.next() diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 600bbbff7a..764ef19b7f 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -40,6 +40,7 @@ mut: inside_or_expr bool inside_for bool inside_fn bool // true even with implicit main + inside_fn_return bool inside_unsafe_fn bool inside_str_interp bool inside_array_lit bool diff --git a/vlib/v/parser/tests/fn_decl_return_type_err_a.out b/vlib/v/parser/tests/fn_decl_return_type_err_a.out new file mode 100644 index 0000000000..5f8f5260a4 --- /dev/null +++ b/vlib/v/parser/tests/fn_decl_return_type_err_a.out @@ -0,0 +1,7 @@ +vlib/v/parser/tests/fn_decl_return_type_err_a.vv:3:13: error: cannot use `mut` on fn return type + 1 | struct Foo{} + 2 | + 3 | fn maker() ?mut Foo { + | ~~~ + 4 | inner := &Foo{} + 5 | return *inner diff --git a/vlib/v/parser/tests/fn_decl_return_type_err_a.vv b/vlib/v/parser/tests/fn_decl_return_type_err_a.vv new file mode 100644 index 0000000000..fc1774d9f5 --- /dev/null +++ b/vlib/v/parser/tests/fn_decl_return_type_err_a.vv @@ -0,0 +1,9 @@ +struct Foo{} + +fn maker() ?mut Foo { + inner := &Foo{} + return *inner +} + +fn main() { +} diff --git a/vlib/v/parser/tests/fn_decl_return_type_err_b.out b/vlib/v/parser/tests/fn_decl_return_type_err_b.out new file mode 100644 index 0000000000..7fe7e8dde7 --- /dev/null +++ b/vlib/v/parser/tests/fn_decl_return_type_err_b.out @@ -0,0 +1,7 @@ +vlib/v/parser/tests/fn_decl_return_type_err_b.vv:3:13: error: cannot use `mut` on fn return type + 1 | struct Foo{} + 2 | + 3 | fn maker() (mut Foo) { + | ~~~ + 4 | inner := &Foo{} + 5 | return *inner diff --git a/vlib/v/parser/tests/fn_decl_return_type_err_b.vv b/vlib/v/parser/tests/fn_decl_return_type_err_b.vv new file mode 100644 index 0000000000..2b89efad64 --- /dev/null +++ b/vlib/v/parser/tests/fn_decl_return_type_err_b.vv @@ -0,0 +1,9 @@ +struct Foo{} + +fn maker() (mut Foo) { + inner := &Foo{} + return *inner +} + +fn main() { +}