From d3b6a986673be55f995cf486af097026eabff10d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 24 Jan 2018 15:41:34 +0100 Subject: [PATCH] Fix #1961: Allow `*` as an infix operator --- .../src/dotty/tools/dotc/parsing/Parsers.scala | 16 ++++++++++++---- tests/pos/i1961.scala | 4 ++++ 2 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 tests/pos/i1961.scala diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 2436ad4081f2..bf929cdd5ce7 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -470,11 +470,11 @@ object Parsers { def infixOps( first: Tree, canStartOperand: Token => Boolean, operand: () => Tree, isType: Boolean = false, - notAnOperator: Name = nme.EMPTY, + isOperator: => Boolean = true, maybePostfix: Boolean = false): Tree = { val base = opStack var top = first - while (isIdent && in.name != notAnOperator) { + while (isIdent && isOperator) { val op = if (isType) typeIdent() else termIdent() top = reduceStack(base, top, precedence(op.name), isLeftAssoc(op.name), op.name) opStack = OpInfo(top, op, in.offset) :: opStack @@ -797,8 +797,16 @@ object Parsers { */ def infixType(): Tree = infixTypeRest(refinedType()) + /** Is current ident a `*`, and is it followed by a `)` or `,`? */ + def isPostfixStar: Boolean = + in.name == nme.raw.STAR && { + val lookahead = in.lookaheadScanner + lookahead.nextToken() + (lookahead.token == RPAREN || lookahead.token == COMMA) + } + def infixTypeRest(t: Tree): Tree = - infixOps(t, canStartTypeTokens, refinedType, isType = true, notAnOperator = nme.raw.STAR) + infixOps(t, canStartTypeTokens, refinedType, isType = true, isOperator = !isPostfixStar) /** RefinedType ::= WithType {Annotation | [nl] Refinement} */ @@ -1556,7 +1564,7 @@ object Parsers { /** InfixPattern ::= SimplePattern {id [nl] SimplePattern} */ def infixPattern(): Tree = - infixOps(simplePattern(), canStartExpressionTokens, simplePattern, notAnOperator = nme.raw.BAR) + infixOps(simplePattern(), canStartExpressionTokens, simplePattern, isOperator = in.name != nme.raw.BAR) /** SimplePattern ::= PatVar * | Literal diff --git a/tests/pos/i1961.scala b/tests/pos/i1961.scala new file mode 100644 index 000000000000..5a1f3fa594b9 --- /dev/null +++ b/tests/pos/i1961.scala @@ -0,0 +1,4 @@ +object InfixType { + trait *[N1, N2] + type Result = Int * Int +}