Skip to content

Commit 357aa08

Browse files
committed
Collapse into 1 etaExpand (to rule them all)
1 parent 6428333 commit 357aa08

File tree

7 files changed

+38
-38
lines changed

7 files changed

+38
-38
lines changed

compiler/src/dotty/tools/dotc/core/TypeApplications.scala

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@ object TypeApplications {
3434
*/
3535
object EtaExpansion:
3636

37-
def apply(tycon: Type)(using Context): Type =
38-
assert(tycon.typeParams.nonEmpty, tycon)
39-
tycon.etaExpand(tycon.typeParamSymbols)
40-
4137
/** Test that the parameter bounds in a hk type lambda `[X1,...,Xn] => C[X1, ..., Xn]`
4238
* contain the bounds of the type parameters of `C`. This is necessary to be able to
4339
* contract the hk lambda to `C`.
@@ -245,7 +241,7 @@ class TypeApplications(val self: Type) extends AnyVal {
245241
def topType(using Context): Type =
246242
if self.hasSimpleKind then
247243
defn.AnyType
248-
else etaExpand(self.typeParams) match
244+
else self.etaExpand match
249245
case tp: HKTypeLambda =>
250246
tp.derivedLambdaType(resType = tp.resultType.topType)
251247
case _ =>
@@ -302,45 +298,49 @@ class TypeApplications(val self: Type) extends AnyVal {
302298
/** Convert a type constructor `TC` which has type parameters `X1, ..., Xn`
303299
* to `[X1, ..., Xn] -> TC[X1, ..., Xn]`.
304300
*/
305-
def etaExpand(tparams: List[TypeParamInfo])(using Context): Type =
306-
HKTypeLambda.fromParams(tparams, self.appliedTo(tparams.map(_.paramRef)))
307-
//.ensuring(res => res.EtaReduce =:= self, s"res = $res, core = ${res.EtaReduce}, self = $self, hc = ${res.hashCode}")
301+
def etaExpand(using Context): Type =
302+
val tparams = self.typeParams
303+
val resType = self.appliedTo(tparams.map(_.paramRef))
304+
self match
305+
case self: TypeRef if tparams.nonEmpty && self.symbol.isClass =>
306+
val prefix = self.prefix
307+
val owner = self.symbol.owner
308+
// Calling asSeenFrom on the type parameter infos is important
309+
// so that class type references within another prefix have
310+
// their type parameters' info fixed.
311+
// e.g. from pos/i18569:
312+
// trait M1:
313+
// trait A
314+
// trait F[T <: A]
315+
// object M2 extends M1
316+
// Type parameter T in M1.F has an upper bound of M1#A
317+
// But eta-expanding M2.F should have type parameters with an upper-bound of M2.A.
318+
// So we take the prefix M2.type and the F symbol's owner, M1,
319+
// to call asSeenFrom on T's info.
320+
HKTypeLambda(tparams.map(_.paramName))(
321+
tl => tparams.map(p => HKTypeLambda.toPInfo(tl.integrate(tparams, p.paramInfo.asSeenFrom(prefix, owner)))),
322+
tl => tl.integrate(tparams, resType))
323+
case _ =>
324+
HKTypeLambda.fromParams(tparams, resType)
308325

309326
/** If self is not lambda-bound, eta expand it. */
310327
def ensureLambdaSub(using Context): Type =
311-
if (isLambdaSub) self else EtaExpansion(self)
328+
if isLambdaSub then self
329+
else
330+
assert(self.typeParams.nonEmpty, self)
331+
self.etaExpand
312332

313333
/** Eta expand if `self` is a (non-lambda) class reference and `bound` is a higher-kinded type */
314334
def etaExpandIfHK(bound: Type)(using Context): Type = {
315335
val hkParams = bound.hkTypeParams
316336
if (hkParams.isEmpty) self
317337
else self match {
318-
case self: TypeRef if self.symbol.isClass && self.typeParams.length == hkParams.length =>
319-
EtaExpansion(self)
338+
case self: TypeRef if self.symbol.isClass && self.typeParams.hasSameLengthAs(hkParams) =>
339+
etaExpand
320340
case _ => self
321341
}
322342
}
323343

324-
// Like `target.etaExpand(target.typeParams)`
325-
// except call `asSeenFrom` to fix class type parameter bounds
326-
// e.g. from pos/i18569:
327-
// trait M1:
328-
// trait A
329-
// trait F[T <: A]
330-
// object M2 extends M1
331-
// Type parameter T in M2.F has an upper bound of M1#A instead of M2.A
332-
// So we take the prefix M2.type and the F symbol's owner, M1,
333-
// to call asSeenFrom on T's info.
334-
def etaExpandWithAsf(using Context): Type = self match
335-
case self: TypeRef if self.symbol.isClass =>
336-
val tparams = self.symbol.typeParams
337-
val prefix = self.prefix
338-
val owner = self.symbol.owner
339-
HKTypeLambda(tparams.map(_.paramName))(
340-
tl => tparams.map(p => HKTypeLambda.toPInfo(tl.integrate(tparams, p.info.asSeenFrom(prefix, owner)))),
341-
tl => tl.integrate(tparams, self.appliedTo(tparams.map(_.paramRef))))
342-
case _ => etaExpand(typeParams)
343-
344344
/** Maps [Ts] => C[Ts] to C */
345345
def etaCollapse(using Context): Type = self match
346346
case EtaExpansion(classType) => classType

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
606606
if (base.typeSymbol == cls2) return true
607607
}
608608
else if tp1.typeParams.nonEmpty && !tp1.isAnyKind then
609-
return recur(tp1, EtaExpansion(tp2))
609+
return recur(tp1, tp2.etaExpand)
610610
fourthTry
611611
}
612612

