aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala4
-rw-r--r--src/dotty/tools/dotc/typer/TypeAssigner.scala13
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