Skip to content

Commit 4746041

Browse files
committed
Fix #6247: Remove incorrect early check
The check relied on the assumption that `locked` is always contained in `state.ownedVars`, but this can stop being true when an owned type variable is garbage-collected.
1 parent 4dd2f94 commit 4746041

File tree

3 files changed

+19
-2
lines changed

3 files changed

+19
-2
lines changed

compiler/src/dotty/tools/dotc/typer/Inferencing.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,8 +406,14 @@ trait Inferencing { this: Typer =>
406406
*/
407407
def interpolateTypeVars(tree: Tree, pt: Type, locked: TypeVars)(implicit ctx: Context): tree.type = {
408408
val state = ctx.typerState
409-
if (state.ownedVars.size > locked.size) {
410-
val qualifying = state.ownedVars -- locked
409+
410+
// Note that some variables in `locked` might not be in `state.ownedVars`
411+
// anymore if they've been garbage-collected, so we can't use
412+
// `state.ownedVars.size > locked.size` as an early check to avoid computing
413+
// `qualifying`.
414+
val qualifying = state.ownedVars -- locked
415+
416+
if (qualifying.nonEmpty) {
411417
typr.println(i"interpolate $tree: ${tree.tpe.widen} in $state, owned vars = ${state.ownedVars.toList}%, %, previous = ${locked.toList}%, % / ${state.constraint}")
412418
val resultAlreadyConstrained =
413419
tree.isInstanceOf[Apply] || tree.tpe.isInstanceOf[MethodOrPoly]

compiler/src/dotty/tools/dotc/util/SimpleIdentitySet.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import collection.mutable.ListBuffer
77
*/
88
abstract class SimpleIdentitySet[+Elem <: AnyRef] {
99
def size: Int
10+
def nonEmpty: Boolean = size > 0
1011
def + [E >: Elem <: AnyRef](x: E): SimpleIdentitySet[E]
1112
def - [E >: Elem <: AnyRef](x: E): SimpleIdentitySet[Elem]
1213
def contains[E >: Elem <: AnyRef](x: E): Boolean

tests/pos/i6247.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class Foo {
2+
implicit class NN[T](x:T|Null) {
3+
def nn: T = x.asInstanceOf[T]
4+
}
5+
6+
val x1: String|Null = null
7+
x1.nn.length
8+
val x2: String = x1.nn
9+
x1.nn.length
10+
}

0 commit comments

Comments
 (0)