Skip to content

Change defaults for NamedPartsAccumulator #9657

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/core/TypeOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ object TypeOps:

def apply(tp: Type): Type = tp match {
case tp: TermRef
if toAvoid(tp.symbol) || partsToAvoid(mutable.Set.empty, tp.info).nonEmpty =>
if toAvoid(tp.symbol) || partsToAvoid(Nil, tp.info).nonEmpty =>
tp.info.widenExpr.dealias match {
case info: SingletonType => apply(info)
case info => range(defn.NothingType, apply(info))
Expand All @@ -422,7 +422,7 @@ object TypeOps:
}
case tp: ThisType if toAvoid(tp.cls) =>
range(defn.NothingType, apply(classBound(tp.cls.classInfo)))
case tp: SkolemType if partsToAvoid(mutable.Set.empty, tp.info).nonEmpty =>
case tp: SkolemType if partsToAvoid(Nil, tp.info).nonEmpty =>
range(defn.NothingType, apply(tp.info))
case tp: TypeVar if mapCtx.typerState.constraint.contains(tp) =>
val lo = TypeComparer.instanceType(
Expand Down
49 changes: 19 additions & 30 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -392,20 +392,13 @@ object Types {
final def foreachPart(p: Type => Unit, stopAtStatic: Boolean = false)(using Context): Unit =
new ForeachAccumulator(p, stopAtStatic).apply((), this)

/** The parts of this type which are type or term refs */
final def namedParts(using Context): collection.Set[NamedType] =
namedPartsWith(alwaysTrue)

/** The parts of this type which are type or term refs and which
* satisfy predicate `p`.
*
* @param p The predicate to satisfy
* @param excludeLowerBounds If set to true, the lower bounds of abstract
* types will be ignored.
*/
def namedPartsWith(p: NamedType => Boolean, excludeLowerBounds: Boolean = false)
(using Context): collection.Set[NamedType] =
new NamedPartsAccumulator(p, excludeLowerBounds).apply(mutable.LinkedHashSet(), this)
def namedPartsWith(p: NamedType => Boolean)(using Context): List[NamedType] =
new NamedPartsAccumulator(p).apply(Nil, this)

/** Map function `f` over elements of an AndType, rebuilding with function `g` */
def mapReduceAnd[T](f: Type => T)(g: (T, T) => T)(using Context): T = stripTypeVar match {
Expand Down Expand Up @@ -5520,38 +5513,34 @@ object Types {
override def hash(x: Type): Int = System.identityHashCode(x)
override def isEqual(x: Type, y: Type) = x.eq(y)

class NamedPartsAccumulator(p: NamedType => Boolean, excludeLowerBounds: Boolean = false)
(using Context) extends TypeAccumulator[mutable.Set[NamedType]] {
override def stopAtStatic: Boolean = false
def maybeAdd(x: mutable.Set[NamedType], tp: NamedType): mutable.Set[NamedType] = if (p(tp)) x += tp else x
class NamedPartsAccumulator(p: NamedType => Boolean)(using Context)
extends TypeAccumulator[List[NamedType]]:
def maybeAdd(xs: List[NamedType], tp: NamedType): List[NamedType] = if p(tp) then tp :: xs else xs
val seen = TypeHashSet()
def apply(x: mutable.Set[NamedType], tp: Type): mutable.Set[NamedType] =
if (seen contains tp) x
else {
def apply(xs: List[NamedType], tp: Type): List[NamedType] =
if seen contains tp then xs
else
seen.addEntry(tp)
tp match {
tp match
case tp: TypeRef =>
foldOver(maybeAdd(x, tp), tp)
foldOver(maybeAdd(xs, tp), tp)
case tp: ThisType =>
apply(x, tp.tref)
apply(xs, tp.tref)
case NoPrefix =>
foldOver(x, tp)
foldOver(xs, tp)
case tp: TermRef =>
apply(foldOver(maybeAdd(x, tp), tp), tp.underlying)
apply(foldOver(maybeAdd(xs, tp), tp), tp.underlying)
case tp: AppliedType =>
foldOver(x, tp)
foldOver(xs, tp)
case TypeBounds(lo, hi) =>
if (!excludeLowerBounds) apply(x, lo)
apply(x, hi)
apply(apply(xs, lo), hi)
case tp: ParamRef =>
apply(x, tp.underlying)
apply(xs, tp.underlying)
case tp: ConstantType =>
apply(x, tp.underlying)
apply(xs, tp.underlying)
case _ =>
foldOver(x, tp)
}
}
}
foldOver(xs, tp)
end NamedPartsAccumulator

class isGroundAccumulator(using Context) extends TypeAccumulator[Boolean] {
def apply(x: Boolean, tp: Type): Boolean = x && {
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -907,7 +907,7 @@ class Typer extends Namer
pt, localSyms(stats1))
}

def escapingRefs(block: Tree, localSyms: => List[Symbol])(using Context): collection.Set[NamedType] = {
def escapingRefs(block: Tree, localSyms: => List[Symbol])(using Context): List[NamedType] = {
lazy val locals = localSyms.toSet
block.tpe.namedPartsWith(tp => locals.contains(tp.symbol) && !tp.isErroneous)
}
Expand Down