Skip to content

Commit 729e5ba

Browse files
committed
Collapse into 1 etaExpand (to rule them all)
1 parent f1fc2eb commit 729e5ba

File tree

7 files changed

+39
-39
lines changed

7 files changed

+39
-39
lines changed

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

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

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

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

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

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

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
594594
if (base.typeSymbol == cls2) return true
595595
}
596596
else if tp1.typeParams.nonEmpty && !tp1.isAnyKind then
597-
return recur(tp1, EtaExpansion(tp2))
597+
return recur(tp1, tp2.etaExpand)
598598
fourthTry
599599
}
600600

@@ -734,7 +734,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
734734
case _ =>
735735
val tparams1 = tp1.typeParams
736736
if (tparams1.nonEmpty)
737-
return recur(tp1.etaExpand(tparams1), tp2) || fourthTry
737+
return recur(tp1.etaExpand, tp2) || fourthTry
738738
tp2 match {
739739
case EtaExpansion(tycon2: TypeRef) if tycon2.symbol.isClass && tycon2.symbol.is(JavaDefined) =>
740740
recur(tp1, tycon2) || fourthTry
@@ -2820,7 +2820,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
28202820
tp.symbol match
28212821
case cls: ClassSymbol =>
28222822
if cls == defn.SingletonClass then defn.AnyType
2823-
else if cls.typeParams.nonEmpty then EtaExpansion(tp)
2823+
else if cls.typeParams.nonEmpty then tp.etaExpand
28242824
else tp
28252825
case sym =>
28262826
if !ctx.erasedTypes && sym == defn.FromJavaObjectSymbol then defn.AnyType

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
850850
}
851851
else if args.nonEmpty then
852852
tycon.safeAppliedTo(EtaExpandIfHK(sym.typeParams, args.map(translateTempPoly)))
853-
else if (sym.typeParams.nonEmpty) tycon.etaExpand(sym.typeParams)
853+
else if (sym.typeParams.nonEmpty) tycon.etaExpand
854854
else tycon
855855
case TYPEBOUNDStpe =>
856856
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
@@ -1200,7 +1200,7 @@ class Namer { typer: Typer =>
12001200
val forwarderName = checkNoConflict(alias.toTypeName, isPrivate = false, span)
12011201
var target = pathType.select(sym)
12021202
if target.typeParams.nonEmpty then
1203-
target = target.etaExpandWithAsf
1203+
target = target.etaExpand
12041204
newSymbol(
12051205
cls, forwarderName,
12061206
MandatoryExportTypeFlags | (sym.flags & RetainedExportTypeFlags),

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ object RefChecks {
377377
*/
378378
def checkOverride(checkSubType: (Type, Type) => Context ?=> Boolean, member: Symbol, other: Symbol): Unit =
379379
def memberTp(self: Type) =
380-
if (member.isClass) TypeAlias(member.typeRef.etaExpand(member.typeParams))
380+
if (member.isClass) TypeAlias(member.typeRef.etaExpand)
381381
else self.memberInfo(member)
382382
def otherTp(self: Type) =
383383
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
@@ -4283,7 +4283,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
42834283
tree1.withType(tp1)
42844284
else
42854285
// Eta-expand higher-kinded type
4286-
val tp1 = tree.tpe.etaExpand(tp.typeParamSymbols)
4286+
val tp1 = tree.tpe.etaExpand
42874287
tree.withType(tp1)
42884288
}
42894289
if (ctx.mode.is(Mode.Pattern) || ctx.mode.isQuotedPattern || tree1.tpe <:< pt) tree1

0 commit comments

Comments
 (0)