diff options
author | Martin Odersky <odersky@gmail.com> | 2015-10-22 13:19:14 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2015-10-22 13:20:10 +0200 |
commit | 9cb35429fc2c52f5d243b9c9d29739df1ff5967a (patch) | |
tree | b37a22b0daeb7127e4b89a85cf3b447b3ef0425f | |
parent | 30e5f322a0fb9c4c43cbeb3231423ac95571a3a7 (diff) | |
download | dotty-9cb35429fc2c52f5d243b9c9d29739df1ff5967a.tar.gz dotty-9cb35429fc2c52f5d243b9c9d29739df1ff5967a.tar.bz2 dotty-9cb35429fc2c52f5d243b9c9d29739df1ff5967a.zip |
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.
-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 +} |