diff options
author | Martin Odersky <odersky@gmail.com> | 2014-08-10 17:48:52 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-08-10 18:32:52 +0200 |
commit | c2cdd3a3dca2a629923327046b213addd93499fc (patch) | |
tree | f893acbf9ab062c96c53d00215a6076f997e84b4 /src/dotty/tools/dotc/core/TypeApplications.scala | |
parent | bbf777a729e5b6e8c8a75466c42004d3ff4c5d32 (diff) | |
download | dotty-c2cdd3a3dca2a629923327046b213addd93499fc.tar.gz dotty-c2cdd3a3dca2a629923327046b213addd93499fc.tar.bz2 dotty-c2cdd3a3dca2a629923327046b213addd93499fc.zip |
More targeted eta-lifting
Eta-lifting picked some arbitrary base type. It turned out that i94-nada failed once we add
a product trait to case classes (in the next commit) because Eta-Kifting picked Product
as the base type, even though the target type was bounded by Monad. We now change the scheme
so that the target type is included in the lifting, in order to avoid that we lift to
useless types.
Diffstat (limited to 'src/dotty/tools/dotc/core/TypeApplications.scala')
-rw-r--r-- | src/dotty/tools/dotc/core/TypeApplications.scala | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala index c63788ec9..2c8e9902b 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -463,16 +463,18 @@ class TypeApplications(val self: Type) extends AnyVal { self.appliedTo(tparams map (_.typeRef)).LambdaAbstract(tparams) } - /** If this type has a base type `B[T1, ..., Tn]` where the type parameters - * of `B` match one-by-one the variances of `tparams`, convert it to + /** Test whether this type has a base type `B[T1, ..., Tn]` 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 ther occurrence in `baseClasses`. * A type parameter matches a varianve V if it has V as its variance or if V == 0. */ - def EtaLiftTo(tparams: List[Symbol])(implicit ctx: Context): Type = { - def tryLift(bcs: List[ClassSymbol]): Type = bcs match { + def testLifted(tparams: List[Symbol], p: Type => Boolean)(implicit ctx: Context): Boolean = { + def tryLift(bcs: List[ClassSymbol]): Boolean = bcs match { case bc :: bcs1 => val tp = self.baseTypeWithArgs(bc) val targs = tp.argInfos @@ -481,19 +483,20 @@ class TypeApplications(val self: Type) extends AnyVal { param2.variance == param2.variance || param2.variance == 0 if ((tycon.typeParams corresponds tparams)(variancesMatch)) { val expanded = tycon.EtaExpand - val res = (expanded /: targs) { (partialInst, targ) => + val lifted = (expanded /: targs) { (partialInst, targ) => val tparam = partialInst.typeParams.head RefinedType(partialInst, tparam.name, targ.bounds.withVariance(tparam.variance)) } - hk.println(i"eta lifting $self --> $res") - res + ctx.traceIndented(i"eta lifting $self --> $lifted", hk) { + p(lifted) || tryLift(bcs1) + } } else tryLift(bcs1) case nil => - NoType + false } - if (tparams.isEmpty) NoType - else if (typeParams.nonEmpty) EtaExpand + if (tparams.isEmpty) false + else if (typeParams.nonEmpty) p(EtaExpand) else tryLift(self.baseClasses) } }
\ No newline at end of file |