Skip to content

Commit 1cd734d

Browse files
committed
Avoid lookahead into interpolation
Since an interpolation is really two tokens deep, for the literal part and the interpolated expression, one-char lookahead does not preserve the second token on reset. Make lookahead itself more robust by falling back to a LookaheadScanner for this case. Also add an internal error for the bad reset.
1 parent 327ecc2 commit 1cd734d

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

compiler/src/dotty/tools/dotc/parsing/Scanners.scala

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -695,10 +695,10 @@ object Scanners {
695695
getNextToken(token)
696696
if token == END && !isEndMarker then token = IDENTIFIER
697697

698-
def reset() = {
698+
def reset() =
699+
if next.token != EMPTY && !isInstanceOf[LookaheadScanner] then report.error(s"Internal: lookAhead/reset would erase next token ${tokenString(next.token)} after ${tokenString(token)}", sourcePos())
699700
next.copyFrom(this)
700701
this.copyFrom(prev)
701-
}
702702

703703
def closeIndented() = currentRegion match
704704
case r: Indented if !r.isOutermost => insert(OUTDENT, offset)
@@ -1080,16 +1080,24 @@ object Scanners {
10801080
// Lookahead ---------------------------------------------------------------
10811081

10821082
/** The next token after this one.
1083+
*
10831084
* The token is computed via fetchToken, so complex two word
10841085
* tokens such as CASECLASS are not recognized.
10851086
* Newlines and indent/unindent tokens are skipped.
10861087
*
1088+
* Since interpolation prefetches both STRINGPART and an expression,
1089+
* use a scanner for rare case. Otherwise the next is overwritten on reset.
10871090
*/
1088-
def lookahead: TokenData =
1089-
if next.token == EMPTY then
1091+
def lookahead: TokenData =
1092+
if next.token != EMPTY then next
1093+
else if token == INTERPOLATIONID then
1094+
val scan = LookaheadScanner()
1095+
scan.nextToken()
1096+
scan
1097+
else
10901098
lookAhead()
10911099
reset()
1092-
next
1100+
next
10931101

10941102
class LookaheadScanner(val allowIndent: Boolean = false) extends Scanner(source, offset) {
10951103
override def languageImportContext = Scanner.this.languageImportContext

tests/pos/i15514.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
object Main { s"Hello $Main.toStr!" }

0 commit comments

Comments
 (0)