@@ -746,7 +746,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
746746
case _ =>
747747
val tparams1 = tp1.typeParams
748748
if (tparams1.nonEmpty)
749-
return recur(tp1.etaExpand(tparams1), tp2) || fourthTry
749+
return recur(tp1.etaExpand, tp2) || fourthTry
750750
tp2 match {
751751
case EtaExpansion(tycon2: TypeRef) if tycon2.symbol.isClass && tycon2.symbol.is(JavaDefined) =>
752752
recur(tp1, tycon2) || fourthTry

compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -832,7 +832,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
832832
}
833833
else if args.nonEmpty then
834834
tycon.safeAppliedTo(EtaExpandIfHK(sym.typeParams, args.map(translateTempPoly)))
835-
else if (sym.typeParams.nonEmpty) tycon.etaExpand(sym.typeParams)
835+
else if (sym.typeParams.nonEmpty) tycon.etaExpand
836836
else tycon
837837
case TYPEBOUNDStpe =>
838838
val lo = readTypeRef()

compiler/src/dotty/tools/dotc/typer/Deriving.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ trait Deriving {
165165
// case (a) ... see description above
166166
val derivedParams = clsParams.dropRight(instanceArity)
167167
val instanceType =
168-
if (instanceArity == clsArity) clsType.etaExpand(clsParams)
168+
if (instanceArity == clsArity) clsType.etaExpand
169169
else {
170170
val derivedParamTypes = derivedParams.map(_.typeRef)
171171

compiler/src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1197,7 +1197,7 @@ class Namer { typer: Typer =>
11971197
val forwarderName = checkNoConflict(alias.toTypeName, isPrivate = false, span)
11981198
var target = pathType.select(sym)
11991199
if target.typeParams.nonEmpty then
1200-
target = target.etaExpandWithAsf
1200+
target = target.etaExpand
12011201
newSymbol(
12021202
cls, forwarderName,
12031203
Exported | Final,

compiler/src/dotty/tools/dotc/typer/RefChecks.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ object RefChecks {
372372
*/
373373
def checkOverride(checkSubType: (Type, Type) => Context ?=> Boolean, member: Symbol, other: Symbol): Unit =
374374
def memberTp(self: Type) =
375-
if (member.isClass) TypeAlias(member.typeRef.etaExpand(member.typeParams))
375+
if (member.isClass) TypeAlias(member.typeRef.etaExpand)
376376
else self.memberInfo(member)
377377
def otherTp(self: Type) =
378378
self.memberInfo(other)

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4306,7 +4306,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
43064306
AppliedType(tree.tpe, tp.typeParams.map(Function.const(TypeBounds.empty)))
43074307
else
43084308
// Eta-expand higher-kinded type
4309-
tree.tpe.etaExpand(tp.typeParamSymbols)
4309+
tree.tpe.etaExpand
43104310
tree.withType(tp1)
43114311
}
43124312
if (ctx.mode.is(Mode.Pattern) || ctx.mode.isQuotedPattern || tree1.tpe <:< pt) tree1

0 commit comments

Comments
 (0)