Skip to content

Commit 279f27b

Browse files
committed
Fix OUTDENT region syncing after skip
1 parent 4180269 commit 279f27b

File tree

2 files changed

+21
-16
lines changed

2 files changed

+21
-16
lines changed

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

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ object Scanners {
300300
while !atStop do
301301
nextToken()
302302
// println(s"\nSTOP SKIP AT ${sourcePos().line + 1}, $this in $currentRegion")
303+
if token == OUTDENT then dropUntil(_.isInstanceOf[Indented])
303304
skipping = false
304305

305306
// Get next token ------------------------------------------------------------
@@ -332,14 +333,8 @@ object Scanners {
332333
result
333334

334335
private inline def dropUntil(inline matches: Region => Boolean): Unit =
335-
while
336-
!currentRegion.isOutermost
337-
&& {
338-
val isLast = matches(currentRegion)
339-
currentRegion = currentRegion.enclosing
340-
!isLast
341-
}
342-
do ()
336+
while !matches(currentRegion) && !currentRegion.isOutermost do
337+
currentRegion = currentRegion.enclosing
343338

344339
def adjustSepRegions(lastToken: Token): Unit = (lastToken: @switch) match {
345340
case LPAREN | LBRACKET =>
@@ -348,6 +343,7 @@ object Scanners {
348343
currentRegion = InBraces(currentRegion)
349344
case RBRACE =>
350345
dropUntil(_.isInstanceOf[InBraces])
346+
if !currentRegion.isOutermost then currentRegion = currentRegion.enclosing
351347
case RPAREN | RBRACKET =>
352348
currentRegion match {
353349
case InParens(prefix, outer) if prefix + 1 == lastToken => currentRegion = outer
@@ -356,9 +352,7 @@ object Scanners {
356352
case OUTDENT =>
357353
currentRegion match
358354
case r: Indented => currentRegion = r.enclosing
359-
case r =>
360-
if skipping && r.enclosing.isClosedByUndentAt(indentWidth(offset)) then
361-
dropUntil(_.isInstanceOf[Indented])
355+
case _ =>
362356
case STRINGLIT =>
363357
currentRegion match {
364358
case InString(_, outer) => currentRegion = outer
@@ -597,11 +591,12 @@ object Scanners {
597591
i"""The start of this line does not match any of the previous indentation widths.
598592
|Indentation width of current line : $nextWidth
599593
|This falls between previous widths: ${ir.width} and $lastWidth"""))
600-
case r: InBraces if !closingRegionTokens.contains(token) && !skipping =>
601-
report.warning("Line is indented too far to the left, or a `}` is missing", sourcePos())
602594
case r =>
603-
if skipping && r.enclosing.isClosedByUndentAt(nextWidth) then
604-
insert(OUTDENT, offset)
595+
if skipping then
596+
if r.enclosing.isClosedByUndentAt(nextWidth) then
597+
insert(OUTDENT, offset)
598+
else if r.isInstanceOf[InBraces] && !closingRegionTokens.contains(token) then
599+
report.warning("Line is indented too far to the left, or a `}` is missing", sourcePos())
605600

606601
else if lastWidth < nextWidth
607602
|| lastWidth == nextWidth && (lastToken == MATCH || lastToken == CATCH) && token == CASE then

tests/neg/syntax-error-recovery.scala

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ object Test {
1414
2
1515
println(baz) // error
1616

17-
}
17+
def foo3(x: Int) =
18+
foo2(x
19+
if x == 0 then println(bar) // error
20+
println(bar) // error
1821

22+
def foo4(x: Int) =
23+
if x < 0) then // error
24+
1
25+
else
26+
2
27+
println(bam)
1928

29+
}

0 commit comments

Comments
 (0)