diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 3d2c80654a..546162f7d7 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -5501,6 +5501,9 @@ pub fn (mut c Checker) map_init(mut node ast.MapInit) table.Type { node.key_type = info.key_type node.value_type = info.value_type 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 @@ -5512,44 +5515,47 @@ pub fn (mut c Checker) map_init(mut node ast.MapInit) table.Type { node.value_type = info.value_type return node.typ } - // `{'age': 20}` - mut key0_type := c.table.mktyp(c.expr(node.keys[0])) - 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 + if node.keys.len > 0 && node.vals.len > 0 { + // `{'age': 20}` + mut key0_type := c.table.mktyp(c.expr(node.keys[0])) + if node.keys[0].is_auto_deref_var() { + key0_type = key0_type.deref() } - 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 + mut val0_type := c.table.mktyp(c.expr(node.vals[0])) + if node.vals[0].is_auto_deref_var() { + val0_type = val0_type.deref() } - if !c.check_types(val_type, val0_type) { - msg := c.expected_msg(val_type, val0_type) - c.error('invalid map value: $msg', val.position()) + mut same_key_type := true + for i, key in node.keys { + 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 { - 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 + return node.typ } // call this *before* calling error or warn diff --git a/vlib/v/checker/tests/map_init_invalid_syntax.out b/vlib/v/checker/tests/map_init_invalid_syntax.out new file mode 100644 index 0000000000..e18f40dc95 --- /dev/null +++ b/vlib/v/checker/tests/map_init_invalid_syntax.out @@ -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 | } diff --git a/vlib/v/checker/tests/map_init_invalid_syntax.vv b/vlib/v/checker/tests/map_init_invalid_syntax.vv new file mode 100644 index 0000000000..a976d70a52 --- /dev/null +++ b/vlib/v/checker/tests/map_init_invalid_syntax.vv @@ -0,0 +1,4 @@ +fn main() { + a := map{} + println(a) +}