aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGuillaume Martres <smarter@ubuntu.com>2016-01-12 17:52:27 +0100
committerGuillaume Martres <smarter@ubuntu.com>2016-01-17 18:40:42 +0100
commit0a2b676e97d1325e6ddd3861b7681f8f8db955b9 (patch)
tree95b90a1c09b8f153f758146dd37b64c8b0ed9410 /src
parentc2513a639df2585f9991d40d6be9fce23b5d4699 (diff)
downloaddotty-0a2b676e97d1325e6ddd3861b7681f8f8db955b9.tar.gz
dotty-0a2b676e97d1325e6ddd3861b7681f8f8db955b9.tar.bz2
dotty-0a2b676e97d1325e6ddd3861b7681f8f8db955b9.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/core/Types.scala5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 84602ccf7..43276d254 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -2558,7 +2558,10 @@ object Types {
* uninstantiated
*/
def instanceOpt(implicit ctx: Context): Type =
- if (inst.exists) inst else ctx.typerState.instType(this)
+ if (inst.exists) inst else {
+ ctx.typerState.ephemeral = true
+ ctx.typerState.instType(this)
+ }
/** Is the variable already instantiated? */
def isInstantiated(implicit ctx: Context) = instanceOpt.exists