Skip to content

Commit bc16c61

Browse files
authored
parser: check using 'mut' on fn_decl return type (#13610)
1 parent 0fb1eae commit bc16c61

File tree

7 files changed

+38
-0
lines changed

7 files changed

+38
-0
lines changed

vlib/v/parser/fn.v

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,9 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
353353
same_line := p.tok.line_nr == p.prev_tok.line_nr
354354
if (p.tok.kind.is_start_of_type() && (same_line || p.tok.kind != .lsbr))
355355
|| (same_line && p.tok.kind == .key_fn) {
356+
p.inside_fn_return = true
356357
return_type = p.parse_type()
358+
p.inside_fn_return = false
357359
return_type_pos = return_type_pos.extend(p.prev_tok.pos())
358360
}
359361
mut type_sym_method_idx := 0

vlib/v/parser/parse_type.v

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,9 @@ pub fn (mut p Parser) parse_type() ast.Type {
376376
p.register_auto_import('sync')
377377
}
378378
mut nr_muls := 0
379+
if p.inside_fn_return && p.tok.kind == .key_mut {
380+
p.error_with_pos('cannot use `mut` on fn return type', p.tok.pos())
381+
}
379382
if p.tok.kind == .key_mut || is_shared || is_atomic {
380383
nr_muls++
381384
p.next()

vlib/v/parser/parser.v

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ mut:
4040
inside_or_expr bool
4141
inside_for bool
4242
inside_fn bool // true even with implicit main
43+
inside_fn_return bool
4344
inside_unsafe_fn bool
4445
inside_str_interp bool
4546
inside_array_lit bool
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
vlib/v/parser/tests/fn_decl_return_type_err_a.vv:3:13: error: cannot use `mut` on fn return type
2+
1 | struct Foo{}
3+
2 |
4+
3 | fn maker() ?mut Foo {
5+
| ~~~
6+
4 | inner := &Foo{}
7+
5 | return *inner
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
struct Foo{}
2+
3+
fn maker() ?mut Foo {
4+
inner := &Foo{}
5+
return *inner
6+
}
7+
8+
fn main() {
9+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
vlib/v/parser/tests/fn_decl_return_type_err_b.vv:3:13: error: cannot use `mut` on fn return type
2+
1 | struct Foo{}
3+
2 |
4+
3 | fn maker() (mut Foo) {
5+
| ~~~
6+
4 | inner := &Foo{}
7+
5 | return *inner
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
struct Foo{}
2+
3+
fn maker() (mut Foo) {
4+
inner := &Foo{}
5+
return *inner
6+
}
7+
8+
fn main() {
9+
}

0 commit comments

Comments
 (0)