aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/core/TypeOps.scala25
-rw-r--r--tests/pos/i998.scala6
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
+ }
+}