Skip to content

Commit 9cb3542

Browse files
committed
Fix #830: Compiler hangs on implicit search with singleton &/|
In fact we get a deep subtype recursion when compileing i830.scala. The problem goes away once we make use of the fact that the intersection of two singleton types which are not subtypes of each other is empty.
1 parent 30e5f32 commit 9cb3542

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
123123
pendingSubTypes = new mutable.HashSet[(Type, Type)]
124124
ctx.log(s"!!! deep subtype recursion involving ${tp1.show} <:< ${tp2.show}, constraint = ${state.constraint.show}")
125125
ctx.log(s"!!! constraint = ${constraint.show}")
126-
assert(!ctx.settings.YnoDeepSubtypes.value)
126+
if (ctx.settings.YnoDeepSubtypes.value) throw new Error("deep subtype")
127127
if (Config.traceDeepSubTypeRecursions && !this.isInstanceOf[ExplainingTypeComparer])
128128
ctx.log(TypeComparer.explained(implicit ctx => ctx.typeComparer.isSubType(tp1, tp2)))
129129
}
@@ -779,8 +779,18 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
779779
else {
780780
val t2 = mergeIfSub(tp2, tp1)
781781
if (t2.exists) t2
782-
else andType(tp1, tp2)
783-
}
782+
else tp1 match {
783+
case tp1: SingletonType =>
784+
tp2 match {
785+
case tp2: SingletonType =>
786+
// Make use of the fact that the intersection of two singleton
787+
// types which are not subtypes of each other is empty.
788+
defn.NothingType
789+
case _ => andType(tp1, tp2)
790+
}
791+
case _ => andType(tp1, tp2)
792+
}
793+
}
784794
}
785795
}
786796
}

tests/pos/i830.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
object C {
2+
trait X[T]
3+
implicit def u[A, B]: X[A | B] = new X[A | B] {}
4+
def y[T](implicit x: X[T]): T = ???
5+
val x: 1 & 2 | 2 & 3 = y
6+
}

0 commit comments

Comments
 (0)