checker, cgen: fix `for in mut val` (#10444)
parent
98a496d70c
commit
bdc8586ddd
|
@ -1156,6 +1156,23 @@ 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)
|
||||
}
|
||||
}
|
||||
} else if (left_sym.kind == .string && !left_type.has_flag(.optional))
|
||||
|| (right_sym.kind == .string && !right_type.has_flag(.optional)) {
|
||||
deref_left_type := if node.left.is_auto_deref_var() {
|
||||
left_type.deref()
|
||||
} else {
|
||||
left_type
|
||||
}
|
||||
deref_right_type := if node.right.is_auto_deref_var() {
|
||||
right_type.deref()
|
||||
} else {
|
||||
right_type
|
||||
}
|
||||
left_name := c.table.type_to_str(deref_left_type)
|
||||
right_name := c.table.type_to_str(deref_right_type)
|
||||
if left_name != right_name {
|
||||
c.error('mismatched types `$left_name` and `$right_name`', left_right_pos)
|
||||
}
|
||||
} else {
|
||||
promoted_type := c.promote(c.table.unalias_num_type(left_type), c.table.unalias_num_type(right_type))
|
||||
if promoted_type.idx() == ast.void_type_idx {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
vlib/v/checker/tests/method_op_alias_err.vv:4:18: error: expected `Foo` not `Foo2` - both operands must be the same type for operator overloading
|
||||
2 | type Foo2 = string
|
||||
3 |
|
||||
3 |
|
||||
4 | fn (f Foo) + (f1 Foo2) Foo2 {
|
||||
| ~~~~
|
||||
5 | return Foo2(f + f1)
|
||||
6 | }
|
||||
vlib/v/checker/tests/method_op_alias_err.vv:5:17: error: infix expr: cannot use `string` (right expression) as `string`
|
||||
3 |
|
||||
vlib/v/checker/tests/method_op_alias_err.vv:5:17: error: mismatched types `Foo` and `Foo2`
|
||||
3 |
|
||||
4 | fn (f Foo) + (f1 Foo2) Foo2 {
|
||||
5 | return Foo2(f + f1)
|
||||
| ~~~~~~
|
||||
|
@ -14,7 +14,7 @@ vlib/v/checker/tests/method_op_alias_err.vv:5:17: error: infix expr: cannot use
|
|||
7 |
|
||||
vlib/v/checker/tests/method_op_alias_err.vv:8:1: error: cannot define operator methods on type alias for `string`
|
||||
6 | }
|
||||
7 |
|
||||
7 |
|
||||
8 | fn (f Foo) * (f1 Foo) Foo {
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
9 | return Foo(f + f1)
|
||||
|
@ -31,13 +31,12 @@ vlib/v/checker/tests/method_op_alias_err.vv:15:9: error: cannot assign to `f`: e
|
|||
14 | f += 'fg'
|
||||
15 | f *= Foo2('2')
|
||||
| ~~~~~~~~~
|
||||
16 | f -= Foo('fo')
|
||||
16 | f -= Foo('fo')
|
||||
17 | println(f)
|
||||
vlib/v/checker/tests/method_op_alias_err.vv:16:6: error: cannot use operator methods on type alias for `string`
|
||||
14 | f += 'fg'
|
||||
15 | f *= Foo2('2')
|
||||
16 | f -= Foo('fo')
|
||||
16 | f -= Foo('fo')
|
||||
| ~~
|
||||
17 | println(f)
|
||||
18 | }
|
||||
|
||||
|
|
|
@ -5,11 +5,3 @@ vlib/v/checker/tests/mismatched_ptr_op_ptr.vv:5:17: error: mismatched types `&st
|
|||
| ~~~
|
||||
6 | println(b+b)
|
||||
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 | }
|
||||
|
||||
|
|
|
@ -3,12 +3,12 @@ vlib/v/checker/tests/sum_type_infix_err.vv:5:9: error: cannot use operator `+` w
|
|||
4 | x := Abc(0)
|
||||
5 | _ := x + Abc(5)
|
||||
| ^
|
||||
6 | _ := 'test' + x
|
||||
6 | _ := 123 + x
|
||||
7 | _ = unsafe{&x + 5}
|
||||
vlib/v/checker/tests/sum_type_infix_err.vv:6:14: error: cannot use operator `+` with `Abc`
|
||||
vlib/v/checker/tests/sum_type_infix_err.vv:6:11: error: cannot use operator `+` with `Abc`
|
||||
4 | x := Abc(0)
|
||||
5 | _ := x + Abc(5)
|
||||
6 | _ := 'test' + x
|
||||
| ^
|
||||
6 | _ := 123 + x
|
||||
| ^
|
||||
7 | _ = unsafe{&x + 5}
|
||||
8 | }
|
||||
8 | }
|
||||
|
|
|
@ -3,6 +3,6 @@ type Abc = int | string
|
|||
fn main() {
|
||||
x := Abc(0)
|
||||
_ := x + Abc(5)
|
||||
_ := 'test' + x
|
||||
_ := 123 + x
|
||||
_ = unsafe{&x + 5}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3874,13 +3874,14 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
|
|||
} else {
|
||||
(left_sym.info as ast.Alias).parent_type
|
||||
}
|
||||
nr_muls := '*'.repeat(the_left_type.nr_muls())
|
||||
left_nr_muls := '*'.repeat(the_left_type.nr_muls())
|
||||
g.write(g.typ(the_left_type.set_nr_muls(0)))
|
||||
g.write('_')
|
||||
g.write(util.replace_op(node.op.str()))
|
||||
g.write('($nr_muls')
|
||||
g.write('($left_nr_muls')
|
||||
g.expr(node.left)
|
||||
g.write(', $nr_muls')
|
||||
right_nr_muls := '*'.repeat(node.right_type.nr_muls())
|
||||
g.write(', $right_nr_muls')
|
||||
g.expr(node.right)
|
||||
g.write(')')
|
||||
} else if node.op in [.ne, .gt, .ge, .le] && ((is_v_struct && !is_alias && not_exception)
|
||||
|
|
|
@ -83,3 +83,15 @@ fn test_for_in_mut_val_of_map_fixed_array() {
|
|||
println(m)
|
||||
assert '$m' == "{'foo': [{'c': 3}], 'bar': [{'c': 3}]}"
|
||||
}
|
||||
|
||||
fn test_for_in_mut_val_of_plus_expr() {
|
||||
b := 'c'
|
||||
mut c := ['a', 'b']
|
||||
mut ret := []string{}
|
||||
for mut a in c {
|
||||
a = a + b
|
||||
ret << a
|
||||
}
|
||||
println(ret)
|
||||
assert ret == ['ac', 'bc']
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue