On Nov 22, 2017, at 5:48 AM, Brian Goetz <brian.go...@oracle.com> wrote: > > What's the L-world story for array subtyping? For any R-type, R[] <: > Object[]. If everything is an L type and everything is <: Object, are arrays > of Q-types/primitives also subtypes of Object[]? > > We didn't have a story for this in QU-world either, but at least in QU-world > it was believable that QFoo[] <! Object[]. But that seems much less tenable > when there's no syntactic difference between L-uses and Q-uses. (And even > less so when we might migrate code from L to Q.)
We were just talking about this in the concall with IBM. Field and array-element flattening are the two places where the Q/R distinction provides a crucial hint that flattening *may* (not always *must*) occur. This hint is crucial because it is statically visible *before* all class files are loaded. The instance layout algorithm and the verifier both need to run before all class files are loaded (because of circularities, also performance). In U-world, the letter 'Q' in a static descriptor tells the instance layout generator to load the field class and extract sub-layout. It also tells the verifier not to assume a covariantly compatible layout relative to the type Object[]. If we don't keep a few Q's around for old times' sake, we will need to signal these subtle difference some other way, with an ACC_FLATTENABLE bit on fields and a special "[@" syntax variant (pick your letter, maybe "Q") for array descriptors. I think of this as the "residual Q problem", of finding offices for the few remaining occurrences of Q that do real work in L-world. (The user-visible distinction of flat vs. legacy arrays was one influence that led us towards user-visible box types. I'd like to resist that this time around. Perhaps "[@" is a syntax that is mutually exclusive with plain "[". And there is a showdown when such an array is created, so that the descriptor has a "@" if and only if the loaded element type is in fact a Q-type. It's a move that of class loader constraints.) I am not opposed to allowing the existing Q-syntax for descriptors, in a limited number of places, to solve those residual problems. That thought leads me to try on the idea (which Remi discourages) that perhaps Q-narrowings of some method descriptors are useful (requiring bridges just like today's generics). A Q-narrowing of a class means: No nulls here, identity is not observable, and value-based semantics are in force, including unmodifiability. Not a bad set of guarantees; maybe that's a job for Q's rather than an invisible type profile. BTW, an Ljava/util/List; would not pass through a Qjava/util/List; descriptor, unless List.copyOf were applied to it first. The VM and java.base can conspire to provide a curated set of Q-able types with enforced value or value-based behavior. — John