aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-12-02 16:48:11 +0100
committerMartin Odersky <odersky@gmail.com>2016-12-02 16:48:19 +0100
commita7003bb223fb535f64a3026ff2a5a3e7d3ab7609 (patch)
tree7e64183a8d31a846e817628d5ea44abfc62a8730
parent131fcf26e65d45bea89989ced209f394457a6d12 (diff)
downloaddotty-a7003bb223fb535f64a3026ff2a5a3e7d3ab7609.tar.gz
dotty-a7003bb223fb535f64a3026ff2a5a3e7d3ab7609.tar.bz2
dotty-a7003bb223fb535f64a3026ff2a5a3e7d3ab7609.zip
Fix insertAfter
Once the context-bounds desugaring of i1765.scala was fixed, another problem came up: We hit an invalid denotation due to some interaction between mixin and memoize. It turned out that `insertInsteadOf` did not do what its doc comment claimed: it did not store a forwarding pointer `nextInRun` in the overwritten denotation. Once that was fixed we also needed to fix a follow-on erorr that now we could have chains of invalid denotations linked by `nextInRun`.
-rw-r--r--compiler/src/dotty/tools/dotc/core/Denotations.scala22
-rw-r--r--tests/pos/i1765.scala21
2 files changed, 40 insertions, 3 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/Denotations.scala b/compiler/src/dotty/tools/dotc/core/Denotations.scala
index 6a39c5787..99c688d50 100644
--- a/compiler/src/dotty/tools/dotc/core/Denotations.scala
+++ b/compiler/src/dotty/tools/dotc/core/Denotations.scala
@@ -132,7 +132,7 @@ object Denotations {
def atSignature(sig: Signature, site: Type = NoPrefix, relaxed: Boolean = false)(implicit ctx: Context): Denotation
/** The variant of this denotation that's current in the given context.
- * If no such denotation exists, returns the denotation with each alternative
+ * If no such denotation exists, returns the denotation with each alternative
* at its first point of definition.
*/
def current(implicit ctx: Context): Denotation
@@ -744,6 +744,20 @@ object Denotations {
else NoDenotation
}
+ /** The next defined denotation (following `nextInRun`) or an arbitrary
+ * undefined denotation, if all denotations in a `nextinRun` cycle are
+ * undefined.
+ */
+ private def nextDefined: SingleDenotation = {
+ var p1 = this
+ var p2 = nextInRun
+ while (p1.validFor == Nowhere && (p1 ne p2)) {
+ p1 = p1.nextInRun
+ p2 = p2.nextInRun.nextInRun
+ }
+ p1
+ }
+
/** Produce a denotation that is valid for the given context.
* Usually called when !(validFor contains ctx.period)
* (even though this is not a precondition).
@@ -763,8 +777,9 @@ object Denotations {
// can happen if we sit on a stale denotation which has been replaced
// wholesale by an installAfter; in this case, proceed to the next
// denotation and try again.
- if (validFor == Nowhere && nextInRun.validFor != Nowhere) return nextInRun.current
- assert(false)
+ val nxt = nextDefined
+ if (nxt.validFor != Nowhere) return nxt
+ assert(false, this)
}
if (valid.runId != currentPeriod.runId)
@@ -905,6 +920,7 @@ object Denotations {
prev.nextInRun = this
this.nextInRun = old.nextInRun
old.validFor = Nowhere
+ old.nextInRun = this
}
def staleSymbolError(implicit ctx: Context) = {
diff --git a/tests/pos/i1765.scala b/tests/pos/i1765.scala
new file mode 100644
index 000000000..d79129638
--- /dev/null
+++ b/tests/pos/i1765.scala
@@ -0,0 +1,21 @@
+trait T[X]
+
+trait U[X]
+
+trait TC[M[_]] {
+ def foo[M[_]: TC, A](ma: U[A]) = ()
+ implicit val TCofT: TC[T] = new TC[T] {}
+ implicit def any2T[A](a: A): T[A] = new T[A] {}
+ implicit def any2U[A](a: A): U[A] = new U[A] {}
+ val x = foo[T, Int](1)
+ val y = ()
+}
+
+// Minimized version exhibiting an assertion violation in Denotation#current at phase lambdalift:
+trait TC2 {
+// implicit val TCofT: TC2[T] = new TC2[T] {}
+ val TCofT: Object = {
+ class C extends TC2
+ new Object
+ }
+}