Skip to content

Commit 4af2401

Browse files
committed
Avoid infinite loop in parser
Parser could get into an infinite loop because `acceptStatSepUnlessAtEnd` did not make progress. I believe the concrete example was a string interpolator where we encounter a `{ ... )`.
1 parent 87f375c commit 4af2401

File tree

2 files changed

+12
-3
lines changed

2 files changed

+12
-3
lines changed

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,16 @@ object Parsers {
284284
}
285285

286286
def acceptStatSepUnlessAtEnd(altEnd: Token = EOF) =
287-
if (!isStatSeqEnd && in.token != altEnd) acceptStatSep()
287+
if (!isStatSeqEnd)
288+
in.token match {
289+
case EOF =>
290+
case `altEnd` =>
291+
case NEWLINE | NEWLINES => in.nextToken()
292+
case SEMI => in.nextToken()
293+
case _ =>
294+
in.nextToken() // needed to ensure progress; otherwise we might cycle forever
295+
accept(SEMI)
296+
}
288297

289298
def errorTermTree = atPos(in.offset) { Literal(Constant(null)) }
290299

tests/neg/i1779.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ object Test {
88
def f = {
99
val _parent = 3
1010
q"val hello = $_parent"
11-
q"class $_" // error // error
12-
}
11+
q"class $_" // error
12+
} // error
1313
}

0 commit comments

Comments
 (0)