Skip to content

Commit 5efada6

Browse files
authored
Merge branch 'main' into simplify-polyfunction-logic
2 parents ea842be + da16f43 commit 5efada6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+1372
-594
lines changed

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,8 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
954954
def isStructuralTermSelectOrApply(tree: Tree)(using Context): Boolean = {
955955
def isStructuralTermSelect(tree: Select) =
956956
def hasRefinement(qualtpe: Type): Boolean = qualtpe.dealias match
957+
case defn.PolyOrErasedFunctionOf(_) =>
958+
false
957959
case RefinedType(parent, rname, rinfo) =>
958960
rname == tree.name || hasRefinement(parent)
959961
case tp: TypeProxy =>
@@ -966,10 +968,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
966968
false
967969
!tree.symbol.exists
968970
&& tree.isTerm
969-
&& {
970-
val qualType = tree.qualifier.tpe
971-
hasRefinement(qualType) && !defn.isPolyOrErasedFunctionType(qualType)
972-
}
971+
&& hasRefinement(tree.qualifier.tpe)
973972
def loop(tree: Tree): Boolean = tree match
974973
case TypeApply(fun, _) =>
975974
loop(fun)

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

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,11 @@ sealed abstract class CaptureSet extends Showable:
210210
* any of the elements in the constant capture set `that`
211211
*/
212212
def -- (that: CaptureSet.Const)(using Context): CaptureSet =
213-
val elems1 = elems.filter(!that.accountsFor(_))
214-
if elems1.size == elems.size then this
215-
else if this.isConst then Const(elems1)
216-
else Diff(asVar, that)
213+
if this.isConst then
214+
val elems1 = elems.filter(!that.accountsFor(_))
215+
if elems1.size == elems.size then this else Const(elems1)
216+
else
217+
if that.isAlwaysEmpty then this else Diff(asVar, that)
217218

218219
/** The largest subset (via <:<) of this capture set that does not account for `ref` */
219220
def - (ref: CaptureRef)(using Context): CaptureSet =
@@ -845,34 +846,45 @@ object CaptureSet:
845846
/** The capture set of the type underlying a CaptureRef */
846847
def ofInfo(ref: CaptureRef)(using Context): CaptureSet = ref match
847848
case ref: TermRef if ref.isRootCapability => ref.singletonCaptureSet
848-
case _ => ofType(ref.underlying)
849+
case _ => ofType(ref.underlying, followResult = true)
849850

850851
/** Capture set of a type */
851-
def ofType(tp: Type)(using Context): CaptureSet =
852-
def recur(tp: Type): CaptureSet = tp.dealias match
853-
case tp: TermRef =>
854-
tp.captureSet
855-
case tp: TermParamRef =>
856-
tp.captureSet
857-
case _: TypeRef =>
858-
if tp.classSymbol.hasAnnotation(defn.CapabilityAnnot) then universal else empty
859-
case _: TypeParamRef =>
860-
empty
861-
case CapturingType(parent, refs) =>
862-
recur(parent) ++ refs
863-
case AppliedType(tycon, args) =>
864-
val cs = recur(tycon)
865-
tycon.typeParams match
866-
case tparams @ (LambdaParam(tl, _) :: _) => cs.substParams(tl, args)
867-
case _ => cs
868-
case tp: TypeProxy =>
869-
recur(tp.underlying)
870-
case AndType(tp1, tp2) =>
871-
recur(tp1) ** recur(tp2)
872-
case OrType(tp1, tp2) =>
873-
recur(tp1) ++ recur(tp2)
874-
case _ =>
875-
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
876888
recur(tp)
877889
.showing(i"capture set of $tp = $result", capt)
878890

0 commit comments

Comments
 (0)