Skip to content

Commit edcb3e5

Browse files
oderskyolsdavis
authored andcommitted
Harden erasure of PolyFunction apply's
Fix in case qualifier is an intersection with a PolyFunction type. Fixes scala#13950
1 parent 097a956 commit edcb3e5

File tree

2 files changed

+18
-3
lines changed

2 files changed

+18
-3
lines changed

compiler/src/dotty/tools/dotc/transform/Erasure.scala

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -667,8 +667,18 @@ object Erasure {
667667
def mapOwner(sym: Symbol): Symbol =
668668
if !sym.exists && tree.name == nme.apply then
669669
// PolyFunction apply Selects will not have a symbol, so deduce the owner
670-
// from the typed the erasure of the original qualifier.
671-
val owner = erasure(tree.qualifier.typeOpt).typeSymbol
670+
// from the typed tree of the erasure of the original qualifier's PolyFunction type.
671+
// Need to sidestep information loss in the erasure of AndTypes, see pos/i13950.scala.
672+
val polyFunctionQualType = inContext(preErasureCtx) {
673+
def narrowToPolyFun(tp: Type)(using Context): Type =
674+
if tp.derivesFrom(defn.PolyFunctionClass) then
675+
tp match
676+
case AndType(tp1, tp2) => narrowToPolyFun(tp1).orElse(narrowToPolyFun(tp2))
677+
case _ => tp
678+
else NoType
679+
narrowToPolyFun(tree.qualifier.typeOpt.widen)
680+
}
681+
val owner = erasure(polyFunctionQualType).typeSymbol
672682
if defn.isFunctionClass(owner) then owner else NoSymbol
673683
else
674684
val owner = sym.maybeOwner
@@ -687,7 +697,7 @@ object Erasure {
687697

688698
val owner = mapOwner(origSym)
689699
val sym = if (owner eq origSym.maybeOwner) origSym else owner.info.decl(tree.name).symbol
690-
assert(sym.exists, origSym.showLocated)
700+
assert(sym.exists, i"no owner from $owner/${origSym.showLocated} in $tree")
691701

692702
if owner == defn.ObjectClass then checkValue(qual1)
693703

tests/pos/i13950.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
def example =
2+
(1,2).map[[_] =>> Int]([C] => (x1: C) => x1 match {
3+
case x2: ([V] => () => Int) =>
4+
x2[Int]()
5+
})

0 commit comments

Comments
 (0)