Skip to content

Commit 6a21e5f

Browse files
committed
Drop LooseRootCapturing
1 parent f786979 commit 6a21e5f

File tree

3 files changed

+86
-107
lines changed

3 files changed

+86
-107
lines changed

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,6 @@ sealed abstract class CaptureSet extends Showable:
132132
* - x is the same as y,
133133
* - x is a this reference and y refers to a field of x
134134
* - x and y are local roots and y is an enclosing root of x
135-
* - the LooseRootChecking property is asserted, and either `x` is `cap`
136-
* or `x` is a local root and y is `cap`.
137135
*/
138136
extension (x: CaptureRef)(using Context)
139137
private def subsumes(y: CaptureRef) =
@@ -142,8 +140,6 @@ sealed abstract class CaptureSet extends Showable:
142140
|| y.match
143141
case y: TermRef => y.prefix eq x
144142
case _ => false
145-
|| (x.isUniversalRootCapability || y.isRootCapability && x.isRootCapability)
146-
&& ctx.property(LooseRootChecking).isDefined
147143

148144
/** x <:< cap, cap[x] <:< cap
149145
* cap[y] <:< cap[x] if y encloses x

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import transform.SymUtils.*
1919
import transform.{Recheck, PreRecheck}
2020
import Recheck.*
2121
import scala.collection.mutable
22-
import CaptureSet.{withCaptureSetsExplained, IdempotentCaptRefMap, CompareResult, LooseRootChecking}
22+
import CaptureSet.{withCaptureSetsExplained, IdempotentCaptRefMap, CompareResult}
2323
import StdNames.nme
2424
import NameKinds.DefaultGetterName
2525
import reporting.trace
@@ -1081,8 +1081,7 @@ class CheckCaptures extends Recheck, SymTransformer:
10811081
def traverse(t: Tree)(using Context) =
10821082
t match
10831083
case t: Template =>
1084-
checkAllOverrides(ctx.owner.asClass, OverridingPairsCheckerCC(_, _, t))(
1085-
using ctx.withProperty(LooseRootChecking, Some(())))
1084+
checkAllOverrides(ctx.owner.asClass, OverridingPairsCheckerCC(_, _, t))
10861085
case _ =>
10871086
traverseChildren(t)
10881087

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

Lines changed: 84 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,12 @@ trait SetupAPI:
2525
def postCheck()(using Context): Unit
2626

2727
object Setup:
28-
def newScheme(using Context) = ctx.settings.YccNew.value // if new impl is conditional
29-
30-
private val IsDuringSetupKey = new Property.Key[Unit]
31-
32-
def isDuringSetup(using Context): Boolean = ctx.property(IsDuringSetupKey).isDefined
33-
3428
case class Box(t: Type) extends UncachedGroundType, TermType:
3529
override def fallbackToText(printer: Printer): Text =
3630
Str("Box(") ~ printer.toText(t) ~ ")"
3731
def derivedBox(t1: Type): Type =
3832
if t1 eq t then this else Box(t1)
3933

40-
trait DepFunSpecializedTypeMap(using Context) extends TypeMap:
41-
override def mapOver(tp: Type) = tp match
42-
case defn.RefinedFunctionOf(rinfo: MethodOrPoly) =>
43-
val rinfo1 = this(rinfo)
44-
if rinfo1 ne rinfo then rinfo1.toFunctionType(alwaysDependent = true)
45-
else tp
46-
case _ =>
47-
super.mapOver(tp)
48-
4934
/** Recognizer for `res $throws exc`, returning `(res, exc)` in case of success */
5035
object throwsAlias:
5136
def unapply(tp: Type)(using Context): Option[(Type, Type)] = tp match
@@ -116,7 +101,6 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
116101
def mappedInfo =
117102
if toBeUpdated.contains(sym) then symd.info
118103
else transformExplicitType(symd.info)
119-
// TODO if sym is class && level owner: add a capture root
120104
if Synthetics.needsTransform(symd) then
121105
Synthetics.transform(symd, mappedInfo)
122106
else if isPreCC(sym) then
@@ -173,91 +157,92 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
173157
*
174158
* Polytype bounds are only cleaned using step 1, but not otherwise transformed.
175159
*/
176-
private def mapInferred(refine: Boolean)(using Context): TypeMap = new TypeMap:
177-
override def toString = "map inferred"
178-
179-
/** Refine a possibly applied class type C where the class has tracked parameters
180-
* x_1: T_1, ..., x_n: T_n to C { val x_1: CV_1 T_1, ..., val x_n: CV_n T_n }
181-
* where CV_1, ..., CV_n are fresh capture sets.
182-
*/
183-
def addCaptureRefinements(tp: Type): Type = tp match
184-
case _: TypeRef | _: AppliedType if refine && tp.typeParams.isEmpty =>
185-
tp.typeSymbol match
186-
case cls: ClassSymbol
187-
if !defn.isFunctionClass(cls) && cls.is(CaptureChecked) =>
188-
cls.paramGetters.foldLeft(tp) { (core, getter) =>
189-
if atPhase(thisPhase.next)(getter.termRef.isTracked) then
190-
val getterType =
191-
mapInferred(refine = false)(tp.memberInfo(getter)).strippedDealias
192-
RefinedType(core, getter.name,
193-
CapturingType(getterType, CaptureSet.RefiningVar(NoSymbol, getter)))
194-
.showing(i"add capture refinement $tp --> $result", ccSetup)
195-
else
196-
core
197-
}
198-
case _ => tp
199-
case _ => tp
160+
private def transformInferredType(tp: Type)(using Context): Type =
161+
def mapInferred(refine: Boolean): TypeMap = new TypeMap:
162+
override def toString = "map inferred"
163+
164+
/** Refine a possibly applied class type C where the class has tracked parameters
165+
* x_1: T_1, ..., x_n: T_n to C { val x_1: CV_1 T_1, ..., val x_n: CV_n T_n }
166+
* where CV_1, ..., CV_n are fresh capture sets.
167+
*/
168+
def addCaptureRefinements(tp: Type): Type = tp match
169+
case _: TypeRef | _: AppliedType if refine && tp.typeParams.isEmpty =>
170+
tp.typeSymbol match
171+
case cls: ClassSymbol
172+
if !defn.isFunctionClass(cls) && cls.is(CaptureChecked) =>
173+
cls.paramGetters.foldLeft(tp) { (core, getter) =>
174+
if atPhase(thisPhase.next)(getter.termRef.isTracked) then
175+
val getterType =
176+
mapInferred(refine = false)(tp.memberInfo(getter)).strippedDealias
177+
RefinedType(core, getter.name,
178+
CapturingType(getterType, CaptureSet.RefiningVar(NoSymbol, getter)))
179+
.showing(i"add capture refinement $tp --> $result", ccSetup)
180+
else
181+
core
182+
}
183+
case _ => tp
184+
case _ => tp
200185

