Skip to content

Commit 0ea6a0a

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 658c8bd commit 0ea6a0a

File tree

4 files changed

+24
-4
lines changed

4 files changed

+24
-4
lines changed

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

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

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

414416
private var inFunReturnType = false
415417
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 & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,7 +1339,7 @@ trait Checking {
13391339
typr.println(i"check no double declarations $cls")
13401340

13411341
def checkDecl(decl: Symbol): Unit = {
1342-
for (other <- seen(decl.name) if !decl.isAbsent() && !other.isAbsent()) {
1342+
for other <- seen(decl.name) if decl.name != nme.ERROR && !decl.isAbsent() && !other.isAbsent() do
13431343
typr.println(i"conflict? $decl $other")
13441344
def javaFieldMethodPair =
13451345
decl.is(JavaDefined) && other.is(JavaDefined) &&
@@ -1356,7 +1356,6 @@ trait Checking {
13561356
if decl.hasDefaultParams && other.hasDefaultParams then
13571357
report.error(em"two or more overloaded variants of $decl have default arguments", decl.srcPos)
13581358
decl.resetFlag(HasDefaultParams)
1359-
}
13601359
if (!excludeFromDoubleDeclCheck(decl))
13611360
seen(decl.name) = decl :: seen(decl.name)
13621361
}

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)