@@ -4,105 +4,80 @@ package cc
4
4
5
5
import core .*
6
6
import Types .* , Symbols .* , Contexts .* , Annotations .*
7
- import ast .Trees .*
8
7
import ast .{tpd , untpd }
9
8
import Decorators .*
10
9
import config .Printers .capt
11
10
import util .Property .Key
12
-
13
- object CaptureOps :
14
- import tpd .*
15
-
16
- private val Captures : Key [CaptureSet ] = Key ()
17
-
18
- def retainedElems (tree : Tree )(using Context ): List [Tree ] = tree match
19
- case Apply (_, Typed (SeqLiteral (elems, _), _) :: Nil ) => elems
20
- case _ => Nil
21
-
22
- extension (tree : Tree )
23
-
24
- def toCaptureRef (using Context ): CaptureRef = tree.tpe.asInstanceOf [CaptureRef ]
25
-
26
- def toCaptureSet (using Context ): CaptureSet =
27
- tree.getAttachment(Captures ) match
28
- case Some (refs) => refs
29
- case None =>
30
- val refs = CaptureSet (retainedElems(tree).map(_.toCaptureRef)* )
31
- .showing(i " toCaptureSet $tree --> $result" , capt)
32
- tree.putAttachment(Captures , refs)
33
- refs
34
-
35
- extension (tp : Type )
36
-
37
- def derivedCapturingType (parent : Type , refs : CaptureSet )(using Context ): Type = tp match
38
- case CapturingType (p, r) =>
39
- if (parent eq p) && (refs eq r) then tp
40
- else CapturingType (parent, refs)
41
-
42
- /** If this is type variable instantiated or upper bounded with a capturing type,
43
- * the capture set associated with that type. Extended to and-or types and
44
- * type proxies in the obvious way. If a term has a type with a boxed captureset,
45
- * that captureset counts towards the capture variables of the envirionment.
46
- */
47
- def boxedCaptured (using Context ): CaptureSet =
48
- def getBoxed (tp : Type , enabled : Boolean ): CaptureSet = tp match
49
- case tp : CapturingType if enabled => tp.refs
50
- case tp : TypeVar => getBoxed(tp.underlying, enabled = true )
51
- case tp : TypeRef if tp.symbol == defn.AnyClass && enabled => CaptureSet .universal
52
- case tp : TypeProxy => getBoxed(tp.superType, enabled)
53
- case tp : AndType => getBoxed(tp.tp1, enabled) ++ getBoxed(tp.tp2, enabled)
54
- case tp : OrType => getBoxed(tp.tp1, enabled) ** getBoxed(tp.tp2, enabled)
55
- case _ => CaptureSet .empty
56
- getBoxed(tp, enabled = false )
57
-
58
- /** If this type appears as an expected type of a term, does it imply
59
- * that the term should be boxed?
60
- * ^^^ Special treat Any? - but the current status is more conservative in that
61
- * it counts free variables in expressions that have Any as expected type.
62
- */
63
- def needsBox (using Context ): Boolean = tp match
64
- case _ : TypeVar => true
65
- case tp : TypeRef =>
66
- tp.info match
67
- case TypeBounds (lo, _) => lo.needsBox
68
- case _ => false
69
- case tp : RefinedOrRecType => tp.parent.needsBox
70
- case tp : AnnotatedType => tp.parent.needsBox
71
- case tp : LazyRef => tp.ref.needsBox
72
- case tp : AndType => tp.tp1.needsBox || tp.tp2.needsBox
73
- case tp : OrType => tp.tp1.needsBox && tp.tp2.needsBox
74
- case _ => false
75
-
76
- def canHaveInferredCapture (using Context ): Boolean = tp match
77
- case tp : TypeRef if tp.symbol.isClass =>
78
- ! tp.symbol.isValueClass && tp.symbol != defn.AnyClass
79
- case tp : TypeProxy =>
80
- tp.superType.canHaveInferredCapture
81
- case tp : AndType =>
82
- tp.tp1.canHaveInferredCapture && tp.tp2.canHaveInferredCapture
83
- case tp : OrType =>
84
- tp.tp1.canHaveInferredCapture || tp.tp2.canHaveInferredCapture
85
- case _ =>
86
- false
87
-
88
- object CapturingAnnotType :
89
-
90
- def apply (parent : Type , refs : CaptureSet )(using Context ): Type =
91
- AnnotatedType (parent, CaptureAnnotation (refs))
92
-
93
- def unapply (tp : AnnotatedType )(using Context ) = tp.annot match
94
- case ann : CaptureAnnotation =>
95
- Some ((tp.parent, ann.refs))
96
- case ann =>
97
- if ann.symbol == defn.RetainsAnnot
98
- then Some ((tp.parent, ann.tree.toCaptureSet))
99
- else None
100
- end CapturingAnnotType
101
-
102
- object PreCapturingType :
103
- def unapply (tp : AnnotatedType )(using Context ) = tp.annot match
104
- case ann : CaptureAnnotation => Some ((tp.parent, ann.refs))
105
- case _ =>
106
- None
107
-
108
- end CaptureOps
11
+ import tpd .*
12
+
13
+ private val Captures : Key [CaptureSet ] = Key ()
14
+
15
+ def retainedElems (tree : Tree )(using Context ): List [Tree ] = tree match
16
+ case Apply (_, Typed (SeqLiteral (elems, _), _) :: Nil ) => elems
17
+ case _ => Nil
18
+
19
+ extension (tree : Tree )
20
+
21
+ def toCaptureRef (using Context ): CaptureRef = tree.tpe.asInstanceOf [CaptureRef ]
22
+
23
+ def toCaptureSet (using Context ): CaptureSet =
24
+ tree.getAttachment(Captures ) match
25
+ case Some (refs) => refs
26
+ case None =>
27
+ val refs = CaptureSet (retainedElems(tree).map(_.toCaptureRef)* )
28
+ .showing(i " toCaptureSet $tree --> $result" , capt)
29
+ tree.putAttachment(Captures , refs)
30
+ refs
31
+
32
+ extension (tp : Type )
33
+
34
+ def derivedCapturingType (parent : Type , refs : CaptureSet )(using Context ): Type = tp match
35
+ case CapturingType (p, r) =>
36
+ if (parent eq p) && (refs eq r) then tp
37
+ else CapturingType (parent, refs)
38
+
39
+ /** If this is type variable instantiated or upper bounded with a capturing type,
40
+ * the capture set associated with that type. Extended to and-or types and
41
+ * type proxies in the obvious way. If a term has a type with a boxed captureset,
42
+ * that captureset counts towards the capture variables of the envirionment.
43
+ */
44
+ def boxedCaptured (using Context ): CaptureSet =
45
+ def getBoxed (tp : Type , enabled : Boolean ): CaptureSet = tp match
46
+ case CapturingType (_, refs) if enabled => refs
47
+ case tp : TypeVar => getBoxed(tp.underlying, enabled = true )
48
+ case tp : TypeRef if tp.symbol == defn.AnyClass && enabled => CaptureSet .universal
49
+ case tp : TypeProxy => getBoxed(tp.superType, enabled)
50
+ case tp : AndType => getBoxed(tp.tp1, enabled) ++ getBoxed(tp.tp2, enabled)
51
+ case tp : OrType => getBoxed(tp.tp1, enabled) ** getBoxed(tp.tp2, enabled)
52
+ case _ => CaptureSet .empty
53
+ getBoxed(tp, enabled = false )
54
+
55
+ /** If this type appears as an expected type of a term, does it imply
56
+ * that the term should be boxed?
57
+ * ^^^ Special treat Any? - but the current status is more conservative in that
58
+ * it counts free variables in expressions that have Any as expected type.
59
+ */
60
+ def needsBox (using Context ): Boolean = tp match
61
+ case _ : TypeVar => true
62
+ case tp : TypeRef =>
63
+ tp.info match
64
+ case TypeBounds (lo, _) => lo.needsBox
65
+ case _ => false
66
+ case tp : RefinedOrRecType => tp.parent.needsBox
67
+ case tp : AnnotatedType => tp.parent.needsBox
68
+ case tp : LazyRef => tp.ref.needsBox
69
+ case tp : AndType => tp.tp1.needsBox || tp.tp2.needsBox
70
+ case tp : OrType => tp.tp1.needsBox && tp.tp2.needsBox
71
+ case _ => false
72
+
73
+ def canHaveInferredCapture (using Context ): Boolean = tp match
74
+ case tp : TypeRef if tp.symbol.isClass =>
75
+ ! tp.symbol.isValueClass && tp.symbol != defn.AnyClass
76
+ case tp : TypeProxy =>
77
+ tp.superType.canHaveInferredCapture
78
+ case tp : AndType =>
79
+ tp.tp1.canHaveInferredCapture && tp.tp2.canHaveInferredCapture
80
+ case tp : OrType =>
81
+ tp.tp1.canHaveInferredCapture || tp.tp2.canHaveInferredCapture
82
+ case _ =>
83
+ false
0 commit comments