Skip to content

Commit 9301c2d

Browse files
committed
Collapse into 1 etaExpand (to rule them all)
1 parent 8f6398a commit 9301c2d

File tree

8 files changed

+40
-40
lines changed

8 files changed

+40
-40
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
@@ -2812,7 +2812,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
28122812
tp.symbol match
28132813
case cls: ClassSymbol =>
28142814
if cls == defn.SingletonClass then defn.AnyType
2815-
else if cls.typeParams.nonEmpty then EtaExpansion(tp)
2815+
else if cls.typeParams.nonEmpty then tp.etaExpand
28162816
else tp
28172817
case sym =>
28182818
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
@@ -854,7 +854,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
854854
}
855855
else if args.nonEmpty then
856856
tycon.safeAppliedTo(EtaExpandIfHK(sym.typeParams, args.map(translateTempPoly)))
857-
else if (sym.typeParams.nonEmpty) tycon.etaExpand(sym.typeParams)
857+
else if (sym.typeParams.nonEmpty) tycon.etaExpand
858858
else tycon
859859
case TYPEBOUNDStpe =>
860860
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
@@ -1196,7 +1196,7 @@ class Namer { typer: Typer =>
11961196
val forwarderName = checkNoConflict(alias.toTypeName, isPrivate = false, span)
11971197
var target = pathType.select(sym)
11981198
if target.typeParams.nonEmpty then
1199-
target = target.etaExpandWithAsf
1199+
target = target.etaExpand
12001200
newSymbol(
12011201
cls, forwarderName,
12021202
Exported | Final,

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
@@ -4274,7 +4274,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
42744274
AppliedType(tree.tpe, tp.typeParams.map(Function.const(TypeBounds.empty)))
42754275
else
42764276
// Eta-expand higher-kinded type
4277-
tree.tpe.etaExpand(tp.typeParamSymbols)
4277+
tree.tpe.etaExpand
42784278
tree.withType(tp1)
42794279
}
42804280
if (ctx.mode.is(Mode.Pattern) || ctx.mode.isQuotedPattern || tree1.tpe <:< pt) tree1

presentation-compiler/test/dotty/tools/pc/tests/completion/CompletionSuite.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1187,7 +1187,7 @@ class CompletionSuite extends BaseCompletionSuite:
11871187
| val x = Bar[M](new Foo[Int]{})
11881188
| x.bar.m@@
11891189
|""".stripMargin,
1190-
"""|map[B](f: A => B): Foo[B]
1190+
"""|map[B](f: Int => B): Foo[B]
11911191
|""".stripMargin,
11921192
topLines = Some(1)
11931193
)

0 commit comments

Comments
 (0)