diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index f468a573f7ca..0e4ac6dc68b8 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -1047,7 +1047,9 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { else hkCombine(tp1, tp2, tparams1, tparams2, op) } - /** Try to distribute `&` inside type, detect and handle conflicts */ + /** Try to distribute `&` inside type, detect and handle conflicts + * pre: !(tp1 <: tp2) && !(tp2 <:< tp2) -- these cases were handled before + */ private def distributeAnd(tp1: Type, tp2: Type): Type = tp1 match { // opportunistically merge same-named refinements // this does not change anything semantically (i.e. merging or not merging @@ -1105,6 +1107,10 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { tp1.underlying & tp2 case tp1: AnnotatedType => tp1.underlying & tp2 + case tp1: SingletonType => + // because of the precondition, `tp1 & tp2 != tp1`, so it must be strictly smaller than `tp1`, + // which means it's `Nothing`. + NothingType case _ => NoType } diff --git a/tests/pos/i864.scala b/tests/pos/i864.scala new file mode 100644 index 000000000000..8d2b859998e9 --- /dev/null +++ b/tests/pos/i864.scala @@ -0,0 +1,10 @@ +object C { + val a: Int = 1 + val b: Int = 2 + val c: Int = 2 + + 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: a.type & b.type | b.type & c.type = y +}