On Dec 10, 2020, at 6:35 AM, Chris Hegarty <chris.hega...@oracle.com> wrote: > > >> On 10 Dec 2020, at 14:11, fo...@univ-mlv.fr <mailto:fo...@univ-mlv.fr> wrote: >>> ... >> >> There is a third choice see above. >> >> Forcing the semantics of Java into the VM is always a bad idea. >> We don't do that for any other constructs, lambda, enums, Java anonymous >> classes, etc. >> Worst, we already know that an inline record is not a record from the JLS >> POV. >> >> For Java 16, given that we are late in the process, i see no problem if the >> VM doesn't trust record fields as a temporary patch, if it's easier than to >> have Field.set() to ask if a class is a plain class or not. It's far better >> than having the the JLS definition of a record bolted into the VM. > > In my view, this is an “everyone loses” option.
+100 The question is, must everyone lose this battle? I hope not. I am content, for the present, with a “hacky” rule that says, as narrowly and restrictively as necessary, “if it’s a JLS record, then the JVM defends the fields, period”. The hackiness can be lifted over time after we (hello Mandy!) figure out how to make final fields more uniformly trustable. We don’t have a complete solution yet, but that does not mandate protecting fields we know can merit special protection. Current examples of fields that enjoy special protection: - static finals (true forever) - fields of certain “locked down” JDK classes (HotSpot ad hoc logic) - hidden classes (new feature, new behavior) - records (assuming non-rollback of JDK-8247444) Perhaps the more important defining feature of records is the restricted process by which instance are created: Via a canonical constructor. This is important to defend, even apart from the integrity of final fields. And this leads me to what I think is the most compelling reason for making a “special pleading” for record fields (i.e., JDK-8247444): If we don’t defend record fields against reflective Field.set, we will open the gate for off-label creation of records *apart from the canonical constructor*. This subverts, not only a desirable set of optimizations on records, but also a crucial invariant, that every record comes from a CC invocation. Let’s not allow that; indeed that would be another aspect of “everybody loses”. > If we do not prevent Field.set() from modifying the fields of a record > class in Java 16, then it will be almost impossible to do so at some > future point. The intermediate step that we’re proposing both allows > for 1) TNSFF in record classes, and 2) an evolution path to a more > general mechanism in the future. I do not see that no.1 is covered by > option three. Yes. I think given the life-cycle restrictions on records, even if our future more general evolution path for finals is *inconsistent* with what we did in JDK-8247444, we still win, because records have a special property. Let’s not dilute that property (having invested so much in records!), even if there is a risk that what we did in JDK-8247444 will be inconsistent with the future general facility. But (spoiler alert) I’m sure it won’t be; I’ve been watching this technology arc in the JVM for a long time, and I think JDK-8247444 is not a side-trip, but squarely along the center-line of what we want to do long term. — John