diff --git a/vlib/v/checker/tests/option_map_or_unwrap_requires_clone_err.out b/vlib/v/checker/tests/option_map_or_unwrap_requires_clone_err.out new file mode 100644 index 00000000000000..75e5cbfc60d882 --- /dev/null +++ b/vlib/v/checker/tests/option_map_or_unwrap_requires_clone_err.out @@ -0,0 +1,21 @@ +vlib/v/checker/tests/option_map_or_unwrap_requires_clone_err.vv:22:13: error: cannot copy map: call `move` or `clone` method (or use a reference) + 20 | } + 21 | } + 22 | field := c.translations or { panic('none') } + | ~~~~~~~~~~~~ + 23 | + 24 | opt := get_opt() +vlib/v/checker/tests/option_map_or_unwrap_requires_clone_err.vv:25:14: error: cannot copy map: call `move` or `clone` method (or use a reference) + 23 | + 24 | opt := get_opt() + 25 | variable := opt or { panic('none') } + | ~~~ + 26 | + 27 | m := { +vlib/v/checker/tests/option_map_or_unwrap_requires_clone_err.vv:30:18: error: cannot copy map: call `move` or `clone` method (or use a reference) + 28 | 'k': get_opt() + 29 | } + 30 | index := m['k'] or { panic('none') } + | ~~~~~~~~~~~~~~~~~~~~ + 31 | + 32 | println(field) diff --git a/vlib/v/checker/tests/option_map_or_unwrap_requires_clone_err.vv b/vlib/v/checker/tests/option_map_or_unwrap_requires_clone_err.vv new file mode 100644 index 00000000000000..4c2e7195764cbf --- /dev/null +++ b/vlib/v/checker/tests/option_map_or_unwrap_requires_clone_err.vv @@ -0,0 +1,35 @@ +// Or-unwrapping an option map into a new variable is a map copy, so it keeps the +// `cannot copy map` guard just like `m2 := m1`: an immutable binding is not proof +// that the unwrapped map is unaliased (e.g. it can wrap a still-mutable map), so +// V requires an explicit `clone`/`move`, e.g. `x := (c.f or { ... }).clone()`. +// See vlang/v issue #27867. +struct Category { + translations ?map[string]int +} + +fn get_opt() ?map[string]int { + return { + 'a': 1 + } +} + +fn main() { + c := Category{ + translations: { + 'x': 1 + } + } + field := c.translations or { panic('none') } + + opt := get_opt() + variable := opt or { panic('none') } + + m := { + 'k': get_opt() + } + index := m['k'] or { panic('none') } + + println(field) + println(variable) + println(index) +}