201-
private var isTopLevel = true
202-
203-
private def mapNested(ts: List[Type]): List[Type] =
204-
val saved = isTopLevel
205-
isTopLevel = false
206-
try ts.mapConserve(this)
207-
finally isTopLevel = saved
208-
209-
def apply(tp: Type) =
210-
val tp1 = tp match
211-
case AnnotatedType(parent, annot) if annot.symbol == defn.RetainsAnnot =>
212-
// Drop explicit retains annotations
213-
apply(parent)
214-
case tp @ AppliedType(tycon, args) =>
215-
val tycon1 = this(tycon)
216-
if defn.isNonRefinedFunction(tp) then
217-
// Convert toplevel generic function types to dependent functions
218-
if !defn.isFunctionSymbol(tp.typeSymbol) && (tp.dealias ne tp) then
219-
// This type is a function after dealiasing, so we dealias and recurse.
220-
// See #15925.
221-
this(tp.dealias)
222-
else
223-
val args0 = args.init
224-
var res0 = args.last
225-
val args1 = mapNested(args0)
226-
val res1 = this(res0)
227-
if isTopLevel then
228-
depFun(args1, res1,
229-
isContextual = defn.isContextFunctionClass(tycon1.classSymbol))
230-
.showing(i"add function refinement $tp ($tycon1, $args1, $res1) (${tp.dealias}) --> $result", ccSetup)
231-
else if (tycon1 eq tycon) && (args1 eq args0) && (res1 eq res0) then
232-
tp
186+
private var isTopLevel = true
187+
188+
private def mapNested(ts: List[Type]): List[Type] =
189+
val saved = isTopLevel
190+
isTopLevel = false
191+
try ts.mapConserve(this)
192+
finally isTopLevel = saved
193+
194+
def apply(tp: Type) =
195+
val tp1 = tp match
196+
case AnnotatedType(parent, annot) if annot.symbol == defn.RetainsAnnot =>
197+
// Drop explicit retains annotations
198+
apply(parent)
199+
case tp @ AppliedType(tycon, args) =>
200+
val tycon1 = this(tycon)
201+
if defn.isNonRefinedFunction(tp) then
202+
// Convert toplevel generic function types to dependent functions
203+
if !defn.isFunctionSymbol(tp.typeSymbol) && (tp.dealias ne tp) then
204+
// This type is a function after dealiasing, so we dealias and recurse.
205+
// See #15925.
206+
this(tp.dealias)
233207
else
234-
tp.derivedAppliedType(tycon1, args1 :+ res1)
235-
else
236-
tp.derivedAppliedType(tycon1, args.mapConserve(arg => box(this(arg))))
237-
case defn.RefinedFunctionOf(rinfo: MethodType) =>
238-
val rinfo1 = apply(rinfo)
239-
if rinfo1 ne rinfo then rinfo1.toFunctionType(alwaysDependent = true)
240-
else tp
241-
case tp: MethodType =>
242-
tp.derivedLambdaType(
243-
paramInfos = mapNested(tp.paramInfos),
244-
resType = this(tp.resType))
245-
case tp: TypeLambda =>
246-
// Don't recurse into parameter bounds, just cleanup any stray retains annotations
247-
// !!! TODO we should also map roots to rootvars here
248-
tp.derivedLambdaType(
249-
paramInfos = tp.paramInfos.mapConserve(_.dropAllRetains.bounds),
250-
resType = this(tp.resType))
251-
case Box(tp1) =>
252-
box(this(tp1))
253-
case _ =>
254-
mapOver(tp)
255-
addVar(addCaptureRefinements(normalizeCaptures(tp1)), ctx.owner)
256-
end apply
257-
end mapInferred
208+
val args0 = args.init
209+
var res0 = args.last
210+
val args1 = mapNested(args0)
211+
val res1 = this(res0)
212+
if isTopLevel then
213+
depFun(args1, res1,
214+
isContextual = defn.isContextFunctionClass(tycon1.classSymbol))
215+
.showing(i"add function refinement $tp ($tycon1, $args1, $res1) (${tp.dealias}) --> $result", ccSetup)
216+
else if (tycon1 eq tycon) && (args1 eq args0) && (res1 eq res0) then
217+
tp
218+
else
219+
tp.derivedAppliedType(tycon1, args1 :+ res1)
220+
else
221+
tp.derivedAppliedType(tycon1, args.mapConserve(arg => box(this(arg))))
222+
case defn.RefinedFunctionOf(rinfo: MethodType) =>
223+
val rinfo1 = apply(rinfo)
224+
if rinfo1 ne rinfo then rinfo1.toFunctionType(alwaysDependent = true)
225+
else tp
226+
case tp: MethodType =>
227+
tp.derivedLambdaType(
228+
paramInfos = mapNested(tp.paramInfos),
229+
resType = this(tp.resType))
230+
case tp: TypeLambda =>
231+
// Don't recurse into parameter bounds, just cleanup any stray retains annotations
232+
// !!! TODO we should also map roots to rootvars here
233+
tp.derivedLambdaType(
234+
paramInfos = tp.paramInfos.mapConserve(_.dropAllRetains.bounds),
235+
resType = this(tp.resType))
236+
case Box(tp1) =>
237+
box(this(tp1))
238+
case _ =>
239+
mapOver(tp)
240+
addVar(addCaptureRefinements(normalizeCaptures(tp1)), ctx.owner)
241+
end apply
242+
end mapInferred
258243

