Record component type can be an inner class of a record

Dan Smith daniel.smith at
Mon Apr 13 19:13:51 UTC 2020

> On Apr 13, 2020, at 11:08 AM, forax at wrote:
> I believe you're right, the following code should not compile, apart if you want to write puzzler for a living :)
> class A { int y; } 
> record B(A a) implements I {  
>   public static void main(String[] args) { 
>     System.out.println(new B(null).a().x); 
>   } 
> } 
> interface I { 
>   class A { int x; } 
> }

You're proposing a novel error check, which I'm not sure is a good idea.

I believe the argument is that 'A' as it appears in the record declaration header means something different than 'A' as it would appear in an accessor or constructor declaration.

That's true—the context in which a name appears in the header is not exactly the same as the context in which a name appears in the body. But I don't think it's our job to detect those cases. Instead, the compiler should interpret the name in the context in which it actually appears, and then ensure implicit members refer to that same entity. (E.g., the return type of the implicit accessor would effectively be spelled 'package.A'. But I don't think implicit members should be thought of as existing at the level of syntax at all.)

I worry that if we go in the other direction—deciding it's an error if a name in implicit code would mean something different than the explicit name in the program—we're taking on a complex task of proving, wherever a name is used in implicit code, that the actual and implicit contexts are equivalent. I'd prefer not to have that responsibility.

(For example: interfaces have implicit members (JLS 9.2). We don't do anything to ensure that, say, 'String' isn't shadowed by a member class of the interface.)

More information about the amber-spec-experts mailing list