diff --git a/compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala b/compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala index d635096b2318..e51bc8e36470 100644 --- a/compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala +++ b/compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala @@ -847,9 +847,13 @@ class CheckCaptures extends Recheck, SymTransformer: * where local capture roots are instantiated to root variables. */ override def checkConformsExpr(actual: Type, expected: Type, tree: Tree, addenda: Addenda)(using Context): Type = - val expected1 = alignDependentFunction(addOuterRefs(expected, actual), actual.stripCapturing) + var expected1 = alignDependentFunction(expected, actual.stripCapturing) val actualBoxed = adaptBoxed(actual, expected1, tree.srcPos) //println(i"check conforms $actualBoxed <<< $expected1") + + if actualBoxed eq actual then + // Only `addOuterRefs` when there is no box adaptation + expected1 = addOuterRefs(expected1, actual) if isCompatible(actualBoxed, expected1) then if debugSuccesses then tree match case Ident(_) => diff --git a/tests/neg-custom-args/captures/cc-selftype-unsound.scala b/tests/neg-custom-args/captures/cc-selftype-unsound.scala new file mode 100644 index 000000000000..5aaaf5e8b8ca --- /dev/null +++ b/tests/neg-custom-args/captures/cc-selftype-unsound.scala @@ -0,0 +1,15 @@ +import language.experimental.captureChecking +trait Logger +case class Boxed[T](unbox: T) + +// a horrible function, but it typechecks +def magic(l: Logger^): Logger = + class Foo: + def foo: Boxed[Logger^{this}] = + // for the following line to typecheck + // the capture checker assumes {l} <: {this} + Boxed[Logger^{this}](l) // error + val x = new Foo + val y = x.foo.unbox // y: Logger^{x} + val z: Logger = y // now the capability becomes pure + z