Skip to content

Commit 0b78b8e

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 0a48fa0 commit 0b78b8e

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
@@ -38,7 +38,7 @@ object TypeApplications {
3838
* contain the bounds of the type parameters of `C`. This is necessary to be able to
3939
* contract the hk lambda to `C`.
4040
*/
41-
private def weakerBounds(tp: HKTypeLambda, tparams: List[ParamInfo])(using Context): Boolean =
41+
private def weakerBounds(tp: HKTypeLambda, fn: Type)(using Context): Boolean =
4242
val onlyEmptyBounds = tp.typeParams.forall(_.paramInfo == TypeBounds.empty)
4343
onlyEmptyBounds
4444
// Note: this pre-test helps efficiency. It is also necessary to workaround #9965 since in some cases
@@ -47,18 +47,21 @@ object TypeApplications {
4747
// In this case, we can still return true if we know that the hk lambda bounds
4848
// are empty anyway.
4949
|| {
50+
val tparams = fn.typeParams
5051
val paramRefs = tparams.map(_.paramRef)
52+
val prefix = fn match { case fn: TypeRef => fn.prefix case _ => NoPrefix }
53+
val owner = fn match { case fn: TypeRef => fn.symbol.owner case _ => NoSymbol }
5154
tp.typeParams.corresponds(tparams) { (param1, param2) =>
52-
param2.paramInfo frozen_<:< param1.paramInfo.substParams(tp, paramRefs)
55+
param2.paramInfo.asSeenFrom(prefix, owner) frozen_<:< param1.paramInfo.substParams(tp, paramRefs)
5356
}
5457
}
5558

5659
def unapply(tp: Type)(using Context): Option[Type] = tp match
57-
case tp @ HKTypeLambda(tparams, AppliedType(fn: Type, args))
60+
case tp @ HKTypeLambda(tparams, AppliedType(fn, args))
5861
if fn.typeSymbol.isClass
5962
&& tparams.hasSameLengthAs(args)
6063
&& args.lazyZip(tparams).forall((arg, tparam) => arg == tparam.paramRef)
61-
&& weakerBounds(tp, fn.typeParams) => Some(fn)
64+
&& weakerBounds(tp, fn) => Some(fn)
6265
case _ => None
6366

6467
end EtaExpansion
@@ -303,7 +306,6 @@ class TypeApplications(val self: Type) extends AnyVal {
303306
val resType = self.appliedTo(tparams.map(_.paramRef))
304307
self match
305308
case self: TypeRef if tparams.nonEmpty && self.symbol.isClass =>
306-
val prefix = self.prefix
307309
val owner = self.symbol.owner
308310
// Calling asSeenFrom on the type parameter infos is important
309311
// so that class type references within another prefix have
@@ -318,7 +320,7 @@ class TypeApplications(val self: Type) extends AnyVal {
318320
// So we take the prefix M2.type and the F symbol's owner, M1,
319321
// to call asSeenFrom on T's info.
320322
HKTypeLambda(tparams.map(_.paramName))(
321-
tl => tparams.map(p => HKTypeLambda.toPInfo(tl.integrate(tparams, p.paramInfo.asSeenFrom(prefix, owner)))),
323+
tl => tparams.map(p => HKTypeLambda.toPInfo(tl.integrate(tparams, p.paramInfo.asSeenFrom(self.prefix, owner)))),
322324
tl => tl.integrate(tparams, resType))
323325
case _ =>
324326
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)