Open
Description
Compiler version
3.6.4 and 3.7.0-RC1
Minimized code
import scala.util.boundary
import scala.annotation.constructorOnly
class Leak()(using @constructorOnly l: boundary.Label[String]) {
Seq("a", "b").foreach(_ => boundary.break("stop"))
}
Output
Compilation error
l is marked `@constructorOnly` but it is retained as a field in class Leak
Expectation
It should compile successfully, as the constructor argument shouldn't be captured.
Note
The compiler currently does capture the variable the moment it sees it passed to a lambda. Running CFR on the compiled code (when the annotation is not present), reveals:
import java.io.Serializable;
import scala.Function1;
import scala.collection.SeqOps;
import scala.collection.immutable.$colon$colon;
import scala.collection.immutable.List;
import scala.collection.immutable.Nil$;
import scala.runtime.Nothing$;
import scala.util.boundary;
import scala.util.boundary$;
public class Leak {
private final boundary.Label<String> l;
public Leak(boundary.Label<String> l) {
this.l = l;
((SeqOps)new $colon$colon<Nothing$>((Nothing$)((Object)"a"), (List<Nothing$>)new $colon$colon<Nothing$>((Nothing$)((Object)"b"), Nil$.MODULE$))).foreach((Function1<String, Object> & Serializable)_$1 -> {
throw boundary$.MODULE$.break("stop", l);
});
}
}
where one can see that this.l
is indeed never used, the Lambda simply closes over the constructor argument as expected.