@@ -846,34 +846,45 @@ object CaptureSet:
846
846
/** The capture set of the type underlying a CaptureRef */
847
847
def ofInfo (ref : CaptureRef )(using Context ): CaptureSet = ref match
848
848
case ref : TermRef if ref.isRootCapability => ref.singletonCaptureSet
849
- case _ => ofType(ref.underlying)
849
+ case _ => ofType(ref.underlying, followResult = true )
850
850
851
851
/** Capture set of a type */
852
- def ofType (tp : Type )(using Context ): CaptureSet =
853
- def recur (tp : Type ): CaptureSet = tp.dealias match
854
- case tp : TermRef =>
855
- tp.captureSet
856
- case tp : TermParamRef =>
857
- tp.captureSet
858
- case _ : TypeRef =>
859
- if tp.classSymbol.hasAnnotation(defn.CapabilityAnnot ) then universal else empty
860
- case _ : TypeParamRef =>
861
- empty
862
- case CapturingType (parent, refs) =>
863
- recur(parent) ++ refs
864
- case AppliedType (tycon, args) =>
865
- val cs = recur(tycon)
866
- tycon.typeParams match
867
- case tparams @ (LambdaParam (tl, _) :: _) => cs.substParams(tl, args)
868
- case _ => cs
869
- case tp : TypeProxy =>
870
- recur(tp.underlying)
871
- case AndType (tp1, tp2) =>
872
- recur(tp1) ** recur(tp2)
873
- case OrType (tp1, tp2) =>
874
- recur(tp1) ++ recur(tp2)
875
- case _ =>
876
- empty
852
+ def ofType (tp : Type , followResult : Boolean )(using Context ): CaptureSet =
853
+ def recur (tp : Type ): CaptureSet = trace(i " ofType $tp, ${tp.getClass} $followResult" , show = true ):
854
+ tp.dealias match
855
+ case tp : TermRef =>
856
+ tp.captureSet
857
+ case tp : TermParamRef =>
858
+ tp.captureSet
859
+ case _ : TypeRef =>
860
+ if tp.classSymbol.hasAnnotation(defn.CapabilityAnnot ) then universal else empty
861
+ case _ : TypeParamRef =>
862
+ empty
863
+ case CapturingType (parent, refs) =>
864
+ recur(parent) ++ refs
865
+ case tpd @ RefinedType (parent, _, rinfo : MethodType )
866
+ if followResult && defn.isFunctionType(tpd) =>
867
+ ofType(parent, followResult = false ) // pick up capture set from parent type
868
+ ++ (recur(rinfo.resType) // add capture set of result
869
+ -- CaptureSet (rinfo.paramRefs.filter(_.isTracked)* )) // but disregard bound parameters
870
+ case tpd @ AppliedType (tycon, args) =>
871
+ if followResult && defn.isNonRefinedFunction(tpd) then
872
+ recur(args.last)
873
+ // must be (pure) FunctionN type since ImpureFunctions have already
874
+ // been eliminated in selector's dealias. Use capture set of result.
875
+ else
876
+ val cs = recur(tycon)
877
+ tycon.typeParams match
878
+ case tparams @ (LambdaParam (tl, _) :: _) => cs.substParams(tl, args)
879
+ case _ => cs
880
+ case tp : TypeProxy =>
881
+ recur(tp.underlying)
882
+ case AndType (tp1, tp2) =>
883
+ recur(tp1) ** recur(tp2)
884
+ case OrType (tp1, tp2) =>
885
+ recur(tp1) ++ recur(tp2)
886
+ case _ =>
887
+ empty
877
888
recur(tp)
878
889
.showing(i " capture set of $tp = $result" , capt)
879
890
0 commit comments