@@ -23,6 +23,7 @@ import collection.mutable
23
23
import ProtoTypes .*
24
24
import staging .StagingLevel
25
25
import inlines .Inlines .inInlineMethod
26
+ import cc .{isRetainsLike , CaptureAnnotation }
26
27
27
28
import dotty .tools .backend .jvm .DottyBackendInterface .symExtensions
28
29
@@ -162,17 +163,34 @@ object TreeChecker {
162
163
*/
163
164
def checkNoOrphans (tp0 : Type , tree : untpd.Tree = untpd.EmptyTree )(using Context ): Type = new TypeMap () {
164
165
val definedBinders = new java.util.IdentityHashMap [Type , Any ]
166
+ private var inRetainingAnnot = false
167
+
168
+ def insideRetainingAnnot [T ](op : => T ): T =
169
+ val saved = inRetainingAnnot
170
+ inRetainingAnnot = true
171
+ try op finally inRetainingAnnot = saved
172
+
165
173
def apply (tp : Type ): Type = {
166
174
tp match {
167
175
case tp : BindingType =>
168
176
definedBinders.put(tp, tp)
169
177
mapOver(tp)
170
178
definedBinders.remove(tp)
171
179
case tp : ParamRef =>
172
- assert(definedBinders.get(tp.binder) != null , s " orphan param: ${tp.show}, hash of binder = ${System .identityHashCode(tp.binder)}, tree = ${tree.show}, type = $tp0" )
180
+ val isValidRef =
181
+ definedBinders.get(tp.binder) != null
182
+ || inRetainingAnnot
183
+ // Inside a normal @retains annotation, the captured references could be ill-formed. See issue #19661.
184
+ // But this is ok since capture checking does not rely on them.
185
+ assert(isValidRef, s " orphan param: ${tp.show}, hash of binder = ${System .identityHashCode(tp.binder)}, tree = ${tree.show}, type = $tp0" )
173
186
case tp : TypeVar =>
174
187
assert(tp.isInstantiated, s " Uninstantiated type variable: ${tp.show}, tree = ${tree.show}" )
175
188
apply(tp.underlying)
189
+ case tp @ AnnotatedType (underlying, annot) if annot.symbol.isRetainsLike && ! annot.isInstanceOf [CaptureAnnotation ] =>
190
+ val underlying1 = this (underlying)
191
+ val annot1 = insideRetainingAnnot :
192
+ annot.mapWith(this )
193
+ derivedAnnotatedType(tp, underlying1, annot1)
176
194
case _ =>
177
195
mapOver(tp)
178
196
}
0 commit comments