diff --git a/vlib/v/checker/assign.v b/vlib/v/checker/assign.v index 215e0b7b40..784232bdd9 100644 --- a/vlib/v/checker/assign.v +++ b/vlib/v/checker/assign.v @@ -109,7 +109,9 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { if left in [ast.Ident, ast.SelectorExpr] { c.prevent_sum_type_unwrapping_once = true } + c.inside_left_assign = true left_type = c.expr(left) + c.inside_left_assign = false c.expected_type = c.unwrap_generic(left_type) } if node.right_types.len < node.left.len { // first type or multi return types added above diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index b83d121259..29b2aa303c 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -111,7 +111,8 @@ mut: inside_println_arg bool inside_decl_rhs bool inside_if_guard bool // true inside the guard condition of `if x := opt() {}` - comptime_call_pos int // needed for correctly checking use before decl for templates + inside_left_assign bool + comptime_call_pos int // needed for correctly checking use before decl for templates goto_labels map[string]ast.GotoLabel // to check for unused goto labels } @@ -3815,7 +3816,8 @@ fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type { node.pos) } - if !c.inside_unsafe && !c.is_builtin_mod && typ_sym.kind == .map && node.or_expr.stmts.len == 0 { + if !c.inside_unsafe && !c.is_builtin_mod && !c.inside_if_guard && !c.inside_left_assign + && typ_sym.kind == .map && node.or_expr.stmts.len == 0 { elem_type := c.table.value_type(typ) if elem_type.is_real_pointer() { c.note('accessing a pointer map value requires an `or{}` block outside `unsafe`', diff --git a/vlib/v/tests/map_reference_value_test.v b/vlib/v/tests/map_reference_value_test.v new file mode 100644 index 0000000000..6d5680a1ed --- /dev/null +++ b/vlib/v/tests/map_reference_value_test.v @@ -0,0 +1,17 @@ +struct Foo { + bar string +} + +fn test_map_reference_value() { + m1 := map[string]&Foo{} + if e := m1['bar'] { + println(e.bar) + } + println(m1) + + mut m2 := map[string]&Foo{} + m2['bar'] = &Foo{} + println(m2) + + assert true +}