From 000461c376807d51964841ae9cb08d5f255ea2a2 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 11 Feb 2015 18:47:56 +0100 Subject: [PATCH] Fix to testLifted If the original type does not have the right type parameters, look in the baseclasses. Previously this was done only if the original type did not have any type parameters. --- src/dotty/tools/dotc/core/TypeApplications.scala | 4 ++-- 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 4a16ca45d62c..6f75142c4bb9 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 f4b0ef4f2592..083dfcb3dc08 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