From eb1197c87b212bd3b776ce9e24f550e80888e5e4 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 19 Jan 2016 21:26:22 +0100 Subject: [PATCH] Fix #998 Needed a fix in approximateUnion. --- src/dotty/tools/dotc/core/TypeOps.scala | 25 ++++++++++++++++++++++--- tests/pos/i998.scala | 6 ++++++ 2 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 tests/pos/i998.scala diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala index 6896468ba884..70e8302d93dc 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 000000000000..4bd3ecf29291 --- /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 + } +}