parser: return incomplete selector expr stmt (#7465)

pull/7462/head
Ned Palacios 2020-12-22 20:00:23 +08:00 committed by GitHub
parent d5b03d16e0
commit 06369a27c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 15 additions and 7 deletions

View File

@ -16,7 +16,7 @@ vlib/v/checker/tests/if_match_expr.vv:10:2: error: `if` expression branch has un
8 | for {break}
9 | {}
10 | match true {true {} else {}} // statement not expression
| ~~~~~
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11 | _ = match true {true {1} else {-1}} // OK
12 | match true {true {1} else {-1}} // result
vlib/v/checker/tests/if_match_expr.vv:17:3: error: `match` expression branch has unsupported statement (`v.ast.IfExpr`)
@ -37,6 +37,6 @@ vlib/v/checker/tests/if_match_expr.vv:23:3: error: `match` expression branch has
21 | else {
22 | assert true
23 | match true {true {} else {}} // statement not expression
| ~~~~~
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 | _ = match true {true {1} else {-1}} // OK
25 | match true {true {1} else {-1}} // result

View File

@ -1,7 +1,7 @@
vlib/v/checker/tests/optional_or_block_mismatch.vv:10:18: error: wrong return type `Bar` in the `or {}` block, expected `&Bar`
8 |
8 |
9 | fn main() {
10 | x := foo() or { Bar{} }
| ~~~
| ~~~~~
11 | println(x)
12 | }

View File

@ -63,6 +63,7 @@ mut:
vet_errors []string
cur_fn_name string
in_generic_params bool // indicates if parsing between `<` and `>` of a method/function
name_error bool
}
// for tests
@ -409,6 +410,9 @@ fn (mut p Parser) check(expected token.Kind) {
} else if p.tok.kind == .name {
p.error('unexpected name `$p.tok.lit`, expecting `$expected.str()`')
} else {
if expected == .name {
p.name_error = true
}
p.error('unexpected `$p.tok.kind.str()`, expecting `$expected.str()`')
}
}
@ -954,14 +958,14 @@ fn (mut p Parser) parse_multi_expr(is_top_level bool) ast.Stmt {
} else if tok.kind !in [.key_if, .key_match, .key_lock, .key_rlock, .key_select] &&
left0 !is ast.CallExpr && (is_top_level || p.tok.kind != .rcbr) && left0 !is ast.PostfixExpr &&
!(left0 is ast.InfixExpr && (left0 as ast.InfixExpr).op in [.left_shift, .arrow]) && left0 !is
ast.ComptimeCall {
ast.ComptimeCall && left0 !is ast.SelectorExpr {
p.error_with_pos('expression evaluated but not used', left0.position())
return ast.Stmt{}
}
if left.len == 1 {
return ast.ExprStmt{
expr: left0
pos: tok.position()
pos: left0.position()
comments: left_comments
is_expr: p.inside_for
}
@ -1466,10 +1470,11 @@ fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr {
else {}
}
}
pos := if p.name_error { left.position().extend(name_pos) } else { name_pos }
sel_expr := ast.SelectorExpr{
expr: left
field_name: field_name
pos: name_pos
pos: pos
is_mut: is_mut
mut_pos: mut_pos
scope: p.scope

View File

@ -259,6 +259,9 @@ pub fn (mut p Parser) expr_with_left(left ast.Expr, precedence int, is_stmt_iden
for precedence < p.tok.precedence() {
if p.tok.kind == .dot {
node = p.dot_expr(node)
if p.name_error {
return node
}
p.is_stmt_ident = is_stmt_ident
} else if p.tok.kind == .lsbr {
node = p.index_expr(node)