Skip to content

Commit 414d421

Browse files
committed
Don't elide capture sets of capability classes in most cases
When printing types deriving from capability, do print their capture sets even if these are implied. This avoids confusing errors where a capability classes has two different implied Fresh instances which are both elided so the types look the same. Exception: When printing a singleton type (x: T) we do elide in T, since the usually the only part that matters is the `x`. But we don't do the elision under -Ycc-verbose or -explain.
1 parent 087a93c commit 414d421

File tree

4 files changed

+46
-29
lines changed

4 files changed

+46
-29
lines changed

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

+16-8
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ class PlainPrinter(_ctx: Context) extends Printer {
3131
/** Print Fresh instances as <cap hiding ...> */
3232
protected def ccVerbose = ctx.settings.YccVerbose.value
3333

34+
/** Elide redundant ^ and ^{cap.rd} when printing instances of Capability
35+
* classes. Gets set when singletons are printed as `(x: T)` to reduce verbosity.
36+
*/
37+
private var elideCapabilityCaps = false
38+
3439
private var openRecs: List[RecType] = Nil
3540

3641
protected def maxToTextRecursions: Int = 100
@@ -276,12 +281,12 @@ class PlainPrinter(_ctx: Context) extends Printer {
276281
}.close
277282
case tp @ CapturingType(parent, refs) =>
278283
val boxText: Text = Str("box ") provided tp.isBoxed //&& ctx.settings.YccDebug.value
279-
if parent.derivesFrom(defn.Caps_Capability)
280-
&& refs.containsRootCapability && refs.isReadOnly && !printDebug
281-
then
282-
toText(parent)
283-
else
284-
toTextCapturing(parent, refs, boxText)
284+
if elideCapabilityCaps
285+
&& parent.derivesFrom(defn.Caps_Capability)
286+
&& refs.containsRootCapability
287+
&& refs.isReadOnly
288+
then toText(parent)
289+
else toTextCapturing(parent, refs, boxText)
285290
case tp @ RetainingType(parent, refs) =>
286291
if Feature.ccEnabledSomewhere then
287292
toTextCapturing(parent, refs, "") ~ Str("R").provided(printDebug)
@@ -367,7 +372,11 @@ class PlainPrinter(_ctx: Context) extends Printer {
367372
}.close
368373

369374
def toTextSingleton(tp: SingletonType): Text =
370-
"(" ~ toTextRef(tp) ~ " : " ~ toTextGlobal(tp.underlying) ~ ")"
375+
val saved = elideCapabilityCaps
376+
elideCapabilityCaps = !ccVerbose && !ctx.settings.explain.value
377+
// don't elide capability capture sets under -Ycc-verbose or -explain
378+
try "(" ~ toTextRef(tp) ~ " : " ~ toTextGlobal(tp.underlying) ~ ")"
379+
finally elideCapabilityCaps = saved
371380

372381
protected def paramsText(lam: LambdaType): Text = {
373382
def paramText(ref: ParamRef) =
@@ -468,7 +477,6 @@ class PlainPrinter(_ctx: Context) extends Printer {
468477
case tp @ root.Fresh(hidden) =>
469478
val idStr = if showUniqueIds then s"#${tp.rootAnnot.id}" else ""
470479
if ccVerbose then s"<fresh$idStr in ${tp.ccOwner} hiding " ~ toTextCaptureSet(hidden) ~ ">"
471-
else if ccVerbose then "fresh"
472480
else "cap"
473481
case tp => toText(tp)
474482

tests/neg-custom-args/captures/effect-swaps.check

+6-4
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/effect-swaps.scala:69:10 ---------------------------------
1818
69 | Future: fut ?=> // error, type mismatch
1919
| ^
20-
|Found: (contextual$9: boundary.Label[box Result[box Future[box T^?]^?, box E^?]^?]) ?->{fr, async}
20+
|Found: (contextual$9: boundary.Label[box Result[box Future[box T^?]^?, box E^?]^?]^{cap.rd}) ?->{fr, async}
2121
| box Future[box T^?]^{fr, contextual$9}
22-
|Required: (contextual$9: boundary.Label[Result[box Future[box T^?]^?, box E^?]]) ?=> box Future[box T^?]^?
22+
|Required: (contextual$9: boundary.Label[Result[box Future[box T^?]^?, box E^?]]^{cap.rd}) ?=> box Future[box T^?]^?
2323
|
2424
|where: ?=> refers to a fresh root capability created in method fail4 when checking argument to parameter body of method make
25+
| cap is the universal root capability
2526
|
2627
|
2728
|Note that reference contextual$9.type
@@ -32,10 +33,11 @@
3233
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/effect-swaps.scala:73:35 ---------------------------------
3334
73 | Result.make[Future[T], E]: lbl ?=> // error: type mismatch
3435
| ^
35-
|Found: (lbl: boundary.Label[box Result[box Future[box T^?]^?, box E^?]^?]) ?->{fr, async} Future[box T^?]^{fr, lbl}
36-
|Required: (lbl: boundary.Label[Result[Future[T], E]]) ?=> Future[T]
36+
|Found: (lbl: boundary.Label[box Result[box Future[box T^?]^?, box E^?]^?]^{cap.rd}) ?->{fr, async} Future[box T^?]^{fr, lbl}
37+
|Required: (lbl: boundary.Label[Result[Future[T], E]]^{cap.rd}) ?=> Future[T]
3738
|
3839
|where: ?=> refers to a fresh root capability created in method fail5 when checking argument to parameter body of method make
40+
| cap is the universal root capability
3941
74 | Future: fut ?=>
4042
75 | fr.await.ok
4143
|

tests/neg-custom-args/captures/extending-cap-classes.check

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/extending-cap-classes.scala:7:15 -------------------------
22
7 | val x2: C1 = new C2 // error
33
| ^^^^^^
4-
| Found: C2
5-
| Required: C1
4+
| Found: C2^{cap.rd}
5+
| Required: C1
6+
|
7+
| where: cap is a fresh root capability created in value x2 when constructing Capability instance C2
68
|
79
| longer explanation available when compiling with `-explain`
810
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/extending-cap-classes.scala:8:15 -------------------------
911
8 | val x3: C1 = new C3 // error
1012
| ^^^^^^
11-
| Found: C3
12-
| Required: C1
13+
| Found: C3^{cap.rd}
14+
| Required: C1
15+
|
16+
| where: cap is a fresh root capability created in value x3 when constructing Capability instance C3
1317
|
1418
| longer explanation available when compiling with `-explain`
1519
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/extending-cap-classes.scala:13:15 ------------------------

tests/neg-custom-args/captures/scoped-caps.check

+16-13
Original file line numberDiff line numberDiff line change
@@ -62,34 +62,37 @@
6262
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/scoped-caps.scala:16:24 ----------------------------------
6363
16 | val _: (x: S) -> B^ = h // error: direct conversion fails
6464
| ^
65-
| Found: (h : S -> B^)
66-
| Required: (x: S) -> B^²
65+
| Found: (h : S -> B^)
66+
| Required: (x: S^{cap.rd}) -> B^²
6767
|
68-
| where: ^ refers to a fresh root capability in the type of value h
69-
| ^² refers to a root capability associated with the result type of (x: S): B^²
68+
| where: ^ refers to a fresh root capability in the type of value h
69+
| ^² refers to a root capability associated with the result type of (x: S^{cap.rd}): B^²
70+
| cap is the universal root capability
7071
|
7172
|
72-
| Note that the existential capture root in B^
73-
| cannot subsume the capability cap
73+
| Note that the existential capture root in B^
74+
| cannot subsume the capability cap
7475
|
7576
| longer explanation available when compiling with `-explain`
7677
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/scoped-caps.scala:22:19 ----------------------------------
7778
22 | val _: S -> B^ = j // error
7879
| ^
79-
| Found: (j : (x: S) -> B^)
80-
| Required: S -> B^²
80+
| Found: (j : (x: S) -> B^)
81+
| Required: S^{cap.rd} -> B^²
8182
|
82-
| where: ^ refers to a root capability associated with the result type of (x: S): B^
83-
| ^² refers to a fresh root capability in the type of value _$11
83+
| where: ^ refers to a root capability associated with the result type of (x: S^{cap.rd}): B^
84+
| ^² refers to a fresh root capability in the type of value _$11
85+
| cap is the universal root capability
8486
|
8587
| longer explanation available when compiling with `-explain`
8688
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/scoped-caps.scala:23:19 ----------------------------------
8789
23 | val _: S -> B^ = x => j(x) // error
8890
| ^^^^^^^^^
89-
| Found: (x: S) ->? B^{x}
90-
| Required: (x: S) -> B^
91+
| Found: (x: S^{cap.rd}) ->? B^{x}
92+
| Required: (x: S^{cap.rd}) -> B^
9193
|
92-
| where: ^ refers to a fresh root capability in the type of value _$12
94+
| where: ^ refers to a fresh root capability in the type of value _$12
95+
| cap is the universal root capability
9396
|
9497
| longer explanation available when compiling with `-explain`
9598
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/scoped-caps.scala:26:20 ----------------------------------

0 commit comments

Comments
 (0)