diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index 03f68506439..12ab1c4f725 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -4186,17 +4186,26 @@ public class Attr extends JCTree.Visitor { @Override public void visitRecordPattern(JCRecordPattern tree) { - Type type = attribType(tree.deconstructor, env); - if (type.isRaw() && type.tsym.getTypeParameters().nonEmpty()) { - Type inferred = infer.instantiatePatternType(resultInfo.pt, type.tsym); - if (inferred == null) { - log.error(tree.pos(), Errors.PatternTypeCannotInfer); - } else { - type = inferred; + Type site; + + if (tree.deconstructor == null) { + log.error(tree.pos(), Errors.DeconstructionPatternVarNotAllowed); + tree.record = syms.errSymbol; + site = tree.type = types.createErrorType(tree.record.type); + } else { + Type type = attribType(tree.deconstructor, env); + if (type.isRaw() && type.tsym.getTypeParameters().nonEmpty()) { + Type inferred = infer.instantiatePatternType(resultInfo.pt, type.tsym); + if (inferred == null) { + log.error(tree.pos(), Errors.PatternTypeCannotInfer); + } else { + type = inferred; + } } + tree.type = tree.deconstructor.type = type; + site = types.capture(tree.type); } - tree.type = tree.deconstructor.type = type; - Type site = types.capture(tree.type); + List expectedRecordTypes; if (site.tsym.kind == Kind.TYP && ((ClassSymbol) site.tsym).isRecord()) { ClassSymbol record = (ClassSymbol) site.tsym; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java index d9566ce3466..55eb421d262 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java @@ -3480,9 +3480,17 @@ public class Flow { ? selectorType : binding.type; return new BindingPattern(type); } else if (pattern instanceof JCRecordPattern record) { - Type[] componentTypes = ((ClassSymbol) record.type.tsym).getRecordComponents() - .map(r -> types.memberType(record.type, r)) - .toArray(s -> new Type[s]); + Type[] componentTypes; + + if (!record.type.isErroneous()) { + componentTypes = ((ClassSymbol) record.type.tsym).getRecordComponents() + .map(r -> types.memberType(record.type, r)) + .toArray(s -> new Type[s]); + } + else { + componentTypes = record.nested.map(t -> types.createErrorType(t.type)).toArray(s -> new Type[s]);; + } + PatternDescription[] nestedDescriptions = new PatternDescription[record.nested.size()]; int i = 0; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties index 278d627fc9b..e99b4a699eb 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -3989,6 +3989,9 @@ compiler.err.preview.without.source.or.release=\ compiler.err.deconstruction.pattern.only.records=\ deconstruction patterns can only be applied to records, {0} is not a record +compiler.err.deconstruction.pattern.var.not.allowed=\ + deconstruction patterns can only be applied to records, var is not allowed + # 0: list of type, 1: list of type compiler.err.incorrect.number.of.nested.patterns=\ incorrect number of nested patterns\n\ diff --git a/test/langtools/tools/javac/T8305582.java b/test/langtools/tools/javac/T8305582.java new file mode 100644 index 00000000000..b05c50ad93f --- /dev/null +++ b/test/langtools/tools/javac/T8305582.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023, 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 8305582 + * @summary Compiler crash when compiling record patterns with var + * @compile/fail/ref=T8305582.out -XDrawDiagnostics -XDshould-stop.at=FLOW T8305582.java + */ + +public class T8305582 { + record Point(int x, int y) {} + enum Color {RED, GREEN, BLUE} + record ColoredPoint (Point p, Color c) {} + + public static void foo(Object o) { + if (o instanceof ColoredPoint(var(var x, var y), var c)) { } + + switch(o) { + case ColoredPoint(var (var x, var y), var c): + break; + default: + } + + if (o instanceof ColoredPoint(var(int x, int y), var c)) { } + if (o instanceof ColoredPoint(var(int x, var y), var c)) { } + if (o instanceof var(Point x, Point y)) { } + } +} diff --git a/test/langtools/tools/javac/T8305582.out b/test/langtools/tools/javac/T8305582.out new file mode 100644 index 00000000000..906cb9e2636 --- /dev/null +++ b/test/langtools/tools/javac/T8305582.out @@ -0,0 +1,6 @@ +T8305582.java:47:26: compiler.err.restricted.type.not.allowed.here: var +T8305582.java:37:39: compiler.err.deconstruction.pattern.var.not.allowed +T8305582.java:40:31: compiler.err.deconstruction.pattern.var.not.allowed +T8305582.java:45:39: compiler.err.deconstruction.pattern.var.not.allowed +T8305582.java:46:39: compiler.err.deconstruction.pattern.var.not.allowed +5 errors \ No newline at end of file diff --git a/test/langtools/tools/javac/diags/examples/DeconstructionpatternsNonVar.java b/test/langtools/tools/javac/diags/examples/DeconstructionpatternsNonVar.java new file mode 100644 index 00000000000..6cfc080761e --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/DeconstructionpatternsNonVar.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023, 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. + */ + +// key: compiler.err.deconstruction.pattern.var.not.allowed + +class DeconstructionpatternsNonVar { + record Point(int x, int y) {} + enum Color {RED, GREEN, BLUE} + record ColoredPoint (Point p, Color c) {} + + public static void foo(Object o) { + if (o instanceof ColoredPoint(var(var x, var y), var c)) { + } + } +}