Skip to content

Commit 85c0527

Browse files
committed
Error tree on outdent is zero extent
Recovery on syntax error may consume remaining input, with an OUTDENT at EOF, so that the parent tree does not actually extend to EOF. Do not report spurious `def <error>` as ambiguous.
1 parent a374c1d commit 85c0527

File tree

5 files changed

+38
-3
lines changed

5 files changed

+38
-3
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,9 @@ object Parsers {
411411
false
412412
}
413413

414-
def errorTermTree(start: Offset): Tree = atSpan(Span(start, in.offset)) { unimplementedExpr }
414+
def errorTermTree(start: Offset): Tree =
415+
val end = if in.token == OUTDENT then start else in.offset
416+
atSpan(Span(start, end)) { unimplementedExpr }
415417

416418
private var inFunReturnType = false
417419
private def fromWithinReturnType[T](body: => T): T = {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ object Scanners {
307307
println(s"\nSTART SKIP AT ${sourcePos().line + 1}, $this in $currentRegion")
308308
var noProgress = 0
309309
// Defensive measure to ensure we always get out of the following while loop
310-
// even if source file is weirly formatted (i.e. we never reach EOF)
310+
// even if source file is weirdly formatted (i.e. we never reach EOF)
311311
var prevOffset = offset
312312
while !atStop && noProgress < 3 do
313313
nextToken()

compiler/src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1346,7 +1346,7 @@ trait Checking {
13461346
typr.println(i"check no double declarations $cls")
13471347

13481348
def checkDecl(decl: Symbol): Unit =
1349-
for other <- seen(decl.name) if !decl.isAbsent() && !other.isAbsent() do
1349+
for other <- seen(decl.name) if decl.name != nme.ERROR && !decl.isAbsent() && !other.isAbsent() do
13501350
typr.println(i"conflict? $decl $other")
13511351
def javaFieldMethodPair =
13521352
decl.is(JavaDefined) && other.is(JavaDefined) &&

tests/neg/i23729.check

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
-- [E018] Syntax Error: tests/neg/i23729.scala:17:33 -------------------------------------------------------------------
2+
17 | def start: List[Direction] = match self // error syntax
3+
| ^^^^^
4+
| expression expected but match found
5+
|
6+
| longer explanation available when compiling with `-explain`
7+
-- [E040] Syntax Error: tests/neg/i23729.scala:18:6 --------------------------------------------------------------------
8+
18 | case Empty => Nil // error poor recovery
9+
| ^^^^
10+
| 'def' expected, but 'case' found
11+
-- [E040] Syntax Error: tests/neg/i23729.scala:19:6 --------------------------------------------------------------------
12+
19 | case Node(_, l, _) => l.start :+ Left // error poor recovery
13+
| ^^^^
14+
| 'def' expected, but 'case' found

tests/neg/i23729.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
trait Collection[Self, Element]:
3+
type Index
4+
extension (self: Self)
5+
def start: Index
6+
7+
sealed trait Tree[+T]
8+
object Tree:
9+
case object Empty extends Tree[Nothing]
10+
case class Node[+T](value: T, lhs: Tree[T], rhs: Tree[T]) extends Tree[T]
11+
12+
enum Direction:
13+
case Left, Right, Here
14+
given [T]: Collection[Tree[T], T] with
15+
type Index = List[Direction]
16+
extension (self: Tree[T])
17+
def start: List[Direction] = match self // error syntax
18+
case Empty => Nil // error poor recovery
19+
case Node(_, l, _) => l.start :+ Left // error poor recovery

0 commit comments

Comments
 (0)