diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index ae68b0ece8..20d5020342 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -642,6 +642,13 @@ fn (mut c Checker) fail_if_immutable(expr_ ast.Expr) (string, token.Pos) { return '', expr.pos } ast.ComptimeSelector { + if mut expr.left is ast.Ident { + if mut expr.left.obj is ast.Var { + if expr.left.obj.ct_type_var != .generic_param { + c.fail_if_immutable(expr.left) + } + } + } return '', expr.pos } ast.Ident { diff --git a/vlib/v/checker/tests/comptime_assign_missing_mut_err.out b/vlib/v/checker/tests/comptime_assign_missing_mut_err.out new file mode 100644 index 0000000000..1ece9e3d45 --- /dev/null +++ b/vlib/v/checker/tests/comptime_assign_missing_mut_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/comptime_assign_missing_mut_err.vv:13:4: error: `res` is immutable, declare it with `mut` to make it mutable + 11 | val := doc.value(field.name) + 12 | $if field.typ is string { + 13 | res.$(field.name) = val.string() + | ~~~ + 14 | } + 15 | } \ No newline at end of file diff --git a/vlib/v/checker/tests/comptime_assign_missing_mut_err.vv b/vlib/v/checker/tests/comptime_assign_missing_mut_err.vv new file mode 100644 index 0000000000..acf91f62ee --- /dev/null +++ b/vlib/v/checker/tests/comptime_assign_missing_mut_err.vv @@ -0,0 +1,21 @@ +import toml + +struct Person { + name string +} + +fn decode[T](toml_str string) !T { + res := T{} + doc := toml.parse_text(toml_str)!.to_any() + $for field in T.fields { + val := doc.value(field.name) + $if field.typ is string { + res.$(field.name) = val.string() + } + } + return res +} + +p_str := 'name = "John"' + +decode[Person](p_str)!