aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/TypeApplications.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-07-16 12:14:33 +0200
committerMartin Odersky <odersky@gmail.com>2015-09-18 18:05:15 +0200
commit8c6b70912984e546f16064817446aea3f3863653 (patch)
treee56e4617073886d9d99bcf88ccc25100f140ec1a /src/dotty/tools/dotc/core/TypeApplications.scala
parentc28f023c0eb35be14c0e649c14ad10b00603e615 (diff)
downloaddotty-8c6b70912984e546f16064817446aea3f3863653.tar.gz
dotty-8c6b70912984e546f16064817446aea3f3863653.tar.bz2
dotty-8c6b70912984e546f16064817446aea3f3863653.zip
Add EtaReduce method.
EtaReduce will be used to keep applications on eta expanded methods small.
Diffstat (limited to 'src/dotty/tools/dotc/core/TypeApplications.scala')
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala
index a97441681..9837b39b1 100644
--- a/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -538,6 +538,7 @@ class TypeApplications(val self: Type) extends AnyVal {
def EtaExpand(implicit ctx: Context): Type = {
val tparams = typeParams
self.appliedTo(tparams map (_.typeRef)).LambdaAbstract(tparams)
+ //.ensuring(res => res.EtaReduce =:= self, s"res = $res, core = ${res.EtaReduce}, self = $self, hc = ${res.hashCode}")
}
/** Eta expand if `bound` is a type lambda */
@@ -545,6 +546,38 @@ class TypeApplications(val self: Type) extends AnyVal {
if (bound.isLambda && self.typeSymbol.isClass && typeParams.nonEmpty && !isLambda) EtaExpand
else self
+ /** If `self` is an eta expansion of type T, return T, otherwise NoType */
+ def EtaReduce(implicit ctx: Context): Type = {
+ def etaCore(tp: Type, tparams: List[Symbol]): Type = tparams match {
+ case Nil => tp
+ case tparam :: otherParams =>
+ tp match {
+ case tp: RefinedType =>
+ tp.refinedInfo match {
+ case TypeAlias(TypeRef(RefinedThis(rt), rname)) // TODO: Drop once hk applications have been updated
+ if (rname == tparam.name) && (rt eq self) =>
+ etaCore(tp.parent, otherParams)
+ case TypeRef(TypeAlias(TypeRef(RefinedThis(rt), rname)), tpnme.Apply)
+ if (rname == tparam.name) && (rt eq self) =>
+ etaCore(tp.parent, otherParams)
+ case _ =>
+ NoType
+ }
+ case _ =>
+ NoType
+ }
+ }
+ self match {
+ case self @ RefinedType(parent, tpnme.Apply) =>
+ val lc = parent.LambdaClass(forcing = false)
+ self.refinedInfo match {
+ case TypeAlias(alias) if lc.exists => etaCore(alias, lc.typeParams.reverse)
+ case _ => NoType
+ }
+ case _ => NoType
+ }
+ }
+
/** 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