checker: disallow infix op on an optional type (#6406)
parent
99574e465d
commit
69c592e0d6
|
@ -182,6 +182,9 @@ pub fn (c &Checker) promote(left_type, right_type table.Type) table.Type {
|
||||||
}
|
}
|
||||||
if right_type.is_number() && left_type.is_number() {
|
if right_type.is_number() && left_type.is_number() {
|
||||||
return c.promote_num(left_type, right_type)
|
return c.promote_num(left_type, right_type)
|
||||||
|
} else if left_type.has_flag(.optional) != right_type.has_flag(.optional) {
|
||||||
|
// incompatible
|
||||||
|
return table.void_type
|
||||||
} else {
|
} else {
|
||||||
return left_type // default to left if not automatic promotion possible
|
return left_type // default to left if not automatic promotion possible
|
||||||
}
|
}
|
||||||
|
|
|
@ -629,6 +629,9 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type {
|
||||||
left_name := c.table.type_to_str(left_type)
|
left_name := c.table.type_to_str(left_type)
|
||||||
right_name := c.table.type_to_str(right_type)
|
right_name := c.table.type_to_str(right_type)
|
||||||
c.error('mismatched types `$left_name` and `$right_name`', infix_expr.pos)
|
c.error('mismatched types `$left_name` and `$right_name`', infix_expr.pos)
|
||||||
|
} else if promoted_type.has_flag(.optional) {
|
||||||
|
s := c.table.type_to_str(promoted_type)
|
||||||
|
c.error('`$infix_expr.op` cannot be used with `$s`', infix_expr.pos)
|
||||||
} else if promoted_type.is_float() {
|
} else if promoted_type.is_float() {
|
||||||
if infix_expr.op in [.mod, .xor, .amp, .pipe] {
|
if infix_expr.op in [.mod, .xor, .amp, .pipe] {
|
||||||
side := if left_type == promoted_type { 'left' } else { 'right' }
|
side := if left_type == promoted_type { 'left' } else { 'right' }
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
vlib/v/checker/tests/infix_err.vv:7:8: error: mismatched types `string` and `?string`
|
||||||
|
5 | return none
|
||||||
|
6 | }
|
||||||
|
7 | _ = '' + f()
|
||||||
|
| ^
|
||||||
|
8 | _ = f() + ''
|
||||||
|
9 | _ = f() + f()
|
||||||
|
vlib/v/checker/tests/infix_err.vv:8:9: error: mismatched types `?string` and `string`
|
||||||
|
6 | }
|
||||||
|
7 | _ = '' + f()
|
||||||
|
8 | _ = f() + ''
|
||||||
|
| ^
|
||||||
|
9 | _ = f() + f()
|
||||||
|
10 |
|
||||||
|
vlib/v/checker/tests/infix_err.vv:9:9: error: `+` cannot be used with `?string`
|
||||||
|
7 | _ = '' + f()
|
||||||
|
8 | _ = f() + ''
|
||||||
|
9 | _ = f() + f()
|
||||||
|
| ^
|
||||||
|
10 |
|
||||||
|
11 | _ = 4 + g()
|
||||||
|
vlib/v/checker/tests/infix_err.vv:11:7: error: `+` cannot be used with `?int`
|
||||||
|
9 | _ = f() + f()
|
||||||
|
10 |
|
||||||
|
11 | _ = 4 + g()
|
||||||
|
| ^
|
||||||
|
12 | _ = int(0) + g() // FIXME not detected
|
||||||
|
13 | _ = g() + int(3)
|
||||||
|
vlib/v/checker/tests/infix_err.vv:13:9: error: `+` cannot be used with `?int`
|
||||||
|
11 | _ = 4 + g()
|
||||||
|
12 | _ = int(0) + g() // FIXME not detected
|
||||||
|
13 | _ = g() + int(3)
|
||||||
|
| ^
|
||||||
|
14 | _ = g() + 3
|
||||||
|
vlib/v/checker/tests/infix_err.vv:14:9: error: `+` cannot be used with `?int`
|
||||||
|
12 | _ = int(0) + g() // FIXME not detected
|
||||||
|
13 | _ = g() + int(3)
|
||||||
|
14 | _ = g() + 3
|
||||||
|
| ^
|
|
@ -0,0 +1,14 @@
|
||||||
|
fn f() ?string {
|
||||||
|
return none
|
||||||
|
}
|
||||||
|
fn g() ?int {
|
||||||
|
return none
|
||||||
|
}
|
||||||
|
_ = '' + f()
|
||||||
|
_ = f() + ''
|
||||||
|
_ = f() + f()
|
||||||
|
|
||||||
|
_ = 4 + g()
|
||||||
|
_ = int(0) + g() // FIXME not detected
|
||||||
|
_ = g() + int(3)
|
||||||
|
_ = g() + 3
|
Loading…
Reference in New Issue