RFR: 8332600: javac uses record components source position during compilation

Jan Lahoda jlahoda at openjdk.org
Fri Jul 12 13:05:53 UTC 2024


On Thu, 11 Jul 2024 21:36:40 GMT, Vicente Romero <vromero at openjdk.org> wrote:

> javac uses the source position of record components to find and later probably remove a given record component during compilation. This could be necessary if annotation processors are present. This is done in part to provide better error messages for silly record definitions like:
> 
> record R(int i, float i) {} // two record components with the same name
> 
> but this is brittle and can backfire if the record is read from a class file as the source positions are not stored there. See [JDK-8332297](https://bugs.openjdk.org/browse/JDK-8332297) for some context
> 
> The idea of this fix is not to use the source position but only the name to find a given record component. This could imply that if the user defines an erroneous record like the one above, then the record could end up with less record components than expected but records like this wouldn't compile anyway
> 
> TIA

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java line 1142:

> 1140:                             boolean paramIsVarArgs = (param.sym.flags_field & VARARGS) != 0;
> 1141:                             if (!types.isSameType(param.type, recordFieldTypes.head) ||
> 1142:                                     (recordComponents.head != null &&

I am afraid `recordComponents.head != null` (which is basically `recordComponents.isEmpty()`, I think) is probably insufficient here. Consider e.g.:

record R(int x, int x, int x) {}


which will fail as `recordComponents` itself will be `null`, due to `tail` being `null`.

Looking at the last record component (`.last()`) might be one of the solutions?

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/20148#discussion_r1675832203


More information about the compiler-dev mailing list