diff options
-rw-r--r-- | src/dotty/tools/dotc/core/TypeApplications.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/TypeAssigner.scala | 13 |
2 files changed, 13 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala index 4a16ca45d..6f75142c4 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -509,7 +509,7 @@ class TypeApplications(val self: Type) extends AnyVal { * { type $hkArg$0 = T1; ...; type $hkArg$n = Tn } * * satisfies predicate `p`. Try base types in the order of their occurrence in `baseClasses`. - * A type parameter matches a varianve V if it has V as its variance or if V == 0. + * A type parameter matches a variance V if it has V as its variance or if V == 0. */ def testLifted(tparams: List[Symbol], p: Type => Boolean)(implicit ctx: Context): Boolean = { def tryLift(bcs: List[ClassSymbol]): Boolean = bcs match { @@ -534,7 +534,7 @@ class TypeApplications(val self: Type) extends AnyVal { false } if (tparams.isEmpty) false - else if (typeParams.nonEmpty) p(EtaExpand) + else if (typeParams.nonEmpty) p(EtaExpand) || tryLift(self.baseClasses) else tryLift(self.baseClasses) } }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala index f85c3a577..ea489f7b0 100644 --- a/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -28,9 +28,18 @@ trait TypeAssigner { } } - def avoid(tp: Type, syms: => List[Symbol])(implicit ctx: Context): Type = { + /** An upper approximation of the given type `tp` that does not refer to any symbol in `symsToAvoid`. + * Approximation steps are: + * + * - follow aliases if the original refers to a forbidden symbol + * - widen termrefs that refer to a forbidden symbol + * - replace ClassInfos of forbidden classes by the intersection of their parents, refined by all + * non-private fields, methods, and type members. + * - drop refinements referring to a forbidden symbol. + */ + def avoid(tp: Type, symsToAvoid: => List[Symbol])(implicit ctx: Context): Type = { val widenMap = new TypeMap { - lazy val forbidden = syms.toSet + lazy val forbidden = symsToAvoid.toSet def toAvoid(tp: Type): Boolean = tp match { case tp: TermRef => val sym = tp.symbol |