diff --git a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala index 2c9c0cabf1e9..4051d1c8db97 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala @@ -77,6 +77,9 @@ object Scanners { /** Is current token first one after a newline? */ def isAfterLineEnd: Boolean = lineOffset >= 0 + + def isOperator = + token == IDENTIFIER && isOperatorPart(name(name.length - 1)) } abstract class ScannerCommon(source: SourceFile)(using Context) extends CharArrayReader with TokenData { @@ -348,12 +351,27 @@ object Scanners { && (isWhitespace(ch) || ch == LF) && !pastBlankLine && { + // Is current lexeme assumed to start an expression? + // This is the case if the lexime is one of the tokens that + // starts an expression. Furthermore, if the previous token is + // in backticks, the lexeme may not be a binary operator. + // I.e. in + // + // a + // `x` += 1 + // + // `+=` is not assumed to start an expression since it follows an identifier + // in backticks and is a binary operator. Hence, `x` is not classified as a + // leading infix operator. + def assumeStartsExpr(lexeme: TokenData) = + canStartExprTokens.contains(lexeme.token) + && (token != BACKQUOTED_IDENT || !lexeme.isOperator || nme.raw.isUnary(lexeme.name)) val lookahead = LookaheadScanner() lookahead.allowLeadingInfixOperators = false // force a NEWLINE a after current token if it is on its own line lookahead.nextToken() - canStartExprTokens.contains(lookahead.token) - || lookahead.token == NEWLINE && canStartExprTokens.contains(lookahead.next.token) + assumeStartsExpr(lookahead) + || lookahead.token == NEWLINE && assumeStartsExpr(lookahead.next) } && { if migrateTo3 then diff --git a/tests/pos/i11371.scala b/tests/pos/i11371.scala new file mode 100644 index 000000000000..a55d463fce14 --- /dev/null +++ b/tests/pos/i11371.scala @@ -0,0 +1,19 @@ +object HelloWorld { + def whileLoop: Int = { + var i = 0 + var acc = 0 + while (i < 3) { + var `i'` = 0 + while (`i'` < 4) { + acc += (i * `i'`) + `i'` += 1 + } + i += 1 + } + acc + } + + def main(args: Array[String]): Unit = { + println(s"hello world: ${whileLoop}") + } +} \ No newline at end of file diff --git a/tests/run/i7031.scala b/tests/run/i7031.scala index 0bc3fe81f9e6..6e141968a19c 100644 --- a/tests/run/i7031.scala +++ b/tests/run/i7031.scala @@ -2,8 +2,7 @@ val a = 5 val x = 1 - + // - `a` * 6 + + `a` * 6 assert(x == 1, x) }