@@ -1727,6 +1727,40 @@ object SymDenotations {
1727
1727
baseTp
1728
1728
}
1729
1729
1730
+ /** Sanitize base type so that wildvard arguments can be safely handled by
1731
+ * substitution. If base type is of the form `B[S_1, ..., S_n]`, then
1732
+ * for every `S_i:
1733
+ * for every wildcard argument args_j in `args`:
1734
+ * if the corresponding parameter `tparam_j` is referenced by `S_i`,
1735
+ * but `S_i != tparam_j`, then
1736
+ * replace S_i with `_`.
1737
+ *
1738
+ * This prevents a non-sensical substitution of `tparam_j` in `S_i` by a wildcard
1739
+ * type (of class TypeBounds). See pos/i5844.scala as a test case.
1740
+ */
1741
+ def handleWildcards (base : Type , tparams : List [Symbol ], args : List [Type ]): Type = {
1742
+ def sanitize (baseArg : Type , tparams : List [Symbol ], args : List [Type ]): Type = args match {
1743
+ case arg :: args1 =>
1744
+ val tparam :: tparams1 = tparams
1745
+ val pref = tparam.typeRef
1746
+ val baseArg1 = arg match {
1747
+ case arg : TypeBounds if baseArg != pref && pref.occursIn(baseArg) =>
1748
+ TypeBounds .empty
1749
+ case _ =>
1750
+ baseArg
1751
+ }
1752
+ sanitize(baseArg1, tparams1, args1)
1753
+ case nil =>
1754
+ baseArg
1755
+ }
1756
+ base match {
1757
+ case base @ AppliedType (tycon, baseArgs) =>
1758
+ base.derivedAppliedType(tycon, baseArgs.mapconserve(sanitize(_, tparams, args)))
1759
+ case _ =>
1760
+ base
1761
+ }
1762
+ }
1763
+
1730
1764
def recur (tp : Type ): Type = try {
1731
1765
tp match {
1732
1766
case tp : CachedType =>
@@ -1790,7 +1824,10 @@ object SymDenotations {
1790
1824
case LambdaParam (_, _) :: _ =>
1791
1825
recur(tp.superType)
1792
1826
case tparams : List [Symbol @ unchecked] =>
1793
- recur(tycon).subst(tparams, args)
1827
+ var base = recur(tycon)
1828
+ if (args.exists(_.isInstanceOf [TypeBounds ]))
1829
+ base = handleWildcards(base, tparams, args)
1830
+ base.subst(tparams, args)
1794
1831
}
1795
1832
record(tp, baseTp)
1796
1833
baseTp
0 commit comments