v.checker: fix spurious warning for `if x := map_of_sumtypes[k] {}`
parent
7145461cc5
commit
5bc6cc9512
|
@ -73,14 +73,14 @@ pub mut:
|
||||||
returns bool
|
returns bool
|
||||||
scope_returns bool
|
scope_returns bool
|
||||||
mod string // current module name
|
mod string // current module name
|
||||||
is_builtin_mod bool // are we in `builtin`?
|
is_builtin_mod bool // true inside the 'builtin', 'os' or 'strconv' modules; TODO: remove the need for special casing this
|
||||||
inside_unsafe bool
|
inside_unsafe bool // true inside `unsafe {}` blocks
|
||||||
inside_const bool
|
inside_const bool // true inside `const ( ... )` blocks
|
||||||
inside_anon_fn bool
|
inside_anon_fn bool // true inside `fn() { ... }()`
|
||||||
inside_ref_lit bool
|
inside_ref_lit bool // true inside `a := &something`
|
||||||
inside_defer bool
|
inside_defer bool // true inside `defer {}` blocks
|
||||||
inside_fn_arg bool // `a`, `b` in `a.f(b)`
|
inside_fn_arg bool // `a`, `b` in `a.f(b)`
|
||||||
inside_ct_attr bool // true inside [if expr]
|
inside_ct_attr bool // true inside `[if expr]`
|
||||||
skip_flags bool // should `#flag` and `#include` be skipped
|
skip_flags bool // should `#flag` and `#include` be skipped
|
||||||
fn_level int // 0 for the top level, 1 for `fn abc() {}`, 2 for a nested fn, etc
|
fn_level int // 0 for the top level, 1 for `fn abc() {}`, 2 for a nested fn, etc
|
||||||
ct_cond_stack []ast.Expr
|
ct_cond_stack []ast.Expr
|
||||||
|
@ -104,6 +104,7 @@ mut:
|
||||||
inside_selector_expr bool
|
inside_selector_expr bool
|
||||||
inside_println_arg bool
|
inside_println_arg bool
|
||||||
inside_decl_rhs bool
|
inside_decl_rhs bool
|
||||||
|
inside_if_guard bool // true inside the guard condition of `if x := opt() {}`
|
||||||
need_recheck_generic_fns bool // need recheck generic fns because there are cascaded nested generic fn
|
need_recheck_generic_fns bool // need recheck generic fns because there are cascaded nested generic fn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5480,7 +5481,10 @@ pub fn (mut c Checker) expr(node ast.Expr) ast.Type {
|
||||||
return c.if_expr(mut node)
|
return c.if_expr(mut node)
|
||||||
}
|
}
|
||||||
ast.IfGuardExpr {
|
ast.IfGuardExpr {
|
||||||
|
old_inside_if_guard := c.inside_if_guard
|
||||||
|
c.inside_if_guard = true
|
||||||
node.expr_type = c.expr(node.expr)
|
node.expr_type = c.expr(node.expr)
|
||||||
|
c.inside_if_guard = old_inside_if_guard
|
||||||
if !node.expr_type.has_flag(.optional) {
|
if !node.expr_type.has_flag(.optional) {
|
||||||
mut no_opt := true
|
mut no_opt := true
|
||||||
match mut node.expr {
|
match mut node.expr {
|
||||||
|
@ -5997,8 +6001,7 @@ pub fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
|
||||||
if mut obj.expr is ast.IfGuardExpr {
|
if mut obj.expr is ast.IfGuardExpr {
|
||||||
// new variable from if guard shouldn't have the optional flag for further use
|
// new variable from if guard shouldn't have the optional flag for further use
|
||||||
// a temp variable will be generated which unwraps it
|
// a temp variable will be generated which unwraps it
|
||||||
if_guard_var_type := c.expr(obj.expr.expr)
|
typ = obj.expr.expr_type.clear_flag(.optional)
|
||||||
typ = if_guard_var_type.clear_flag(.optional)
|
|
||||||
} else {
|
} else {
|
||||||
typ = c.expr(obj.expr)
|
typ = c.expr(obj.expr)
|
||||||
}
|
}
|
||||||
|
@ -7462,7 +7465,7 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type {
|
||||||
}
|
}
|
||||||
value_sym := c.table.get_type_symbol(info.value_type)
|
value_sym := c.table.get_type_symbol(info.value_type)
|
||||||
if !node.is_setter && value_sym.kind == .sum_type && node.or_expr.kind == .absent
|
if !node.is_setter && value_sym.kind == .sum_type && node.or_expr.kind == .absent
|
||||||
&& !c.inside_unsafe {
|
&& !c.inside_unsafe && !c.inside_if_guard {
|
||||||
c.warn('`or {}` block required when indexing a map with sum type value',
|
c.warn('`or {}` block required when indexing a map with sum type value',
|
||||||
node.pos)
|
node.pos)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
vlib/v/checker/tests/require_or_block_sumtype_map.err.vv:5:8: error: `or {}` block required when indexing a map with sum type value
|
vlib/v/checker/tests/require_or_block_sumtype_map.err.vv:8:8: error: `or {}` block required when indexing a map with sum type value
|
||||||
3 | fn main() {
|
6 | println(y)
|
||||||
4 | x := map[string]Abc{}
|
7 | }
|
||||||
5 | _ := x['nonexisting']
|
8 | _ := x['nonexisting']
|
||||||
| ~~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~~
|
||||||
6 | }
|
9 | }
|
||||||
|
|
|
@ -2,5 +2,8 @@ type Abc = string | int
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
x := map[string]Abc{}
|
x := map[string]Abc{}
|
||||||
|
if y := x['nonexisting'] {
|
||||||
|
println(y)
|
||||||
|
}
|
||||||
_ := x['nonexisting']
|
_ := x['nonexisting']
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
// NB: this test should be able to run without warnings/errors
|
||||||
|
|
||||||
|
type SumType = bool | int | string
|
||||||
|
|
||||||
|
fn test_reading_from_a_map_of_sumtype_values() {
|
||||||
|
mut values := map[string]SumType{}
|
||||||
|
values['abc'] = 'xyz'
|
||||||
|
values['xyz'] = 123
|
||||||
|
values['xxx'] = true
|
||||||
|
println(unsafe { values['abcz'] }) // no warning/error, due to the unsafe{}
|
||||||
|
if value := values['abc'] {
|
||||||
|
eprintln('existing key `abc` is present, value: $value')
|
||||||
|
assert true
|
||||||
|
}
|
||||||
|
if (values['abc'] or { 'zzzz' }) is string {
|
||||||
|
eprintln('existing key `abc` is present, value is a string')
|
||||||
|
assert true
|
||||||
|
}
|
||||||
|
if (values['abc'] or { 123 }) is int {
|
||||||
|
eprintln('the existing keyed value is an int')
|
||||||
|
assert false
|
||||||
|
}
|
||||||
|
if (values['something else'] or { 'zzzz' }) is string {
|
||||||
|
eprintln('default value for non existing key is a string')
|
||||||
|
assert true
|
||||||
|
}
|
||||||
|
if (values['something else'] or { 123 }) is int {
|
||||||
|
eprintln('default value for non existing key is an int')
|
||||||
|
assert true
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue