From 3e5a712dcf6be732c5d2e0ff8bfad09f70e7c4ec Mon Sep 17 00:00:00 2001 From: odersky Date: Sat, 9 Aug 2025 16:30:56 +0200 Subject: [PATCH 1/6] Improve closure typing If the closure has an expected function type with a fully defined result type, take the internalized result type as the local return type of the closure. This has the effect that some conformance tests are now done with Fresh instead Result caps. This means a now can widen a local reference to a result cap, since the comparison is done between the local reference and the internalized FreshCap. Previously this failed since we compared a local cap with result cap, and result caps only subtype other result caps. It also propagates types more aggressively into closure bodies, which sometimes reduces the error span and improves the error message. --- .../src/dotty/tools/dotc/cc/Capability.scala | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/compiler/src/dotty/tools/dotc/cc/Capability.scala b/compiler/src/dotty/tools/dotc/cc/Capability.scala index 55e7762a9269..4c3e1580be91 100644 --- a/compiler/src/dotty/tools/dotc/cc/Capability.scala +++ b/compiler/src/dotty/tools/dotc/cc/Capability.scala @@ -1014,6 +1014,69 @@ object Capabilities: def inverse = Inverse() end Internalize + /** The local dual of a result type of a closure type. + * @param binder the method type of the anonymous function whose result is mapped + * @pre the context's owner is the anonymous function + */ + class Internalize(binder: MethodType)(using Context) extends BiTypeMap: + thisMap => + + val sym = ctx.owner + assert(sym.isAnonymousFunction) + val paramSyms = atPhase(ctx.phase.prev): + // We need to ask one phase before since `sym` should not be completed as a side effect. + // The result of Internalize is used to se the result type of an anonymous function, and + // the new info of that function is built with the result. + sym.paramSymss.head + val resultToFresh = EqHashMap[ResultCap, FreshCap]() + val freshToResult = EqHashMap[FreshCap, ResultCap]() + + override def apply(t: Type) = + if variance < 0 then t + else t match + case t: ParamRef => + if t.binder == this.binder then paramSyms(t.paramNum).termRef else t + case _ => mapOver(t) + + override def mapCapability(c: Capability, deep: Boolean): Capability = c match + case r: ResultCap if r.binder == this.binder => + resultToFresh.get(r) match + case Some(f) => f + case None => + val f = FreshCap(Origin.LocalInstance(binder.resType)) + resultToFresh(r) = f + freshToResult(f) = r + f + case _ => + super.mapCapability(c, deep) + + class Inverse extends BiTypeMap: + def apply(t: Type): Type = + if variance < 0 then t + else t match + case t: TermRef if paramSyms.contains(t) => + binder.paramRefs(paramSyms.indexOf(t.symbol)) + case _ => mapOver(t) + + override def mapCapability(c: Capability, deep: Boolean): Capability = c match + case f: FreshCap if f.owner == sym => + freshToResult.get(f) match + case Some(r) => r + case None => + val r = ResultCap(binder) + resultToFresh(r) = f + freshToResult(f) = r + r + case _ => super.mapCapability(c, deep) + + def inverse = thisMap + override def toString = thisMap.toString + ".inverse" + end Inverse + + override def toString = "InternalizeClosureResult" + def inverse = Inverse() + end Internalize + /** Map top-level free existential variables one-to-one to Fresh instances */ def resultToFresh(tp: Type, origin: Origin)(using Context): Type = val subst = new TypeMap: From c4fe284743627a4f893b14fd847db84a9dddb032 Mon Sep 17 00:00:00 2001 From: odersky Date: Sat, 9 Aug 2025 19:24:10 +0200 Subject: [PATCH 2/6] Better printing of capabilities in error messages - Special case in some situations so that we only print the name, not the underlying type. - Print TermParamRefs like other singleton types --- .../src/dotty/tools/dotc/cc/Capability.scala | 3 +++ .../src/dotty/tools/dotc/cc/CaptureSet.scala | 17 ++++++------ .../tools/dotc/printing/PlainPrinter.scala | 2 -- docs/_docs/reference/experimental/cc.md | 10 ++++--- .../captures/box-adapt-cases.check | 4 +-- tests/neg-custom-args/captures/byname.check | 6 ++--- .../captures/capt-depfun.check | 2 +- tests/neg-custom-args/captures/capt1.check | 10 +++---- tests/neg-custom-args/captures/cc-glb.check | 2 +- .../neg-custom-args/captures/cc-poly-2.check | 2 +- tests/neg-custom-args/captures/cc-this.check | 2 +- tests/neg-custom-args/captures/cc-this5.check | 2 +- .../captures/class-contra.check | 2 +- .../captures/class-level-attack.check | 2 +- .../neg-custom-args/captures/contracap.check | 8 +++--- .../captures/effect-swaps-explicit.check | 7 +++-- .../captures/effect-swaps.check | 7 +++-- tests/neg-custom-args/captures/eta.check | 2 +- tests/neg-custom-args/captures/filevar.check | 5 ++-- .../captures/heal-tparam-cs.check | 11 ++++---- tests/neg-custom-args/captures/i15772.check | 2 +- tests/neg-custom-args/captures/i15923.check | 10 +++---- tests/neg-custom-args/captures/i15923a.check | 3 +-- tests/neg-custom-args/captures/i15923b.check | 3 +-- tests/neg-custom-args/captures/i16226.check | 6 ++--- tests/neg-custom-args/captures/i19330.check | 2 +- tests/neg-custom-args/captures/i19470.check | 2 +- tests/neg-custom-args/captures/i21313.check | 2 +- tests/neg-custom-args/captures/i21401.check | 4 +-- tests/neg-custom-args/captures/i21614.check | 3 +-- tests/neg-custom-args/captures/i21620.check | 4 +-- tests/neg-custom-args/captures/i21920.check | 3 +-- tests/neg-custom-args/captures/i23207.check | 6 ++--- tests/neg-custom-args/captures/lazylist.check | 26 +++++++++---------- .../neg-custom-args/captures/lazylists1.check | 6 ++--- .../neg-custom-args/captures/lazylists2.check | 6 ++--- tests/neg-custom-args/captures/lazyref.check | 20 +++++++------- .../captures/leak-problem-2.check | 2 +- .../captures/leaking-iterators.check | 3 +-- tests/neg-custom-args/captures/leaky.check | 6 ++--- tests/neg-custom-args/captures/levels.check | 2 +- tests/neg-custom-args/captures/lubs.check | 6 ++--- .../captures/nestedclass.check | 2 +- tests/neg-custom-args/captures/readOnly.check | 2 +- .../captures/ro-mut-conformance.check | 2 +- .../captures/scoped-caps.check | 6 ++--- .../captures/sep-curried.check | 8 +++--- .../captures/simple-using.check | 3 +-- tests/neg-custom-args/captures/try.check | 12 ++++----- .../captures/unsound-reach-6.check | 2 +- .../neg-custom-args/captures/use-capset.check | 8 +++--- tests/neg-custom-args/captures/uses.check | 8 +++--- .../captures/usingLogFile.check | 12 +++------ .../captures/vars-simple.check | 4 +-- tests/neg-custom-args/captures/vars.check | 9 +++---- tests/neg/i16842.check | 2 +- tests/neg/i18058.check | 2 +- tests/neg/lambda-rename.check | 4 +-- tests/neg/polymorphic-functions1.check | 4 +-- 59 files changed, 153 insertions(+), 170 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/cc/Capability.scala b/compiler/src/dotty/tools/dotc/cc/Capability.scala index 4c3e1580be91..9cc8e83fca09 100644 --- a/compiler/src/dotty/tools/dotc/cc/Capability.scala +++ b/compiler/src/dotty/tools/dotc/cc/Capability.scala @@ -788,6 +788,9 @@ object Capabilities: case _: Maybe => MaybeCapability(c1) case _ => c1 + def showAsCapability(using Context) = + i"capability ${ctx.printer.toTextCapability(this).show}" + def toText(printer: Printer): Text = printer.toTextCapability(this) end Capability diff --git a/compiler/src/dotty/tools/dotc/cc/CaptureSet.scala b/compiler/src/dotty/tools/dotc/cc/CaptureSet.scala index 70274f3fc057..6e35f44a5604 100644 --- a/compiler/src/dotty/tools/dotc/cc/CaptureSet.scala +++ b/compiler/src/dotty/tools/dotc/cc/CaptureSet.scala @@ -1300,24 +1300,23 @@ object CaptureSet: case cs: Var => if !cs.levelOK(elem) then val levelStr = elem match - case ref: TermRef => i", defined in ${ref.symbol.maybeOwner}" - case _ => "" - i"""capability ${elem}$levelStr - |cannot be included in outer capture set $cs""" + case ref: TermRef => i", defined in ${ref.symbol.maybeOwner}\n" + case _ => " " + i"""${elem.showAsCapability}${levelStr}cannot be included in outer capture set $cs""" else if !elem.tryClassifyAs(cs.classifier) then - i"""capability ${elem} is not classified as ${cs.classifier}, therefore it + i"""${elem.showAsCapability} is not classified as ${cs.classifier}, therefore it |cannot be included in capture set $cs of ${cs.classifier.name} elements""" else if cs.isBadRoot(elem) then elem match case elem: FreshCap => - i"""local capability $elem created in ${elem.ccOwner} + i"""local ${elem.showAsCapability} created in ${elem.ccOwner} |cannot be included in outer capture set $cs""" case _ => - i"universal capability $elem cannot be included in capture set $cs" + i"universal ${elem.showAsCapability} cannot be included in capture set $cs" else - i"capability $elem cannot be included in capture set $cs" + i"${elem.showAsCapability} cannot be included in capture set $cs" case _ => - i"capability $elem is not included in capture set $cs$why" + i"${elem.showAsCapability} is not included in capture set $cs$why" override def toText(printer: Printer): Text = inContext(printer.printerContext): diff --git a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala index c00c4d04a0ee..2d53854c074c 100644 --- a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala @@ -243,8 +243,6 @@ class PlainPrinter(_ctx: Context) extends Printer { selectionString(tp) else toTextPrefixOf(tp) ~ selectionString(tp) - case tp: TermParamRef => - ParamRefNameString(tp) ~ hashStr(tp.binder) ~ ".type" case tp: TypeParamRef => val suffix = if showNestingLevel then diff --git a/docs/_docs/reference/experimental/cc.md b/docs/_docs/reference/experimental/cc.md index 04c9d440a427..b53eb682c3dd 100644 --- a/docs/_docs/reference/experimental/cc.md +++ b/docs/_docs/reference/experimental/cc.md @@ -43,10 +43,12 @@ followed by `^`. We'll see that this turns the parameter into a _capability_ who If we now try to define the problematic value `later`, we get a static error: ``` - | val later = usingLogFile { f => () => f.write(0) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |The expression's type () => Unit is not allowed to capture the root capability `cap`. - |This usually means that a capability persists longer than its allowed lifetime. + |val later = usingLogFile { f => () => f.write(0) } // error + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + |Found: (f: java.io.FileOutputStream^?) ->? () ->{f} Unit + |Required: java.io.FileOutputStream^ => () ->? Unit + | + |Note that capability f cannot be included in outer capture set ?. ``` In this case, it was easy to see that the `logFile` capability escapes in the closure passed to `usingLogFile`. But capture checking also works for more complex cases. For instance, capture checking is able to distinguish between the following safe code: diff --git a/tests/neg-custom-args/captures/box-adapt-cases.check b/tests/neg-custom-args/captures/box-adapt-cases.check index 5cbceb1d6c64..fc4fb57186d6 100644 --- a/tests/neg-custom-args/captures/box-adapt-cases.check +++ b/tests/neg-custom-args/captures/box-adapt-cases.check @@ -3,7 +3,7 @@ | ^^^^^^^^^^^^^^^^ | Found: (cap: Cap^{io}) ->{io} Int | Required: Cap^{io} -> Int - | Note that capability (io : Cap^) is not included in capture set {}. + | Note that capability io is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/box-adapt-cases.scala:29:10 ------------------------------ @@ -11,6 +11,6 @@ | ^^^^^^^^^^^^^^^^ | Found: (cap: Cap^?) ->{io, fs} Int | Required: Cap^{io, fs} ->{io} Int - | Note that capability (fs : Cap^) is not included in capture set {io}. + | Note that capability fs is not included in capture set {io}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/byname.check b/tests/neg-custom-args/captures/byname.check index 152900a5b29a..91e4094a6c9f 100644 --- a/tests/neg-custom-args/captures/byname.check +++ b/tests/neg-custom-args/captures/byname.check @@ -12,7 +12,7 @@ | |where: ?=> refers to a fresh root capability created in method test when checking argument to parameter ff of method h | - |Note that capability (cap1 : Cap) is not included in capture set {cap2}. + |Note that capability cap1 is not included in capture set {cap2}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/byname.scala:19:5 ---------------------------------------- @@ -20,7 +20,7 @@ | ^^^ | Found: () ?->{cap2} I^? | Required: () ?->{cap1} I - | Note that capability (cap2 : Cap) is not included in capture set {cap1}. + | Note that capability cap2 is not included in capture set {cap1}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/byname.scala:22:5 ---------------------------------------- @@ -28,6 +28,6 @@ | ^^^^^^^^^ | Found: () ->{cap2} I^? | Required: () ->{cap1} I - | Note that capability (cap2 : Cap) is not included in capture set {cap1}. + | Note that capability cap2 is not included in capture set {cap1}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/capt-depfun.check b/tests/neg-custom-args/captures/capt-depfun.check index ee80bb335d61..fe60eea0b886 100644 --- a/tests/neg-custom-args/captures/capt-depfun.check +++ b/tests/neg-custom-args/captures/capt-depfun.check @@ -6,6 +6,6 @@ | | where: => refers to a fresh root capability in the type of value dc | - | Note that capability (y : C^) is not included in capture set {}. + | Note that capability y is not included in capture set {}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/capt1.check b/tests/neg-custom-args/captures/capt1.check index 0cd908d081ee..1aaaece13f04 100644 --- a/tests/neg-custom-args/captures/capt1.check +++ b/tests/neg-custom-args/captures/capt1.check @@ -3,7 +3,7 @@ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | Found: () ->{x} C | Required: () -> C - | Note that capability (x : C^) is not included in capture set {}. + | Note that capability x is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/capt1.scala:8:2 ------------------------------------------ @@ -11,7 +11,7 @@ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | Found: () ->{x} C^? | Required: Matchable - | Note that capability (x : C^) is not included in capture set {}. + | Note that capability x is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/capt1.scala:15:2 ----------------------------------------- @@ -19,7 +19,7 @@ | ^ | Found: (y: Int) ->{x} Int | Required: Matchable - | Note that capability (x : C^) is not included in capture set {}. + | Note that capability x is not included in capture set {}. 16 | f | | longer explanation available when compiling with `-explain` @@ -28,7 +28,7 @@ | ^ | Found: A^{x} | Required: A - | Note that capability (x : C^) is not included in capture set {}. + | Note that capability x is not included in capture set {}. 23 | def m() = if x == null then y else y 24 | F(22) | @@ -38,7 +38,7 @@ | ^ | Found: A^{x} | Required: A - | Note that capability (x : C^) is not included in capture set {}. + | Note that capability x is not included in capture set {}. 28 | def m() = if x == null then y else y | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/cc-glb.check b/tests/neg-custom-args/captures/cc-glb.check index 1d978f834175..eff591ea6ea1 100644 --- a/tests/neg-custom-args/captures/cc-glb.check +++ b/tests/neg-custom-args/captures/cc-glb.check @@ -3,6 +3,6 @@ | ^^ | Found: (x1 : (Foo[T] & Foo[Any])^{io}) | Required: Foo[T] - | Note that capability (io : Cap^) is not included in capture set {}. + | Note that capability io is not included in capture set {}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/cc-poly-2.check b/tests/neg-custom-args/captures/cc-poly-2.check index 0577b4f9d22b..863a3fa98539 100644 --- a/tests/neg-custom-args/captures/cc-poly-2.check +++ b/tests/neg-custom-args/captures/cc-poly-2.check @@ -14,6 +14,6 @@ | ^ | Found: (x : Test.D^{d}) | Required: Test.D^{c1} - | Note that capability (d : Test.D^) is not included in capture set {c1}. + | Note that capability d is not included in capture set {c1}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/cc-this.check b/tests/neg-custom-args/captures/cc-this.check index 85040bbaa0b3..672d8f57d3d2 100644 --- a/tests/neg-custom-args/captures/cc-this.check +++ b/tests/neg-custom-args/captures/cc-this.check @@ -3,7 +3,7 @@ | ^^^^ | Found: (C.this : C^{C.this.x}) | Required: C - | Note that capability (C.this.x : () => Int) is not included in capture set {}. + | Note that capability C.this.x is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- Error: tests/neg-custom-args/captures/cc-this.scala:12:15 ----------------------------------------------------------- diff --git a/tests/neg-custom-args/captures/cc-this5.check b/tests/neg-custom-args/captures/cc-this5.check index 253ef3985af9..4ff9452a0956 100644 --- a/tests/neg-custom-args/captures/cc-this5.check +++ b/tests/neg-custom-args/captures/cc-this5.check @@ -8,7 +8,7 @@ | ^^^^ | Found: (A.this : A^{c}) | Required: A - | Note that capability (c : Cap) is not included in capture set {}. + | Note that capability c is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- [E058] Type Mismatch Error: tests/neg-custom-args/captures/cc-this5.scala:7:9 --------------------------------------- diff --git a/tests/neg-custom-args/captures/class-contra.check b/tests/neg-custom-args/captures/class-contra.check index 1c2b7f8e2157..f5ac2ebb219f 100644 --- a/tests/neg-custom-args/captures/class-contra.check +++ b/tests/neg-custom-args/captures/class-contra.check @@ -3,6 +3,6 @@ | ^ | Found: (a : T^{x, y}) | Required: T^{k.f} - | Note that capability (x : C^) is not included in capture set {k.f}. + | Note that capability x is not included in capture set {k.f}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/class-level-attack.check b/tests/neg-custom-args/captures/class-level-attack.check index 9c22c305b1bd..e005dca26b29 100644 --- a/tests/neg-custom-args/captures/class-level-attack.check +++ b/tests/neg-custom-args/captures/class-level-attack.check @@ -13,7 +13,7 @@ | | where: ^ refers to a fresh root capability in the type of value r | - | Note that capability (x : IO^) is not included in capture set {cap} + | Note that capability x is not included in capture set {cap} | because (x : IO^) in method set is not visible from cap in value r. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/contracap.check b/tests/neg-custom-args/captures/contracap.check index 65af3d27cf1d..a18fb11d4883 100644 --- a/tests/neg-custom-args/captures/contracap.check +++ b/tests/neg-custom-args/captures/contracap.check @@ -1,11 +1,11 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/contracap.scala:15:48 ------------------------------------ 15 | val g: (Ref[Int]^{a}, Ref[Int]^{a}) -> Unit = f // error | ^ - | Found: (f : (Ref[Int]^, Ref[Int]^) -> Unit) - | Required: (Ref[Int]^{a}, Ref[Int]^{a}) -> Unit + | Found: (f : (Ref[Int]^, Ref[Int]^) -> Unit) + | Required: (Ref[Int]^{a}, Ref[Int]^{a}) -> Unit | - | where: ^ refers to the universal root capability + | where: ^ refers to the universal root capability | - | Note that capability (a : Ref[Int]^) is not included in capture set {cap}. + | Note that capability a is not included in capture set {cap}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/effect-swaps-explicit.check b/tests/neg-custom-args/captures/effect-swaps-explicit.check index 4b38fb01d207..97bc1f778c5d 100644 --- a/tests/neg-custom-args/captures/effect-swaps-explicit.check +++ b/tests/neg-custom-args/captures/effect-swaps-explicit.check @@ -4,7 +4,7 @@ | ^ | Found: Result.Ok[Future[T^?]^{fr, contextual$1}] | Required: Result[Future[T], Nothing] - | Note that capability (fr : Future[Result[T, E]]^) is not included in capture set {}. + | Note that capability fr is not included in capture set {}. 65 | fr.await.ok |-------------------------------------------------------------------------------------------------------------------- |Inline stack trace @@ -24,8 +24,7 @@ |where: ?=> refers to a fresh root capability created in method fail4 when checking argument to parameter body of method make | ^ refers to the universal root capability | - |Note that capability contextual$9.type - |cannot be included in outer capture set ?. + |Note that capability contextual$9 cannot be included in outer capture set ?. 70 | fr.await.ok | | longer explanation available when compiling with `-explain` @@ -38,7 +37,7 @@ |where: ?=> refers to a fresh root capability created in method fail5 when checking argument to parameter body of method make | ^ refers to the universal root capability | - |Note that capability (fr : Future[Result[T, E]]^) is not included in capture set {}. + |Note that capability fr is not included in capture set {}. 74 | Future: fut ?=> 75 | fr.await.ok | diff --git a/tests/neg-custom-args/captures/effect-swaps.check b/tests/neg-custom-args/captures/effect-swaps.check index 25b3247ea161..6f7cd5e7046e 100644 --- a/tests/neg-custom-args/captures/effect-swaps.check +++ b/tests/neg-custom-args/captures/effect-swaps.check @@ -4,7 +4,7 @@ | ^ | Found: Result.Ok[Future[T^?]^{fr, contextual$1}] | Required: Result[Future[T], Nothing] - | Note that capability (fr : Future[Result[T, E]]^) is not included in capture set {}. + | Note that capability fr is not included in capture set {}. 65 | fr.await.ok |-------------------------------------------------------------------------------------------------------------------- |Inline stack trace @@ -24,8 +24,7 @@ |where: ?=> refers to a fresh root capability created in method fail4 when checking argument to parameter body of method make | ^ refers to the universal root capability | - |Note that capability contextual$9.type - |cannot be included in outer capture set ?. + |Note that capability contextual$9 cannot be included in outer capture set ?. 70 | fr.await.ok | | longer explanation available when compiling with `-explain` @@ -38,7 +37,7 @@ |where: ?=> refers to a fresh root capability created in method fail5 when checking argument to parameter body of method make | ^ refers to the universal root capability | - |Note that capability (fr : Future[Result[T, E]]^) is not included in capture set {}. + |Note that capability fr is not included in capture set {}. 74 | Future: fut ?=> 75 | fr.await.ok | diff --git a/tests/neg-custom-args/captures/eta.check b/tests/neg-custom-args/captures/eta.check index c0123ec59ae4..bc11637022b0 100644 --- a/tests/neg-custom-args/captures/eta.check +++ b/tests/neg-custom-args/captures/eta.check @@ -3,6 +3,6 @@ | ^ | Found: (g : () -> A) | Required: () -> Proc^{f} - | Note that capability (f : Proc^) is not included in capture set {}. + | Note that capability f is not included in capture set {}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/filevar.check b/tests/neg-custom-args/captures/filevar.check index 84101f64b963..c78a642c1cfd 100644 --- a/tests/neg-custom-args/captures/filevar.check +++ b/tests/neg-custom-args/captures/filevar.check @@ -6,8 +6,7 @@ | |where: => refers to a fresh root capability created in anonymous function of type (using l²: scala.caps.Capability): File^{l²} -> Unit when instantiating expected result type (f: File^{l}) ->{cap} Unit of function literal | - |Note that capability l.type - |cannot be included in outer capture set ? of parameter f. + |Note that capability l cannot be included in outer capture set ? of parameter f. 16 | val o = Service() 17 | o.file = f 18 | o.log @@ -16,4 +15,4 @@ -- Warning: tests/neg-custom-args/captures/filevar.scala:11:55 --------------------------------------------------------- 11 |def withFile[T](op: (l: caps.Capability) ?-> (f: File^{l}) => T): T = | ^ - | redundant capture: File already accounts for l.type + | redundant capture: File already accounts for (l : scala.caps.Capability) diff --git a/tests/neg-custom-args/captures/heal-tparam-cs.check b/tests/neg-custom-args/captures/heal-tparam-cs.check index 8a149664ffe7..bdc36a89c116 100644 --- a/tests/neg-custom-args/captures/heal-tparam-cs.check +++ b/tests/neg-custom-args/captures/heal-tparam-cs.check @@ -7,8 +7,7 @@ |where: => refers to a fresh root capability created in value test1 when checking argument to parameter op of method localCap | ^ refers to the universal root capability | - |Note that capability c.type - |cannot be included in outer capture set ?. + |Note that capability c cannot be included in outer capture set ?. 11 | () => { c.use() } 12 | } | @@ -22,7 +21,7 @@ | where: => refers to a root capability associated with the result type of (c: Capp^): () => Unit | ^ refers to the universal root capability | - | Note that capability x$0.type is not included in capture set {{x$0} Unit>}. + | Note that capability x$0 is not included in capture set {{x$0} Unit>}. 16 | (c1: Capp^) => () => { c1.use() } 17 | } | @@ -32,7 +31,7 @@ | ^ | Found: (x$0: Capp^?) ->? () ->{x$0} Unit | Required: (c: Capp^{io}) -> () ->{net} Unit - | Note that capability x$0.type is not included in capture set {net}. + | Note that capability x$0 is not included in capture set {net}. 26 | (c1: Capp^{io}) => () => { c1.use() } 27 | } | @@ -42,7 +41,7 @@ | ^^^^^^^^^^^^^^ | Found: () ->{io} Unit | Required: () -> Unit - | Note that capability (io : Capp^) is not included in capture set {}. + | Note that capability io is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/heal-tparam-cs.scala:44:10 ------------------------------- @@ -50,6 +49,6 @@ | ^^^^^^^^^^^^^^ | Found: () ->{io} Unit | Required: () -> Unit - | Note that capability (io : Capp^) is not included in capture set {}. + | Note that capability io is not included in capture set {}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/i15772.check b/tests/neg-custom-args/captures/i15772.check index 4fbd86815112..d285e2715aa7 100644 --- a/tests/neg-custom-args/captures/i15772.check +++ b/tests/neg-custom-args/captures/i15772.check @@ -37,7 +37,7 @@ | ^ | Found: (x : () ->{filesList, sayHello} Unit) | Required: () -> Unit - | Note that capability (filesList : List[File]^{io}) is not included in capture set {}. + | Note that capability filesList is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- Error: tests/neg-custom-args/captures/i15772.scala:34:10 ------------------------------------------------------------ diff --git a/tests/neg-custom-args/captures/i15923.check b/tests/neg-custom-args/captures/i15923.check index 70d8acffd227..07bc6400ca24 100644 --- a/tests/neg-custom-args/captures/i15923.check +++ b/tests/neg-custom-args/captures/i15923.check @@ -8,8 +8,7 @@ | op is a reference to a value parameter | op² is a reference to a value parameter | - |Note that capability lcap.type - |cannot be included in outer capture set ? of parameter cap. + |Note that capability lcap cannot be included in outer capture set ? of parameter cap. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15923.scala:12:21 --------------------------------------- @@ -20,15 +19,14 @@ | |where: => refers to a fresh root capability created in anonymous function of type (using lcap²: scala.caps.Capability): Cap^{lcap²} -> Id[Cap] when instantiating expected result type Cap^{lcap} ->{cap²} Id[Cap^?]^? of function literal | - |Note that capability lcap.type - |cannot be included in outer capture set ? of parameter cap. + |Note that capability lcap cannot be included in outer capture set ? of parameter cap. | | longer explanation available when compiling with `-explain` -- Warning: tests/neg-custom-args/captures/i15923.scala:21:56 ---------------------------------------------------------- 21 | def withCap[X](op: (lcap: caps.Capability) ?-> Cap^{lcap} => X): X = { | ^^^^ - | redundant capture: test2.Cap already accounts for lcap.type + | redundant capture: test2.Cap already accounts for (lcap : scala.caps.Capability) -- Warning: tests/neg-custom-args/captures/i15923.scala:6:54 ----------------------------------------------------------- 6 | def withCap[X](op: (lcap: caps.Capability) ?-> Cap^{lcap} => X): X = { | ^^^^ - | redundant capture: Cap already accounts for lcap.type + | redundant capture: Cap already accounts for (lcap : scala.caps.Capability) diff --git a/tests/neg-custom-args/captures/i15923a.check b/tests/neg-custom-args/captures/i15923a.check index 6d2156d89a97..d64a3d2b1d03 100644 --- a/tests/neg-custom-args/captures/i15923a.check +++ b/tests/neg-custom-args/captures/i15923a.check @@ -8,7 +8,6 @@ | =>² refers to a root capability associated with the result type of (lcap: Cap^): () =>² Id[Cap^?]^? | ^ refers to the universal root capability | - |Note that capability - |cannot be included in outer capture set ?. + |Note that capability cannot be included in outer capture set ?. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/i15923b.check b/tests/neg-custom-args/captures/i15923b.check index 80e1b3f8b4ba..9d67c47f4c2a 100644 --- a/tests/neg-custom-args/captures/i15923b.check +++ b/tests/neg-custom-args/captures/i15923b.check @@ -7,7 +7,6 @@ |where: => refers to a fresh root capability created in value leak when checking argument to parameter op of method withCap | ^ refers to the universal root capability | - |Note that capability lcap.type - |cannot be included in outer capture set ?. + |Note that capability lcap cannot be included in outer capture set ?. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/i16226.check b/tests/neg-custom-args/captures/i16226.check index e7acc515af2c..76ce50869f41 100644 --- a/tests/neg-custom-args/captures/i16226.check +++ b/tests/neg-custom-args/captures/i16226.check @@ -9,8 +9,8 @@ | =>³ refers to a fresh root capability in the result type of method mapc | ^ refers to a fresh root capability in the result type of method mapc | - |Note that capability f1.type is not included in capture set {cap} - |because f1.type is not visible from cap in method mapc. + |Note that capability f1 is not included in capture set {cap} + |because (f1 : A^? ->? B^?) is not visible from cap in method mapc. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i16226.scala:15:4 ---------------------------------------- @@ -24,6 +24,6 @@ | =>³ refers to a fresh root capability in the result type of method mapd | ^ refers to a root capability associated with the result type of (ref: LazyRef[A]^{io}, f: A =>² B): LazyRef[B]^ | - |Note that capability f1.type is not included in capture set {? A^?}^?, f1: A^? ->? B^?): LazyRef[B^?]{val elem: () => B^?}^{f1, ref1}>}. + |Note that capability f1 is not included in capture set {? A^?}^?, f1: A^? ->? B^?): LazyRef[B^?]{val elem: () => B^?}^{f1, ref1}>}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/i19330.check b/tests/neg-custom-args/captures/i19330.check index 044ebd553c07..88219f0ffa83 100644 --- a/tests/neg-custom-args/captures/i19330.check +++ b/tests/neg-custom-args/captures/i19330.check @@ -8,7 +8,7 @@ | ^ | Found: () ->{t} Logger^{t*} | Required: x.T - | Note that capability (t : () => Logger^) is not included in capture set {}. + | Note that capability t is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i19330.scala:22:22 --------------------------------------- diff --git a/tests/neg-custom-args/captures/i19470.check b/tests/neg-custom-args/captures/i19470.check index d674e8f1c764..355ccf6e297c 100644 --- a/tests/neg-custom-args/captures/i19470.check +++ b/tests/neg-custom-args/captures/i19470.check @@ -3,6 +3,6 @@ | ^^^^^^^^ | Found: Inv[IO^{f?}] | Required: Inv[IO^?]^? - | Note that capability (f : () => IO^) is not included in capture set {f?}. + | Note that capability f is not included in capture set {f?}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/i21313.check b/tests/neg-custom-args/captures/i21313.check index 04c5f452bf54..c1af867788af 100644 --- a/tests/neg-custom-args/captures/i21313.check +++ b/tests/neg-custom-args/captures/i21313.check @@ -10,6 +10,6 @@ | |where: ^ refers to a fresh root capability created in method test when checking argument to parameter src of method await | - |Note that capability (ac1 : Async^) cannot be included in capture set {ac2} of value src2. + |Note that capability ac1 cannot be included in capture set {ac2} of value src2. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/i21401.check b/tests/neg-custom-args/captures/i21401.check index 52be12983cbb..8c88e115204a 100644 --- a/tests/neg-custom-args/captures/i21401.check +++ b/tests/neg-custom-args/captures/i21401.check @@ -22,8 +22,8 @@ | ^ refers to the universal root capability | ^² refers to a fresh root capability created in value a when checking argument to parameter op of method usingIO | - |Note that capability x.type is not included in capture set {cap} - |because x.type is not visible from cap in value a. + |Note that capability x is not included in capture set {cap} + |because (x : IO^?) is not visible from cap in value a. | | longer explanation available when compiling with `-explain` -- Error: tests/neg-custom-args/captures/i21401.scala:16:66 ------------------------------------------------------------ diff --git a/tests/neg-custom-args/captures/i21614.check b/tests/neg-custom-args/captures/i21614.check index 90dee8a8dbe5..a598e7a47937 100644 --- a/tests/neg-custom-args/captures/i21614.check +++ b/tests/neg-custom-args/captures/i21614.check @@ -18,7 +18,6 @@ |where: => refers to a fresh root capability created in method mkLoggers2 when checking argument to parameter f of method map | cap is a root capability associated with the result type of (_$1: File^?): Logger{val f: File^{_$1}}^{cap.rd, _$1} | - |Note that capability C is not classified as trait SharedCapability, therefore it - |cannot be included in capture set ? of parameter _$1 of SharedCapability elements. + |Note that capability .rd cannot be included in outer capture set ?. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/i21620.check b/tests/neg-custom-args/captures/i21620.check index 019ae9623dca..d5c99ede02ec 100644 --- a/tests/neg-custom-args/captures/i21620.check +++ b/tests/neg-custom-args/captures/i21620.check @@ -15,7 +15,7 @@ | ^ | Found: (f : () ->{x} () ->{x} Unit) | Required: () -> () ->{x} Unit - | Note that capability (x : C^) is not included in capture set {}. + | Note that capability x is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i21620.scala:20:33 --------------------------------------- @@ -23,6 +23,6 @@ | ^ | Found: (f : () ->{x} () ->{x} Unit) | Required: () -> () ->{x} Unit - | Note that capability (x : C^) is not included in capture set {}. + | Note that capability x is not included in capture set {}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/i21920.check b/tests/neg-custom-args/captures/i21920.check index 2b860553c3af..dedb073a2181 100644 --- a/tests/neg-custom-args/captures/i21920.check +++ b/tests/neg-custom-args/captures/i21920.check @@ -7,7 +7,6 @@ |where: => refers to a fresh root capability created in value cell when checking argument to parameter f of method open | ^ refers to the universal root capability | - |Note that capability - |cannot be included in outer capture set ?. + |Note that capability cannot be included in outer capture set ?. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/i23207.check b/tests/neg-custom-args/captures/i23207.check index e66b6fb0e285..cc41779b6b47 100644 --- a/tests/neg-custom-args/captures/i23207.check +++ b/tests/neg-custom-args/captures/i23207.check @@ -3,7 +3,7 @@ | ^^^^^ | Found: (box.x : (b : B^{io})^{b}) | Required: A - | Note that capability (io : AnyRef^) is not included in capture set {}. + | Note that capability io is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i23207.scala:18:13 --------------------------------------- @@ -11,7 +11,7 @@ | ^ | Found: (c : B^{b}) | Required: A - | Note that capability (b : B^{io}) is not included in capture set {}. + | Note that capability b is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i23207.scala:23:2 ---------------------------------------- @@ -19,7 +19,7 @@ | ^ | Found: A^{io} | Required: A - | Note that capability (io : AnyRef^) is not included in capture set {}. + | Note that capability io is not included in capture set {}. 24 | val hide: AnyRef^{io} = io 25 | val b = new B 26 | val c = b.getBox.x diff --git a/tests/neg-custom-args/captures/lazylist.check b/tests/neg-custom-args/captures/lazylist.check index 4bf4f1ac94f9..f2fbef088d18 100644 --- a/tests/neg-custom-args/captures/lazylist.check +++ b/tests/neg-custom-args/captures/lazylist.check @@ -1,9 +1,9 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylist.scala:17:15 ------------------------------------- 17 | def tail = xs() // error | ^^^^ - | Found: lazylists.LazyList[T]^{LazyCons.this.xs} - | Required: lazylists.LazyList[T] - | Note that capability (LazyCons.this.xs : () => lazylists.LazyList[T]^) is not included in capture set {}. + | Found: lazylists.LazyList[T]^{LazyCons.this.xs} + | Required: lazylists.LazyList[T] + | Note that capability LazyCons.this.xs is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylist.scala:35:29 ------------------------------------- @@ -11,31 +11,31 @@ | ^^^^ | Found: (ref1 : lazylists.LazyCons[Int]{val xs: () ->{cap1} lazylists.LazyList[Int]^{}}^{cap1}) | Required: lazylists.LazyList[Int] - | Note that capability (cap1 : lazylists.CC^) is not included in capture set {}. + | Note that capability cap1 is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylist.scala:37:36 ------------------------------------- 37 | val ref2c: LazyList[Int]^{ref1} = ref2 // error | ^^^^ - | Found: (ref2 : lazylists.LazyList[Int]^{cap2, ref1}) - | Required: lazylists.LazyList[Int]^{ref1} - | Note that capability (cap2 : lazylists.CC^) is not included in capture set {ref1}. + | Found: (ref2 : lazylists.LazyList[Int]^{cap2, ref1}) + | Required: lazylists.LazyList[Int]^{ref1} + | Note that capability cap2 is not included in capture set {ref1}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylist.scala:39:36 ------------------------------------- 39 | val ref3c: LazyList[Int]^{cap2} = ref3 // error | ^^^^ - |Found: (ref3 : lazylists.LazyList[Int]^{cap2, ref1}) - |Required: lazylists.LazyList[Int]^{cap2} - |Note that capability (ref1 : lazylists.LazyCons[Int]{val xs: () ->{cap1} lazylists.LazyList[Int]^{}}^{cap1}) is not included in capture set {cap2}. + | Found: (ref3 : lazylists.LazyList[Int]^{cap2, ref1}) + | Required: lazylists.LazyList[Int]^{cap2} + | Note that capability ref1 is not included in capture set {cap2}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylist.scala:41:42 ------------------------------------- 41 | val ref4c: LazyList[Int]^{cap1, ref3} = ref4 // error | ^^^^ - | Found: (ref4 : lazylists.LazyList[Int]^{cap3, cap1, cap2}) - | Required: lazylists.LazyList[Int]^{cap1, ref3} - | Note that capability (cap3 : lazylists.CC^) is not included in capture set {cap1, ref3}. + | Found: (ref4 : lazylists.LazyList[Int]^{cap3, cap1, cap2}) + | Required: lazylists.LazyList[Int]^{cap1, ref3} + | Note that capability cap3 is not included in capture set {cap1, ref3}. | | longer explanation available when compiling with `-explain` -- [E164] Declaration Error: tests/neg-custom-args/captures/lazylist.scala:22:6 ---------------------------------------- diff --git a/tests/neg-custom-args/captures/lazylists1.check b/tests/neg-custom-args/captures/lazylists1.check index c14568b9600c..a642351ddea9 100644 --- a/tests/neg-custom-args/captures/lazylists1.check +++ b/tests/neg-custom-args/captures/lazylists1.check @@ -1,8 +1,8 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylists1.scala:25:66 ----------------------------------- 25 | def concat(other: LazyList[A]^{f}): LazyList[A]^{this, f} = ??? : (LazyList[A]^{xs, f}) // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | Found: LazyList[A]^{xs, f} - | Required: LazyList[A]^{Mapped.this, f} - | Note that capability (xs : LazyList[A]^) is not included in capture set {Mapped.this, f}. + | Found: LazyList[A]^{xs, f} + | Required: LazyList[A]^{Mapped.this, f} + | Note that capability xs is not included in capture set {Mapped.this, f}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/lazylists2.check b/tests/neg-custom-args/captures/lazylists2.check index 1f7fd0e509cb..88b7b8c111ca 100644 --- a/tests/neg-custom-args/captures/lazylists2.check +++ b/tests/neg-custom-args/captures/lazylists2.check @@ -3,7 +3,7 @@ | ^ | Found: LazyList[B^?]^{f, xs} | Required: LazyList[B]^{f} - | Note that capability (xs : LazyList[A]^) is not included in capture set {f}. + | Note that capability xs is not included in capture set {f}. 19 | this: (Mapped^{xs, f}) => 20 | def isEmpty = false 21 | def head: B = f(xs.head) @@ -16,7 +16,7 @@ | ^ | Found: LazyList[B^?]^{f, xs} | Required: LazyList[B]^{xs} - | Note that capability (f : A => B) is not included in capture set {xs}. + | Note that capability f is not included in capture set {xs}. 28 | this: Mapped^{xs, f} => 29 | def isEmpty = false 30 | def head: B = f(xs.head) @@ -37,7 +37,7 @@ | ^ | Found: LazyList[B^?]^{f, xs} | Required: LazyList[B]^{xs} - | Note that capability (f : A => B) is not included in capture set {xs}. + | Note that capability f is not included in capture set {xs}. 46 | this: (Mapped^{xs, f}) => 47 | def isEmpty = false 48 | def head: B = f(xs.head) diff --git a/tests/neg-custom-args/captures/lazyref.check b/tests/neg-custom-args/captures/lazyref.check index 933b75cabdb8..596e688faf0b 100644 --- a/tests/neg-custom-args/captures/lazyref.check +++ b/tests/neg-custom-args/captures/lazyref.check @@ -3,31 +3,31 @@ | ^^^^ | Found: (ref1 : LazyRef[Int]{val elem: () ->{cap1} Int}^{cap1}) | Required: LazyRef[Int] - | Note that capability (cap1 : CC^) is not included in capture set {}. + | Note that capability cap1 is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazyref.scala:22:35 -------------------------------------- 22 | val ref2c: LazyRef[Int]^{cap2} = ref2 // error | ^^^^ - |Found: LazyRef[Int]{val elem: () ->{ref2*} Int}^{ref2} - |Required: LazyRef[Int]^{cap2} - |Note that capability (ref2 : LazyRef[Int]{val elem: () => Int}^{cap2, ref1}) is not included in capture set {cap2}. + | Found: LazyRef[Int]{val elem: () ->{ref2*} Int}^{ref2} + | Required: LazyRef[Int]^{cap2} + | Note that capability ref2 is not included in capture set {cap2}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazyref.scala:24:35 -------------------------------------- 24 | val ref3c: LazyRef[Int]^{ref1} = ref3 // error | ^^^^ - |Found: LazyRef[Int]{val elem: () ->{ref3*} Int}^{ref3} - |Required: LazyRef[Int]^{ref1} - |Note that capability (ref3 : LazyRef[Int]{val elem: () => Int}^{cap2, ref1}) is not included in capture set {ref1}. + | Found: LazyRef[Int]{val elem: () ->{ref3*} Int}^{ref3} + | Required: LazyRef[Int]^{ref1} + | Note that capability ref3 is not included in capture set {ref1}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazyref.scala:30:35 -------------------------------------- 30 | val ref4c: LazyRef[Int]^{cap1} = ref4 // error | ^^^^ - |Found: LazyRef[Int]{val elem: () ->{ref4*} Int}^{ref4} - |Required: LazyRef[Int]^{cap1} - |Note that capability (ref4 : LazyRef[Int]{val elem: () => Int}^{cap2, ref1}) is not included in capture set {cap1}. + | Found: LazyRef[Int]{val elem: () ->{ref4*} Int}^{ref4} + | Required: LazyRef[Int]^{cap1} + | Note that capability ref4 is not included in capture set {cap1}. | | longer explanation available when compiling with `-explain` -- Error: tests/neg-custom-args/captures/lazyref.scala:8:24 ------------------------------------------------------------ diff --git a/tests/neg-custom-args/captures/leak-problem-2.check b/tests/neg-custom-args/captures/leak-problem-2.check index 5af4d1135454..6fa6478c7d9a 100644 --- a/tests/neg-custom-args/captures/leak-problem-2.check +++ b/tests/neg-custom-args/captures/leak-problem-2.check @@ -3,6 +3,6 @@ | ^^^^^^^^^^^^^^^^^^^^^ | Found: Source[T^?]^{src1, src2} | Required: Source[T] - | Note that capability (src1 : Source[T]^) is not included in capture set {}. + | Note that capability src1 is not included in capture set {}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/leaking-iterators.check b/tests/neg-custom-args/captures/leaking-iterators.check index 80461c0496ee..f446fe783f0a 100644 --- a/tests/neg-custom-args/captures/leaking-iterators.check +++ b/tests/neg-custom-args/captures/leaking-iterators.check @@ -7,8 +7,7 @@ |where: => refers to a fresh root capability created in method test when checking argument to parameter op of method usingLogFile | ^ refers to the universal root capability | - |Note that capability log.type - |cannot be included in outer capture set ?. + |Note that capability log cannot be included in outer capture set ?. 57 | xs.iterator.map: x => 58 | log.write(x) 59 | x * x diff --git a/tests/neg-custom-args/captures/leaky.check b/tests/neg-custom-args/captures/leaky.check index 57630a636f73..932ab1ebf7af 100644 --- a/tests/neg-custom-args/captures/leaky.check +++ b/tests/neg-custom-args/captures/leaky.check @@ -3,7 +3,7 @@ | ^ | Found: test.runnable.Transform{val fun: Any ->{a} Any}^{a} | Required: test.runnable.Transform - | Note that capability (a : test.runnable.A) is not included in capture set {}. + | Note that capability a is not included in capture set {}. 15 | a.print() 16 | () 17 | Transform(f) @@ -14,7 +14,7 @@ | ^ | Found: test.runnable.Transform{val fun: Any ->{a} Any}^{a} | Required: test.runnable.Transform - | Note that capability (a : test.runnable.A) is not included in capture set {}. + | Note that capability a is not included in capture set {}. 21 | a.print() 22 | () 23 | val x = Transform(f) @@ -26,7 +26,7 @@ | ^ | Found: test.runnable.Transform{val fun: Any ->{a} Any}^{a} | Required: test.runnable.Transform - | Note that capability (a : test.runnable.A) is not included in capture set {}. + | Note that capability a is not included in capture set {}. 28 | a.print() 29 | () 30 | val x = Transform.app(f) diff --git a/tests/neg-custom-args/captures/levels.check b/tests/neg-custom-args/captures/levels.check index 34f339e57869..30bad568e021 100644 --- a/tests/neg-custom-args/captures/levels.check +++ b/tests/neg-custom-args/captures/levels.check @@ -10,6 +10,6 @@ | ^ | Found: (x: String) ->{cap3} String | Required: String -> String - | Note that capability (cap3 : CC^) is not included in capture set {}. + | Note that capability cap3 is not included in capture set {}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/lubs.check b/tests/neg-custom-args/captures/lubs.check index 24f4d2e6546b..b290c442956a 100644 --- a/tests/neg-custom-args/captures/lubs.check +++ b/tests/neg-custom-args/captures/lubs.check @@ -3,7 +3,7 @@ | ^^ | Found: (x1 : D^{d1}) | Required: D - | Note that capability (d1 : D^{c1}) is not included in capture set {}. + | Note that capability d1 is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lubs.scala:18:13 ----------------------------------------- @@ -11,7 +11,7 @@ | ^^ | Found: (x2 : D^{d1}) | Required: D - | Note that capability (d1 : D^{c1}) is not included in capture set {}. + | Note that capability d1 is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lubs.scala:19:13 ----------------------------------------- @@ -19,6 +19,6 @@ | ^^ | Found: (x3 : D^{d1, d2}) | Required: D - | Note that capability (d1 : D^{c1}) is not included in capture set {}. + | Note that capability d1 is not included in capture set {}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/nestedclass.check b/tests/neg-custom-args/captures/nestedclass.check index 5c4125b30535..c50c06d908cd 100644 --- a/tests/neg-custom-args/captures/nestedclass.check +++ b/tests/neg-custom-args/captures/nestedclass.check @@ -3,6 +3,6 @@ | ^^ | Found: (xs : C^{cap1}) | Required: C - | Note that capability (cap1 : CC^) is not included in capture set {}. + | Note that capability cap1 is not included in capture set {}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/readOnly.check b/tests/neg-custom-args/captures/readOnly.check index e212cf2f1a6f..31d9940ab87e 100644 --- a/tests/neg-custom-args/captures/readOnly.check +++ b/tests/neg-custom-args/captures/readOnly.check @@ -11,7 +11,7 @@ | ^^^^ | Found: (putA : Int ->{a} Unit) | Required: Int -> Unit - | Note that capability (a : Ref^) is not included in capture set {}. + | Note that capability a is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- Error: tests/neg-custom-args/captures/readOnly.scala:20:23 ---------------------------------------------------------- diff --git a/tests/neg-custom-args/captures/ro-mut-conformance.check b/tests/neg-custom-args/captures/ro-mut-conformance.check index 0f6ce6bfcf58..5fe6730551b4 100644 --- a/tests/neg-custom-args/captures/ro-mut-conformance.check +++ b/tests/neg-custom-args/captures/ro-mut-conformance.check @@ -11,6 +11,6 @@ | | where: ^ refers to a fresh root capability classified as Mutable in the type of value t | - | Note that capability (a : Ref) is not included in capture set {}. + | Note that capability a is not included in capture set {}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/scoped-caps.check b/tests/neg-custom-args/captures/scoped-caps.check index 90b957c4cb43..04420dd5c319 100644 --- a/tests/neg-custom-args/captures/scoped-caps.check +++ b/tests/neg-custom-args/captures/scoped-caps.check @@ -48,7 +48,7 @@ | ^² refers to a root capability associated with the result type of (x: A^): B^² | ^³ refers to a fresh root capability in the type of value _$5 | - | Note that capability (g : A^ -> B^) is not included in capture set {}. + | Note that capability g is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/scoped-caps.scala:16:24 ---------------------------------- @@ -73,7 +73,7 @@ | ^² refers to a root capability associated with the result type of (x: S^): B^² | ^³ refers to a root capability associated with the result type of (x: S^): B^³ | - | Note that capability (h : S -> B^) is not included in capture set {}. + | Note that capability h is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/scoped-caps.scala:21:23 ---------------------------------- @@ -86,7 +86,7 @@ | ^² refers to a root capability associated with the result type of (x: S^): S^² | ^³ refers to a root capability associated with the result type of (x: S^): S^³ | - | Note that capability (h2 : S -> S) is not included in capture set {}. + | Note that capability h2 is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/scoped-caps.scala:27:19 ---------------------------------- diff --git a/tests/neg-custom-args/captures/sep-curried.check b/tests/neg-custom-args/captures/sep-curried.check index dd0c4d14efa2..47a3aecd9511 100644 --- a/tests/neg-custom-args/captures/sep-curried.check +++ b/tests/neg-custom-args/captures/sep-curried.check @@ -1,12 +1,12 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/sep-curried.scala:48:43 ---------------------------------- 48 | val f: (y: Ref[Int]^{a}) ->{a} Unit = foo(a) // error | ^^^^^^ - | Found: (y: Ref[Int]^) ->{a} Unit - | Required: (y: Ref[Int]^{a}) ->{a} Unit + | Found: (y: Ref[Int]^) ->{a} Unit + | Required: (y: Ref[Int]^{a}) ->{a} Unit | - | where: ^ refers to the universal root capability + | where: ^ refers to the universal root capability | - | Note that capability (a : Ref[Int]^) is not included in capture set {cap}. + | Note that capability a is not included in capture set {cap}. | | longer explanation available when compiling with `-explain` -- Error: tests/neg-custom-args/captures/sep-curried.scala:16:6 -------------------------------------------------------- diff --git a/tests/neg-custom-args/captures/simple-using.check b/tests/neg-custom-args/captures/simple-using.check index 681e83136571..b40debc03153 100644 --- a/tests/neg-custom-args/captures/simple-using.check +++ b/tests/neg-custom-args/captures/simple-using.check @@ -7,7 +7,6 @@ |where: => refers to a fresh root capability created in method test when checking argument to parameter op of method usingLogFile | ^ refers to the universal root capability | - |Note that capability f.type - |cannot be included in outer capture set ?. + |Note that capability f cannot be included in outer capture set ?. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/try.check b/tests/neg-custom-args/captures/try.check index 1d5434b04010..5fecd9309ba4 100644 --- a/tests/neg-custom-args/captures/try.check +++ b/tests/neg-custom-args/captures/try.check @@ -15,8 +15,8 @@ | ^ refers to the universal root capability | ^² refers to a fresh root capability created in value a when checking argument to parameter op of method handle | - |Note that capability x.type is not included in capture set {cap} - |because x.type is not visible from cap in value a. + |Note that capability x is not included in capture set {cap} + |because (x : CT[Exception]^) is not visible from cap in value a. 24 | (x: CanThrow[Exception]) => x 25 | }{ | @@ -30,7 +30,7 @@ |where: => refers to a fresh root capability created in value b when checking argument to parameter op of method handle | ^ refers to the universal root capability | - |Note that capability x.type is not included in capture set {}. + |Note that capability x is not included in capture set {}. 30 | (x: CanThrow[Exception]) => () => raise(new Exception)(using x) 31 | } { | @@ -44,8 +44,7 @@ |where: => refers to a fresh root capability created in value xx when checking argument to parameter op of method handle | ^ refers to the universal root capability | - |Note that capability x.type - |cannot be included in outer capture set ?. + |Note that capability x cannot be included in outer capture set ?. 36 | (x: CanThrow[Exception]) => 37 | () => 38 | raise(new Exception)(using x) @@ -62,8 +61,7 @@ |where: => refers to a fresh root capability created in value global when checking argument to parameter op of method handle | ^ refers to the universal root capability | - |Note that capability x.type - |cannot be included in outer capture set ?. + |Note that capability x cannot be included in outer capture set ?. 48 | (x: CanThrow[Exception]) => 49 | () => 50 | raise(new Exception)(using x) diff --git a/tests/neg-custom-args/captures/unsound-reach-6.check b/tests/neg-custom-args/captures/unsound-reach-6.check index 9cbcf4d37145..9a21ef84cb97 100644 --- a/tests/neg-custom-args/captures/unsound-reach-6.check +++ b/tests/neg-custom-args/captures/unsound-reach-6.check @@ -11,7 +11,7 @@ | ^ | Found: (x : () ->{io} Unit) | Required: () -> Unit - | Note that capability (io : IO^) is not included in capture set {}. + | Note that capability io is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- Error: tests/neg-custom-args/captures/unsound-reach-6.scala:7:13 ---------------------------------------------------- diff --git a/tests/neg-custom-args/captures/use-capset.check b/tests/neg-custom-args/captures/use-capset.check index d093a9ceff15..a00d77fc560f 100644 --- a/tests/neg-custom-args/captures/use-capset.check +++ b/tests/neg-custom-args/captures/use-capset.check @@ -3,15 +3,15 @@ | ^ | Found: (h : () ->{io} Unit) | Required: () -> Unit - | Note that capability (io : Object^) is not included in capture set {}. + | Note that capability io is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/use-capset.scala:13:50 ----------------------------------- 13 | val _: () -> List[Object^{io}] -> Object^{io} = h2 // error, should be ->{io} | ^^ - | Found: (h2 : () ->{} List[Object^{io}]^{} ->{io} Object^{io}) - | Required: () -> List[Object^{io}] -> Object^{io} - | Note that capability (io : Object^) is not included in capture set {}. + | Found: (h2 : () ->{} List[Object^{io}]^{} ->{io} Object^{io}) + | Required: () -> List[Object^{io}] -> Object^{io} + | Note that capability io is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- Error: tests/neg-custom-args/captures/use-capset.scala:5:49 --------------------------------------------------------- diff --git a/tests/neg-custom-args/captures/uses.check b/tests/neg-custom-args/captures/uses.check index c5044c647ce0..43d0ff8cec6d 100644 --- a/tests/neg-custom-args/captures/uses.check +++ b/tests/neg-custom-args/captures/uses.check @@ -3,7 +3,7 @@ | ^ | Found: (d : D^{x, y}) | Required: D^{y} - | Note that capability (x : C^) is not included in capture set {y}. + | Note that capability x is not included in capture set {y}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/uses.scala:9:13 ------------------------------------------ @@ -11,7 +11,7 @@ | ^ | Found: (d : D^{x, y}) | Required: D - | Note that capability (x : C^) is not included in capture set {}. + | Note that capability x is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/uses.scala:18:34 ----------------------------------------- @@ -19,7 +19,7 @@ | ^ | Found: () ->{x, y} () ->{y} Unit | Required: () ->{x} () ->{y} Unit - | Note that capability (y : C^) is not included in capture set {x}. + | Note that capability y is not included in capture set {x}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/uses.scala:19:28 ----------------------------------------- @@ -27,6 +27,6 @@ | ^ | Found: () ->{x, y} () ->{y} Unit | Required: () -> () -> Unit - | Note that capability (x : C^) is not included in capture set {}. + | Note that capability x is not included in capture set {}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/usingLogFile.check b/tests/neg-custom-args/captures/usingLogFile.check index 3add71106063..c7c7dbd6a0ee 100644 --- a/tests/neg-custom-args/captures/usingLogFile.check +++ b/tests/neg-custom-args/captures/usingLogFile.check @@ -7,8 +7,7 @@ |where: => refers to a fresh root capability created in value later when checking argument to parameter op of method usingLogFile | ^ refers to the universal root capability | - |Note that capability f.type - |cannot be included in outer capture set ?. + |Note that capability f cannot be included in outer capture set ?. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/usingLogFile.scala:27:36 --------------------------------- @@ -20,8 +19,7 @@ |where: => refers to a fresh root capability created in value later2 when checking argument to parameter op of method usingLogFile | ^ refers to the universal root capability | - |Note that capability f.type - |cannot be included in outer capture set ?. + |Note that capability f cannot be included in outer capture set ?. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/usingLogFile.scala:43:33 --------------------------------- @@ -33,8 +31,7 @@ |where: => refers to a fresh root capability created in value later when checking argument to parameter op of method usingFile | ^ refers to the universal root capability | - |Note that capability f.type - |cannot be included in outer capture set ?. + |Note that capability f cannot be included in outer capture set ?. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/usingLogFile.scala:52:6 ---------------------------------- @@ -46,7 +43,6 @@ |where: => refers to a fresh root capability created in value later when checking argument to parameter op of method usingFile | ^ refers to the universal root capability | - |Note that capability _$1.type - |cannot be included in outer capture set ?. + |Note that capability _$1 cannot be included in outer capture set ?. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/vars-simple.check b/tests/neg-custom-args/captures/vars-simple.check index 931fb0c19cca..2fd7ead20da3 100644 --- a/tests/neg-custom-args/captures/vars-simple.check +++ b/tests/neg-custom-args/captures/vars-simple.check @@ -14,7 +14,7 @@ | ^ | Found: (x: String) ->{cap3} String | Required: String ->{cap1, cap2} String - | Note that capability (cap3 : CC^) is not included in capture set {cap1, cap2}. + | Note that capability cap3 is not included in capture set {cap1, cap2}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/vars-simple.scala:17:12 ---------------------------------- @@ -22,6 +22,6 @@ | ^^^^^^^ | Found: List[String ->{cap3} String] | Required: List[String ->{cap1, cap2} String] - | Note that capability (cap3 : CC^) is not included in capture set {cap1, cap2}. + | Note that capability cap3 is not included in capture set {cap1, cap2}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/vars.check b/tests/neg-custom-args/captures/vars.check index 0ce74f481b56..66354892efd8 100644 --- a/tests/neg-custom-args/captures/vars.check +++ b/tests/neg-custom-args/captures/vars.check @@ -3,7 +3,7 @@ | ^^^^^^^^^ | Found: (x: String) ->{cap3} String | Required: String ->{cap1} String - | Note that capability (cap3 : CC^), defined in method scope + | Note that capability cap3, defined in method scope | cannot be included in outer capture set {cap1} of variable a. | | longer explanation available when compiling with `-explain` @@ -12,7 +12,7 @@ | ^ | Found: (x: String) ->{cap3} String | Required: String ->{cap1} String - | Note that capability (cap3 : CC^), defined in method scope + | Note that capability cap3, defined in method scope | cannot be included in outer capture set {cap1} of variable a. | | longer explanation available when compiling with `-explain` @@ -21,7 +21,7 @@ | ^^^^^^^ | Found: List[String ->{cap3} String] | Required: List[String ->{cap1, cap2} String] - | Note that capability (cap3 : CC^) is not included in capture set {cap1, cap2}. + | Note that capability cap3 is not included in capture set {cap1, cap2}. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/vars.scala:36:8 ------------------------------------------ @@ -34,8 +34,7 @@ | =>² refers to a fresh root capability created in method test of parameter parameter cap3² of method $anonfun | ^ refers to the universal root capability | - |Note that capability String> - |cannot be included in outer capture set {cap}. + | Note that capability String> cannot be included in outer capture set {cap}. 37 | def g(x: String): String = if cap3 == cap3 then "" else "a" 38 | g 39 | } diff --git a/tests/neg/i16842.check b/tests/neg/i16842.check index 936b08f95dbb..9a77e194add0 100644 --- a/tests/neg/i16842.check +++ b/tests/neg/i16842.check @@ -1,4 +1,4 @@ -- Error: tests/neg/i16842.scala:24:7 ---------------------------------------------------------------------------------- 24 | Liter(SemanticArray[SemanticInt.type], x) // error | ^ - | invalid new prefix (dim: Int): SemanticArray[SemanticInt.type] cannot replace ty.type in type ty.T + |invalid new prefix (dim: Int): SemanticArray[SemanticInt.type] cannot replace (ty : SemanticArray[SemanticType]) in type ty.T diff --git a/tests/neg/i18058.check b/tests/neg/i18058.check index f610d9e7abb1..993b7b0362ed 100644 --- a/tests/neg/i18058.check +++ b/tests/neg/i18058.check @@ -1,4 +1,4 @@ -- Error: tests/neg/i18058.scala:4:21 ---------------------------------------------------------------------------------- 4 |type G = (f: ? <: F) => f.A // error | ^ - | invalid new prefix <: F cannot replace f.type in type f.A + | invalid new prefix <: F cannot replace (f : <: F) in type f.A diff --git a/tests/neg/lambda-rename.check b/tests/neg/lambda-rename.check index 39969d4a7cfa..53c43ca8f1b4 100644 --- a/tests/neg/lambda-rename.check +++ b/tests/neg/lambda-rename.check @@ -1,8 +1,8 @@ -- [E007] Type Mismatch Error: tests/neg/lambda-rename.scala:4:33 ------------------------------------------------------ 4 |val a: (x: Int) => Bar[x.type] = ??? : ((x: Int) => Foo[x.type]) // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | Found: (x: Int) => Foo[x.type] - | Required: (x: Int) => Bar[x.type] + | Found: (x: Int) => Foo[(x : Int)] + | Required: (x: Int) => Bar[(x : Int)] | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg/lambda-rename.scala:7:33 ------------------------------------------------------ diff --git a/tests/neg/polymorphic-functions1.check b/tests/neg/polymorphic-functions1.check index f925fe7b0f52..612c1d0688a1 100644 --- a/tests/neg/polymorphic-functions1.check +++ b/tests/neg/polymorphic-functions1.check @@ -1,8 +1,8 @@ -- [E007] Type Mismatch Error: tests/neg/polymorphic-functions1.scala:1:33 --------------------------------------------- 1 |val f: [T] => (x: T) => x.type = [T] => (x: Int) => x // error | ^^^^^^^^^^^^^^^^^^^^ - | Found: [T] => (x: Int) => x.type - | Required: [T] => (x²: T) => x².type + | Found: [T] => (x: Int) => (x : Int) + | Required: [T] => (x²: T) => (x² : T) | | where: x is a reference to a value parameter | x² is a reference to a value parameter From 3196676c0738cc7bdb4c9c1e91eaabd5055f67ae Mon Sep 17 00:00:00 2001 From: odersky Date: Sat, 9 Aug 2025 21:36:28 +0200 Subject: [PATCH 3/6] Fix completion test --- .../test/dotty/tools/languageserver/CompletionTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/language-server/test/dotty/tools/languageserver/CompletionTest.scala b/language-server/test/dotty/tools/languageserver/CompletionTest.scala index 528aa1055c6f..f796ba0e0646 100644 --- a/language-server/test/dotty/tools/languageserver/CompletionTest.scala +++ b/language-server/test/dotty/tools/languageserver/CompletionTest.scala @@ -27,7 +27,7 @@ class CompletionTest { @Test def completionFromNewScalaPredef: Unit = { code"class Foo { val foo = summ${m1} }" - .completion(("summon", Method, "[T](using x: T): x.type")) + .completion(("summon", Method, "[T](using x: T): (x : T)")) } @Test def completionFromScalaPackage: Unit = { From 174849d16389e8a73d55e5800d8d8e52ebee825a Mon Sep 17 00:00:00 2001 From: odersky Date: Sun, 10 Aug 2025 12:11:32 +0200 Subject: [PATCH 4/6] Use unique names to print empty capture set variables --- .../src/dotty/tools/dotc/cc/CaptureSet.scala | 14 +++++++++++ .../src/dotty/tools/dotc/core/NameKinds.scala | 1 + .../tools/dotc/printing/PlainPrinter.scala | 7 +++--- .../captures/box-adapt-cases.check | 2 +- tests/neg-custom-args/captures/byname.check | 4 ++-- tests/neg-custom-args/captures/capt1.check | 6 ++--- .../captures/depfun-reach.check | 2 +- .../captures/effect-swaps-explicit.check | 10 ++++---- .../captures/effect-swaps.check | 10 ++++---- tests/neg-custom-args/captures/filevar.check | 4 ++-- .../captures/heal-tparam-cs.check | 12 +++++----- tests/neg-custom-args/captures/i15923.check | 16 ++++++------- tests/neg-custom-args/captures/i15923a.check | 8 +++---- tests/neg-custom-args/captures/i15923b.check | 4 ++-- tests/neg-custom-args/captures/i16226.check | 19 ++++++++++----- tests/neg-custom-args/captures/i19470.check | 2 +- tests/neg-custom-args/captures/i21401.check | 18 +++++++------- tests/neg-custom-args/captures/i21614.check | 4 ++-- tests/neg-custom-args/captures/i21920.check | 6 ++--- tests/neg-custom-args/captures/i23431.check | 2 +- .../neg-custom-args/captures/lazylists2.check | 6 ++--- .../captures/leak-problem-2.check | 2 +- .../captures/leaking-iterators.check | 6 ++--- tests/neg-custom-args/captures/reaches.check | 12 +++++----- tests/neg-custom-args/captures/reaches2.check | 4 ++-- tests/neg-custom-args/captures/real-try.check | 4 ++-- .../captures/scoped-caps.check | 2 +- .../captures/simple-using.check | 6 ++--- tests/neg-custom-args/captures/try.check | 16 ++++++------- .../captures/unsound-reach-4.check | 2 +- .../captures/unsound-reach.check | 2 +- .../captures/usingLogFile.check | 24 +++++++++---------- tests/neg-custom-args/captures/vars.check | 4 ++-- .../captures/widen-reach.check | 2 +- 34 files changed, 133 insertions(+), 110 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/cc/CaptureSet.scala b/compiler/src/dotty/tools/dotc/cc/CaptureSet.scala index 6e35f44a5604..0ababe60e743 100644 --- a/compiler/src/dotty/tools/dotc/cc/CaptureSet.scala +++ b/compiler/src/dotty/tools/dotc/cc/CaptureSet.scala @@ -20,6 +20,8 @@ import CCState.* import TypeOps.AvoidMap import compiletime.uninitialized import Capabilities.* +import Names.Name +import NameKinds.CapsetName /** A class for capture sets. Capture sets can be constants or variables. * Capture sets support inclusion constraints <:< where <:< is subcapturing. @@ -738,6 +740,17 @@ object CaptureSet: var description: String = "" + private var myRepr: Name | Null = null + + /** A represtentation of this capture set as a unique name. We print + * empty capture set variables in this representation. Bimapped sets have + * the representation of their source set. + */ + def repr(using Context): Name = { + if (myRepr == null) myRepr = CapsetName.fresh() + myRepr.nn + } + /** Check that all maps recorded in skippedMaps map `elem` to itself * or something subsumed by it. */ @@ -1028,6 +1041,7 @@ object CaptureSet: override def isMaybeSet: Boolean = bimap.isInstanceOf[MaybeMap] override def toString = s"BiMapped$id($source, elems = $elems)" override def summarize = bimap.getClass.toString + override def repr(using Context): Name = source.repr end BiMapped /** A variable with elements given at any time as { x <- source.elems | p(x) } */ diff --git a/compiler/src/dotty/tools/dotc/core/NameKinds.scala b/compiler/src/dotty/tools/dotc/core/NameKinds.scala index ff41eeb81ca0..f41062d908e9 100644 --- a/compiler/src/dotty/tools/dotc/core/NameKinds.scala +++ b/compiler/src/dotty/tools/dotc/core/NameKinds.scala @@ -328,6 +328,7 @@ object NameKinds { val ExceptionBinderName: UniqueNameKind = new UniqueNameKind("ex") val ExistentialBinderName: UniqueNameKind = new UniqueNameKind("ex$") val SkolemName: UniqueNameKind = new UniqueNameKind("?") + val CapsetName: UniqueNameKind = new UniqueNameKind("'s") val SuperArgName: UniqueNameKind = new UniqueNameKind("$superArg$") val DocArtifactName: UniqueNameKind = new UniqueNameKind("$doc") val UniqueInlineName: UniqueNameKind = new UniqueNameKind("$i") diff --git a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala index 2d53854c074c..cda3e7d4b6f2 100644 --- a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala @@ -173,10 +173,11 @@ class PlainPrinter(_ctx: Context) extends Printer { else if cs == CaptureSet.Fluid then "" else val core: Text = - if !cs.isConst && cs.elems.isEmpty then "?" - else "{" ~ Text(cs.processElems(_.toList.map(toTextCapability)), ", ") ~ "}" + if !cs.isConst && cs.elems.isEmpty then cs.asVar.repr.show + else + Str("'").provided(ccVerbose && !cs.isConst) + ~ "{" ~ Text(cs.processElems(_.toList.map(toTextCapability)), ", ") ~ "}" ~ Str(".reader").provided(ccVerbose && cs.mutability == Mutability.Reader) - ~ Str("?").provided(ccVerbose && !cs.isConst) ~ Str(s"#${cs.asVar.id}").provided(showUniqueIds && !cs.isConst) core ~ cs.optionalInfo diff --git a/tests/neg-custom-args/captures/box-adapt-cases.check b/tests/neg-custom-args/captures/box-adapt-cases.check index fc4fb57186d6..0e403308ec2f 100644 --- a/tests/neg-custom-args/captures/box-adapt-cases.check +++ b/tests/neg-custom-args/captures/box-adapt-cases.check @@ -9,7 +9,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/box-adapt-cases.scala:29:10 ------------------------------ 29 | x.value(cap => cap.use()) // error | ^^^^^^^^^^^^^^^^ - | Found: (cap: Cap^?) ->{io, fs} Int + | Found: (cap: Cap^'s1) ->{io, fs} Int | Required: Cap^{io, fs} ->{io} Int | Note that capability fs is not included in capture set {io}. | diff --git a/tests/neg-custom-args/captures/byname.check b/tests/neg-custom-args/captures/byname.check index 91e4094a6c9f..7fbeb6f2ddbe 100644 --- a/tests/neg-custom-args/captures/byname.check +++ b/tests/neg-custom-args/captures/byname.check @@ -18,7 +18,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/byname.scala:19:5 ---------------------------------------- 19 | h(g()) // error | ^^^ - | Found: () ?->{cap2} I^? + | Found: () ?->{cap2} I^'s1 | Required: () ?->{cap1} I | Note that capability cap2 is not included in capture set {cap1}. | @@ -26,7 +26,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/byname.scala:22:5 ---------------------------------------- 22 | h2(() => g())() // error | ^^^^^^^^^ - | Found: () ->{cap2} I^? + | Found: () ->{cap2} I^'s2 | Required: () ->{cap1} I | Note that capability cap2 is not included in capture set {cap1}. | diff --git a/tests/neg-custom-args/captures/capt1.check b/tests/neg-custom-args/captures/capt1.check index 1aaaece13f04..9d2ae82d814c 100644 --- a/tests/neg-custom-args/captures/capt1.check +++ b/tests/neg-custom-args/captures/capt1.check @@ -9,7 +9,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/capt1.scala:8:2 ------------------------------------------ 8 | () => if x == null then y else y // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | Found: () ->{x} C^? + | Found: () ->{x} C^'s1 | Required: Matchable | Note that capability x is not included in capture set {}. | @@ -52,7 +52,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/capt1.scala:36:24 ---------------------------------------- 36 | val z2 = h[() -> Cap](() => x) // error // error | ^^^^^^^ - |Found: () ->? C^ + |Found: () ->'s2 C^ |Required: () -> C^² | |where: ^ refers to a root capability associated with the result type of (): C^ @@ -65,7 +65,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/capt1.scala:37:5 ----------------------------------------- 37 | (() => C()) // error | ^^^^^^^^^ - |Found: () ->? C^ + |Found: () ->'s3 C^ |Required: () -> C^² | |where: ^ refers to a root capability associated with the result type of (): C^ diff --git a/tests/neg-custom-args/captures/depfun-reach.check b/tests/neg-custom-args/captures/depfun-reach.check index 446ba4151c9a..310ca9abc2c2 100644 --- a/tests/neg-custom-args/captures/depfun-reach.check +++ b/tests/neg-custom-args/captures/depfun-reach.check @@ -1,7 +1,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/depfun-reach.scala:12:27 --------------------------------- 12 | List(() => op.foreach((f,g) => { f(); g() })) // error (???) | ^^^^^^^^^^^^^^^^^^^^ - |Found: (x$1: (() ->? Unit, () ->? Unit)^?) ->? Unit + |Found: (x$1: (() ->'s1 Unit, () ->'s2 Unit)^'s3) ->'s4 Unit |Required: ((() ->{op*} Unit, () ->{op*} Unit)) => Unit | |where: => refers to a fresh root capability created in anonymous function of type (): Unit when checking argument to parameter op of method foreach diff --git a/tests/neg-custom-args/captures/effect-swaps-explicit.check b/tests/neg-custom-args/captures/effect-swaps-explicit.check index 97bc1f778c5d..cd2efbc233c6 100644 --- a/tests/neg-custom-args/captures/effect-swaps-explicit.check +++ b/tests/neg-custom-args/captures/effect-swaps-explicit.check @@ -2,7 +2,7 @@ 63 | Result: 64 | Future: // error, type mismatch | ^ - | Found: Result.Ok[Future[T^?]^{fr, contextual$1}] + | Found: Result.Ok[Future[T^'s1]^{fr, contextual$1}] | Required: Result[Future[T], Nothing] | Note that capability fr is not included in capture set {}. 65 | fr.await.ok @@ -18,20 +18,20 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/effect-swaps-explicit.scala:69:10 ------------------------ 69 | Future: fut ?=> // error, type mismatch | ^ - |Found: (contextual$9: boundary.Label[Result[Future[T^?]^?, E^?]^?]^?) ?->{fr, async} Future[T^?]^{fr, contextual$9} - |Required: (boundary.Label[Result[Future[T^?]^?, E^?]]^) ?=> Future[T^?]^? + |Found: (contextual$9: boundary.Label[Result[Future[T^'s2]^'s3, E^'s4]^'s5]^'s6) ?->{fr, async} Future[T^'s7]^{fr, contextual$9} + |Required: (boundary.Label[Result[Future[T^'s8]^'s9, E^'s10]]^) ?=> Future[T^'s8]^'s9 | |where: ?=> refers to a fresh root capability created in method fail4 when checking argument to parameter body of method make | ^ refers to the universal root capability | - |Note that capability contextual$9 cannot be included in outer capture set ?. + |Note that capability contextual$9 cannot be included in outer capture set 's9. 70 | fr.await.ok | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/effect-swaps-explicit.scala:73:35 ------------------------ 73 | Result.make[Future[T], E]: lbl ?=> // error: type mismatch | ^ - |Found: (lbl: boundary.Label[Result[Future[T^?]^?, E^?]^?]^?) ?->{fr, async} Future[T^?]^{fr, lbl} + |Found: (lbl: boundary.Label[Result[Future[T^'s11]^'s12, E^'s13]^'s14]^'s15) ?->{fr, async} Future[T^'s16]^{fr, lbl} |Required: (boundary.Label[Result[Future[T], E]]^) ?=> Future[T] | |where: ?=> refers to a fresh root capability created in method fail5 when checking argument to parameter body of method make diff --git a/tests/neg-custom-args/captures/effect-swaps.check b/tests/neg-custom-args/captures/effect-swaps.check index 6f7cd5e7046e..b9bcfdfa667d 100644 --- a/tests/neg-custom-args/captures/effect-swaps.check +++ b/tests/neg-custom-args/captures/effect-swaps.check @@ -2,7 +2,7 @@ 63 | Result: 64 | Future: // error, type mismatch | ^ - | Found: Result.Ok[Future[T^?]^{fr, contextual$1}] + | Found: Result.Ok[Future[T^'s1]^{fr, contextual$1}] | Required: Result[Future[T], Nothing] | Note that capability fr is not included in capture set {}. 65 | fr.await.ok @@ -18,20 +18,20 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/effect-swaps.scala:69:10 --------------------------------- 69 | Future: fut ?=> // error, type mismatch | ^ - |Found: (contextual$9: boundary.Label[Result[Future[T^?]^?, E^?]^?]^?) ?->{fr, async} Future[T^?]^{fr, contextual$9} - |Required: (boundary.Label[Result[Future[T^?]^?, E^?]]^) ?=> Future[T^?]^? + |Found: (contextual$9: boundary.Label[Result[Future[T^'s2]^'s3, E^'s4]^'s5]^'s6) ?->{fr, async} Future[T^'s7]^{fr, contextual$9} + |Required: (boundary.Label[Result[Future[T^'s8]^'s9, E^'s10]]^) ?=> Future[T^'s8]^'s9 | |where: ?=> refers to a fresh root capability created in method fail4 when checking argument to parameter body of method make | ^ refers to the universal root capability | - |Note that capability contextual$9 cannot be included in outer capture set ?. + |Note that capability contextual$9 cannot be included in outer capture set 's9. 70 | fr.await.ok | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/effect-swaps.scala:73:35 --------------------------------- 73 | Result.make[Future[T], E]: lbl ?=> // error: type mismatch | ^ - |Found: (lbl: boundary.Label[Result[Future[T^?]^?, E^?]^?]^?) ?->{fr, async} Future[T^?]^{fr, lbl} + |Found: (lbl: boundary.Label[Result[Future[T^'s11]^'s12, E^'s13]^'s14]^'s15) ?->{fr, async} Future[T^'s16]^{fr, lbl} |Required: (boundary.Label[Result[Future[T], E]]^) ?=> Future[T] | |where: ?=> refers to a fresh root capability created in method fail5 when checking argument to parameter body of method make diff --git a/tests/neg-custom-args/captures/filevar.check b/tests/neg-custom-args/captures/filevar.check index c78a642c1cfd..81a41fe3c257 100644 --- a/tests/neg-custom-args/captures/filevar.check +++ b/tests/neg-custom-args/captures/filevar.check @@ -1,12 +1,12 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/filevar.scala:15:12 -------------------------------------- 15 | withFile: f => // error with level checking, was OK under both schemes before | ^ - |Found: (f: File^?) ->? Unit + |Found: (f: File^'s1) ->'s2 Unit |Required: (f: File^{l}) => Unit | |where: => refers to a fresh root capability created in anonymous function of type (using l²: scala.caps.Capability): File^{l²} -> Unit when instantiating expected result type (f: File^{l}) ->{cap} Unit of function literal | - |Note that capability l cannot be included in outer capture set ? of parameter f. + |Note that capability l cannot be included in outer capture set 's1 of parameter f. 16 | val o = Service() 17 | o.file = f 18 | o.log diff --git a/tests/neg-custom-args/captures/heal-tparam-cs.check b/tests/neg-custom-args/captures/heal-tparam-cs.check index bdc36a89c116..2d5ee98059f3 100644 --- a/tests/neg-custom-args/captures/heal-tparam-cs.check +++ b/tests/neg-custom-args/captures/heal-tparam-cs.check @@ -1,13 +1,13 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/heal-tparam-cs.scala:10:23 ------------------------------- 10 | val test1 = localCap { c => // error | ^ - |Found: (c: Capp^?) ->? () ->{c} Unit - |Required: (c: Capp^) => () ->? Unit + |Found: (c: Capp^'s1) ->'s2 () ->{c} Unit + |Required: (c: Capp^) => () ->'s3 Unit | |where: => refers to a fresh root capability created in value test1 when checking argument to parameter op of method localCap | ^ refers to the universal root capability | - |Note that capability c cannot be included in outer capture set ?. + |Note that capability c cannot be included in outer capture set 's3. 11 | () => { c.use() } 12 | } | @@ -15,13 +15,13 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/heal-tparam-cs.scala:15:13 ------------------------------- 15 | localCap { c => // error | ^ - | Found: (x$0: Capp^?) ->? () ->{x$0} Unit + | Found: (x$0: Capp^'s4) ->'s5 () ->{x$0} Unit | Required: (c: Capp^) -> () => Unit | | where: => refers to a root capability associated with the result type of (c: Capp^): () => Unit | ^ refers to the universal root capability | - | Note that capability x$0 is not included in capture set {{x$0} Unit>}. + | Note that capability x$0 is not included in capture set {{x$0} Unit>}. 16 | (c1: Capp^) => () => { c1.use() } 17 | } | @@ -29,7 +29,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/heal-tparam-cs.scala:25:13 ------------------------------- 25 | localCap { c => // error | ^ - | Found: (x$0: Capp^?) ->? () ->{x$0} Unit + | Found: (x$0: Capp^'s6) ->'s7 () ->{x$0} Unit | Required: (c: Capp^{io}) -> () ->{net} Unit | Note that capability x$0 is not included in capture set {net}. 26 | (c1: Capp^{io}) => () => { c1.use() } diff --git a/tests/neg-custom-args/captures/i15923.check b/tests/neg-custom-args/captures/i15923.check index 07bc6400ca24..1adeeb60edb8 100644 --- a/tests/neg-custom-args/captures/i15923.check +++ b/tests/neg-custom-args/captures/i15923.check @@ -1,25 +1,25 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15923.scala:27:23 --------------------------------------- 27 | val leak = withCap(cap => mkId(cap)) // error (was: no error here since type aliases don't box) | ^^^^^^^^^^^^^^^^ - |Found: (cap: test2.Cap^?) ->? [T] => (op: test2.Cap^? ->? T) ->? T - |Required: test2.Cap^{lcap} => [T] => (op²: test2.Cap^? ->? T) ->? T + |Found: (cap: test2.Cap^'s1) ->'s2 [T] => (op: test2.Cap^'s3 ->'s4 T) ->'s5 T + |Required: test2.Cap^{lcap} => [T] => (op²: test2.Cap^'s6 ->'s7 T) ->'s8 T | - |where: => refers to a fresh root capability created in anonymous function of type (using lcap²: scala.caps.Capability): test2.Cap^{lcap²} -> [T] => (op³: test2.Cap^{lcap²} => T) -> T when instantiating expected result type test2.Cap^{lcap} ->{cap²} [T] => (op²: test2.Cap^? ->? T) ->? T of function literal + |where: => refers to a fresh root capability created in anonymous function of type (using lcap²: scala.caps.Capability): test2.Cap^{lcap²} -> [T] => (op³: test2.Cap^{lcap²} => T) -> T when instantiating expected result type test2.Cap^{lcap} ->{cap²} [T] => (op²: test2.Cap^'s6 ->'s7 T) ->'s8 T of function literal | op is a reference to a value parameter | op² is a reference to a value parameter | - |Note that capability lcap cannot be included in outer capture set ? of parameter cap. + |Note that capability lcap cannot be included in outer capture set 's1 of parameter cap. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15923.scala:12:21 --------------------------------------- 12 | val leak = withCap(cap => mkId(cap)) // error | ^^^^^^^^^^^^^^^^ - |Found: (cap: Cap^?) ->? Id[Cap^?]^? - |Required: Cap^{lcap} => Id[Cap^?]^? + |Found: (cap: Cap^'s9) ->'s10 Id[Cap^'s11]^'s12 + |Required: Cap^{lcap} => Id[Cap^'s13]^'s14 | - |where: => refers to a fresh root capability created in anonymous function of type (using lcap²: scala.caps.Capability): Cap^{lcap²} -> Id[Cap] when instantiating expected result type Cap^{lcap} ->{cap²} Id[Cap^?]^? of function literal + |where: => refers to a fresh root capability created in anonymous function of type (using lcap²: scala.caps.Capability): Cap^{lcap²} -> Id[Cap] when instantiating expected result type Cap^{lcap} ->{cap²} Id[Cap^'s13]^'s14 of function literal | - |Note that capability lcap cannot be included in outer capture set ? of parameter cap. + |Note that capability lcap cannot be included in outer capture set 's9 of parameter cap. | | longer explanation available when compiling with `-explain` -- Warning: tests/neg-custom-args/captures/i15923.scala:21:56 ---------------------------------------------------------- diff --git a/tests/neg-custom-args/captures/i15923a.check b/tests/neg-custom-args/captures/i15923a.check index d64a3d2b1d03..0971b025f653 100644 --- a/tests/neg-custom-args/captures/i15923a.check +++ b/tests/neg-custom-args/captures/i15923a.check @@ -1,13 +1,13 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i15923a.scala:7:21 --------------------------------------- 7 | val leak = withCap(lcap => () => mkId(lcap)) // error | ^^^^^^^^^^^^^^^^^^^^^^^^ - |Found: (lcap: Cap^?) ->? () ->? Id[Cap^?]^? - |Required: (lcap: Cap^) => () =>² Id[Cap^?]^? + |Found: (lcap: Cap^'s1) ->'s2 () ->'s3 Id[Cap^'s4]^'s5 + |Required: (lcap: Cap^) => () =>² Id[Cap^'s6]^'s7 | |where: => refers to a fresh root capability created in value leak when checking argument to parameter op of method withCap - | =>² refers to a root capability associated with the result type of (lcap: Cap^): () =>² Id[Cap^?]^? + | =>² refers to a root capability associated with the result type of (lcap: Cap^): () =>² Id[Cap^'s6]^'s7 | ^ refers to the universal root capability | - |Note that capability cannot be included in outer capture set ?. + |Note that capability cannot be included in outer capture set 's6. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/i15923b.check b/tests/neg-custom-args/captures/i15923b.check index 9d67c47f4c2a..cba83424a4ca 100644 --- a/tests/neg-custom-args/captures/i15923b.check +++ b/tests/neg-custom-args/captures/i15923b.check @@ -2,11 +2,11 @@ 8 | val leak = withCap(f) // error | ^ |Found: (x$0: Cap^) -> Id[Cap^{x$0}] - |Required: (lcap: Cap^) => Id[Cap^?]^? + |Required: (lcap: Cap^) => Id[Cap^'s1]^'s2 | |where: => refers to a fresh root capability created in value leak when checking argument to parameter op of method withCap | ^ refers to the universal root capability | - |Note that capability lcap cannot be included in outer capture set ?. + |Note that capability lcap cannot be included in outer capture set 's1. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/i16226.check b/tests/neg-custom-args/captures/i16226.check index 76ce50869f41..7cd8b91aa076 100644 --- a/tests/neg-custom-args/captures/i16226.check +++ b/tests/neg-custom-args/captures/i16226.check @@ -1,29 +1,36 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i16226.scala:13:4 ---------------------------------------- 13 | (ref1, f1) => map[A, B](ref1, f1) // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |Found: (ref1: LazyRef[A^?]{val elem: () ->? A^?}^?, f1: A^? ->? B^?) ->? LazyRef[B^?]{val elem: () => B^?}^{f1, ref1} + |Found: (ref1: LazyRef[A^'s1]{val elem: () ->'s2 A^'s3}^'s4, f1: A^'s5 ->'s6 B^'s7) ->'s8 + | LazyRef[B^'s9]{val elem: () => B^'s10}^{f1, ref1} |Required: (LazyRef[A]^{io}, A =>² B) =>³ LazyRef[B]^ | - |where: => refers to a root capability associated with the result type of (ref1: LazyRef[A^?]{val elem: () ->? A^?}^?, f1: A^? ->? B^?): LazyRef[B^?]{val elem: () => B^?}^{f1, ref1} + |where: => refers to a root capability associated with the result type of (ref1: LazyRef[A^'s1]{val elem: () ->'s2 A^'s3}^'s4, f1: A^'s5 ->'s6 B^'s7): + | LazyRef[B^'s9]{val elem: () => B^'s10}^{f1, ref1} | =>² refers to the universal root capability | =>³ refers to a fresh root capability in the result type of method mapc | ^ refers to a fresh root capability in the result type of method mapc | |Note that capability f1 is not included in capture set {cap} - |because (f1 : A^? ->? B^?) is not visible from cap in method mapc. + |because (f1 : A^'s5 ->'s6 B^'s7) is not visible from cap in method mapc. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i16226.scala:15:4 ---------------------------------------- 15 | (ref1, f1) => map[A, B](ref1, f1) // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |Found: (ref1: LazyRef[A^?]{val elem: () ->? A^?}^?, f1: A^? ->? B^?) ->? LazyRef[B^?]{val elem: () => B^?}^{f1, ref1} + |Found: (ref1: LazyRef[A^'s11]{val elem: () ->'s12 A^'s13}^'s14, f1: A^'s15 ->'s16 B^'s17) ->'s18 + | LazyRef[B^'s19]{val elem: () => B^'s20}^{f1, ref1} |Required: (ref: LazyRef[A]^{io}, f: A =>² B) =>³ LazyRef[B]^ | - |where: => refers to a root capability associated with the result type of (ref1: LazyRef[A^?]{val elem: () ->? A^?}^?, f1: A^? ->? B^?): LazyRef[B^?]{val elem: () => B^?}^{f1, ref1} + |where: => refers to a root capability associated with the result type of (ref1: LazyRef[A^'s11]{val elem: () ->'s12 A^'s13}^'s14, f1: A^'s15 ->'s16 B^'s17): + | LazyRef[B^'s19]{val elem: () => B^'s20}^{f1, ref1} | =>² refers to the universal root capability | =>³ refers to a fresh root capability in the result type of method mapd | ^ refers to a root capability associated with the result type of (ref: LazyRef[A]^{io}, f: A =>² B): LazyRef[B]^ | - |Note that capability f1 is not included in capture set {? A^?}^?, f1: A^? ->? B^?): LazyRef[B^?]{val elem: () => B^?}^{f1, ref1}>}. + |Note that capability f1 is not included in capture set {'s12 A^'s13}^'s14, f1: A^'s15 ->'s16 B^'s17): + | LazyRef[B^'s19]{val elem: () => B^'s20}^{f1, ref1} + |>}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/i19470.check b/tests/neg-custom-args/captures/i19470.check index 355ccf6e297c..b1279c9f1ef1 100644 --- a/tests/neg-custom-args/captures/i19470.check +++ b/tests/neg-custom-args/captures/i19470.check @@ -2,7 +2,7 @@ 9 | List(foo(f())) // error | ^^^^^^^^ | Found: Inv[IO^{f?}] - | Required: Inv[IO^?]^? + | Required: Inv[IO^'s1]^'s2 | Note that capability f is not included in capture set {f?}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/i21401.check b/tests/neg-custom-args/captures/i21401.check index 8c88e115204a..a8dfba1296c9 100644 --- a/tests/neg-custom-args/captures/i21401.check +++ b/tests/neg-custom-args/captures/i21401.check @@ -15,7 +15,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i21401.scala:15:23 --------------------------------------- 15 | val a = usingIO[IO^](x => x) // error // error | ^^^^^^ - |Found: (x: IO^?) ->? IO^{x} + |Found: (x: IO^'s1) ->'s2 IO^{x} |Required: IO^ => IO^² | |where: => refers to a fresh root capability created in value a when checking argument to parameter op of method usingIO @@ -23,7 +23,7 @@ | ^² refers to a fresh root capability created in value a when checking argument to parameter op of method usingIO | |Note that capability x is not included in capture set {cap} - |because (x : IO^?) is not visible from cap in value a. + |because (x : IO^'s1) is not visible from cap in value a. | | longer explanation available when compiling with `-explain` -- Error: tests/neg-custom-args/captures/i21401.scala:16:66 ------------------------------------------------------------ @@ -50,14 +50,14 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i21401.scala:17:67 --------------------------------------- 17 | val x: Boxed[IO^] = leaked[Boxed[IO^], Boxed[IO^] -> Boxed[IO^]](x => x) // error // error // error | ^^^^^^ - | Found: (x: Boxed[IO^]^?) ->? Boxed[IO^²] - | Required: Boxed[IO^] -> Boxed[IO^³] + | Found: (x: Boxed[IO^]^'s3) ->'s4 Boxed[IO^²] + | Required: Boxed[IO^] -> Boxed[IO^³] | - | where: ^ refers to the universal root capability - | ^² refers to a root capability associated with the result type of (x: Boxed[IO^]^?): Boxed[IO^²] - | ^³ refers to a fresh root capability created in value x² + | where: ^ refers to the universal root capability + | ^² refers to a root capability associated with the result type of (x: Boxed[IO^]^'s3): Boxed[IO^²] + | ^³ refers to a fresh root capability created in value x² | - | Note that capability is not included in capture set {cap} - | because is not visible from cap in value x. + | Note that capability is not included in capture set {cap} + | because is not visible from cap in value x. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/i21614.check b/tests/neg-custom-args/captures/i21614.check index a598e7a47937..1399946116d6 100644 --- a/tests/neg-custom-args/captures/i21614.check +++ b/tests/neg-custom-args/captures/i21614.check @@ -16,8 +16,8 @@ |Required: File^{C} => Logger{val f: File^?}^? | |where: => refers to a fresh root capability created in method mkLoggers2 when checking argument to parameter f of method map - | cap is a root capability associated with the result type of (_$1: File^?): Logger{val f: File^{_$1}}^{cap.rd, _$1} + | cap is a root capability associated with the result type of (_$1: File^'s1): Logger{val f: File^{_$1}}^{cap.rd, _$1} | - |Note that capability .rd cannot be included in outer capture set ?. + |Note that capability .rd cannot be included in outer capture set 's3. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/i21920.check b/tests/neg-custom-args/captures/i21920.check index dedb073a2181..66994fc36122 100644 --- a/tests/neg-custom-args/captures/i21920.check +++ b/tests/neg-custom-args/captures/i21920.check @@ -1,12 +1,12 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i21920.scala:34:35 --------------------------------------- 34 | val cell: Cell[File] = File.open(f => Cell(() => Seq(f))) // error | ^^^^^^^^^^^^^^^^^^^^^^^ - |Found: (f: File^?) ->? Cell[File^?]{val head: () ->? IterableOnce[File^?]^?}^? - |Required: File^ => Cell[File^?]{val head: () ->? IterableOnce[File^?]^?}^? + |Found: (f: File^'s1) ->'s2 Cell[File^'s3]{val head: () ->'s4 IterableOnce[File^'s5]^'s6}^'s7 + |Required: File^ => Cell[File^'s8]{val head: () ->'s9 IterableOnce[File^'s10]^'s11}^'s12 | |where: => refers to a fresh root capability created in value cell when checking argument to parameter f of method open | ^ refers to the universal root capability | - |Note that capability cannot be included in outer capture set ?. + |Note that capability cannot be included in outer capture set 's13. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/i23431.check b/tests/neg-custom-args/captures/i23431.check index 9d48a8f4e099..34f8e3beac72 100644 --- a/tests/neg-custom-args/captures/i23431.check +++ b/tests/neg-custom-args/captures/i23431.check @@ -27,7 +27,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i23431.scala:12:12 --------------------------------------- 12 | withIO: io3 => // error | ^ - |Found: (io3: IO^?) ->? Unit + |Found: (io3: IO^'s1) ->'s2 Unit |Required: IO^ => Unit | |where: => refers to a fresh root capability created in anonymous function of type (io1: IO^): Unit when checking argument to parameter op of method withIO diff --git a/tests/neg-custom-args/captures/lazylists2.check b/tests/neg-custom-args/captures/lazylists2.check index 88b7b8c111ca..bd90de396a22 100644 --- a/tests/neg-custom-args/captures/lazylists2.check +++ b/tests/neg-custom-args/captures/lazylists2.check @@ -1,7 +1,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylists2.scala:18:4 ------------------------------------ 18 | final class Mapped extends LazyList[B]: // error | ^ - | Found: LazyList[B^?]^{f, xs} + | Found: LazyList[B^'s1]^{f, xs} | Required: LazyList[B]^{f} | Note that capability xs is not included in capture set {f}. 19 | this: (Mapped^{xs, f}) => @@ -14,7 +14,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylists2.scala:27:4 ------------------------------------ 27 | final class Mapped extends LazyList[B]: // error | ^ - | Found: LazyList[B^?]^{f, xs} + | Found: LazyList[B^'s2]^{f, xs} | Required: LazyList[B]^{xs} | Note that capability f is not included in capture set {xs}. 28 | this: Mapped^{xs, f} => @@ -35,7 +35,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylists2.scala:45:4 ------------------------------------ 45 | final class Mapped extends LazyList[B]: // error | ^ - | Found: LazyList[B^?]^{f, xs} + | Found: LazyList[B^'s3]^{f, xs} | Required: LazyList[B]^{xs} | Note that capability f is not included in capture set {xs}. 46 | this: (Mapped^{xs, f}) => diff --git a/tests/neg-custom-args/captures/leak-problem-2.check b/tests/neg-custom-args/captures/leak-problem-2.check index 6fa6478c7d9a..71af3da33844 100644 --- a/tests/neg-custom-args/captures/leak-problem-2.check +++ b/tests/neg-custom-args/captures/leak-problem-2.check @@ -1,7 +1,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/leak-problem-2.scala:8:8 --------------------------------- 8 | = race(Seq(src1, src2)) // error | ^^^^^^^^^^^^^^^^^^^^^ - | Found: Source[T^?]^{src1, src2} + | Found: Source[T^'s1]^{src1, src2} | Required: Source[T] | Note that capability src1 is not included in capture set {}. | diff --git a/tests/neg-custom-args/captures/leaking-iterators.check b/tests/neg-custom-args/captures/leaking-iterators.check index f446fe783f0a..51bef2ed5e0f 100644 --- a/tests/neg-custom-args/captures/leaking-iterators.check +++ b/tests/neg-custom-args/captures/leaking-iterators.check @@ -1,13 +1,13 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/leaking-iterators.scala:56:16 ---------------------------- 56 | usingLogFile: log => // error | ^ - |Found: (log: java.io.FileOutputStream^?) ->? cctest.Iterator[Int]^{log} - |Required: java.io.FileOutputStream^ => cctest.Iterator[Int]^? + |Found: (log: java.io.FileOutputStream^'s1) ->'s2 cctest.Iterator[Int]^{log} + |Required: java.io.FileOutputStream^ => cctest.Iterator[Int]^'s3 | |where: => refers to a fresh root capability created in method test when checking argument to parameter op of method usingLogFile | ^ refers to the universal root capability | - |Note that capability log cannot be included in outer capture set ?. + |Note that capability log cannot be included in outer capture set 's3. 57 | xs.iterator.map: x => 58 | log.write(x) 59 | x * x diff --git a/tests/neg-custom-args/captures/reaches.check b/tests/neg-custom-args/captures/reaches.check index d3847b13e870..74330eb4cedb 100644 --- a/tests/neg-custom-args/captures/reaches.check +++ b/tests/neg-custom-args/captures/reaches.check @@ -1,7 +1,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/reaches.scala:22:13 -------------------------------------- 22 | usingFile: f => // error | ^ - |Found: (f: File^?) ->? Unit + |Found: (f: File^'s1) ->'s2 Unit |Required: File^ => Unit | |where: => refers to a fresh root capability created in method runAll0 when checking argument to parameter f of method usingFile @@ -14,7 +14,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/reaches.scala:32:13 -------------------------------------- 32 | usingFile: f => // error | ^ - |Found: (f: File^?) ->? Unit + |Found: (f: File^'s3) ->'s4 Unit |Required: File^ => Unit | |where: => refers to a fresh root capability created in method runAll1 when checking argument to parameter f of method usingFile @@ -68,7 +68,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/reaches.scala:59:27 -------------------------------------- 59 | val id: File^ -> File^ = x => x // error | ^^^^^^ - | Found: (x: File^) ->? File^² + | Found: (x: File^) ->'s5 File^² | Required: File^ -> File^³ | | where: ^ refers to the universal root capability @@ -82,7 +82,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/reaches.scala:69:38 -------------------------------------- 69 | val leaked = usingFile[File^{id*}]: f => // error | ^ - |Found: (f: File^?) ->? File^{id*} + |Found: (f: File^'s6) ->'s7 File^{id*} |Required: File^ => File^{id*} | |where: => refers to a fresh root capability created in value leaked when checking argument to parameter f of method usingFile @@ -96,8 +96,8 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/reaches.scala:87:10 -------------------------------------- 87 | ps.map((x, y) => compose1(x, y)) // error | ^^^^^^^^^^^^^^^^^^^^^^^ - |Found: (x$1: (A^ ->? A^?, A^ ->? A^?)^?) ->? A^? ->? A^? - |Required: ((A ->{ps*} A, A ->{ps*} A)) => A^? ->? A^? + |Found: (x$1: (A^ ->'s8 A^'s9, A^ ->'s10 A^'s11)^'s12) ->'s13 A^'s14 ->'s15 A^'s16 + |Required: ((A ->{ps*} A, A ->{ps*} A)) => A^'s17 ->'s18 A^'s19 | |where: => refers to a fresh root capability created in method mapCompose when checking argument to parameter f of method map | ^ refers to the universal root capability diff --git a/tests/neg-custom-args/captures/reaches2.check b/tests/neg-custom-args/captures/reaches2.check index e91ea3c3859e..5ab7b14a85c1 100644 --- a/tests/neg-custom-args/captures/reaches2.check +++ b/tests/neg-custom-args/captures/reaches2.check @@ -1,8 +1,8 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/reaches2.scala:10:10 ------------------------------------- 10 | ps.map((x, y) => compose1(x, y)) // error | ^^^^^^^^^^^^^^^^^^^^^^^ - | Found: (x$1: (A^? ->{ps*} A^?, A^? ->{ps*} A^?)^?) ->{ps*} A^? ->{ps*} A^? - | Required: ((A ->{ps*} A, A ->{ps*} A)) -> A^? ->{ps*} A^? + | Found: (x$1: (A^'s1 ->{ps*} A^'s2, A^'s3 ->{ps*} A^'s4)^'s5) ->{ps*} A^'s6 ->{ps*} A^'s7 + | Required: ((A ->{ps*} A, A ->{ps*} A)) -> A^'s6 ->{ps*} A^'s7 | Note that capability ps* is not included in capture set {}. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/real-try.check b/tests/neg-custom-args/captures/real-try.check index 9663a134a3a1..bca841e11094 100644 --- a/tests/neg-custom-args/captures/real-try.check +++ b/tests/neg-custom-args/captures/real-try.check @@ -31,7 +31,7 @@ -- Error: tests/neg-custom-args/captures/real-try.scala:26:10 ---------------------------------------------------------- 26 | val y = try // error | ^ - | The result of `try` cannot have type () => Cell[Unit]^? since + | The result of `try` cannot have type () => Cell[Unit]^'s1 since | that type captures the root capability `cap`. | This is often caused by a locally generated exception capability leaking as part of its result. | @@ -43,7 +43,7 @@ -- Error: tests/neg-custom-args/captures/real-try.scala:32:10 ---------------------------------------------------------- 32 | val b = try // error | ^ - | The result of `try` cannot have type Cell[() => Unit]^? since + | The result of `try` cannot have type Cell[() => Unit]^'s2 since | the part () => Unit of that type captures the root capability `cap`. | This is often caused by a locally generated exception capability leaking as part of its result. | diff --git a/tests/neg-custom-args/captures/scoped-caps.check b/tests/neg-custom-args/captures/scoped-caps.check index 04420dd5c319..d1559c50f0fc 100644 --- a/tests/neg-custom-args/captures/scoped-caps.check +++ b/tests/neg-custom-args/captures/scoped-caps.check @@ -106,7 +106,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/scoped-caps.scala:28:19 ---------------------------------- 28 | val _: S -> B^ = x => j(x) // error | ^^^^^^^^^ - | Found: (x: S^) ->? B^² + | Found: (x: S^) ->'s1 B^² | Required: S^ -> B^³ | | where: ^ refers to the universal root capability diff --git a/tests/neg-custom-args/captures/simple-using.check b/tests/neg-custom-args/captures/simple-using.check index b40debc03153..dbe4ee74ff52 100644 --- a/tests/neg-custom-args/captures/simple-using.check +++ b/tests/neg-custom-args/captures/simple-using.check @@ -1,12 +1,12 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/simple-using.scala:8:15 ---------------------------------- 8 | usingLogFile { f => () => f.write(2) } // error | ^^^^^^^^^^^^^^^^^^^^^^^^^ - |Found: (f: java.io.FileOutputStream^?) ->? () ->{f} Unit - |Required: java.io.FileOutputStream^ => () ->? Unit + |Found: (f: java.io.FileOutputStream^'s1) ->'s2 () ->{f} Unit + |Required: java.io.FileOutputStream^ => () ->'s3 Unit | |where: => refers to a fresh root capability created in method test when checking argument to parameter op of method usingLogFile | ^ refers to the universal root capability | - |Note that capability f cannot be included in outer capture set ?. + |Note that capability f cannot be included in outer capture set 's3. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/try.check b/tests/neg-custom-args/captures/try.check index 5fecd9309ba4..ea67bcd4b414 100644 --- a/tests/neg-custom-args/captures/try.check +++ b/tests/neg-custom-args/captures/try.check @@ -8,7 +8,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/try.scala:23:49 ------------------------------------------ 23 | val a = handle[Exception, CanThrow[Exception]] { // error // error | ^ - |Found: (x: CT[Exception]^) ->? CT[Exception]^{x} + |Found: (x: CT[Exception]^) ->'s1 CT[Exception]^{x} |Required: CT[Exception]^ => CT[Exception]^² | |where: => refers to a fresh root capability created in value a when checking argument to parameter op of method handle @@ -24,7 +24,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/try.scala:29:43 ------------------------------------------ 29 | val b = handle[Exception, () -> Nothing] { // error | ^ - |Found: (x: CT[Exception]^) ->? () ->{x} Nothing + |Found: (x: CT[Exception]^) ->'s2 () ->{x} Nothing |Required: CT[Exception]^ => () -> Nothing | |where: => refers to a fresh root capability created in value b when checking argument to parameter op of method handle @@ -38,13 +38,13 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/try.scala:35:18 ------------------------------------------ 35 | val xx = handle { // error | ^ - |Found: (x: CT[Exception]^) ->? () ->{x} Int - |Required: CT[Exception]^ => () ->? Int + |Found: (x: CT[Exception]^) ->'s3 () ->{x} Int + |Required: CT[Exception]^ => () ->'s4 Int | |where: => refers to a fresh root capability created in value xx when checking argument to parameter op of method handle | ^ refers to the universal root capability | - |Note that capability x cannot be included in outer capture set ?. + |Note that capability x cannot be included in outer capture set 's4. 36 | (x: CanThrow[Exception]) => 37 | () => 38 | raise(new Exception)(using x) @@ -55,13 +55,13 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/try.scala:47:31 ------------------------------------------ 47 |val global: () -> Int = handle { // error | ^ - |Found: (x: CT[Exception]^) ->? () ->{x} Int - |Required: CT[Exception]^ => () ->? Int + |Found: (x: CT[Exception]^) ->'s5 () ->{x} Int + |Required: CT[Exception]^ => () ->'s6 Int | |where: => refers to a fresh root capability created in value global when checking argument to parameter op of method handle | ^ refers to the universal root capability | - |Note that capability x cannot be included in outer capture set ?. + |Note that capability x cannot be included in outer capture set 's6. 48 | (x: CanThrow[Exception]) => 49 | () => 50 | raise(new Exception)(using x) diff --git a/tests/neg-custom-args/captures/unsound-reach-4.check b/tests/neg-custom-args/captures/unsound-reach-4.check index be216502f3ad..2baeaa5b9ad6 100644 --- a/tests/neg-custom-args/captures/unsound-reach-4.check +++ b/tests/neg-custom-args/captures/unsound-reach-4.check @@ -8,7 +8,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/unsound-reach-4.scala:20:29 ------------------------------ 20 | val backdoor: Foo[File^] = new Bar // error (follow-on, since the parent Foo[File^] of bar is illegal). | ^^^^^^^ - | Found: Bar^? + | Found: Bar^'s1 | Required: Foo[File^] | | where: ^ refers to a fresh root capability in the type of value backdoor diff --git a/tests/neg-custom-args/captures/unsound-reach.check b/tests/neg-custom-args/captures/unsound-reach.check index b9cb97a9819a..512d1088fa27 100644 --- a/tests/neg-custom-args/captures/unsound-reach.check +++ b/tests/neg-custom-args/captures/unsound-reach.check @@ -15,7 +15,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/unsound-reach.scala:18:31 -------------------------------- 18 | val backdoor: Foo[File^] = new Bar // error (follow-on, since the parent Foo[File^] of bar is illegal). | ^^^^^^^ - | Found: Bar^? + | Found: Bar^'s1 | Required: Foo[File^] | | where: ^ refers to a fresh root capability in the type of value backdoor diff --git a/tests/neg-custom-args/captures/usingLogFile.check b/tests/neg-custom-args/captures/usingLogFile.check index c7c7dbd6a0ee..e4a8ae2e42f3 100644 --- a/tests/neg-custom-args/captures/usingLogFile.check +++ b/tests/neg-custom-args/captures/usingLogFile.check @@ -1,48 +1,48 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/usingLogFile.scala:22:27 --------------------------------- 22 | val later = usingLogFile { f => () => f.write(0) } // error | ^^^^^^^^^^^^^^^^^^^^^^^^^ - |Found: (f: java.io.FileOutputStream^?) ->? () ->{f} Unit - |Required: java.io.FileOutputStream^ => () ->? Unit + |Found: (f: java.io.FileOutputStream^'s1) ->'s2 () ->{f} Unit + |Required: java.io.FileOutputStream^ => () ->'s3 Unit | |where: => refers to a fresh root capability created in value later when checking argument to parameter op of method usingLogFile | ^ refers to the universal root capability | - |Note that capability f cannot be included in outer capture set ?. + |Note that capability f cannot be included in outer capture set 's3. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/usingLogFile.scala:27:36 --------------------------------- 27 | private val later2 = usingLogFile { f => Cell(() => f.write(0)) } // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |Found: (f: java.io.FileOutputStream^?) ->? Test2.Cell[() ->{f} Unit]^? - |Required: java.io.FileOutputStream^ => Test2.Cell[() ->? Unit]^? + |Found: (f: java.io.FileOutputStream^'s4) ->'s5 Test2.Cell[() ->{f} Unit]^'s6 + |Required: java.io.FileOutputStream^ => Test2.Cell[() ->'s7 Unit]^'s8 | |where: => refers to a fresh root capability created in value later2 when checking argument to parameter op of method usingLogFile | ^ refers to the universal root capability | - |Note that capability f cannot be included in outer capture set ?. + |Note that capability f cannot be included in outer capture set 's7. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/usingLogFile.scala:43:33 --------------------------------- 43 | val later = usingFile("out", f => (y: Int) => xs.foreach(x => f.write(x + y))) // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |Found: (f: java.io.OutputStream^?) ->? Int ->{f} Unit - |Required: java.io.OutputStream^ => Int ->? Unit + |Found: (f: java.io.OutputStream^'s9) ->'s10 Int ->{f} Unit + |Required: java.io.OutputStream^ => Int ->'s11 Unit | |where: => refers to a fresh root capability created in value later when checking argument to parameter op of method usingFile | ^ refers to the universal root capability | - |Note that capability f cannot be included in outer capture set ?. + |Note that capability f cannot be included in outer capture set 's11. | | longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/usingLogFile.scala:52:6 ---------------------------------- 52 | usingLogger(_, l => () => l.log("test"))) // error after checking mapping scheme | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |Found: (_$1: java.io.OutputStream^?) ->? () ->{_$1} Unit - |Required: java.io.OutputStream^ => () ->? Unit + |Found: (_$1: java.io.OutputStream^'s12) ->'s13 () ->{_$1} Unit + |Required: java.io.OutputStream^ => () ->'s14 Unit | |where: => refers to a fresh root capability created in value later when checking argument to parameter op of method usingFile | ^ refers to the universal root capability | - |Note that capability _$1 cannot be included in outer capture set ?. + |Note that capability _$1 cannot be included in outer capture set 's14. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/vars.check b/tests/neg-custom-args/captures/vars.check index 66354892efd8..b1a3ba0314be 100644 --- a/tests/neg-custom-args/captures/vars.check +++ b/tests/neg-custom-args/captures/vars.check @@ -27,8 +27,8 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/vars.scala:36:8 ------------------------------------------ 36 | local { cap3 => // error | ^ - |Found: (cap3: CC^) ->? String => String - |Required: CC^ -> String =>² String + | Found: (cap3: CC^) ->'s1 String => String + | Required: CC^ -> String =>² String | |where: => refers to a root capability associated with the result type of (cap3: CC^): String => String | =>² refers to a fresh root capability created in method test of parameter parameter cap3² of method $anonfun diff --git a/tests/neg-custom-args/captures/widen-reach.check b/tests/neg-custom-args/captures/widen-reach.check index 7e25b96d87b1..e1f76704a3d2 100644 --- a/tests/neg-custom-args/captures/widen-reach.check +++ b/tests/neg-custom-args/captures/widen-reach.check @@ -8,7 +8,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/widen-reach.scala:9:24 ----------------------------------- 9 | val foo: IO^ -> IO^ = x => x // error | ^^^^^^ - | Found: (x: IO^) ->? IO^² + | Found: (x: IO^) ->'s1 IO^² | Required: IO^ -> IO^³ | | where: ^ refers to the universal root capability From 8be05c4936cfd6399d62470d3e64a1d38f275cca Mon Sep 17 00:00:00 2001 From: odersky Date: Sun, 10 Aug 2025 13:31:14 +0200 Subject: [PATCH 5/6] Fix rebase breakage --- .../src/dotty/tools/dotc/cc/Capability.scala | 71 ------------------- tests/neg-custom-args/captures/i21347.check | 2 +- tests/neg-custom-args/captures/i21614.check | 7 +- tests/neg-custom-args/captures/reaches.check | 4 +- tests/neg-custom-args/captures/vars.check | 6 +- 5 files changed, 10 insertions(+), 80 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/cc/Capability.scala b/compiler/src/dotty/tools/dotc/cc/Capability.scala index 9cc8e83fca09..41a084a5d87e 100644 --- a/compiler/src/dotty/tools/dotc/cc/Capability.scala +++ b/compiler/src/dotty/tools/dotc/cc/Capability.scala @@ -703,14 +703,6 @@ object Capabilities: (this eq y) || this.match case x: FreshCap => - def levelOK = - if ccConfig.useFreshLevels && !CCState.collapseFresh then - val yOwner = y.levelOwner - yOwner.isStaticOwner || x.ccOwner.isContainedIn(yOwner) - else y.core match - case ResultCap(_) | _: ParamRef => false - case _ => true - vs.ifNotSeen(this)(x.hiddenSet.elems.exists(_.subsumes(y))) || x.acceptsLevelOf(y) && ( y.tryClassifyAs(x.hiddenSet.classifier) @@ -1017,69 +1009,6 @@ object Capabilities: def inverse = Inverse() end Internalize - /** The local dual of a result type of a closure type. - * @param binder the method type of the anonymous function whose result is mapped - * @pre the context's owner is the anonymous function - */ - class Internalize(binder: MethodType)(using Context) extends BiTypeMap: - thisMap => - - val sym = ctx.owner - assert(sym.isAnonymousFunction) - val paramSyms = atPhase(ctx.phase.prev): - // We need to ask one phase before since `sym` should not be completed as a side effect. - // The result of Internalize is used to se the result type of an anonymous function, and - // the new info of that function is built with the result. - sym.paramSymss.head - val resultToFresh = EqHashMap[ResultCap, FreshCap]() - val freshToResult = EqHashMap[FreshCap, ResultCap]() - - override def apply(t: Type) = - if variance < 0 then t - else t match - case t: ParamRef => - if t.binder == this.binder then paramSyms(t.paramNum).termRef else t - case _ => mapOver(t) - - override def mapCapability(c: Capability, deep: Boolean): Capability = c match - case r: ResultCap if r.binder == this.binder => - resultToFresh.get(r) match - case Some(f) => f - case None => - val f = FreshCap(Origin.LocalInstance(binder.resType)) - resultToFresh(r) = f - freshToResult(f) = r - f - case _ => - super.mapCapability(c, deep) - - class Inverse extends BiTypeMap: - def apply(t: Type): Type = - if variance < 0 then t - else t match - case t: TermRef if paramSyms.contains(t) => - binder.paramRefs(paramSyms.indexOf(t.symbol)) - case _ => mapOver(t) - - override def mapCapability(c: Capability, deep: Boolean): Capability = c match - case f: FreshCap if f.owner == sym => - freshToResult.get(f) match - case Some(r) => r - case None => - val r = ResultCap(binder) - resultToFresh(r) = f - freshToResult(f) = r - r - case _ => super.mapCapability(c, deep) - - def inverse = thisMap - override def toString = thisMap.toString + ".inverse" - end Inverse - - override def toString = "InternalizeClosureResult" - def inverse = Inverse() - end Internalize - /** Map top-level free existential variables one-to-one to Fresh instances */ def resultToFresh(tp: Type, origin: Origin)(using Context): Type = val subst = new TypeMap: diff --git a/tests/neg-custom-args/captures/i21347.check b/tests/neg-custom-args/captures/i21347.check index ec0e708e079a..39f97eed7539 100644 --- a/tests/neg-custom-args/captures/i21347.check +++ b/tests/neg-custom-args/captures/i21347.check @@ -3,7 +3,7 @@ | ^^^^^^^^^^^^^^^^^^^^^^ | Found: () ->{f} Unit | Required: () -> Unit - | Note that capability (f : () => Unit) is not included in capture set {}. + | Note that capability f is not included in capture set {}. | | longer explanation available when compiling with `-explain` -- Error: tests/neg-custom-args/captures/i21347.scala:11:15 ------------------------------------------------------------ diff --git a/tests/neg-custom-args/captures/i21614.check b/tests/neg-custom-args/captures/i21614.check index 1399946116d6..dfc4f9ce2e40 100644 --- a/tests/neg-custom-args/captures/i21614.check +++ b/tests/neg-custom-args/captures/i21614.check @@ -12,12 +12,13 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/i21614.scala:15:12 --------------------------------------- 15 | files.map(new Logger(_)) // error, Q: can we improve the error message? | ^^^^^^^^^^^^^ - |Found: (_$1: File^?) ->{C} Logger{val f: File^{_$1}}^{cap.rd, _$1} - |Required: File^{C} => Logger{val f: File^?}^? + |Found: (_$1: File^'s1) ->{C} Logger{val f: File^{_$1}}^{cap.rd, _$1} + |Required: File^{C} => Logger{val f: File^'s2}^'s3 | |where: => refers to a fresh root capability created in method mkLoggers2 when checking argument to parameter f of method map | cap is a root capability associated with the result type of (_$1: File^'s1): Logger{val f: File^{_$1}}^{cap.rd, _$1} | - |Note that capability .rd cannot be included in outer capture set 's3. + |Note that capability C is not classified as trait SharedCapability, therefore it + |cannot be included in capture set 's1 of parameter _$1 of SharedCapability elements. | | longer explanation available when compiling with `-explain` diff --git a/tests/neg-custom-args/captures/reaches.check b/tests/neg-custom-args/captures/reaches.check index 74330eb4cedb..25574538070a 100644 --- a/tests/neg-custom-args/captures/reaches.check +++ b/tests/neg-custom-args/captures/reaches.check @@ -108,8 +108,8 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/reaches.scala:90:10 -------------------------------------- 90 | ps.map((x, y) => compose1(x, y)) // error | ^^^^^^^^^^^^^^^^^^^^^^^ - |Found: (x$1: (A^ ->? A^?, A^ ->? A^?)^?) ->? A^? ->? A^? - |Required: ((A ->{C} A, A ->{C} A)) => A^? ->? A^? + |Found: (x$1: (A^ ->'s20 A^'s21, A^ ->'s22 A^'s23)^'s24) ->'s25 A^'s26 ->'s27 A^'s28 + |Required: ((A ->{C} A, A ->{C} A)) => A^'s29 ->'s30 A^'s31 | |where: => refers to a fresh root capability created in method mapCompose2 when checking argument to parameter f of method map | ^ refers to the universal root capability diff --git a/tests/neg-custom-args/captures/vars.check b/tests/neg-custom-args/captures/vars.check index b1a3ba0314be..052fd6bec10f 100644 --- a/tests/neg-custom-args/captures/vars.check +++ b/tests/neg-custom-args/captures/vars.check @@ -27,14 +27,14 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/vars.scala:36:8 ------------------------------------------ 36 | local { cap3 => // error | ^ - | Found: (cap3: CC^) ->'s1 String => String - | Required: CC^ -> String =>² String + |Found: (cap3: CC^) ->'s1 String => String + |Required: CC^ -> String =>² String | |where: => refers to a root capability associated with the result type of (cap3: CC^): String => String | =>² refers to a fresh root capability created in method test of parameter parameter cap3² of method $anonfun | ^ refers to the universal root capability | - | Note that capability String> cannot be included in outer capture set {cap}. + |Note that capability String> cannot be included in outer capture set {cap}. 37 | def g(x: String): String = if cap3 == cap3 then "" else "a" 38 | g 39 | } From cce5762a7d246f35e52a583ae5b20367d41d726a Mon Sep 17 00:00:00 2001 From: odersky Date: Sun, 10 Aug 2025 14:00:43 +0200 Subject: [PATCH 6/6] cc.md: Update error messages and change LazyList to LzyList --- docs/_docs/reference/experimental/cc.md | 89 ++++++++++--------------- 1 file changed, 36 insertions(+), 53 deletions(-) diff --git a/docs/_docs/reference/experimental/cc.md b/docs/_docs/reference/experimental/cc.md index b53eb682c3dd..0fdcf143ae72 100644 --- a/docs/_docs/reference/experimental/cc.md +++ b/docs/_docs/reference/experimental/cc.md @@ -43,12 +43,12 @@ followed by `^`. We'll see that this turns the parameter into a _capability_ who If we now try to define the problematic value `later`, we get a static error: ``` - |val later = usingLogFile { f => () => f.write(0) } // error - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - |Found: (f: java.io.FileOutputStream^?) ->? () ->{f} Unit - |Required: java.io.FileOutputStream^ => () ->? Unit + | val later = usingLogFile { f => () => f.write(0) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | Found: (f: java.io.FileOutputStream^'s1) ->'s2 () ->{f} Unit + | Required: java.io.FileOutputStream^ => () ->'s3 Unit | - |Note that capability f cannot be included in outer capture set ?. + | Note that capability f cannot be included in outer capture set 's3. ``` In this case, it was easy to see that the `logFile` capability escapes in the closure passed to `usingLogFile`. But capture checking also works for more complex cases. For instance, capture checking is able to distinguish between the following safe code: @@ -60,11 +60,11 @@ val xs = usingLogFile { f => and the following unsafe one: ```scala val xs = usingLogFile { f => - LazyList(1, 2, 3).map { x => f.write(x); x * x } + LzyList(1, 2, 3).map { x => f.write(x); x * x } } ``` An error would be issued in the second case, but not the first one (this assumes a capture-aware -formulation of `LazyList` which we will present later in this page). +formulation `LzyList` of lazily evaluated lists, which we will present later in this page). It turns out that capture checking has very broad applications. Besides the various try-with-resources patterns, it can also be a key part to the solutions of many other long standing problems in programming languages. Among them: @@ -89,12 +89,12 @@ The capture checker extension introduces a new kind of types and it enforces som Capture checking is done in terms of _capturing types_ of the form `T^{c₁, ..., cᵢ}`. Here `T` is a type, and `{c₁, ..., cᵢ}` is a _capture set_ consisting of references to capabilities `c₁, ..., cᵢ`. -A _capability_ is syntactically a method- or class-parameter, a local variable, or the `this` of an enclosing class. The type of a capability +An _object capability_ is syntactically a method- or class-parameter, a local variable, or the `this` of an enclosing class. The type of a capability must be a capturing type with a non-empty capture set. We also say that variables that are capabilities are _tracked_. In a sense, every -capability gets its authority from some other, more sweeping capability which it captures. The most sweeping capability, from which ultimately all others are derived is written `cap`. We call it the _universal capability_. +capability gets its authority from some other, more sweeping capability which it captures. The recursion stops with a _universal capability_, written `cap`, from which all other capabilities are ultimately derived. If `T` is a type, then `T^` is a shorthand for `T^{cap}`, meaning `T` can capture arbitrary capabilities. Here is an example: @@ -107,8 +107,8 @@ class Logger(fs: FileSystem^): def test(fs: FileSystem^) = val l: Logger^{fs} = Logger(fs) l.log("hello world!") - val xs: LazyList[Int]^{l} = - LazyList.from(1) + val xs: LzyList[Int]^{l} = + LzyList.from(1) .map { i => l.log(s"computing elem # $i") i * i @@ -120,9 +120,9 @@ and retained as a field in class `Logger`. Hence, the local variable `l` has typ `Logger^{fs}`: it is a `Logger` which retains the `fs` capability. The second variable defined in `test` is `xs`, a lazy list that is obtained from -`LazyList.from(1)` by logging and mapping consecutive numbers. Since the list is lazy, +`LzyList.from(1)` by logging and mapping consecutive numbers. Since the list is lazy, it needs to retain the reference to the logger `l` for its computations. Hence, the -type of the list is `LazyList[Int]^{l}`. On the other hand, since `xs` only logs but does +type of the list is `LzyList[Int]^{l}`. On the other hand, since `xs` only logs but does not do other file operations, it retains the `fs` capability only indirectly. That's why `fs` does not show up in the capture set of `xs`. @@ -140,7 +140,7 @@ This type is a shorthand for `(A -> B)^{c, d}`, i.e. the function type `A -> B` The impure function type `A => B` is treated as an alias for `A ->{cap} B`. That is, impure functions are functions that can capture anything. A capture annotation `^` binds more strongly than a function arrow. So -`A -> B^{c}` is read as `A -> (B^{c})`. +`A -> B^{c}` is read as `A -> (B^{c})` and `A -> B^` is read as `A -> (B^{cap})`. Analogous conventions apply to context function types. `A ?=> B` is an impure context function, with `A ?-> B` as its pure complement. @@ -205,15 +205,15 @@ we have The set consisting of the root capability `{cap}` covers every other capture set. This is a consequence of the fact that, ultimately, every capability is created from `cap`. -**Example 2.** Consider again the FileSystem/Logger example from before. `LazyList[Int]` is a proper subtype of `LazyList[Int]^{l}`. So if the `test` method in that example -was declared with a result type `LazyList[Int]`, we'd get a type error. Here is the error message: +**Example 2.** Consider again the FileSystem/Logger example from before. `LzyList[Int]` is a proper subtype of `LzyList[Int]^{l}`. So if the `test` method in that example +was declared with a result type `LzyList[Int]`, we'd get a type error. Here is the error message: ``` -11 |def test(using fs: FileSystem^): LazyList[Int] = { +11 |def test(using fs: FileSystem^): LzyList[Int] = { | ^ - | Found: LazyList[Int]^{fs} - | Required: LazyList[Int] + | Found: LzyList[Int]^{fs} + | Required: LzyList[Int] ``` -Why does it say `LazyList[Int]^{fs}` and not `LazyList[Int]^{l}`, which is, after all, the type of the returned value `xs`? The reason is that `l` is a local variable in the body of `test`, so it cannot be referred to in a type outside that body. What happens instead is that the type is _widened_ to the smallest supertype that does not mention `l`. Since `l` has capture set `fs`, we have that `{fs}` covers `{l}`, and `{fs}` is acceptable in a result type of `test`, so `{fs}` is the result of that widening. +Why does it say `LzyList[Int]^{fs}` and not `LzyList[Int]^{l}`, which is, after all, the type of the returned value `xs`? The reason is that `l` is a local variable in the body of `test`, so it cannot be referred to in a type outside that body. What happens instead is that the type is _widened_ to the smallest supertype that does not mention `l`. Since `l` has capture set `fs`, we have that `{fs}` covers `{l}`, and `{fs}` is acceptable in a result type of `test`, so `{fs}` is the result of that widening. This widening is called _avoidance_; it is not specific to capture checking but applies to all variable references in Scala types. ## Capability Classes @@ -363,16 +363,11 @@ This principle plays an important part in making capture checking concise and pr ## Escape Checking -Some capture sets are restricted so that -they are not allowed to contain the universal capability. -Specifically, if a capturing type is an instance of a type variable, that capturing type -is not allowed to carry the universal capability `cap`. There's a connection to tunnelling here. -The capture set of a type has to be present in the environment when a type is instantiated from -a type variable. But `cap` is not itself available as a global entity in the environment. Hence, -an error should result. +Capabilities follow the usual scoping discipline, which means that capture sets +can contain only capabilities that are visible at the point where the set is defined. -We can now reconstruct how this principle produced the error in the introductory example, where +We now reconstruct how this principle produced the error in the introductory example, where `usingLogFile` was declared like this: ```scala def usingLogFile[T](op: FileOutputStream^ => T): T = ... @@ -380,22 +375,25 @@ def usingLogFile[T](op: FileOutputStream^ => T): T = ... The error message was: ``` | val later = usingLogFile { f => () => f.write(0) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |The expression's type () => Unit is not allowed to capture the root capability `cap`. - |This usually means that a capability persists longer than its allowed lifetime. + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | Found: (f: java.io.FileOutputStream^'s1) ->'s2 () ->{f} Unit + | Required: java.io.FileOutputStream^ => () ->'s3 Unit + | + | Note that capability f cannot be included in outer capture set 's3. ``` This error message was produced by the following logic: - The `f` parameter has type `FileOutputStream^`, which makes it a capability. - Therefore, the type of the expression `() => f.write(0)` is `() ->{f} Unit`. - This makes the type of the whole closure passed to `usingLogFile` the dependent function type - `(f: FileOutputStream^) -> () ->{f} Unit`. + `(f: FileOutputStream^'s1) ->'s2 () ->{f} Unit`, + for some as yet uncomputed capture sets `'s1` and `'s2`. - The expected type of the closure is a simple, parametric, impure function type `FileOutputStream^ => T`, for some instantiation of the type variable `T`. - - The smallest supertype of the closure's dependent function type that is a parametric function type is - `FileOutputStream^ => () ->{cap} Unit` - - Hence, the type variable `T` is instantiated to `() ->{cap} Unit`, or abbreviated `() => Unit`, - which causes the error. + - Matching with the found type, `T` must have the shape `() ->'s3 Unit`, for + some capture set `'s3` defined at the level of value `later`. + - That capture set cannot include the capability `f` since `f` is locally bound. + This causes the error. An analogous restriction applies to the type of a mutable variable. Another way one could try to undermine capture checking would be to @@ -408,23 +406,8 @@ usingLogFile { f => } loophole() ``` -But this will not compile either, since mutable variables cannot have universal capture sets. - -One also needs to prevent returning or assigning a closure with a local capability in an argument of a parametric type. For instance, here is a -slightly more refined attack: -```scala -class Cell[+A](x: A) -val sneaky = usingLogFile { f => Cell(() => f.write(0)) } -sneaky.x() -``` -At the point where the `Cell` is created, the capture set of the argument is `f`, which -is OK. But at the point of use, it is `cap` (because `f` is no longer in scope), which causes again an error: -``` - | sneaky.x() - | ^^^^^^^^ - |The expression's type () => Unit is not allowed to capture the root capability `cap`. - |This usually means that a capability persists longer than its allowed lifetime. -``` +But this will not compile either, since the capture set of the mutable variable `loophole` cannot refer to variable `f`, which is not visible +where `loophole` is defined. Looking at object graphs, we observe a monotonicity property: The capture set of an object `x` covers the capture sets of all objects reachable through `x`. This property is reflected in the type system by the following _monotonicity rule_: