Skip to content

Commit a7003bb

Browse files
committed
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`.
1 parent 131fcf2 commit a7003bb

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

compiler/src/dotty/tools/dotc/core/Denotations.scala

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ object Denotations {
132132
def atSignature(sig: Signature, site: Type = NoPrefix, relaxed: Boolean = false)(implicit ctx: Context): Denotation
133133

134134
/** The variant of this denotation that's current in the given context.
135-
* If no such denotation exists, returns the denotation with each alternative
135+
* If no such denotation exists, returns the denotation with each alternative
136136
* at its first point of definition.
137137
*/
138138
def current(implicit ctx: Context): Denotation
@@ -744,6 +744,20 @@ object Denotations {
744744
else NoDenotation
745745
}
746746

747+
/** The next defined denotation (following `nextInRun`) or an arbitrary
748+
* undefined denotation, if all denotations in a `nextinRun` cycle are
749+
* undefined.
750+
*/
751+
private def nextDefined: SingleDenotation = {
752+
var p1 = this
753+
var p2 = nextInRun
754+
while (p1.validFor == Nowhere && (p1 ne p2)) {
755+
p1 = p1.nextInRun
756+
p2 = p2.nextInRun.nextInRun
757+
}
758+
p1
759+
}
760+
747761
/** Produce a denotation that is valid for the given context.
748762
* Usually called when !(validFor contains ctx.period)
749763
* (even though this is not a precondition).
@@ -763,8 +777,9 @@ object Denotations {
763777
// can happen if we sit on a stale denotation which has been replaced
764778
// wholesale by an installAfter; in this case, proceed to the next
765779
// denotation and try again.
766-
if (validFor == Nowhere && nextInRun.validFor != Nowhere) return nextInRun.current
767-
assert(false)
780+
val nxt = nextDefined
781+
if (nxt.validFor != Nowhere) return nxt
782+
assert(false, this)
768783
}
769784

770785
if (valid.runId != currentPeriod.runId)
@@ -905,6 +920,7 @@ object Denotations {
905920
prev.nextInRun = this
906921
this.nextInRun = old.nextInRun
907922
old.validFor = Nowhere
923+
old.nextInRun = this
908924
}
909925

910926
def staleSymbolError(implicit ctx: Context) = {

tests/pos/i1765.scala

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
trait T[X]
2+
3+
trait U[X]
4+
5+
trait TC[M[_]] {
6+
def foo[M[_]: TC, A](ma: U[A]) = ()
7+
implicit val TCofT: TC[T] = new TC[T] {}
8+
implicit def any2T[A](a: A): T[A] = new T[A] {}
9+
implicit def any2U[A](a: A): U[A] = new U[A] {}
10+
val x = foo[T, Int](1)
11+
val y = ()
12+
}
13+
14+
// Minimized version exhibiting an assertion violation in Denotation#current at phase lambdalift:
15+
trait TC2 {
16+
// implicit val TCofT: TC2[T] = new TC2[T] {}
17+
val TCofT: Object = {
18+
class C extends TC2
19+
new Object
20+
}
21+
}

0 commit comments

Comments
 (0)