diff options
-rw-r--r-- | src/dotty/tools/dotc/core/TypeComparer.scala | 16 | ||||
-rw-r--r-- | tests/pos/i830.scala | 6 |
2 files changed, 19 insertions, 3 deletions
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index 5fbffe6e9..f7fd145ad 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -123,7 +123,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { pendingSubTypes = new mutable.HashSet[(Type, Type)] ctx.log(s"!!! deep subtype recursion involving ${tp1.show} <:< ${tp2.show}, constraint = ${state.constraint.show}") ctx.log(s"!!! constraint = ${constraint.show}") - assert(!ctx.settings.YnoDeepSubtypes.value) + if (ctx.settings.YnoDeepSubtypes.value) throw new Error("deep subtype") if (Config.traceDeepSubTypeRecursions && !this.isInstanceOf[ExplainingTypeComparer]) ctx.log(TypeComparer.explained(implicit ctx => ctx.typeComparer.isSubType(tp1, tp2))) } @@ -779,8 +779,18 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { else { val t2 = mergeIfSub(tp2, tp1) if (t2.exists) t2 - else andType(tp1, tp2) - } + else tp1 match { + case tp1: SingletonType => + tp2 match { + case tp2: SingletonType => + // Make use of the fact that the intersection of two singleton + // types which are not subtypes of each other is empty. + defn.NothingType + case _ => andType(tp1, tp2) + } + case _ => andType(tp1, tp2) + } + } } } } diff --git a/tests/pos/i830.scala b/tests/pos/i830.scala new file mode 100644 index 000000000..8fcb29f36 --- /dev/null +++ b/tests/pos/i830.scala @@ -0,0 +1,6 @@ +object C { + trait X[T] + implicit def u[A, B]: X[A | B] = new X[A | B] {} + def y[T](implicit x: X[T]): T = ??? + val x: 1 & 2 | 2 & 3 = y +} |