diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index f44703a562f1..b205d3159241 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -411,7 +411,9 @@ object Parsers { false } - def errorTermTree(start: Offset): Tree = atSpan(Span(start, in.offset)) { unimplementedExpr } + def errorTermTree(start: Offset): Tree = + val end = if in.token == OUTDENT then start else in.offset + atSpan(Span(start, end)) { unimplementedExpr } private var inFunReturnType = false private def fromWithinReturnType[T](body: => T): T = { diff --git a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala index ec246f7a3742..2445f4772f91 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala @@ -307,7 +307,7 @@ object Scanners { println(s"\nSTART SKIP AT ${sourcePos().line + 1}, $this in $currentRegion") var noProgress = 0 // Defensive measure to ensure we always get out of the following while loop - // even if source file is weirly formatted (i.e. we never reach EOF) + // even if source file is weirdly formatted (i.e. we never reach EOF) var prevOffset = offset while !atStop && noProgress < 3 do nextToken() diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 7f52c871f9de..310f32f2cedb 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -1346,7 +1346,7 @@ trait Checking { typr.println(i"check no double declarations $cls") def checkDecl(decl: Symbol): Unit = - for other <- seen(decl.name) if !decl.isAbsent() && !other.isAbsent() do + for other <- seen(decl.name) if decl.name != nme.ERROR && !decl.isAbsent() && !other.isAbsent() do typr.println(i"conflict? $decl $other") def javaFieldMethodPair = decl.is(JavaDefined) && other.is(JavaDefined) && diff --git a/tests/neg/i23729.check b/tests/neg/i23729.check new file mode 100644 index 000000000000..2f067c42c6c1 --- /dev/null +++ b/tests/neg/i23729.check @@ -0,0 +1,14 @@ +-- [E018] Syntax Error: tests/neg/i23729.scala:17:33 ------------------------------------------------------------------- +17 | def start: List[Direction] = match self // error syntax + | ^^^^^ + | expression expected but match found + | + | longer explanation available when compiling with `-explain` +-- [E040] Syntax Error: tests/neg/i23729.scala:18:6 -------------------------------------------------------------------- +18 | case Empty => Nil // error poor recovery + | ^^^^ + | 'def' expected, but 'case' found +-- [E040] Syntax Error: tests/neg/i23729.scala:19:6 -------------------------------------------------------------------- +19 | case Node(_, l, _) => l.start :+ Left // error poor recovery + | ^^^^ + | 'def' expected, but 'case' found diff --git a/tests/neg/i23729.scala b/tests/neg/i23729.scala new file mode 100644 index 000000000000..b575cbc0c35f --- /dev/null +++ b/tests/neg/i23729.scala @@ -0,0 +1,19 @@ + +trait Collection[Self, Element]: + type Index + extension (self: Self) + def start: Index + +sealed trait Tree[+T] +object Tree: + case object Empty extends Tree[Nothing] + case class Node[+T](value: T, lhs: Tree[T], rhs: Tree[T]) extends Tree[T] + +enum Direction: + case Left, Right, Here +given [T]: Collection[Tree[T], T] with + type Index = List[Direction] + extension (self: Tree[T]) + def start: List[Direction] = match self // error syntax + case Empty => Nil // error poor recovery + case Node(_, l, _) => l.start :+ Left // error poor recovery