-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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 LeakExpectation
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.