Skip to content

Commit 9a998d4

Browse files
committed
Refactor stopAtStatic
Introduce a third boundary for stopping at packages
1 parent fcd837a commit 9a998d4

File tree

9 files changed

+28
-18
lines changed

9 files changed

+28
-18
lines changed

compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ trait ConstraintHandling {
9999
val bound = dropWildcards(rawBound)
100100
val oldBounds @ TypeBounds(lo, hi) = constraint.nonParamBounds(param)
101101
val equalBounds = (if isUpper then lo else hi) eq bound
102-
if equalBounds && !bound.existsPart(_ eq param, stopAtStatic = true) then
102+
if equalBounds && !bound.existsPart(_ eq param, StopAt.Static) then
103103
// The narrowed bounds are equal and not recursive,
104104
// so we can remove `param` from the constraint.
105105
constraint = constraint.replace(param, bound)

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1391,7 +1391,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
13911391
*/
13921392
def canCompare(ts: Set[Type]) =
13931393
ctx.phase.isTyper
1394-
|| !ts.exists(_.existsPart(_.isInstanceOf[SkolemType], stopAtStatic = true))
1394+
|| !ts.exists(_.existsPart(_.isInstanceOf[SkolemType], StopAt.Static))
13951395

13961396
def verified(result: Boolean): Boolean =
13971397
if Config.checkAtomsComparisons then

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -439,23 +439,23 @@ object Types {
439439

440440
/** Does this type contain wildcard types? */
441441
final def containsWildcardTypes(using Context) =
442-
existsPart(_.isInstanceOf[WildcardType], stopAtStatic = true, forceLazy = false)
442+
existsPart(_.isInstanceOf[WildcardType], StopAt.Static, forceLazy = false)
443443

444444
// ----- Higher-order combinators -----------------------------------
445445

446446
/** Returns true if there is a part of this type that satisfies predicate `p`.
447447
*/
448-
final def existsPart(p: Type => Boolean, stopAtStatic: Boolean = false, forceLazy: Boolean = true)(using Context): Boolean =
449-
new ExistsAccumulator(p, stopAtStatic, forceLazy).apply(false, this)
448+
final def existsPart(p: Type => Boolean, stopAt: StopAt = StopAt.None, forceLazy: Boolean = true)(using Context): Boolean =
449+
new ExistsAccumulator(p, stopAt, forceLazy).apply(false, this)
450450

451451
/** Returns true if all parts of this type satisfy predicate `p`.
452452
*/
453453
final def forallParts(p: Type => Boolean)(using Context): Boolean =
454454
!existsPart(!p(_))
455455

456456
/** Performs operation on all parts of this type */
457-
final def foreachPart(p: Type => Unit, stopAtStatic: Boolean = false)(using Context): Unit =
458-
new ForeachAccumulator(p, stopAtStatic).apply((), this)
457+
final def foreachPart(p: Type => Unit, stopAt: StopAt = StopAt.None)(using Context): Unit =
458+
new ForeachAccumulator(p, stopAt).apply((), this)
459459

460460
/** The parts of this type which are type or term refs and which
461461
* satisfy predicate `p`.
@@ -5199,6 +5199,12 @@ object Types {
51995199

52005200
// ----- TypeMaps --------------------------------------------------------------------
52015201

5202+
/** Where a traversal should stop */
5203+
enum StopAt:
5204+
case None // traverse everything
5205+
case Package // stop at package references
5206+
case Static // stop at static references
5207+
52025208
/** Common base class of TypeMap and TypeAccumulator */
52035209
abstract class VariantTraversal:
52045210
protected[core] var variance: Int = 1
@@ -5211,7 +5217,7 @@ object Types {
52115217
res
52125218
}
52135219

5214-
protected def stopAtStatic: Boolean = true
5220+
protected def stopAt: StopAt = StopAt.Static
52155221

52165222
/** Can the prefix of this static reference be omitted if the reference
52175223
* itself can be omitted? Overridden in TypeOps#avoid.
@@ -5220,7 +5226,11 @@ object Types {
52205226

52215227
protected def stopBecauseStaticOrLocal(tp: NamedType)(using Context): Boolean =
52225228
(tp.prefix eq NoPrefix)
5223-
|| stopAtStatic && tp.currentSymbol.isStatic && isStaticPrefix(tp.prefix)
5229+
|| {
5230+
val stop = stopAt
5231+
stop == StopAt.Static && tp.currentSymbol.isStatic && isStaticPrefix(tp.prefix)
5232+
|| stop == StopAt.Package && tp.currentSymbol.is(Package)
5233+
}
52245234
end VariantTraversal
52255235

52265236
abstract class TypeMap(implicit protected var mapCtx: Context)
@@ -5409,7 +5419,7 @@ object Types {
54095419
derivedClassInfo(tp, this(tp.prefix))
54105420

54115421
def andThen(f: Type => Type): TypeMap = new TypeMap {
5412-
override def stopAtStatic = thisMap.stopAtStatic
5422+
override def stopAt = thisMap.stopAt
54135423
def apply(tp: Type) = f(thisMap(tp))
54145424
}
54155425
}
@@ -5831,12 +5841,12 @@ object Types {
58315841

58325842
class ExistsAccumulator(
58335843
p: Type => Boolean,
5834-
override val stopAtStatic: Boolean,
5844+
override val stopAt: StopAt,
58355845
forceLazy: Boolean)(using Context) extends TypeAccumulator[Boolean]:
58365846
def apply(x: Boolean, tp: Type): Boolean =
58375847
x || p(tp) || (forceLazy || !tp.isInstanceOf[LazyRef]) && foldOver(x, tp)
58385848

5839-
class ForeachAccumulator(p: Type => Unit, override val stopAtStatic: Boolean)(using Context) extends TypeAccumulator[Unit] {
5849+
class ForeachAccumulator(p: Type => Unit, override val stopAt: StopAt)(using Context) extends TypeAccumulator[Unit] {
58405850
def apply(x: Unit, tp: Type): Unit = foldOver(p(tp), tp)
58415851
}
58425852

compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
700700
}
701701
// Cannot use standard `existsPart` method because it calls `lookupRefined`
702702
// which can cause CyclicReference errors.
703-
val isBoundAccumulator = new ExistsAccumulator(isBound, stopAtStatic = true, forceLazy = true):
703+
val isBoundAccumulator = new ExistsAccumulator(isBound, StopAt.Static, forceLazy = true):
704704
override def foldOver(x: Boolean, tp: Type): Boolean = tp match
705705
case tp: TypeRef => applyToPrefix(x, tp)
706706
case _ => super.foldOver(x, tp)

compiler/src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1088,7 +1088,7 @@ trait Checking {
10881088
}
10891089
case _ =>
10901090
}
1091-
tp.foreachPart(check, stopAtStatic = true)
1091+
tp.foreachPart(check, StopAt.Static)
10921092
if (ok) tp else UnspecifiedErrorType
10931093
}
10941094

compiler/src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ trait ImplicitRunInfo:
732732
case null =>
733733
record(i"implicitScope")
734734
val liftToAnchors = new TypeMap:
735-
override def stopAtStatic = true
735+
override def stopAt = StopAt.Static
736736
private val seen = util.HashSet[Type]()
737737

738738
def applyToUnderlying(t: TypeProxy) =

compiler/src/dotty/tools/dotc/typer/Inliner.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
669669
/** Register type of leaf node */
670670
private def registerLeaf(tree: Tree): Unit = tree match {
671671
case _: This | _: Ident | _: TypeTree =>
672-
tree.typeOpt.foreachPart(registerType, stopAtStatic = true)
672+
tree.typeOpt.foreachPart(registerType, StopAt.Static)
673673
case _ =>
674674
}
675675

compiler/src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1519,7 +1519,7 @@ class Namer { typer: Typer =>
15191519
approxTp.stripPoly match
15201520
case atp @ defn.ContextFunctionType(_, resType, _)
15211521
if !defn.isNonRefinedFunction(atp) // in this case `resType` is lying, gives us only the non-dependent upper bound
1522-
|| resType.existsPart(_.isInstanceOf[WildcardType], stopAtStatic = true, forceLazy = false) =>
1522+
|| resType.existsPart(_.isInstanceOf[WildcardType], StopAt.Static, forceLazy = false) =>
15231523
originalTp
15241524
case _ =>
15251525
approxTp

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2803,7 +2803,7 @@ class Typer extends Namer
28032803
// see tests/pos/i7778b.scala
28042804

28052805
val paramTypes = {
2806-
val hasWildcard = formals.exists(_.existsPart(_.isInstanceOf[WildcardType], stopAtStatic = true))
2806+
val hasWildcard = formals.exists(_.existsPart(_.isInstanceOf[WildcardType], StopAt.Static))
28072807
if hasWildcard then formals.map(_ => untpd.TypeTree())
28082808
else formals.map(untpd.TypeTree)
28092809
}

0 commit comments

Comments
 (0)