diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java index d18ff674648..43ddff079ab 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java @@ -2526,7 +2526,8 @@ JCTree generateRecordMethod(JCClassDecl tree, Name name, List vars, M syms.typeDescriptorType).appendList(staticArgTypes), staticArgsValues, bootstrapName, name, false); - VarSymbol _this = new VarSymbol(SYNTHETIC, names._this, tree.sym.type, tree.sym); + Type receiverType = tree.sym.type.isPrimitiveReferenceType() ? tree.sym.type.asValueType() : tree.sym.type; + VarSymbol _this = new VarSymbol(SYNTHETIC, names._this, receiverType, tree.sym); JCMethodInvocation proxyCall; if (!isEquals) { @@ -2610,8 +2611,9 @@ JCFieldAccess makeIndyQualifier( bootstrapName, staticArgTypes, List.nil()); MethodType indyType = msym.type.asMethodType(); + Type receiverType = tree.sym.type.isPrimitiveReferenceType() ? tree.sym.type.asValueType() : tree.sym.type; indyType = new MethodType( - isStatic ? List.nil() : indyType.argtypes.prepend(tree.sym.type), + isStatic ? List.nil() : indyType.argtypes.prepend(receiverType), indyType.restype, indyType.thrown, syms.methodClass diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java index 7929ee6b97d..83887bbd891 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -4062,6 +4062,15 @@ protected JCClassDecl recordDeclaration(JCModifiers mods, Comment dc) { nextToken(); mods.flags |= Flags.RECORD; Name name = typeName(); + if ((mods.flags & Flags.PRIMITIVE_CLASS) != 0) { + if (token.kind == DOT) { + final Token pastDot = S.token(1); + if (pastDot.kind == IDENTIFIER && pastDot.name() == names.val) { + nextToken(); nextToken(); // discard .val + mods.flags |= Flags.REFERENCE_FAVORING; + } + } + } List typarams = typeParametersOpt(); @@ -4497,6 +4506,7 @@ protected boolean isRecordStart() { if (token.kind == IDENTIFIER && token.name() == names.record && (peekToken(TokenKind.IDENTIFIER, TokenKind.LPAREN) || peekToken(TokenKind.IDENTIFIER, TokenKind.EOF) || + peekToken(TokenKind.IDENTIFIER, TokenKind.DOT) || peekToken(TokenKind.IDENTIFIER, TokenKind.LT))) { checkSourceLevel(Feature.RECORDS); return true; diff --git a/test/langtools/tools/javac/valhalla/lworld-values/records/RefFlavoredRecord.java b/test/langtools/tools/javac/valhalla/lworld-values/records/RefFlavoredRecord.java new file mode 100644 index 00000000000..a287591b226 --- /dev/null +++ b/test/langtools/tools/javac/valhalla/lworld-values/records/RefFlavoredRecord.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8271583 + * @summary [lworld] primitive records can't be reference favoring + * @run main/othervm RefFlavoredRecord + */ + +public primitive record RefFlavoredRecord.val(int theInteger, String theString) { + public static void main(String[] args) { + RefFlavoredRecord rec = RefFlavoredRecord.default; + if (rec != null) { + throw new AssertionError("Ref-favoring record .default should be null?"); + } + + if (! new RefFlavoredRecord(42, "Fortytwo").equals(new RefFlavoredRecord(42, "Fortytwo"))) { + throw new AssertionError("Records should be equal"); + } + } +}