From 50a56141bafffde09ef87abd640e499da63521c2 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Tue, 7 Jan 2020 09:21:07 -0500 Subject: [PATCH] 8234445: spurious error message for record constructors with receiver parameters Reviewed-by: mcimadamore --- .../com/sun/tools/javac/comp/TypeEnter.java | 38 ++++++++++++------- .../javac/records/RecordCompilationTests.java | 30 ++++++++++++++- 2 files changed, 53 insertions(+), 15 deletions(-) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java index 5265bee5f6..8ce3b7b348 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, 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 @@ -884,6 +884,24 @@ public class TypeEnter implements Completer { completing = prevCompleting; } } + + void enterThisAndSuper(ClassSymbol sym, Env env) { + ClassType ct = (ClassType)sym.type; + // enter symbols for 'this' into current scope. + VarSymbol thisSym = + new VarSymbol(FINAL | HASINIT, names._this, sym.type, sym); + thisSym.pos = Position.FIRSTPOS; + env.info.scope.enter(thisSym); + // if this is a class, enter symbol for 'super' into current scope. + if ((sym.flags_field & INTERFACE) == 0 && + ct.supertype_field.hasTag(CLASS)) { + VarSymbol superSym = + new VarSymbol(FINAL | HASINIT, names._super, + ct.supertype_field, sym); + superSym.pos = Position.FIRSTPOS; + env.info.scope.enter(superSym); + } + } } private final class RecordPhase extends AbstractMembersPhase { @@ -902,6 +920,9 @@ public class TypeEnter implements Completer { for (JCVariableDecl field : fields) { sym.getRecordComponent(field.sym, true); } + + enterThisAndSuper(sym, env); + // lets enter all constructors for (JCTree def : tree.defs) { if (TreeInfo.isConstructor(def)) { @@ -932,19 +953,8 @@ public class TypeEnter implements Completer { JCTree constrDef = defaultConstructor(make.at(tree.pos), helper); tree.defs = tree.defs.prepend(constrDef); } - // enter symbols for 'this' into current scope. - VarSymbol thisSym = - new VarSymbol(FINAL | HASINIT, names._this, sym.type, sym); - thisSym.pos = Position.FIRSTPOS; - env.info.scope.enter(thisSym); - // if this is a class, enter symbol for 'super' into current scope. - if ((sym.flags_field & INTERFACE) == 0 && - ct.supertype_field.hasTag(CLASS)) { - VarSymbol superSym = - new VarSymbol(FINAL | HASINIT, names._super, - ct.supertype_field, sym); - superSym.pos = Position.FIRSTPOS; - env.info.scope.enter(superSym); + if (!sym.isRecord()) { + enterThisAndSuper(sym, env); } if (!tree.typarams.isEmpty()) { diff --git a/test/langtools/tools/javac/records/RecordCompilationTests.java b/test/langtools/tools/javac/records/RecordCompilationTests.java index 48b5380251..f8af16a869 100644 --- a/test/langtools/tools/javac/records/RecordCompilationTests.java +++ b/test/langtools/tools/javac/records/RecordCompilationTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, 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 @@ -432,4 +432,32 @@ public class RecordCompilationTests extends CompilationTestCase { " }\n" + "}"); } + + public void testReceiverParameter() { + assertFail("compiler.err.receiver.parameter.not.applicable.constructor.toplevel.class", + """ + record R(int i) { + public R(R this, int i) { + this.i = i; + } + } + """); + assertFail("compiler.err.non-static.cant.be.ref", + """ + class Outer { + record R(int i) { + public R(Outer Outer.this, int i) { + this.i = i; + } + } + } + """); + assertOK( + """ + record R(int i) { + void m(R this) {} + public int i(R this) { return i; } + } + """); + } }