diff options
-rw-r--r-- | src/dotty/tools/dotc/core/TypeOps.scala | 25 | ||||
-rw-r--r-- | tests/pos/i998.scala | 6 |
2 files changed, 28 insertions, 3 deletions
diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala index 6896468ba..70e8302d9 100644 --- a/src/dotty/tools/dotc/core/TypeOps.scala +++ b/src/dotty/tools/dotc/core/TypeOps.scala @@ -269,9 +269,28 @@ trait TypeOps { this: Context => // TODO: Make standalone object. if (ctx.featureEnabled(defn.LanguageModuleClass, nme.keepUnions)) tp else tp match { case tp: OrType => - val commonBaseClasses = tp.mapReduceOr(_.baseClasses)(intersect) - val doms = dominators(commonBaseClasses, Nil) - doms.map(tp.baseTypeWithArgs).reduceLeft(AndType.apply) + def isClassRef(tp: Type): Boolean = tp match { + case tp: TypeRef => tp.symbol.isClass + case tp: RefinedType => isClassRef(tp.parent) + case _ => false + } + def next(tp: TypeProxy) = tp.underlying match { + case TypeBounds(_, hi) => hi + case nx => nx + } + tp.tp1 match { + case tp1: TypeProxy if !isClassRef(tp1) => + approximateUnion(next(tp1) | tp.tp2) + case _ => + tp.tp2 match { + case tp2: TypeProxy if !isClassRef(tp2) => + approximateUnion(tp.tp1 | next(tp2)) + case _ => + val commonBaseClasses = tp.mapReduceOr(_.baseClasses)(intersect) + val doms = dominators(commonBaseClasses, Nil) + doms.map(tp.baseTypeWithArgs).reduceLeft(AndType.apply) + } + } case tp @ AndType(tp1, tp2) => tp derived_& (approximateUnion(tp1), approximateUnion(tp2)) case tp: RefinedType => diff --git a/tests/pos/i998.scala b/tests/pos/i998.scala new file mode 100644 index 000000000..4bd3ecf29 --- /dev/null +++ b/tests/pos/i998.scala @@ -0,0 +1,6 @@ +object Test { + def foo[A <: X, B <: X, X](left: A, right: B): Unit = { + val elem = if (false) left else right + val check: X = elem + } +} |