aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/core/Types.scala15
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala4
2 files changed, 14 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 3801f1914..c502162ab 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -257,9 +257,14 @@ object Types {
/** 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)(implicit ctx: Context): collection.Set[NamedType] =
- new NamedPartsAccumulator(p).apply(mutable.LinkedHashSet(), this)
+ def namedPartsWith(p: NamedType => Boolean, excludeLowerBounds: Boolean = false)
+ (implicit ctx: Context): collection.Set[NamedType] =
+ new NamedPartsAccumulator(p, excludeLowerBounds).apply(mutable.LinkedHashSet(), this)
/** Map function `f` over elements of an AndType, rebuilding with function `g` */
def mapReduceAnd[T](f: Type => T)(g: (T, T) => T)(implicit ctx: Context): T = stripTypeVar match {
@@ -3331,7 +3336,8 @@ object Types {
def apply(x: Boolean, tp: Type) = x || tp.isUnsafeNonvariant || foldOver(x, tp)
}
- class NamedPartsAccumulator(p: NamedType => Boolean)(implicit ctx: Context) extends TypeAccumulator[mutable.Set[NamedType]] {
+ class NamedPartsAccumulator(p: NamedType => Boolean, excludeLowerBounds: Boolean = false)
+ (implicit ctx: Context) extends TypeAccumulator[mutable.Set[NamedType]] {
override def stopAtStatic = false
def maybeAdd(x: mutable.Set[NamedType], tp: NamedType) = if (p(tp)) x += tp else x
val seen: mutable.Set[Type] = mutable.Set()
@@ -3344,7 +3350,8 @@ object Types {
apply(foldOver(maybeAdd(x, tp), tp), tp.underlying)
case tp: TypeRef =>
foldOver(maybeAdd(x, tp), tp)
- case TypeBounds(_, hi) =>
+ case TypeBounds(lo, hi) =>
+ if (!excludeLowerBounds) apply(x, lo)
apply(x, hi)
case tp: ThisType =>
apply(x, tp.underlying)
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala
index 5b336c2e9..446b39799 100644
--- a/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/src/dotty/tools/dotc/typer/Implicits.scala
@@ -329,7 +329,9 @@ trait ImplicitRunInfo { self: RunInfo =>
}
tp.classSymbols(liftingCtx) foreach addClassScope
case _ =>
- for (part <- tp.namedPartsWith(_.isType))
+ // We exclude lower bounds to conform to SLS 7.2:
+ // "The parts of a type T are: [...] if T is an abstract type, the parts of its upper bound"
+ for (part <- tp.namedPartsWith(_.isType, excludeLowerBounds = true))
comps ++= iscopeRefs(part)
}
comps