From 1c57fd8914a9f12e2e50ccf9bb61fe0cb0773bf8 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 9 Dec 2019 09:56:34 +0100 Subject: [PATCH 1/2] Fix infix of match `match` should have the same precedence as alphanumeric operators. This means that `a match { ... } + 1` should give a syntax error. --- .../src/dotty/tools/dotc/parsing/Parsers.scala | 14 ++++++++++---- tests/neg/match-infix.scala | 3 +++ 2 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 tests/neg/match-infix.scala diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 992b98fffbf5..297c44d1a07d 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -983,9 +983,15 @@ object Parsers { } else val t = reduceStack(base, top, minPrec, leftAssoc = true, in.name, isType) - if !isType && in.token == MATCH then recur(matchClause(t)) + if !isType && in.token == MATCH then recurAtMinPrec(matchClause(t)) else t + def recurAtMinPrec(top: Tree): Tree = + if isIdent && isOperator && precedence(in.name) == minInfixPrec + || in.token == MATCH + then recur(top) + else top + recur(first) } @@ -2758,8 +2764,8 @@ object Parsers { /** OLD: GivenTypes ::= AnnotType {‘,’ AnnotType} * NEW: GivenTypes ::= Type {‘,’ Type} */ - def givenTypes(newStyle: Boolean, nparams: Int, ofClass: Boolean): List[ValDef] = - val tps = commaSeparated(() => if newStyle then typ() else annotType()) + def givenTypes(nparams: Int, ofClass: Boolean): List[ValDef] = + val tps = commaSeparated(typ) var counter = nparams def nextIdx = { counter += 1; counter } val paramFlags = if ofClass then Private | Local | ParamAccessor else Param @@ -2862,7 +2868,7 @@ object Parsers { || startParamTokens.contains(in.token) || isIdent && (in.name == nme.inline || in.lookaheadIn(BitSet(COLON))) if isParams then commaSeparated(() => param()) - else givenTypes(true, nparams, ofClass) + else givenTypes(nparams, ofClass) checkVarArgsRules(clause) clause } diff --git a/tests/neg/match-infix.scala b/tests/neg/match-infix.scala new file mode 100644 index 000000000000..12b57f4dc418 --- /dev/null +++ b/tests/neg/match-infix.scala @@ -0,0 +1,3 @@ +def f = 1 + 1 match { + case 2 => 3 +} + 1 // error // error From dff5ade7e84df3c0acc94ab9c44bf81bb752fb47 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 9 Dec 2019 10:51:29 +0100 Subject: [PATCH 2/2] Avoid lookahead in constrApps --- compiler/src/dotty/tools/dotc/parsing/Parsers.scala | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 297c44d1a07d..34f871ba7a5b 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -3483,12 +3483,11 @@ object Parsers { val t = constrApp() val ts = if in.token == WITH then - val lookahead = in.LookaheadScanner(indent = true) - lookahead.nextToken() - if templateCanFollow && (lookahead.token == LBRACE || lookahead.token == INDENT) then + in.nextToken() + newLineOptWhenFollowedBy(LBRACE) + if templateCanFollow && (in.token == LBRACE || in.token == INDENT) then Nil else - in.nextToken() checkNotWithAtEOL() constrApps(commaOK, templateCanFollow) else if commaOK && in.token == COMMA then