checker: fix `for in mut val` for floats (#10470)

pull/10477/head
yuyi 2021-06-16 09:04:31 +08:00 committed by GitHub
parent c3b9336f21
commit ffcc6cf6d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 9 deletions

View File

@ -1156,8 +1156,7 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
c.error('mismatched types `$left_name` and `$right_name`', left_right_pos) c.error('mismatched types `$left_name` and `$right_name`', left_right_pos)
} }
} }
} else if (left_sym.kind == .string && !left_type.has_flag(.optional)) } else if node.left.is_auto_deref_var() || node.right.is_auto_deref_var() {
|| (right_sym.kind == .string && !right_type.has_flag(.optional)) {
deref_left_type := if node.left.is_auto_deref_var() { deref_left_type := if node.left.is_auto_deref_var() {
left_type.deref() left_type.deref()
} else { } else {
@ -1168,8 +1167,8 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
} else { } else {
right_type right_type
} }
left_name := c.table.type_to_str(deref_left_type) left_name := c.table.type_to_str(c.table.mktyp(deref_left_type))
right_name := c.table.type_to_str(deref_right_type) right_name := c.table.type_to_str(c.table.mktyp(deref_right_type))
if left_name != right_name { if left_name != right_name {
c.error('mismatched types `$left_name` and `$right_name`', left_right_pos) c.error('mismatched types `$left_name` and `$right_name`', left_right_pos)
} }
@ -1374,7 +1373,7 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
} }
// Dual sides check (compatibility check) // Dual sides check (compatibility check)
if !(c.symmetric_check(left_type, right_type) && c.symmetric_check(right_type, left_type)) if !(c.symmetric_check(left_type, right_type) && c.symmetric_check(right_type, left_type))
&& !c.pref.translated { && !c.pref.translated && !node.left.is_auto_deref_var() && !node.right.is_auto_deref_var() {
// for type-unresolved consts // for type-unresolved consts
if left_type == ast.void_type || right_type == ast.void_type { if left_type == ast.void_type || right_type == ast.void_type {
return ast.void_type return ast.void_type
@ -3619,8 +3618,8 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
} }
} }
} }
if !is_blank_ident && !right.is_auto_deref_var() && right_sym.kind != .placeholder if !is_blank_ident && !left.is_auto_deref_var() && !right.is_auto_deref_var()
&& left_sym.kind != .interface_ { && right_sym.kind != .placeholder && left_sym.kind != .interface_ {
// Dual sides check (compatibility check) // Dual sides check (compatibility check)
c.check_expected(right_type_unwrapped, left_type_unwrapped) or { c.check_expected(right_type_unwrapped, left_type_unwrapped) or {
// allow for ptr += 2 // allow for ptr += 2

View File

@ -5,7 +5,7 @@ vlib/v/checker/tests/method_op_alias_err.vv:4:18: error: expected `Foo` not `Foo
| ~~~~ | ~~~~
5 | return Foo2(f + f1) 5 | return Foo2(f + f1)
6 | } 6 | }
vlib/v/checker/tests/method_op_alias_err.vv:5:17: error: mismatched types `Foo` and `Foo2` vlib/v/checker/tests/method_op_alias_err.vv:5:17: error: infix expr: cannot use `string` (right expression) as `string`
3 | 3 |
4 | fn (f Foo) + (f1 Foo2) Foo2 { 4 | fn (f Foo) + (f1 Foo2) Foo2 {
5 | return Foo2(f + f1) 5 | return Foo2(f + f1)

View File

@ -5,3 +5,10 @@ vlib/v/checker/tests/mismatched_ptr_op_ptr.vv:5:17: error: mismatched types `&st
| ~~~ | ~~~
6 | println(b+b) 6 | println(b+b)
7 | } 7 | }
vlib/v/checker/tests/mismatched_ptr_op_ptr.vv:6:17: error: mismatched types `&string` and `&string`
4 | b := &a
5 | println(b+*b)
6 | println(b+b)
| ~~~
7 | }
8 | }

View File

@ -84,7 +84,7 @@ fn test_for_in_mut_val_of_map_fixed_array() {
assert '$m' == "{'foo': [{'c': 3}], 'bar': [{'c': 3}]}" assert '$m' == "{'foo': [{'c': 3}], 'bar': [{'c': 3}]}"
} }
fn test_for_in_mut_val_of_plus_expr() { fn test_for_in_mut_val_of_string() {
b := 'c' b := 'c'
mut c := ['a', 'b'] mut c := ['a', 'b']
mut ret := []string{} mut ret := []string{}
@ -95,3 +95,15 @@ fn test_for_in_mut_val_of_plus_expr() {
println(ret) println(ret)
assert ret == ['ac', 'bc'] assert ret == ['ac', 'bc']
} }
fn test_for_in_mut_val_of_float() {
mut values := [1., 2, 3]
println(values)
for mut v in values {
v = 1.
v = v + 1.
}
println(values)
assert values == [2., 2, 2]
}