aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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