Skip to content

Commit ecf62cf

Browse files
committed
Merge pull request #843 from dotty-staging/fix-#830
Fix #830: Compiler hangs on implicit search with singleton &/|
2 parents 77f7b2a + 0a386a8 commit ecf62cf

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

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

Lines changed: 19 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,24 @@ 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: ConstantType =>
784+
tp2 match {
785+
case tp2: ConstantType =>
786+
// Make use of the fact that the intersection of two constant types
787+
// types which are not subtypes of each other is known to be empty.
788+
// Note: The same does not apply to singleton types in general.
789+
// E.g. we could have a pattern match against `x.type & y.type`
790+
// which might succeed if `x` and `y` happen to be the same ref
791+
// at run time. It would not work to replace that with `Nothing`.
792+
// However, maybe we can still apply the replacement to
793+
// types which are not explicitly written.
794+
defn.NothingType
795+
case _ => andType(tp1, tp2)
796+
}
797+
case _ => andType(tp1, tp2)
798+
}
799+
}
784800
}
785801
}
786802
}

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)