From 2215ff839ae0bbdbb59afbeebff90f0db8699392 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 16 Nov 2020 10:07:13 +0100 Subject: [PATCH 1/3] Fix #9992: Reset toplevel indent region width on left indent If we start with a toplevel region with greater than 0 indent, and we find a following line with less indentation, reset the current indentation width to that smaller number. --- .../src/dotty/tools/dotc/parsing/Scanners.scala | 14 ++++++++------ tests/pos/i9992.scala | 5 +++++ 2 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 tests/pos/i9992.scala diff --git a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala index 4c902b0574e2..2f8e576e494b 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala @@ -470,16 +470,16 @@ object Scanners { else if indentIsSignificant then if nextWidth < lastWidth || nextWidth == lastWidth && (indentPrefix == MATCH || indentPrefix == CATCH) && token != CASE then - if !currentRegion.isOutermost && - !isLeadingInfixOperator() && - !statCtdTokens.contains(lastToken) then + if currentRegion.isOutermost then + if nextWidth < lastWidth then currentRegion = topLevelRegion(nextWidth) +// report.error("Line is indented too far to the left", sourcePos()) + else if !isLeadingInfixOperator() && !statCtdTokens.contains(lastToken) then currentRegion match case r: Indented => currentRegion = r.enclosing insert(OUTDENT, offset) case r: InBraces if !closingRegionTokens.contains(token) => - report.warning("Line is indented too far to the left, or a `}` is missing", - source.atSpan(Span(offset))) + report.warning("Line is indented too far to the left, or a `}` is missing", sourcePos()) case _ => else if lastWidth < nextWidth @@ -1316,7 +1316,7 @@ object Scanners { /* Initialization: read first char, then first token */ nextChar() nextToken() - currentRegion = Indented(indentWidth(offset), Set(), EMPTY, null) + currentRegion = topLevelRegion(indentWidth(offset)) } // end Scanner @@ -1357,6 +1357,8 @@ object Scanners { case class Indented(width: IndentWidth, others: Set[IndentWidth], prefix: Token, outer: Region | Null) extends Region: knownWidth = width + def topLevelRegion(width: IndentWidth) = Indented(width, Set(), EMPTY, null) + enum IndentWidth { case Run(ch: Char, n: Int) case Conc(l: IndentWidth, r: Run) diff --git a/tests/pos/i9992.scala b/tests/pos/i9992.scala new file mode 100644 index 000000000000..1a7a9e519645 --- /dev/null +++ b/tests/pos/i9992.scala @@ -0,0 +1,5 @@ + import scala.concurrent._ + +@main def test(): Unit = + def test = () + test From 3ea82b0bb2727f050f3792dbb2d411b003e13f74 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 16 Nov 2020 10:08:57 +0100 Subject: [PATCH 2/3] Unrelated test for opaque types --- tests/pos/opaques-queue.scala | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 tests/pos/opaques-queue.scala diff --git a/tests/pos/opaques-queue.scala b/tests/pos/opaques-queue.scala new file mode 100644 index 000000000000..079ef7fde4f6 --- /dev/null +++ b/tests/pos/opaques-queue.scala @@ -0,0 +1,25 @@ +class Elem +trait QueueSignature: + type Queue + def empty: Queue + def append(q: Queue, e: Elem): Queue + def pop(q: Queue): Option[(Elem, Queue)] +val QueueModule: QueueSignature = + object QueueImpl extends QueueSignature: + type Queue = (List[Elem], List[Elem]) + def empty = (Nil, Nil) + def append(q: Queue, e: Elem): Queue = (q._1, e :: q._2) + def pop(q: Queue): Option[(Elem, Queue)] = q match + case (Nil, Nil) => None + case (x :: xs, ys) => Some((x, (xs, ys))) + case (Nil, ys) => pop((ys.reverse, Nil)) + QueueImpl + +object queues: + opaque type Queue = (List[Elem], List[Elem]) + def empty = (Nil, Nil) + def append(q: Queue, e: Elem): Queue = (q._1, e :: q._2) + def pop(q: Queue): Option[(Elem, Queue)] = q match + case (Nil, Nil) => None + case (x :: xs, ys) => Some((x, (xs, ys))) + case (Nil, ys) => pop((ys.reverse, Nil)) From 956d0c15031c8ccab9cf325f2873f1feda778cb8 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 16 Nov 2020 18:39:58 +0100 Subject: [PATCH 3/3] Update compiler/src/dotty/tools/dotc/parsing/Scanners.scala --- compiler/src/dotty/tools/dotc/parsing/Scanners.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala index 2f8e576e494b..1cb9a29c6aef 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala @@ -472,7 +472,6 @@ object Scanners { || nextWidth == lastWidth && (indentPrefix == MATCH || indentPrefix == CATCH) && token != CASE then if currentRegion.isOutermost then if nextWidth < lastWidth then currentRegion = topLevelRegion(nextWidth) -// report.error("Line is indented too far to the left", sourcePos()) else if !isLeadingInfixOperator() && !statCtdTokens.contains(lastToken) then currentRegion match case r: Indented =>