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 {
m[arr[i]] = i
}
assert (m.len == 10)
assert m.len == 10
println(m.len)
for i in 0 .. 10 {
m.delete(arr[i])
@ -485,14 +485,18 @@ fn test_int_keys() {
m[5] += 24
m[5]++
assert m[5] == 25
m2 := {3:9 4:16 5:25}
m2 := {
3: 9
4: 16
5: 25
}
assert m2.len == 3
// clone
mc := m.clone()
same := mc == m
assert same
assert mc.len == 3
assert mc.keys() == [3,4,5]
assert mc.keys() == [3, 4, 5]
mut all := []int{}
for k, v in mc {
assert m[k] == v
@ -513,14 +517,17 @@ fn test_voidptr_keys() {
}
fn test_rune_keys() {
mut m := {`!`:2 `%`:3}
mut m := {
`!`: 2
`%`: 3
}
assert typeof(m).name == 'map[rune]int'
assert m[`!`] == 2
m[`@`] = 7
assert m.len == 3
println(m)
assert '$m' == '{`!`: 2, `%`: 3, `@`: 7}'
mut a := []rune{}
for k, v in m {
a << k
@ -593,7 +600,25 @@ fn test_eq() {
}
fn test_non_string_key_map_str() {
assert {23: 4}.str() == '{23: 4}'
assert {`a`: 12, `b`: 13}.str() == '{`a`: 12, `b`: 13}'
assert {23: 'foo', 25: 'bar'}.str() == "{23: 'foo', 25: 'bar'}"
assert {
23: 4
}.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
pub struct AssignStmt {
pub:
right []Expr
op token.Kind // include: =,:=,+=,-=,*=,/= and so on; for a list of all the assign operators, see vlib/token/token.v
pos token.Position
comments []Comment
end_comments []Comment
pub mut:
right []Expr
left []Expr
left_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)
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
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 {
// `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
if node.typ != 0 {
info := c.table.get_type_symbol(node.typ).map_info()