checker: check empty map invalid syntax (fix #9162) (#9186)

pull/9199/head
yuyi 2021-03-09 01:48:17 +08:00 committed by GitHub
parent 9a7d9e047b
commit 10c9f61d61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 34 deletions

View File

@ -5501,6 +5501,9 @@ pub fn (mut c Checker) map_init(mut node ast.MapInit) table.Type {
node.key_type = info.key_type node.key_type = info.key_type
node.value_type = info.value_type node.value_type = info.value_type
return node.typ return node.typ
} else {
c.error('invalid empty map initilization syntax, use e.g. map[string]int{} instead',
node.pos)
} }
} }
// `x := map[string]string` - set in parser // `x := map[string]string` - set in parser
@ -5512,44 +5515,47 @@ pub fn (mut c Checker) map_init(mut node ast.MapInit) table.Type {
node.value_type = info.value_type node.value_type = info.value_type
return node.typ return node.typ
} }
// `{'age': 20}` if node.keys.len > 0 && node.vals.len > 0 {
mut key0_type := c.table.mktyp(c.expr(node.keys[0])) // `{'age': 20}`
if node.keys[0].is_auto_deref_var() { mut key0_type := c.table.mktyp(c.expr(node.keys[0]))
key0_type = key0_type.deref() if node.keys[0].is_auto_deref_var() {
} key0_type = key0_type.deref()
mut val0_type := c.table.mktyp(c.expr(node.vals[0]))
if node.vals[0].is_auto_deref_var() {
val0_type = val0_type.deref()
}
mut same_key_type := true
for i, key in node.keys {
if i == 0 {
continue
} }
val := node.vals[i] mut val0_type := c.table.mktyp(c.expr(node.vals[0]))
key_type := c.expr(key) if node.vals[0].is_auto_deref_var() {
c.expected_type = val0_type val0_type = val0_type.deref()
val_type := c.expr(val)
if !c.check_types(key_type, key0_type) {
msg := c.expected_msg(key_type, key0_type)
c.error('invalid map key: $msg', key.position())
same_key_type = false
} }
if !c.check_types(val_type, val0_type) { mut same_key_type := true
msg := c.expected_msg(val_type, val0_type) for i, key in node.keys {
c.error('invalid map value: $msg', val.position()) if i == 0 {
continue
}
val := node.vals[i]
key_type := c.expr(key)
c.expected_type = val0_type
val_type := c.expr(val)
if !c.check_types(key_type, key0_type) {
msg := c.expected_msg(key_type, key0_type)
c.error('invalid map key: $msg', key.position())
same_key_type = false
}
if !c.check_types(val_type, val0_type) {
msg := c.expected_msg(val_type, val0_type)
c.error('invalid map value: $msg', val.position())
}
} }
if same_key_type {
for i in 1 .. node.keys.len {
c.check_dup_keys(node, i)
}
}
map_type := table.new_type(c.table.find_or_register_map(key0_type, val0_type))
node.typ = map_type
node.key_type = key0_type
node.value_type = val0_type
return map_type
} }
if same_key_type { return node.typ
for i in 1 .. node.keys.len {
c.check_dup_keys(node, i)
}
}
map_type := table.new_type(c.table.find_or_register_map(key0_type, val0_type))
node.typ = map_type
node.key_type = key0_type
node.value_type = val0_type
return map_type
} }
// call this *before* calling error or warn // call this *before* calling error or warn

View File

@ -0,0 +1,6 @@
vlib/v/checker/tests/map_init_invalid_syntax.vv:2:10: error: invalid empty map initilization syntax, use e.g. map[string]int{} instead
1 | fn main() {
2 | a := map{}
| ~~
3 | println(a)
4 | }

View File

@ -0,0 +1,4 @@
fn main() {
a := map{}
println(a)
}