@@ -300,9 +300,12 @@ trait ConstraintHandling[AbstractContext] {
300300 * (i.e. `inst.widenSingletons <:< bound` succeeds with satisfiable constraint)
301301 * 2. If `inst` is a union type, approximate the union type from above by an intersection
302302 * of all common base types, provided the result is a subtype of `bound`.
303- * 3. If `inst` a super trait instance or an intersection with some super trait
304- * parents, replace all super trait instances with AnyRef (or Any, if the trait
305- * is a universal trait) as long as the result is a subtype of `bound`.
303+ * 3. If `inst` an intersection such that some operands are super trait instances
304+ * and others are not, replace as many super trait instances as possible with Any
305+ * as long as the result is still a subtype of `bound`. But fall back to the
306+ * original type if the resulting widened type is a supertype of all dropped
307+ * types (since in this case the type was not a true intersection of super traits
308+ * and other types to start with).
306309 *
307310 * Don't do these widenings if `bound` is a subtype of `scala.Singleton`.
308311 * Also, if the result of these widenings is a TypeRef to a module class,
@@ -315,14 +318,14 @@ trait ConstraintHandling[AbstractContext] {
315318 def widenInferred (inst : Type , bound : Type )(implicit actx : AbstractContext ): Type =
316319
317320 def dropSuperTraits (tp : Type ): Type =
318- var keep : Set [Type ] = Set () // types to keep since otherwise bound would not fit
319- var lastDropped : Type = NoType // the last type dropped in dropOneSuperTrait
321+ var kept : Set [Type ] = Set () // types to keep since otherwise bound would not fit
322+ var dropped : List [ Type ] = List () // the types dropped so far, last one on top
320323
321324 def dropOneSuperTrait (tp : Type ): Type =
322325 val tpd = tp.dealias
323- if tpd.typeSymbol.isSuperTrait && ! tpd.isLambdaSub && ! keep .contains(tpd) then
324- lastDropped = tpd
325- if tpd.derivesFrom(defn. ObjectClass ) then defn. ObjectType else defn.AnyType
326+ if tpd.typeSymbol.isSuperTrait && ! tpd.isLambdaSub && ! kept .contains(tpd) then
327+ dropped = tpd :: dropped
328+ defn.AnyType
326329 else tpd match
327330 case AndType (tp1, tp2) =>
328331 val tp1w = dropOneSuperTrait(tp1)
@@ -339,10 +342,12 @@ trait ConstraintHandling[AbstractContext] {
339342 if tpw eq tp then tp
340343 else if tpw <:< bound then recur(tpw)
341344 else
342- keep += lastDropped
345+ kept += dropped.head
346+ dropped = dropped.tail
343347 recur(tp)
344348
345- recur(tp)
349+ val tpw = recur(tp)
350+ if (tpw eq tp) || dropped.forall(_ frozen_<:< tpw) then tp else tpw
346351 end dropSuperTraits
347352
348353 def widenOr (tp : Type ) =
0 commit comments