259-
private def transformInferredType(tp: Type)(using Context): Type =
260244
mapInferred(refine = true)(tp)
245+
end transformInferredType
261246

262247
private def transformExplicitType(tp: Type, tptToCheck: Option[Tree] = None)(using Context): Type =
263248
val expandAliases = new DeepTypeMap:
@@ -312,6 +297,7 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
312297
else t.info match
313298
case TypeAlias(alias) =>
314299
val transformed = this(alias)
300+
// TODO: Do we need an eager expansion, presumably, we need that only for normalizeCaptures
315301
if transformed ne alias then transformed else t
316302
//.showing(i"EXPAND $t with ${t.info} to $result in ${t.symbol.owner}/${ctx.owner}")
317303
case _ =>
@@ -568,7 +554,6 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
568554
def complete(denot: SymDenotation)(using Context) =
569555
// infos of other methods are determined from their definitions which
570556
// are checked on demand
571-
assert(!isDuringSetup, i"$sym")
572557
assert(ctx.phase == thisPhase.next, i"$sym")
573558
ccSetup.println(i"forcing $sym, printing = ${ctx.mode.is(Mode.Printing)}")
574559
//if ctx.mode.is(Mode.Printing) then new Error().printStackTrace()
@@ -711,8 +696,7 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
711696
case _ => CaptureSet.Var(owner))
712697

713698
def setupUnit(tree: Tree, recheckDef: DefRecheck)(using Context): Unit =
714-
setupTraverser(recheckDef).traverse(tree)(
715-
using ctx.withPhase(thisPhase).withProperty(IsDuringSetupKey, Some(())))
699+
setupTraverser(recheckDef).traverse(tree)(using ctx.withPhase(thisPhase))
716700

717701
// ------ Checks to run after main capture checking --------------------------
718702

0 commit comments

Comments
 (0)