Skip to content

Commit 395383e

Browse files
committed
Typer#escapingRefs: don't let the types of lower bounds escape
In 0efa171 I changed the definition of NamedPartsAccumulator to exclude lower bounds as this is required for the implicit search, but NamedPartsAccumulator is also used by Typer#escapingRefs so in the following code: class Foo[T](x:T) val z = { class C new Foo(new C) } the type of z was inferred to be Foo[C] instead of Foo. To avoid this, NamedPartsAccumulator will only exclude lower bounds if the parameter excludeLowerBounds is explicitely set to true. No test because there is no way to detect that a type has escaped, this might be something that could be added to TreeChecker.
1 parent cf17b73 commit 395383e

File tree

2 files changed

+12
-5
lines changed

2 files changed

+12
-5
lines changed

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,14 @@ object Types {
245245

246246
/** The parts of this type which are type or term refs and which
247247
* satisfy predicate `p`.
248+
*
249+
* @param p The predicate to satisfy
250+
* @param excludeLowerBounds If set to true, the lower bounds of abstract
251+
* types will be ignored.
248252
*/
249-
def namedPartsWith(p: NamedType => Boolean)(implicit ctx: Context): collection.Set[NamedType] =
250-
new NamedPartsAccumulator(p).apply(mutable.LinkedHashSet(), this)
253+
def namedPartsWith(p: NamedType => Boolean, excludeLowerBounds: Boolean = false)
254+
(implicit ctx: Context): collection.Set[NamedType] =
255+
new NamedPartsAccumulator(p, excludeLowerBounds).apply(mutable.LinkedHashSet(), this)
251256

252257
/** Map function `f` over elements of an AndType, rebuilding with function `g` */
253258
def mapReduceAnd[T](f: Type => T)(g: (T, T) => T)(implicit ctx: Context): T = stripTypeVar match {
@@ -3105,7 +3110,8 @@ object Types {
31053110
def apply(x: Unit, tp: Type): Unit = foldOver(p(tp), tp)
31063111
}
31073112

3108-
class NamedPartsAccumulator(p: NamedType => Boolean)(implicit ctx: Context) extends TypeAccumulator[mutable.Set[NamedType]] {
3113+
class NamedPartsAccumulator(p: NamedType => Boolean, excludeLowerBounds: Boolean = false)
3114+
(implicit ctx: Context) extends TypeAccumulator[mutable.Set[NamedType]] {
31093115
override def stopAtStatic = false
31103116
def maybeAdd(x: mutable.Set[NamedType], tp: NamedType) = if (p(tp)) x += tp else x
31113117
val seen: mutable.Set[Type] = mutable.Set()
@@ -3118,7 +3124,8 @@ object Types {
31183124
apply(foldOver(maybeAdd(x, tp), tp), tp.underlying)
31193125
case tp: TypeRef =>
31203126
foldOver(maybeAdd(x, tp), tp)
3121-
case TypeBounds(_, hi) =>
3127+
case TypeBounds(lo, hi) =>
3128+
if (!excludeLowerBounds) apply(x, lo)
31223129
apply(x, hi)
31233130
case tp: ThisType =>
31243131
apply(x, tp.underlying)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ trait ImplicitRunInfo { self: RunInfo =>
325325
}
326326
tp.classSymbols(liftingCtx) foreach addClassScope
327327
case _ =>
328-
for (part <- tp.namedPartsWith(_.isType))
328+
for (part <- tp.namedPartsWith(_.isType, excludeLowerBounds = true))
329329
comps ++= iscopeRefs(part)
330330
}
331331
comps

0 commit comments

Comments
 (0)