checker: disallow infix op on an optional type (#6406)

pull/6411/head
Nick Treleaven 2020-09-18 00:03:55 +01:00 committed by GitHub
parent 99574e465d
commit 69c592e0d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 59 additions and 0 deletions

View File

@ -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
} }

View File

@ -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' }

View File

@ -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
| ^

View File

@ -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