diff --git a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala index 967b35f4f87b..bfcd8a152fb9 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala @@ -406,8 +406,14 @@ trait Inferencing { this: Typer => */ def interpolateTypeVars(tree: Tree, pt: Type, locked: TypeVars)(implicit ctx: Context): tree.type = { val state = ctx.typerState - if (state.ownedVars.size > locked.size) { - val qualifying = state.ownedVars -- locked + + // Note that some variables in `locked` might not be in `state.ownedVars` + // anymore if they've been garbage-collected, so we can't use + // `state.ownedVars.size > locked.size` as an early check to avoid computing + // `qualifying`. + val qualifying = state.ownedVars -- locked + + if (!qualifying.isEmpty) { typr.println(i"interpolate $tree: ${tree.tpe.widen} in $state, owned vars = ${state.ownedVars.toList}%, %, previous = ${locked.toList}%, % / ${state.constraint}") val resultAlreadyConstrained = tree.isInstanceOf[Apply] || tree.tpe.isInstanceOf[MethodOrPoly] diff --git a/compiler/src/dotty/tools/dotc/util/SimpleIdentitySet.scala b/compiler/src/dotty/tools/dotc/util/SimpleIdentitySet.scala index a857c2163006..2161d597e150 100644 --- a/compiler/src/dotty/tools/dotc/util/SimpleIdentitySet.scala +++ b/compiler/src/dotty/tools/dotc/util/SimpleIdentitySet.scala @@ -7,6 +7,7 @@ import collection.mutable.ListBuffer */ abstract class SimpleIdentitySet[+Elem <: AnyRef] { def size: Int + def isEmpty: Boolean = size == 0 def + [E >: Elem <: AnyRef](x: E): SimpleIdentitySet[E] def - [E >: Elem <: AnyRef](x: E): SimpleIdentitySet[Elem] def contains[E >: Elem <: AnyRef](x: E): Boolean diff --git a/tests/pos/i6247.scala b/tests/pos/i6247.scala new file mode 100644 index 000000000000..20a3ae091692 --- /dev/null +++ b/tests/pos/i6247.scala @@ -0,0 +1,10 @@ +class Foo { + implicit class NN[T](x:T|Null) { + def nn: T = x.asInstanceOf[T] + } + + val x1: String|Null = null + x1.nn.length + val x2: String = x1.nn + x1.nn.length +}