From 085085a2b9aba85827b3255c386c6d3e15f5a316 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20D=C3=A4schle?= Date: Thu, 7 Jan 2021 20:12:35 +0100 Subject: [PATCH] parser: fix sumtype match with array type (#7939) --- .../checker/tests/match_duplicate_branch.out | 12 +++++----- vlib/v/checker/tests/match_else_last_expr.out | 4 ++-- vlib/v/checker/tests/match_expr_else.out | 4 ++-- vlib/v/parser/if_match.v | 13 ++++------- vlib/v/tests/match_test.v | 23 +++++++++++++++++++ 5 files changed, 38 insertions(+), 18 deletions(-) diff --git a/vlib/v/checker/tests/match_duplicate_branch.out b/vlib/v/checker/tests/match_duplicate_branch.out index 8af6ae1bab..11263d5b63 100644 --- a/vlib/v/checker/tests/match_duplicate_branch.out +++ b/vlib/v/checker/tests/match_duplicate_branch.out @@ -2,41 +2,41 @@ vlib/v/checker/tests/match_duplicate_branch.vv:15:3: error: match case `St1` is 13 | match i { 14 | St1 { println('St1') } 15 | St1 { println('St1') } - | ~~~~~ + | ~~~ 16 | St2 { println('St2') } 17 | } vlib/v/checker/tests/match_duplicate_branch.vv:20:3: error: match case `St1` is handled more than once 18 | match i { 19 | St1 { println('St1') } 20 | St1 { println('St1') } - | ~~~~~ + | ~~~ 21 | else { println('else') } 22 | } vlib/v/checker/tests/match_duplicate_branch.vv:29:3: error: match case `green` is handled more than once 27 | .red { println('red') } 28 | .green { println('green') } 29 | .green { println('green') } - | ~~~~~~~~ + | ~~~~~~ 30 | .blue { println('blue') } 31 | } vlib/v/checker/tests/match_duplicate_branch.vv:34:3: error: match case `green` is handled more than once 32 | match c { 33 | .red, .green { println('red green') } 34 | .green { println('green') } - | ~~~~~~~~ + | ~~~~~~ 35 | else { println('else') } 36 | } vlib/v/checker/tests/match_duplicate_branch.vv:43:3: error: match case `2` is handled more than once 41 | 1 { println('1') } 42 | 2 { println('2') } 43 | 2 { println('3') } - | ~~~ + | ^ 44 | else { println('else') } 45 | } vlib/v/checker/tests/match_duplicate_branch.vv:51:3: error: match case `3` is handled more than once 49 | match i { 50 | 1...5 { println('1 to 5') } 51 | 3 { println('3') } - | ~~~ + | ^ 52 | else { println('else') } 53 | } \ No newline at end of file diff --git a/vlib/v/checker/tests/match_else_last_expr.out b/vlib/v/checker/tests/match_else_last_expr.out index e2b2abd37f..c3331f18ed 100644 --- a/vlib/v/checker/tests/match_else_last_expr.out +++ b/vlib/v/checker/tests/match_else_last_expr.out @@ -2,6 +2,6 @@ vlib/v/checker/tests/match_else_last_expr.vv:4:3: error: `else` must be the last 2 | match 1 { 3 | 1 { println('1') } 4 | else { println('else') } - | ~~~~~~ + | ~~~~ 5 | 4 { println('4') } - 6 | } + 6 | } \ No newline at end of file diff --git a/vlib/v/checker/tests/match_expr_else.out b/vlib/v/checker/tests/match_expr_else.out index 64f5c9caa0..cf708333d1 100644 --- a/vlib/v/checker/tests/match_expr_else.out +++ b/vlib/v/checker/tests/match_expr_else.out @@ -9,13 +9,13 @@ vlib/v/checker/tests/match_expr_else.vv:23:3: error: match expression is exhaust 21 | 'f64' 22 | } 23 | else { - | ~~~~~~ + | ~~~~ 24 | 'else' 25 | } vlib/v/checker/tests/match_expr_else.vv:34:3: error: `else` must be the last branch of `match` 32 | 'string' 33 | } 34 | else { - | ~~~~~~ + | ~~~~ 35 | 'else' 36 | } diff --git a/vlib/v/parser/if_match.v b/vlib/v/parser/if_match.v index 0edc5120bb..3515134317 100644 --- a/vlib/v/parser/if_match.v +++ b/vlib/v/parser/if_match.v @@ -175,9 +175,10 @@ fn (mut p Parser) match_expr() ast.MatchExpr { if p.tok.kind == .key_else { is_else = true p.next() - } else if p.tok.kind == .name && !(p.tok.lit == 'C' && + } else if (p.tok.kind == .name && !(p.tok.lit == 'C' && p.peek_tok.kind == .dot) && (p.tok.lit in table.builtin_type_names || p.tok.lit[0].is_capital() || - (p.peek_tok.kind == .dot && p.peek_tok2.lit.len > 0 && p.peek_tok2.lit[0].is_capital())) { + (p.peek_tok.kind == .dot && p.peek_tok2.lit.len > 0 && p.peek_tok2.lit[0].is_capital()))) || + p.tok.kind == .lsbr { mut types := []table.Type{} for { // Sum type match @@ -224,18 +225,14 @@ fn (mut p Parser) match_expr() ast.MatchExpr { p.check(.comma) } } - branch_last_pos := p.tok.position() + branch_last_pos := p.prev_tok.position() // p.warn('match block') p.inside_match_body = true stmts := p.parse_block_no_scope(false) branch_scope := p.scope p.close_scope() p.inside_match_body = false - pos := token.Position{ - line_nr: branch_first_pos.line_nr - pos: branch_first_pos.pos - len: branch_last_pos.pos - branch_first_pos.pos + branch_last_pos.len - } + pos := branch_first_pos.extend(branch_last_pos) post_comments := p.eat_comments() branches << ast.MatchBranch{ exprs: exprs diff --git a/vlib/v/tests/match_test.v b/vlib/v/tests/match_test.v index 9f829d3d69..44934e6f40 100644 --- a/vlib/v/tests/match_test.v +++ b/vlib/v/tests/match_test.v @@ -245,3 +245,26 @@ fn test_match_constant_string() { } } } + +type WithArray = []WithArray | int + +fn test_sumtype_with_array() { + fa := [WithArray(0)] + f := WithArray(fa) + match f { + []WithArray { + assert true + } + int { + assert false + } + } + match f { + int { + assert false + } + []WithArray { + assert true + } + } +}