Skip to content

Commit 699e2d4

Browse files
committed
Turn assert in RetainingType into test
We used to have the case where a RetainingType needs to be tested after a CapturingType. It would be better to reverse that order: If a RetainingType is possible test this first, and then test a CapturingType. If we just test for CapturingType we should crash if it's a RetainingType. That way we can express expectations that a retaining type was transformed. This commit does the first half: RetainingType unapply now can handle a CapturingType (and respond with a None). We still need to do the second half, that a CapturingType unapply does not handle a RetainingType.
1 parent b9fdf60 commit 699e2d4

File tree

2 files changed

+9
-8
lines changed

2 files changed

+9
-8
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ object CapturingType:
5252
else decomposeCapturingType(tp)
5353

5454
/** Decompose `tp` as a capturing type without taking IgnoreCaptures into account */
55-
def decomposeCapturingType(tp: Type)(using Context): Option[(Type, CaptureSet)] = tp match
55+
def decomposeCapturingType(using Context)(tp: Type, alsoRetains: Boolean = isCaptureChecking): Option[(Type, CaptureSet)] = tp match
5656
case AnnotatedType(parent, ann: CaptureAnnotation)
5757
if isCaptureCheckingOrSetup =>
5858
Some((parent, ann.refs))
59-
case AnnotatedType(parent, ann) if ann.symbol.isRetains && isCaptureChecking =>
59+
case AnnotatedType(parent, ann) if ann.symbol.isRetains && alsoRetains =>
6060
// There are some circumstances where we cannot map annotated types
6161
// with retains annotations to capturing types, so this second recognizer
6262
// path still has to exist. One example is when checking capture sets
@@ -68,6 +68,9 @@ object CapturingType:
6868
// type `C^{f}` which does not have a capture annotation yet. The transformed
6969
// type would be in a copy of the dependent function type, but it is useless
7070
// since we need to check the original reference.
71+
//
72+
// TODO In other situations we expect that the type is already transformed to a
73+
// CapturingType and we should crash if this not the case.
7174
try Some((parent, ann.tree.toCaptureSet))
7275
catch case ex: IllegalCaptureRef => None
7376
case _ =>

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

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import ast.tpd.*
88
import Annotations.Annotation
99
import Decorators.i
1010

11-
/** A builder and extractor for annotated types with @retains or @retainsByName annotations.
11+
/** A builder and extractor for annotated types with @retains or @retainsByName annotations
12+
* excluding CapturingTypes.
1213
*/
1314
object RetainingType:
1415

@@ -21,11 +22,8 @@ object RetainingType:
2122
val sym = tp.annot.symbol
2223
if sym.isRetainsLike then
2324
tp.annot match
24-
case _: CaptureAnnotation =>
25-
assert(ctx.mode.is(Mode.IgnoreCaptures), s"bad retains $tp at ${ctx.phase}")
26-
None
27-
case ann =>
28-
Some((tp.parent, ann.tree.retainedSet))
25+
case _: CaptureAnnotation => None
26+
case ann => Some((tp.parent, ann.tree.retainedSet))
2927
else
3028
None
3129
end RetainingType

0 commit comments

Comments
 (0)