Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
fa25149
checker: fix or-unwrapping an option map field/var/index (fix #27867)
medvednikov Jul 19, 2026
756eced
checker: address review — only relax the map-copy guard for immutable…
medvednikov Jul 19, 2026
2a6f7dd
checker: address review — only exempt or-unwrap that clears the option
medvednikov Jul 19, 2026
8c4713c
checker: address review — keep map-copy guard for mutable option sources
medvednikov Jul 19, 2026
66afd39
tests: use the review's exact mutable-source form in the alias regres…
medvednikov Jul 19, 2026
b870fb7
checker: reject or-unwrap through immutable pointers to mutable data
medvednikov Jul 19, 2026
6448418
checker: never exempt shared/atomic or-unwrap destinations from map-c…
medvednikov Jul 19, 2026
e65b20e
checker: keep map-copy guard when or-block default returns a mutable …
medvednikov Jul 19, 2026
5e63eb7
checker: unalias types before the or-unwrap pointer check
medvednikov Jul 19, 2026
b599c51
checker: only exempt fresh/owned or-block map defaults, not immutable…
medvednikov Jul 19, 2026
8f35843
checker: filter semicolons and tighten or-block default classification
medvednikov Jul 19, 2026
6565262
checker: only exempt fresh/noreturn or-block map call defaults
medvednikov Jul 19, 2026
b82d49b
checker: restrict fresh or-block clone/move defaults to builtin map ops
medvednikov Jul 19, 2026
01d21af
checker: require direct map receiver for fresh or-block clone/move de…
medvednikov Jul 19, 2026
c31f53b
checker: strip parens before classifying or-block map defaults
medvednikov Jul 19, 2026
73ce15c
checker: revert unsound option-map or-unwrap exemption; require clone…
medvednikov Jul 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions vlib/v/checker/tests/option_map_or_unwrap_requires_clone_err.out
Original file line number Diff line number Diff line change
@@ -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)
35 changes: 35 additions & 0 deletions vlib/v/checker/tests/option_map_or_unwrap_requires_clone_err.vv
Original file line number Diff line number Diff line change
@@ -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)
}
Loading