Skip to content

Commit b8316d8

Browse files
committed
Fix indent insertion at arrow eol
1 parent fb9bc69 commit b8316d8

File tree

5 files changed

+38
-27
lines changed

5 files changed

+38
-27
lines changed

Diff for: compiler/src/dotty/tools/dotc/parsing/Parsers.scala

+3-6
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import config.Feature.{sourceVersion, migrateTo3}
3434
import config.SourceVersion.*
3535
import config.SourceVersion
3636
import dotty.tools.dotc.config.MigrationVersion
37+
import dotty.tools.dotc.util.chaining.*
3738

3839
object Parsers {
3940

@@ -1087,11 +1088,11 @@ object Parsers {
10871088
*/
10881089
def followingIsLambdaAfterColon(): Boolean =
10891090
val lookahead = in.LookaheadScanner(allowIndent = true)
1091+
.tap(_.currentRegion.knownWidth = in.currentRegion.indentWidth)
10901092
def isArrowIndent() =
10911093
lookahead.isArrow
10921094
&& {
1093-
lookahead.observeArrowEOL()
1094-
lookahead.nextToken()
1095+
lookahead.observeArrowIndented()
10951096
lookahead.token == INDENT || lookahead.token == EOF
10961097
}
10971098
lookahead.nextToken()
@@ -2655,14 +2656,10 @@ object Parsers {
26552656

26562657
def closureRest(start: Int, location: Location, params: List[Tree]): Tree =
26572658
atSpan(start, in.offset) {
2658-
if location == Location.InColonArg then
2659-
in.observeArrowEOL()
26602659
if in.token == CTXARROW then
26612660
if params.isEmpty then
26622661
syntaxError(em"context function literals require at least one formal parameter", Span(start, in.lastOffset))
26632662
in.nextToken()
2664-
else if in.token == ARROWeol then
2665-
in.nextToken()
26662663
else
26672664
accept(ARROW)
26682665
val body =

Diff for: compiler/src/dotty/tools/dotc/parsing/Scanners.scala

+11-5
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ object Scanners {
9292
|| token == IDENTIFIER && isOperatorPart(name(name.length - 1))
9393

9494
def isArrow =
95-
token == ARROW || token == CTXARROW || token == ARROWeol
95+
token == ARROW || token == CTXARROW
9696
}
9797

9898
abstract class ScannerCommon(source: SourceFile)(using Context) extends CharArrayReader with TokenData {
@@ -646,7 +646,6 @@ object Scanners {
646646
|| lastWidth == nextWidth
647647
&& lastToken.match
648648
case MATCH | CATCH => token == CASE
649-
case ARROWeol => true
650649
case _ => false
651650
then
652651
if canStartIndentTokens.contains(lastToken) then
@@ -680,12 +679,19 @@ object Scanners {
680679
reset()
681680
if atEOL then token = COLONeol
682681

683-
def observeArrowEOL(): Unit =
684-
if indentSyntax && token == ARROW then
682+
// consume => and insert <indent> if applicable
683+
def observeArrowIndented(): Unit =
684+
if isArrow && indentSyntax then
685685
peekAhead()
686686
val atEOL = isAfterLineEnd || token == EOF
687687
reset()
688-
if atEOL then token = ARROWeol
688+
if atEOL then
689+
val nextWidth = indentWidth(next.offset)
690+
val lastWidth = currentRegion.indentWidth
691+
if lastWidth < nextWidth then
692+
currentRegion = Indented(nextWidth, COLONeol, currentRegion)
693+
offset = next.offset
694+
token = INDENT
689695

690696
def observeIndented(): Unit =
691697
if indentSyntax && isNewLine then

Diff for: compiler/src/dotty/tools/dotc/parsing/Tokens.scala

+2-3
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,9 @@ object Tokens extends TokensCommon {
202202
inline val COLONeol = 89; enter(COLONeol, ":", ": at eol")
203203
// A `:` recognized as starting an indentation block
204204
inline val SELFARROW = 90; enter(SELFARROW, "=>") // reclassified ARROW following self-type
205-
inline val ARROWeol = 99; enter(ARROWeol, "=>", "=> at eol") // lambda ARROW at eol followed by indent
206205

207206
/** XML mode */
208-
inline val XMLSTART = 100; enter(XMLSTART, "$XMLSTART$<") // TODO: deprecate
207+
inline val XMLSTART = 99; enter(XMLSTART, "$XMLSTART$<") // TODO: deprecate
209208

210209
final val alphaKeywords: TokenSet = tokenRange(IF, END)
211210
final val symbolicKeywords: TokenSet = tokenRange(USCORE, CTXARROW)
@@ -283,7 +282,7 @@ object Tokens extends TokensCommon {
283282
final val closingRegionTokens = BitSet(RBRACE, RPAREN, RBRACKET, CASE) | statCtdTokens
284283

285284
final val canStartIndentTokens: BitSet =
286-
statCtdTokens | BitSet(COLONeol, WITH, EQUALS, ARROWeol, ARROW, CTXARROW, LARROW, WHILE, TRY, FOR, IF, THROW, RETURN)
285+
statCtdTokens | BitSet(COLONeol, WITH, EQUALS, ARROW, CTXARROW, LARROW, WHILE, TRY, FOR, IF, THROW, RETURN)
287286

288287
/** Faced with the choice between a type and a formal parameter, the following
289288
* tokens determine it's a formal parameter.

Diff for: tests/neg/i22193.scala

+1-13
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ def fn3(arg: String, arg2: String)(f: => Unit): Unit = f
55

66
def test1() =
77

8+
// ok baseline
89
fn2(arg = "blue sleeps faster than tuesday", arg2 = "the quick brown fox jumped over the lazy dog"): env =>
910
val x = env
1011
println(x)
@@ -15,12 +16,6 @@ def test1() =
1516
val x = env // error
1617
println(x)
1718

18-
fn2( // error
19-
arg = "blue sleeps faster than tuesday",
20-
arg2 = "the quick brown fox jumped over the lazy dog"): env =>
21-
val x = env // error
22-
println(x)
23-
2419
fn2(
2520
arg = "blue sleeps faster than tuesday",
2621
arg2 = "the quick brown fox jumped over the lazy dog"):
@@ -30,13 +25,6 @@ def test1() =
3025

3126
def test2() =
3227

33-
fn2(
34-
arg = "blue sleeps faster than tuesday",
35-
arg2 = "the quick brown fox jumped over the lazy dog"
36-
): env =>
37-
val x = env
38-
println(x)
39-
4028
fn3( // error missing argument list for value of type (=> Unit) => Unit
4129
arg = "blue sleeps faster than tuesday",
4230
arg2 = "the quick brown fox jumped over the lazy dog"):

Diff for: tests/pos/i22193.scala

+21
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ def test() =
2222
val x = env
2323
println(x)
2424

25+
fn2(
26+
arg = "blue sleeps faster than tuesday",
27+
arg2 = "the quick brown fox jumped over the lazy dog"): env =>
28+
val x = env
29+
println(x)
30+
2531
// does compile
2632
fn2(
2733
arg = "blue sleeps faster than tuesday",
@@ -38,6 +44,13 @@ def test() =
3844
val x = env
3945
println(x)
4046

47+
fn2(
48+
arg = "blue sleeps faster than tuesday",
49+
arg2 = "the quick brown fox jumped over the lazy dog"
50+
): env =>
51+
val x = env
52+
println(x)
53+
4154
fn3(
4255
arg = "blue sleeps faster than tuesday",
4356
arg2 = "the quick brown fox jumped over the lazy dog"):
@@ -55,3 +68,11 @@ def regress(x: Int) =
5568
x match
5669
case 42 =>
5770
case _ =>
71+
72+
// previously lookahead calculated indent width at the colon
73+
def k(xs: List[Int]) =
74+
xs.foldLeft(
75+
0)
76+
: (acc, x) =>
77+
acc + x
78+

0 commit comments

Comments
 (0)