diff options
author | Martin Odersky <odersky@gmail.com> | 2015-05-18 12:01:56 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2015-05-21 17:41:15 +0200 |
commit | d5975dc740bd55ea72477e9f726882edcd18dbe3 (patch) | |
tree | 53d9b9d1ba79ef61f60cc70ffb33bba87723875c /src/dotty/tools/dotc/core/TypeApplications.scala | |
parent | 17f1c5fc26d2b1390ef5a224c8187dcc10ce0784 (diff) | |
download | dotty-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.scala | 18 |
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) } } |