Skip to content

Commit 02c7048

Browse files
committed
Refine printing of recursive types
Show the self type binder of a RecType only if the RecType was referred to in its body. This is needed so that we can add RecTypes to class types without polluting error messages.
1 parent 0aa6794 commit 02c7048

File tree

3 files changed

+34
-5
lines changed

3 files changed

+34
-5
lines changed

compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
3939
private var elideCapabilityCaps = false
4040

4141
private var openRecs: List[RecType] = Nil
42+
private var referredRecs: Set[RecType] = Set.empty
4243

4344
protected def maxToTextRecursions: Int = 100
4445

@@ -260,11 +261,15 @@ class PlainPrinter(_ctx: Context) extends Printer {
260261
refinementChain(tp).reverse: @unchecked
261262
toTextLocal(parent) ~ "{" ~ Text(refined map toTextRefinement, "; ").close ~ "}"
262263
case tp: RecType =>
263-
try {
264+
try
264265
openRecs = tp :: openRecs
265-
"{" ~ selfRecName(openRecs.length) ~ " => " ~ toTextGlobal(tp.parent) ~ "}"
266-
}
267-
finally openRecs = openRecs.tail
266+
val parentTxt = toTextGlobal(tp.parent)
267+
if referredRecs.contains(tp) || printDebug
268+
then "{" ~ selfRecName(openRecs.length) ~ " => " ~ parentTxt ~ "}"
269+
else parentTxt
270+
finally
271+
referredRecs -= openRecs.head
272+
openRecs = openRecs.tail
268273
case AndType(tp1, tp2) =>
269274
changePrec(AndTypePrec) { toText(tp1) ~ " & " ~ atPrec(AndTypePrec + 1) { toText(tp2) } }
270275
case OrType(tp1, tp2) =>
@@ -457,7 +462,9 @@ class PlainPrinter(_ctx: Context) extends Printer {
457462
ParamRefNameString(pref) ~ hashStr(pref.binder)
458463
case tp: RecThis =>
459464
val idx = openRecs.reverse.indexOf(tp.binder)
460-
if (idx >= 0) selfRecName(idx + 1)
465+
if idx >= 0 then
466+
referredRecs += tp.binder
467+
selfRecName(idx + 1)
461468
else "{...}.this" // TODO move underlying type to an addendum, e.g. ... z3 ... where z3: ...
462469
case tp: SkolemType =>
463470
def reprStr = toText(tp.repr) ~ hashStr(tp)

tests/neg/show-rec-types.check

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-- [E007] Type Mismatch Error: tests/neg/show-rec-types.scala:13:13 ----------------------------------------------------
2+
13 |val _: Int = c // error
3+
| ^
4+
| Found: (c : {z1 => C{val x: {z2 => C{val x: z2.T}}; val y: z1.T}})
5+
| Required: Int
6+
|
7+
| longer explanation available when compiling with `-explain`

tests/neg/show-rec-types.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
trait C {
2+
type T
3+
val x: Any
4+
val y: Any
5+
}
6+
7+
val c: C {
8+
val x: C {
9+
val x: this.T
10+
}
11+
val y: this.T
12+
} = ???
13+
val _: Int = c // error
14+
15+

0 commit comments

Comments
 (0)