@@ -158,31 +158,30 @@ 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
+ loop(ts)
171
+ }
172
+
161
173
/** Eliminate from list of types all elements which are a supertype
162
174
* 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
- }
175
+ private def elimSuper (ts : List [Type ]): List [Type ] =
176
+ maxTypes(ts)((t1, t2) => t2 <:< t1)
169
177
170
178
/** Eliminate from list of types all elements which are a subtype
171
179
* 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)
180
+ @ tailrec private def elimSub (ts : List [Type ], depth : Depth ): List [Type ] = {
181
+ val ts1 = maxTypes(ts)(isSubType(_, _, depth.decr))
182
+ if (ts1.lengthCompare(1 ) <= 0 ) ts1 else {
183
+ val ts2 = ts1.mapConserve(t => elimAnonymousClass(t.dealiasWiden))
184
+ if (ts1 eq ts2) ts1 else elimSub(ts2, depth)
186
185
}
187
186
}
188
187
0 commit comments