@@ -158,31 +158,37 @@ private[internal] trait GlbLubs {
158
158
rest filter (t => ! first.typeSymbol.isSubClass(t.typeSymbol)))
159
159
}
160
160
161
+ /** From a list of types, retain only maximal types as determined by the partial order `po`. */
162
+ private def maxTypes (ts : List [Type ])(po : (Type , Type ) => Boolean ): List [Type ] = {
163
+ def loop (ts : List [Type ]): List [Type ] = ts match {
164
+ case t :: ts1 =>
165
+ val ts2 = loop(ts1.filterNot(po(_, t)))
166
+ if (ts2.exists(po(t, _))) ts2 else t :: ts2
167
+ case Nil => Nil
168
+ }
169
+
170
+ // The order here matters because type variables and
171
+ // wildcards can act both as subtypes and supertypes.
172
+ val (ts2, ts1) = ts.partition(_ exists {
173
+ case tv : TypeVar => ! tv.isGround
174
+ case t => t.isWildcard
175
+ })
176
+
177
+ loop(ts1 ::: ts2)
178
+ }
179
+
161
180
/** Eliminate from list of types all elements which are a supertype
162
181
* of some other element of the list. */
163
- private def elimSuper (ts : List [Type ]): List [Type ] = ts match {
164
- case List () | List (_) => ts
165
- case t :: ts1 =>
166
- val rest = elimSuper(ts1 filter (t1 => ! (t <:< t1)))
167
- if (rest exists (t1 => t1 <:< t)) rest else t :: rest
168
- }
182
+ private def elimSuper (ts : List [Type ]): List [Type ] =
183
+ maxTypes(ts)((t1, t2) => t2 <:< t1)
169
184
170
185
/** Eliminate from list of types all elements which are a subtype
171
186
* of some other element of the list. */
172
- private def elimSub (ts : List [Type ], depth : Depth ): List [Type ] = {
173
- def elimSub0 (ts : List [Type ]): List [Type ] = ts match {
174
- case List () => ts
175
- case List (t) => ts
176
- case t :: ts1 =>
177
- val rest = elimSub0(ts1 filter (t1 => ! isSubType(t1, t, depth.decr)))
178
- if (rest exists (t1 => isSubType(t, t1, depth.decr))) rest else t :: rest
179
- }
180
- val ts0 = elimSub0(ts)
181
- if (ts0.isEmpty || ts0.tail.isEmpty) ts0
182
- else {
183
- val ts1 = ts0 mapConserve (t => elimAnonymousClass(t.dealiasWiden))
184
- if (ts1 eq ts0) ts0
185
- else elimSub(ts1, depth)
187
+ @ tailrec private def elimSub (ts : List [Type ], depth : Depth ): List [Type ] = {
188
+ val ts1 = maxTypes(ts)(isSubType(_, _, depth.decr))
189
+ if (ts1.lengthCompare(1 ) <= 0 ) ts1 else {
190
+ val ts2 = ts1.mapConserve(t => elimAnonymousClass(t.dealiasWiden))
191
+ if (ts1 eq ts2) ts1 else elimSub(ts2, depth)
186
192
}
187
193
}
188
194
0 commit comments