Skip to content

Commit 4ff8bb1

Browse files
committed
Fix EtaExpansion extractor, to also honour prefix
When looking at the info of the type parameters of a TypeRef, make sure to honour the reference's prefix.
1 parent 729e5ba commit 4ff8bb1

File tree

2 files changed

+19
-6
lines changed

2 files changed

+19
-6
lines changed

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ object TypeApplications {
3737
* contain the bounds of the type parameters of `C`. This is necessary to be able to
3838
* contract the hk lambda to `C`.
3939
*/
40-
private def weakerBounds(tp: HKTypeLambda, tparams: List[ParamInfo])(using Context): Boolean =
40+
private def weakerBounds(tp: HKTypeLambda, fn: Type)(using Context): Boolean =
4141
val onlyEmptyBounds = tp.typeParams.forall(_.paramInfo == TypeBounds.empty)
4242
onlyEmptyBounds
4343
// Note: this pre-test helps efficiency. It is also necessary to workaround #9965 since in some cases
@@ -46,18 +46,21 @@ object TypeApplications {
4646
// In this case, we can still return true if we know that the hk lambda bounds
4747
// are empty anyway.
4848
|| {
49+
val tparams = fn.typeParams
4950
val paramRefs = tparams.map(_.paramRef)
51+
val prefix = fn match { case fn: TypeRef => fn.prefix case _ => NoPrefix }
52+
val owner = fn match { case fn: TypeRef => fn.symbol.owner case _ => NoSymbol }
5053
tp.typeParams.corresponds(tparams) { (param1, param2) =>
51-
param2.paramInfo frozen_<:< param1.paramInfo.substParams(tp, paramRefs)
54+
param2.paramInfo.asSeenFrom(prefix, owner) frozen_<:< param1.paramInfo.substParams(tp, paramRefs)
5255
}
5356
}
5457

5558
def unapply(tp: Type)(using Context): Option[Type] = tp match
56-
case tp @ HKTypeLambda(tparams, AppliedType(fn: Type, args))
59+
case tp @ HKTypeLambda(tparams, AppliedType(fn, args))
5760
if fn.typeSymbol.isClass
5861
&& tparams.hasSameLengthAs(args)
5962
&& args.lazyZip(tparams).forall((arg, tparam) => arg == tparam.paramRef)
60-
&& weakerBounds(tp, fn.typeParams) => Some(fn)
63+
&& weakerBounds(tp, fn) => Some(fn)
6164
case _ => None
6265

6366
end EtaExpansion
@@ -302,7 +305,6 @@ class TypeApplications(val self: Type) extends AnyVal {
302305
val resType = self.appliedTo(tparams.map(_.paramRef))
303306
self match
304307
case self: TypeRef if tparams.nonEmpty && self.symbol.isClass =>
305-
val prefix = self.prefix
306308
val owner = self.symbol.owner
307309
// Calling asSeenFrom on the type parameter infos is important
308310
// so that class type references within another prefix have
@@ -317,7 +319,7 @@ class TypeApplications(val self: Type) extends AnyVal {
317319
// So we take the prefix M2.type and the F symbol's owner, M1,
318320
// to call asSeenFrom on T's info.
319321
HKTypeLambda(tparams.map(_.paramName))(
320-
tl => tparams.map(p => HKTypeLambda.toPInfo(tl.integrate(tparams, p.paramInfo.asSeenFrom(prefix, owner)))),
322+
tl => tparams.map(p => HKTypeLambda.toPInfo(tl.integrate(tparams, p.paramInfo.asSeenFrom(self.prefix, owner)))),
321323
tl => tl.integrate(tparams, resType))
322324
case _ =>
323325
HKTypeLambda.fromParams(tparams, resType)

tests/pos/i18569.reg1.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Minimisation of the CI failure
2+
// in scala-parallel-collections
3+
// to do with how EtaExpansion is used
4+
// by typeOfNew when typing a New tree
5+
6+
trait Foo[+A]:
7+
class Bar[B >: A]
8+
9+
class Test:
10+
def t1[X](foo: Foo[X]): Unit =
11+
val bar = new foo.Bar()

0 commit comments

Comments
 (0)