@@ -266,31 +266,50 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
266
266
val accu1 = if (accu exists (_ derivesFrom c)) accu else c :: accu
267
267
if (cs == c.baseClasses) accu1 else dominators(rest, accu1)
268
268
}
269
+ def approximateOr (tp1 : Type , tp2 : Type )(implicit ctx : Context ): Type = {
270
+ def isClassRef (tp : Type ): Boolean = tp match {
271
+ case tp : TypeRef => tp.symbol.isClass
272
+ case tp : RefinedType => isClassRef(tp.parent)
273
+ case _ => false
274
+ }
275
+ def next (tp : TypeProxy ) = tp.underlying match {
276
+ case TypeBounds (_, hi) => hi
277
+ case nx => nx
278
+ }
279
+ tp1 match {
280
+ case tp1 : RefinedType =>
281
+ tp2 match {
282
+ case tp2 : RefinedType if tp1.refinedName == tp2.refinedName =>
283
+ return tp1.derivedRefinedType(
284
+ approximateUnion(OrType (tp1.parent, tp2.parent)),
285
+ tp1.refinedName,
286
+ (tp1.refinedInfo | tp2.refinedInfo).substRefinedThis(tp2, RefinedThis (tp1)))
287
+ .ensuring { x => println(i " approx or $tp1 | $tp2 = $x" ); true } // DEBUG
288
+ case _ =>
289
+ }
290
+ case _ =>
291
+ }
292
+ tp1 match {
293
+ case tp1 : TypeProxy if ! isClassRef(tp1) =>
294
+ approximateUnion(next(tp1) | tp2)
295
+ case _ =>
296
+ tp2 match {
297
+ case tp2 : TypeProxy if ! isClassRef(tp2) =>
298
+ approximateUnion(tp1 | next(tp2))
299
+ case _ =>
300
+ val commonBaseClasses = tp.mapReduceOr(_.baseClasses)(intersect)
301
+ val doms = dominators(commonBaseClasses, Nil )
302
+ def baseTp (cls : ClassSymbol ): Type =
303
+ if (tp1.typeParams.nonEmpty) tp.baseTypeRef(cls)
304
+ else tp.baseTypeWithArgs(cls)
305
+ doms.map(baseTp).reduceLeft(AndType .apply)
306
+ }
307
+ }
308
+ }
269
309
if (ctx.featureEnabled(defn.LanguageModuleClass , nme.keepUnions)) tp
270
310
else tp match {
271
311
case tp : OrType =>
272
- def isClassRef (tp : Type ): Boolean = tp match {
273
- case tp : TypeRef => tp.symbol.isClass
274
- case tp : RefinedType => isClassRef(tp.parent)
275
- case _ => false
276
- }
277
- def next (tp : TypeProxy ) = tp.underlying match {
278
- case TypeBounds (_, hi) => hi
279
- case nx => nx
280
- }
281
- tp.tp1 match {
282
- case tp1 : TypeProxy if ! isClassRef(tp1) =>
283
- approximateUnion(next(tp1) | tp.tp2)
284
- case _ =>
285
- tp.tp2 match {
286
- case tp2 : TypeProxy if ! isClassRef(tp2) =>
287
- approximateUnion(tp.tp1 | next(tp2))
288
- case _ =>
289
- val commonBaseClasses = tp.mapReduceOr(_.baseClasses)(intersect)
290
- val doms = dominators(commonBaseClasses, Nil )
291
- doms.map(tp.baseTypeWithArgs).reduceLeft(AndType .apply)
292
- }
293
- }
312
+ approximateOr(tp.tp1, tp.tp2)
294
313
case tp @ AndType (tp1, tp2) =>
295
314
tp derived_& (approximateUnion(tp1), approximateUnion(tp2))
296
315
case tp : RefinedType =>
0 commit comments