aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/TypeApplications.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-05-18 12:01:56 +0200
committerMartin Odersky <odersky@gmail.com>2015-05-21 17:41:15 +0200
commitd5975dc740bd55ea72477e9f726882edcd18dbe3 (patch)
tree53d9b9d1ba79ef61f60cc70ffb33bba87723875c /src/dotty/tools/dotc/core/TypeApplications.scala
parent17f1c5fc26d2b1390ef5a224c8187dcc10ce0784 (diff)
downloaddotty-d5975dc740bd55ea72477e9f726882edcd18dbe3.tar.gz
dotty-d5975dc740bd55ea72477e9f726882edcd18dbe3.tar.bz2
dotty-d5975dc740bd55ea72477e9f726882edcd18dbe3.zip
Generaize canWiden to classBounds
This gives us a cheap way to bound the search of all baseclasses in testLifted.
Diffstat (limited to 'src/dotty/tools/dotc/core/TypeApplications.scala')
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala18
1 files changed, 10 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala
index 17f6a8209..7f3f8a446 100644
--- a/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -515,18 +515,19 @@ class TypeApplications(val self: Type) extends AnyVal {
self.appliedTo(tparams map (_.typeRef)).LambdaAbstract(tparams)
}
- /** Test whether this type if od the form `B[T1, ..., Tn]`, or,
- * if `canWiden` if true, has a base type of the form `B[T1, ..., Bn]` where the type parameters
- * of `B` match one-by-one the variances of `tparams`, and where the lambda
- * abstracted type
+ /** Test whether this type has a base type of the form `B[T1, ..., Bn]` where
+ * the type parameters of `B` match one-by-one the variances of `tparams`,
+ * and where the lambda abstracted type
*
* LambdaXYZ { type Apply = B[$hkArg$0, ..., $hkArg$n] }
* { 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 variance V if it has V as its variance or if V == 0.
+ * @param classBounds A hint to bound the search. Only types that derive from one of the
+ * classes in classBounds are considered.
*/
- def testLifted(tparams: List[Symbol], p: Type => Boolean, canWiden: Boolean)(implicit ctx: Context): Boolean = {
+ def testLifted(tparams: List[Symbol], p: Type => Boolean, classBounds: List[ClassSymbol])(implicit ctx: Context): Boolean = {
def tryLift(bcs: List[ClassSymbol]): Boolean = bcs match {
case bc :: bcs1 =>
val tp = self.baseTypeWithArgs(bc)
@@ -534,7 +535,8 @@ class TypeApplications(val self: Type) extends AnyVal {
val tycon = tp.withoutArgs(targs)
def variancesMatch(param1: Symbol, param2: Symbol) =
param2.variance == param2.variance || param2.variance == 0
- if ((tycon.typeParams corresponds tparams)(variancesMatch)) {
+ if (classBounds.exists(tycon.derivesFrom(_)) &&
+ tycon.typeParams.corresponds(tparams)(variancesMatch)) {
val expanded = tycon.EtaExpand
val lifted = (expanded /: targs) { (partialInst, targ) =>
val tparam = partialInst.typeParams.head
@@ -549,7 +551,7 @@ class TypeApplications(val self: Type) extends AnyVal {
false
}
if (tparams.isEmpty) false
- else if (typeParams.nonEmpty) p(EtaExpand) || canWiden && tryLift(self.baseClasses)
- else canWiden && tryLift(self.baseClasses)
+ else if (typeParams.nonEmpty) p(EtaExpand) || classBounds.nonEmpty && tryLift(self.baseClasses)
+ else classBounds.nonEmpty && tryLift(self.baseClasses)
}
}