I'd like to go into a bit more detail about why these consequences exist. Hopefully that will tell us whether we agree on the reasoning behind this list.
> Alpha-renaming a type variable (to a non-shadowed name) should be binary and source compatible.
The name is only used internally in the generic class in the GenericClass attribute, and recompiling with different names will therefore not affect users of the generic class.
> Reordering or removing type variables is not compatible. (These first two together match the story for method argument lists; you can rename method arguments, but not reorder or remove them.)
Other classes will refer to the generic class using ParamTypes in their CPs. ParamType provides the type parameters in the order that the generic type specified at compilation time. Reordering and recompiling will therefore invalidate all ParamTypes referring to the modified generic type.
> Anyfying an existing erased type variable should be binary and source compatible.
All ParamTypes referring to a ref-generic type variable will be providing a reference type (erased) as the type parameter (or no parameters?). As references are a subset of any, anyfying the type variable does not invalidate existing ParamTypes.
I have one question here: What happens if I refer to Foo<T> (not any T) using ParamType[Foo, String]? Is it valid because String is a reference type, or invalid because Foo is not specializable?
> Adding a new type variable at the end of the argument list should be binary compatible (though not source compatible.) Adding a new type variable other than at the end is not compatible.
The last point already said that we have to support missing type parameters, and this point is really just and extension of that. If a type parameter is not provided, the type variable is assumed to be erased.
> Generifying an enclosing scope (evolving
Outer.Inner<U> to Outer<T>.Inner<U>) should be binary compatible.At first glance, this might look like anyfying an existing erased type or generifying a non-generic class. However, the complicating factor is that the added type variable will also be added to the scope of the enclosed class, and the question becomes whether we can handle this. An enclosed class must be compiled with its enclosing class, so the GenericClass attribute will be updated correctly. The type parameters to Inner and Outer are provided separately, and any missing type parameter will still be treated as erased.
> Changing type variable bounds is not binary compatible.
Type variables are erased to their bound, i.e. not necessarily j.l.Object. Any descriptor that contained a type variable will therefore contain the bound after compilation. Changing the bound invalidates the descriptors in existing method refs, and is therefore binary incompatible. Also, this is not a new constraint, as it already applies to erased generics.
--
Bjørn Vårdal
Bjørn Vårdal
IBM Runtimes
----- Original message -----
From: Brian Goetz <[email protected]>
Sent by: "valhalla-spec-experts" <[email protected]>
To: [email protected]
Cc:
Subject: Compatibility goals
Date: Tue, May 31, 2016 2:37 PM
The Model 3 document posits several migration compatibility goals. I'd like to drill into these and get consensus on them, as they influence many other decisions (such as the requirements around raw types.) Here's what the doc said:Compatibility
Classes will evolve; some evolutions are compatible, and some are not. The following enumerates the compatibility consequences of the proposed approach.
- Alpha-renaming a type variable (to a non-shadowed name) should be binary and source compatible.
- Reordering or removing type variables is not compatible. (These first two together match the story for method argument lists; you can rename method arguments, but not reorder or remove them.)
- Anyfying an existing erased type variable should be binary and source compatible.
- Adding a new type variable at the end of the argument list should be binary compatible (though not source compatible.) Adding a new type variable other than at the end is not compatible.
- Generifying an enclosing scope (evolving
Outer.Inner<U>toOuter<T>.Inner<U>) should be binary compatible.- Changing type variable bounds is not binary compatible.
Does anyone have any concerns with these compatibility goals (in either direction -- that they are too constraining, or not constraining enough?)
