diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index 38244f88b6..a4b769c952 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -376,8 +376,12 @@ 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 { + if p.inside_fn_return { + p.error_with_pos('cannot use `mut` on fn return type', p.tok.pos()) + } else if p.inside_struct_field_decl { + p.error_with_pos('cannot use `mut` on struct field type', p.tok.pos()) + } } if p.tok.kind == .key_mut || is_shared || is_atomic { nr_muls++ diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 5608996559..f19384aca8 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -54,8 +54,9 @@ mut: inside_asm_template bool inside_asm bool inside_defer bool - inside_generic_params bool // indicates if parsing between `<` and `>` of a method/function - inside_receiver_param bool // indicates if parsing the receiver parameter inside the first `(` and `)` of a method + inside_generic_params bool // indicates if parsing between `<` and `>` of a method/function + inside_receiver_param bool // indicates if parsing the receiver parameter inside the first `(` and `)` of a method + inside_struct_field_decl bool or_is_handled bool // ignore `or` in this expression builtin_mod bool // are we in the `builtin` module? mod string // current module name diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index 819ec7e3ec..9ef473eae0 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -223,7 +223,9 @@ fn (mut p Parser) struct_decl() ast.StructDecl { break } } + p.inside_struct_field_decl = true typ = p.parse_type() + p.inside_struct_field_decl = false if typ.idx() == 0 { // error is set in parse_type return ast.StructDecl{} diff --git a/vlib/v/parser/tests/struct_field_mut_type_err.out b/vlib/v/parser/tests/struct_field_mut_type_err.out new file mode 100644 index 0000000000..03e984bee0 --- /dev/null +++ b/vlib/v/parser/tests/struct_field_mut_type_err.out @@ -0,0 +1,7 @@ +vlib/v/parser/tests/struct_field_mut_type_err.vv:3:6: error: cannot use `mut` on struct field type + 1 | struct Foo { + 2 | mut: + 3 | foo mut string + | ~~~ + 4 | } + 5 | diff --git a/vlib/v/parser/tests/struct_field_mut_type_err.vv b/vlib/v/parser/tests/struct_field_mut_type_err.vv new file mode 100644 index 0000000000..c5b14d83e3 --- /dev/null +++ b/vlib/v/parser/tests/struct_field_mut_type_err.vv @@ -0,0 +1,9 @@ +struct Foo { +mut: + foo mut string +} + +fn main() { + f := Foo{} + println(f) +}