checker: fix `map = {}` (#8435)

pull/8441/head
yuyi 2021-01-30 18:55:10 +08:00 committed by GitHub
parent dad68e00d5
commit 77b3d40f46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 9 deletions

View File

@ -243,7 +243,7 @@ fn test_delete_size() {
for i in 0 .. 10 { for i in 0 .. 10 {
m[arr[i]] = i m[arr[i]] = i
} }
assert (m.len == 10) assert m.len == 10
println(m.len) println(m.len)
for i in 0 .. 10 { for i in 0 .. 10 {
m.delete(arr[i]) m.delete(arr[i])
@ -485,7 +485,11 @@ fn test_int_keys() {
m[5] += 24 m[5] += 24
m[5]++ m[5]++
assert m[5] == 25 assert m[5] == 25
m2 := {3:9 4:16 5:25} m2 := {
3: 9
4: 16
5: 25
}
assert m2.len == 3 assert m2.len == 3
// clone // clone
mc := m.clone() mc := m.clone()
@ -513,7 +517,10 @@ fn test_voidptr_keys() {
} }
fn test_rune_keys() { fn test_rune_keys() {
mut m := {`!`:2 `%`:3} mut m := {
`!`: 2
`%`: 3
}
assert typeof(m).name == 'map[rune]int' assert typeof(m).name == 'map[rune]int'
assert m[`!`] == 2 assert m[`!`] == 2
m[`@`] = 7 m[`@`] = 7
@ -593,7 +600,25 @@ fn test_eq() {
} }
fn test_non_string_key_map_str() { fn test_non_string_key_map_str() {
assert {23: 4}.str() == '{23: 4}' assert {
assert {`a`: 12, `b`: 13}.str() == '{`a`: 12, `b`: 13}' 23: 4
assert {23: 'foo', 25: 'bar'}.str() == "{23: 'foo', 25: 'bar'}" }.str() == '{23: 4}'
assert {
`a`: 12
`b`: 13
}.str() == '{`a`: 12, `b`: 13}'
assert {
23: 'foo'
25: 'bar'
}.str() == "{23: 'foo', 25: 'bar'}"
}
fn test_map_assign_empty_map_init() {
mut a := {
'one': 1
}
a = {}
println(a)
assert a == map[string]int{}
assert '$a' == '{}'
} }

View File

@ -784,12 +784,12 @@ pub:
// variable assign statement // variable assign statement
pub struct AssignStmt { pub struct AssignStmt {
pub: pub:
right []Expr
op token.Kind // include: =,:=,+=,-=,*=,/= and so on; for a list of all the assign operators, see vlib/token/token.v op token.Kind // include: =,:=,+=,-=,*=,/= and so on; for a list of all the assign operators, see vlib/token/token.v
pos token.Position pos token.Position
comments []Comment comments []Comment
end_comments []Comment end_comments []Comment
pub mut: pub mut:
right []Expr
left []Expr left []Expr
left_types []table.Type left_types []table.Type
right_types []table.Type right_types []table.Type

View File

@ -2437,6 +2437,11 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
} }
left_type = c.expr(left) left_type = c.expr(left)
c.expected_type = c.unwrap_generic(left_type) c.expected_type = c.unwrap_generic(left_type)
// `map = {}`
sym := c.table.get_type_symbol(left_type)
if sym.kind == .map && assign_stmt.right[i] is ast.StructInit {
assign_stmt.right[i] = ast.MapInit{}
}
} }
if assign_stmt.right_types.len < assign_stmt.left.len { // first type or multi return types added above if assign_stmt.right_types.len < assign_stmt.left.len { // first type or multi return types added above
right_type := c.expr(assign_stmt.right[i]) right_type := c.expr(assign_stmt.right[i])
@ -5065,6 +5070,17 @@ pub fn (mut c Checker) check_dup_keys(node &ast.MapInit, i int) {
} }
pub fn (mut c Checker) map_init(mut node ast.MapInit) table.Type { pub fn (mut c Checker) map_init(mut node ast.MapInit) table.Type {
// `map = {}`
if node.keys.len == 0 && node.vals.len == 0 && node.typ == 0 {
sym := c.table.get_type_symbol(c.expected_type)
if sym.kind == .map {
info := sym.map_info()
node.typ = c.expected_type
node.key_type = info.key_type
node.value_type = info.value_type
return node.typ
}
}
// `x := map[string]string` - set in parser // `x := map[string]string` - set in parser
if node.typ != 0 { if node.typ != 0 {
info := c.table.get_type_symbol(node.typ).map_info() info := c.table.get_type_symbol(node.typ).map_info()