Skip to content

Commit bca3978

Browse files
committed
Drop restrictions in widenReachCaptures
These should be no longer necessary with existentials.
1 parent 516df7c commit bca3978

File tree

4 files changed

+15
-12
lines changed

4 files changed

+15
-12
lines changed

compiler/src/dotty/tools/dotc/cc/CaptureOps.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -381,11 +381,13 @@ extension (tp: Type)
381381
t.dealias match
382382
case t1 @ CapturingType(p, cs) if cs.isUniversal && !isFlipped =>
383383
t1.derivedCapturingType(apply(p), ref.reach.singletonCaptureSet)
384-
case t @ FunctionOrMethod(args, res @ Existential(_, _))
384+
case t1 @ FunctionOrMethod(args, res @ Existential(_, _))
385385
if args.forall(_.isAlwaysPure) =>
386386
// Also map existentials in results to reach capabilities if all
387387
// preceding arguments are known to be always pure
388-
apply(t.derivedFunctionOrMethod(args, Existential.toCap(res)))
388+
apply(t1.derivedFunctionOrMethod(args, Existential.toCap(res)))
389+
case Existential(_, _) =>
390+
t
389391
case _ => t match
390392
case t @ CapturingType(p, cs) =>
391393
t.derivedCapturingType(apply(p), cs) // don't map capture set variables
@@ -397,7 +399,7 @@ extension (tp: Type)
397399
ref match
398400
case ref: CaptureRef if ref.isTrackableRef =>
399401
val checker = new CheckContraCaps
400-
checker.traverse(tp)
402+
if !ccConfig.useExistentials then checker.traverse(tp)
401403
if checker.ok then
402404
val tp1 = narrowCaps(tp)
403405
if tp1 ne tp then capt.println(i"narrow $tp of $ref to $tp1")

compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,7 @@ class CheckCaptures extends Recheck, SymTransformer:
11031103
ccConfig.allowUniversalInBoxed
11041104
|| expected.hasAnnotation(defn.UncheckedCapturesAnnot)
11051105
|| actual.widen.hasAnnotation(defn.UncheckedCapturesAnnot)
1106-
if criticalSet.isUniversal && expected.isValueType && !allowUniversalInBoxed then
1106+
if criticalSet.isUnboxable && expected.isValueType && !allowUniversalInBoxed then
11071107
// We can't box/unbox the universal capability. Leave `actual` as it is
11081108
// so we get an error in checkConforms. Add the error message generated
11091109
// from boxing as an addendum. This tends to give better error

tests/neg-custom-args/captures/widen-reach.check

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212
| Required: IO^ -> IO^{x*}
1313
|
1414
| longer explanation available when compiling with `-explain`
15-
-- Error: tests/neg-custom-args/captures/widen-reach.scala:8:18 --------------------------------------------------------
16-
8 |trait Bar extends Foo[IO^]: // error
17-
| ^
18-
| IO^{ex$3} cannot be box-converted to box IO^
19-
| since at least one of their capture sets contains the root capability `cap`
20-
9 | val foo: IO^ -> IO^ = x => x
15+
-- [E164] Declaration Error: tests/neg-custom-args/captures/widen-reach.scala:9:6 --------------------------------------
16+
9 | val foo: IO^ -> IO^ = x => x // error
17+
| ^
18+
| error overriding value foo in trait Foo of type IO^ -> box IO^;
19+
| value foo of type IO^ -> (ex$3: caps.Exists) -> IO^{ex$3} has incompatible type
20+
|
21+
| longer explanation available when compiling with `-explain`

tests/neg-custom-args/captures/widen-reach.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ trait IO
55
trait Foo[+T]:
66
val foo: IO^ -> T
77

8-
trait Bar extends Foo[IO^]: // error
9-
val foo: IO^ -> IO^ = x => x
8+
trait Bar extends Foo[IO^]:
9+
val foo: IO^ -> IO^ = x => x // error
1010

1111
def test(x: Foo[IO^]): Unit =
1212
val y1: Foo[IO^{x*}] = x

0 commit comments

Comments
 (0)