Skip to content

Commit 0a2b676

Browse files
committed
Fix caching bug: don't assume that tvars instantiation cannot be retracted
When TypeVar#inst is empty but an instantiation exists in the typer state, we should set ephemeral to true, because this instantiation will be retracted if we throw away the current typer state. This makes hkrange.scala pass, it compiled before but the type parameter of `f` was inferred to be `Nothing` because of this bug, and this failed Ycheck. For anyone who wonders how caching bugs manifest themselves, here's what happened in details in hkrange.scala: 1. In an ExploreTyperState we set `CC` to be `IndexedSeq` in the constraint set 2. In that same typer state the TypeRef `CC[Int]` (it's a TypeRef because `CC` is a type lambda) gets the denotation `IndexedSeq[Int]`, which is correct, but the denotation is cached since `ephemeral` is false, which is wrong. 3. Later, we retract the ExplorerTyperState, so `CC` is uninstantiated again and unconstrained. 4. Then we do the subtyping check `CC[Int] <:< IndexedSeq[Int]`, because the denotation of `CC[Int]` was cached, this returns true, but `CC` stays unconstrained. 5. This means that when we instantiate `CC`, we get `Nothing` After this fix, the TypeRef denotation is no longer cached, so when we do `CC[Int] <:< IndexedSeq[Int]`, `CC` gets constrained as expected.
1 parent c2513a6 commit 0a2b676

File tree

2 files changed

+4
-1
lines changed

2 files changed

+4
-1
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2558,7 +2558,10 @@ object Types {
25582558
* uninstantiated
25592559
*/
25602560
def instanceOpt(implicit ctx: Context): Type =
2561-
if (inst.exists) inst else ctx.typerState.instType(this)
2561+
if (inst.exists) inst else {
2562+
ctx.typerState.ephemeral = true
2563+
ctx.typerState.instType(this)
2564+
}
25622565

25632566
/** Is the variable already instantiated? */
25642567
def isInstantiated(implicit ctx: Context) = instanceOpt.exists
File renamed without changes.

0 commit comments

Comments
 (0)