@@ -1533,18 +1533,48 @@ object Types {
1533
1533
ctx.underlyingRecursions -= 1
1534
1534
}
1535
1535
1536
+ /** A selection of the same kind, but with potentially a differet prefix.
1537
+ * The following normalizations are performed for type selections T#A:
1538
+ *
1539
+ * 1. If Config.splitProjections is true:
1540
+ *
1541
+ * (S & T)#A --> S#A & T#A
1542
+ * (S | T)#A --> S#A | T#A
1543
+ *
1544
+ * 2. If A is bound to an alias `= B` in T
1545
+ *
1546
+ * T#A --> B
1547
+ */
1536
1548
def derivedSelect (prefix : Type )(implicit ctx : Context ): Type =
1537
1549
if (prefix eq this .prefix) this
1538
1550
else {
1551
+ if (Config .splitProjections && isType)
1552
+ prefix match {
1553
+ case prefix : AndType =>
1554
+ def isMissing (tp : Type ) = tp match {
1555
+ case tp : TypeRef => ! tp.info.exists
1556
+ case _ => false
1557
+ }
1558
+ val derived1 = derivedSelect(prefix.tp1)
1559
+ val derived2 = derivedSelect(prefix.tp2)
1560
+ return (
1561
+ if (isMissing(derived1)) derived2
1562
+ else if (isMissing(derived2)) derived1
1563
+ else prefix.derivedAndType(derived1, derived2))
1564
+ case prefix : OrType =>
1565
+ val derived1 = derivedSelect(prefix.tp1)
1566
+ val derived2 = derivedSelect(prefix.tp2)
1567
+ return prefix.derivedOrType(derived1, derived2)
1568
+ case _ =>
1569
+ }
1539
1570
val res = prefix.lookupRefined(name)
1540
1571
if (res.exists) res
1541
1572
else if (name == tpnme.hkApply && prefix.classNotLambda) {
1542
1573
// After substitution we might end up with a type like
1543
1574
// `C { type hk$0 = T0; ...; type hk$n = Tn } # $Apply`
1544
1575
// where C is a class. In that case we eta expand `C`.
1545
1576
derivedSelect(prefix.EtaExpandCore (this .prefix.typeConstructor.typeParams))
1546
- }
1547
- else newLikeThis(prefix)
1577
+ } else newLikeThis(prefix)
1548
1578
}
1549
1579
1550
1580
/** Create a NamedType of the same kind as this type, but with a new prefix.
0 commit comments