> On Dec 20, 2021, at 10:54 AM, Brian Goetz <brian.go...@oracle.com> wrote:
> 
> 
> So the choices for VM infer&inject seem to be:
> 
>  - Only inject IO for legacy concrete classes, based on classfile version, 
> otherwise require everything to be explicit;
>  - Inject IO for concrete classes when ACC_VALUE is not present, require VO 
> to be explicit;
>  - Inject IO for concrete classes when ACC_VALUE is not present; inject VO 
> for concrete classes when ACC_VALUE is present
> 

One more dimension to this is whether "inject" and "require" are talking about 
an element in the `interfaces` array of the declaration, or simply the presence 
of the interface via some combination of inheritance/declaration.

The latter seems more natural. But in "require" cases, it leads to surprising 
binary incompatibilities (per some comments I made earlier in the thread):

1) declare `interface Foo extends ValueObject` and `value class Bar extends Foo`

2) compile; javac excludes ValueObject from Bar's `interfaces`

3) Modify Foo, removing `extends ValueObject` (turns out I was overly eager 
when I put in that constraint, and I actually wouldn't mind subclasses that are 
identity classes)

4) recompile Foo separately, which succeeds

5) Try running, and discover that class Bar refuses to load, with an error 
saying it doesn't implement ValueObject ("of course it does!" you say—"it's a 
value class")

Inference is nice in that it will happily paper over these sorts of separate 
compilation mismatches.

Reply via email to