nested) {
this.deconstructor = deconstructor;
this.nested = nested;
- this.var = var;
}
@DefinedBy(Api.COMPILER_TREE)
@@ -2475,11 +2476,6 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
return RECORDPATTERN;
}
- @Override @DefinedBy(Api.COMPILER_TREE)
- public VariableTree getVariable() {
- return var;
- }
-
}
/**
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java
index 3b07bf9f6d7..e2c942a3523 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java
@@ -945,10 +945,6 @@ public class Pretty extends JCTree.Visitor {
print("(");
printExprs(tree.nested);
print(")");
- if (tree.var != null) {
- print(" ");
- print(tree.var.name);
- }
} catch (IOException e) {
throw new UncheckedIOException(e);
}
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java
index 90f7a8c4f1e..4e73f8def85 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java
@@ -530,8 +530,7 @@ public class TreeCopier implements TreeVisitor {
JCRecordPattern t = (JCRecordPattern) node;
JCExpression deconstructor = copy(t.deconstructor, p);
List nested = copy(t.nested, p);
- JCVariableDecl var = copy(t.var, p);
- return M.at(t.pos).RecordPattern(deconstructor, nested, var);
+ return M.at(t.pos).RecordPattern(deconstructor, nested);
}
@DefinedBy(Api.COMPILER_TREE)
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java
index f1c1d2fea1e..986e786a129 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java
@@ -512,9 +512,8 @@ public class TreeMaker implements JCTree.Factory {
return tree;
}
- public JCRecordPattern RecordPattern(JCExpression deconstructor, List nested,
- JCVariableDecl var) {
- JCRecordPattern tree = new JCRecordPattern(deconstructor, nested, var);
+ public JCRecordPattern RecordPattern(JCExpression deconstructor, List nested) {
+ JCRecordPattern tree = new JCRecordPattern(deconstructor, nested);
tree.pos = pos;
return tree;
}
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeScanner.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeScanner.java
index dd4129fa85b..f64684bda05 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeScanner.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeScanner.java
@@ -331,9 +331,6 @@ public class TreeScanner extends Visitor {
public void visitRecordPattern(JCRecordPattern that) {
scan(that.deconstructor);
scan(that.nested);
- if (that.var != null) {
- scan(that.var);
- }
}
public void visitIndexed(JCArrayAccess tree) {
diff --git a/test/langtools/tools/javac/diags/examples/RawDeconstructionPattern.java b/test/langtools/tools/javac/diags/examples/DefaultLabelNotAllowed.java
similarity index 75%
rename from test/langtools/tools/javac/diags/examples/RawDeconstructionPattern.java
rename to test/langtools/tools/javac/diags/examples/DefaultLabelNotAllowed.java
index 007ac1a85a3..65d339fb33b 100644
--- a/test/langtools/tools/javac/diags/examples/RawDeconstructionPattern.java
+++ b/test/langtools/tools/javac/diags/examples/DefaultLabelNotAllowed.java
@@ -21,15 +21,15 @@
* questions.
*/
-// key: compiler.err.raw.deconstruction.pattern
-// key: compiler.note.preview.filename
-// key: compiler.note.preview.recompile
-// options: --enable-preview -source ${jdk.version}
+// key: compiler.err.default.label.not.allowed
+// key: compiler.misc.feature.pattern.switch
+// key: compiler.warn.preview.feature.use.plural
+// options: --enable-preview -source ${jdk.version} -Xlint:preview
-class RawDeconstructionPattern {
- boolean test(Object o) {
- return o instanceof R(String s);
+class DefaultLabelNotAllowed {
+ private void doSwitch(Object o) {
+ switch (o) {
+ case default: break;
+ }
}
-
- record R(T t) {}
}
diff --git a/test/langtools/tools/javac/diags/examples/FlowsThroughToPattern.java b/test/langtools/tools/javac/diags/examples/FlowsThroughToPattern.java
index 1ab22992f03..6c212b23281 100644
--- a/test/langtools/tools/javac/diags/examples/FlowsThroughToPattern.java
+++ b/test/langtools/tools/javac/diags/examples/FlowsThroughToPattern.java
@@ -24,12 +24,14 @@
// key: compiler.err.flows.through.to.pattern
// key: compiler.misc.feature.pattern.switch
// key: compiler.warn.preview.feature.use.plural
+// key: compiler.misc.feature.case.null
+// key: compiler.warn.preview.feature.use
// options: --enable-preview -source ${jdk.version} -Xlint:preview
class FlowsThroughToPattern {
private void doSwitch(Object o) {
switch (o) {
- case String str:
+ case null:
case Object obj: break;
}
}
diff --git a/test/langtools/tools/javac/diags/examples/InvalidCaseLabelCombination.java b/test/langtools/tools/javac/diags/examples/InvalidCaseLabelCombination.java
new file mode 100644
index 00000000000..505b73df595
--- /dev/null
+++ b/test/langtools/tools/javac/diags/examples/InvalidCaseLabelCombination.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2022, 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.invalid.case.label.combination
+// key: compiler.misc.feature.case.null
+// key: compiler.warn.preview.feature.use
+// options: --enable-preview -source ${jdk.version} -Xlint:preview
+
+class InvalidCaseLabelCombination {
+ private void doSwitch(Integer i) {
+ switch (i) {
+ case null, 1: break;
+ default: break;
+ }
+ }
+}
diff --git a/test/langtools/tools/javac/diags/examples/PatternTypeCannotInfer.java b/test/langtools/tools/javac/diags/examples/PatternTypeCannotInfer.java
new file mode 100644
index 00000000000..3d500a45431
--- /dev/null
+++ b/test/langtools/tools/javac/diags/examples/PatternTypeCannotInfer.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2022, 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.pattern.type.cannot.infer
+// key: compiler.warn.preview.feature.use.plural
+// key: compiler.misc.feature.deconstruction.patterns
+// options: --enable-preview -source ${jdk.version} -Xlint:preview
+
+class PatternTypeCannotInfer {
+ interface A {}
+ record R() implements A {}
+ void test(A i) {
+ if (i instanceof R()) {
+ }
+ }
+}
diff --git a/test/langtools/tools/javac/patterns/CaseDefault.java b/test/langtools/tools/javac/patterns/CaseDefault.java
deleted file mode 100644
index 8b36386af85..00000000000
--- a/test/langtools/tools/javac/patterns/CaseDefault.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * @test /nodynamiccopyright/
- * @bug 8262891
- * @summary Check null handling for non-pattern switches.
- * @compile/fail/ref=CaseDefault.out --release 16 -XDrawDiagnostics CaseDefault.java
- * @compile --enable-preview -source ${jdk.version} CaseDefault.java
- * @run main/othervm --enable-preview CaseDefault
- */
-
-public class CaseDefault {
-
- public static void main(String[] args) {
- new CaseDefault().run();
- }
-
- void run() {
- String str = "other";
- switch (str) {
- case "a": throw new AssertionError("Wrong branch.");
- case default: break; //OK
- }
- switch (str) {
- case "a" -> throw new AssertionError("Wrong branch.");
- case default -> {} //OK
- }
- int i;
- i = switch (str) {
- case "a": throw new AssertionError("Wrong branch.");
- case default: yield 0; //OK
- };
- i = switch (str) {
- case "a" -> throw new AssertionError("Wrong branch.");
- case default -> 0; //OK
- };
- }
-
-}
diff --git a/test/langtools/tools/javac/patterns/CaseDefault.out b/test/langtools/tools/javac/patterns/CaseDefault.out
deleted file mode 100644
index ffea67361fb..00000000000
--- a/test/langtools/tools/javac/patterns/CaseDefault.out
+++ /dev/null
@@ -1,2 +0,0 @@
-CaseDefault.java:20:18: compiler.err.preview.feature.disabled.plural: (compiler.misc.feature.pattern.switch)
-1 error
diff --git a/test/langtools/tools/javac/patterns/CaseStructureTest.java b/test/langtools/tools/javac/patterns/CaseStructureTest.java
index bdc6e385128..3d0e1e1d217 100644
--- a/test/langtools/tools/javac/patterns/CaseStructureTest.java
+++ b/test/langtools/tools/javac/patterns/CaseStructureTest.java
@@ -95,7 +95,6 @@ public class CaseStructureTest extends ComboInstance {
task.generate(result -> {
boolean shouldPass = true;
long patternCases = Arrays.stream(caseLabels).filter(l -> l == CaseLabel.TYPE_PATTERN || l == CaseLabel.PARENTHESIZED_PATTERN).count();
- long typePatternCases = Arrays.stream(caseLabels).filter(l -> l == CaseLabel.TYPE_PATTERN || l == CaseLabel.PARENTHESIZED_PATTERN).count();
long constantCases = Arrays.stream(caseLabels).filter(l -> l == CaseLabel.CONSTANT).count();
long nullCases = Arrays.stream(caseLabels).filter(l -> l == CaseLabel.NULL).count();
long defaultCases = Arrays.stream(caseLabels).filter(l -> l == CaseLabel.DEFAULT).count();
@@ -105,14 +104,22 @@ public class CaseStructureTest extends ComboInstance {
if (constantCases > 0) {
shouldPass &= patternCases == 0;
}
+ if (defaultCases > 0) {
+ shouldPass &= asCaseLabelElements && nullCases > 0;
+ }
if (defaultCases > 1) {
shouldPass &= false;
}
if (nullCases > 1) {
shouldPass &= false;
}
- if (nullCases > 0 && patternCases > 0) {
- shouldPass &= patternCases == typePatternCases;
+ if (nullCases > 0) {
+ shouldPass &= patternCases == 0 && (constantCases == 0 || !asCaseLabelElements);
+ if (defaultCases > 0 && asCaseLabelElements) {
+ int nullIndex = Arrays.asList(caseLabels).indexOf(CaseLabel.NULL);
+ int defaultIndex = Arrays.asList(caseLabels).indexOf(CaseLabel.DEFAULT);
+ shouldPass &= nullIndex < defaultIndex;
+ }
}
if (patternCases > 1) {
shouldPass &= false;
diff --git a/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.java b/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.java
index fc82d00a108..7c7d8a90a74 100644
--- a/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.java
+++ b/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.java
@@ -26,8 +26,8 @@ public class DeconstructionPatternErrors {
if (p instanceof GenRecord(var v)); //incorrect generic type
if (p instanceof P4(GenRecord(var v))); //incorrect generic type
if (p instanceof GenRecord(Integer v)); //inconsistency in types
- if (p instanceof P2(var v, var v) v); //duplicated variables
- if (p instanceof P6(P2(var v1, var v2) v1, P2(var v1, var v2) v2) v1); //duplicated variables
+ if (p instanceof P2(var v, var v)); //duplicated variables
+ if (p instanceof P6(P2(var v1, var v2), P2(var v1, var v2))); //duplicated variables
if (p instanceof P7(byte b)); //incorrect pattern type
if (p instanceof P7(long l)); //incorrect pattern type
switch (p) {
@@ -44,6 +44,7 @@ public class DeconstructionPatternErrors {
switch (r1) {
case GenRecord<>(String s) -> {}
}
+ boolean b = p instanceof P(int i) p; //introducing a variable for the record pattern
}
public record P(int i) {
diff --git a/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.out b/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.out
index cf7a8ab7301..d4fbf80b199 100644
--- a/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.out
+++ b/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.out
@@ -2,6 +2,8 @@ DeconstructionPatternErrors.java:15:28: compiler.err.underscore.as.identifier
DeconstructionPatternErrors.java:15:29: compiler.err.expected: token.identifier
DeconstructionPatternErrors.java:43:37: compiler.err.illegal.start.of.type
DeconstructionPatternErrors.java:45:28: compiler.err.illegal.start.of.type
+DeconstructionPatternErrors.java:47:42: compiler.err.expected: ';'
+DeconstructionPatternErrors.java:47:43: compiler.err.not.stmt
DeconstructionPatternErrors.java:16:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.util.List, java.util.ArrayList)
DeconstructionPatternErrors.java:17:29: compiler.err.instanceof.reifiable.not.safe: java.lang.Object, java.util.ArrayList
DeconstructionPatternErrors.java:18:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, int)
@@ -18,18 +20,13 @@ DeconstructionPatternErrors.java:27:29: compiler.err.instanceof.reifiable.not.sa
DeconstructionPatternErrors.java:28:44: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer)
DeconstructionPatternErrors.java:28:13: compiler.err.instanceof.reifiable.not.safe: java.lang.Object, DeconstructionPatternErrors.GenRecord
DeconstructionPatternErrors.java:29:40: compiler.err.match.binding.exists
-DeconstructionPatternErrors.java:29:43: compiler.err.match.binding.exists
-DeconstructionPatternErrors.java:30:48: compiler.err.match.binding.exists
-DeconstructionPatternErrors.java:30:59: compiler.err.already.defined: kindname.variable, v1, kindname.method, main(java.lang.String...)
-DeconstructionPatternErrors.java:30:67: compiler.err.already.defined: kindname.variable, v2, kindname.method, main(java.lang.String...)
-DeconstructionPatternErrors.java:30:71: compiler.err.match.binding.exists
-DeconstructionPatternErrors.java:30:75: compiler.err.match.binding.exists
+DeconstructionPatternErrors.java:30:56: compiler.err.already.defined: kindname.variable, v1, kindname.method, main(java.lang.String...)
+DeconstructionPatternErrors.java:30:64: compiler.err.already.defined: kindname.variable, v2, kindname.method, main(java.lang.String...)
DeconstructionPatternErrors.java:31:29: compiler.err.prob.found.req: (compiler.misc.not.applicable.types: int, byte)
DeconstructionPatternErrors.java:32:29: compiler.err.prob.found.req: (compiler.misc.not.applicable.types: int, long)
DeconstructionPatternErrors.java:34:21: compiler.err.prob.found.req: (compiler.misc.not.applicable.types: int, byte)
DeconstructionPatternErrors.java:35:21: compiler.err.prob.found.req: (compiler.misc.not.applicable.types: int, long)
-DeconstructionPatternErrors.java:39:27: compiler.err.raw.deconstruction.pattern
-DeconstructionPatternErrors.java:41:18: compiler.err.raw.deconstruction.pattern
+DeconstructionPatternErrors.java:44:9: compiler.err.not.exhaustive.statement
- compiler.note.preview.filename: DeconstructionPatternErrors.java, DEFAULT
- compiler.note.preview.recompile
-32 errors
+29 errors
diff --git a/test/langtools/tools/javac/patterns/Exhaustiveness.java b/test/langtools/tools/javac/patterns/Exhaustiveness.java
index 39fe1e558ce..95c24b0a6e3 100644
--- a/test/langtools/tools/javac/patterns/Exhaustiveness.java
+++ b/test/langtools/tools/javac/patterns/Exhaustiveness.java
@@ -1170,6 +1170,29 @@ public class Exhaustiveness extends TestRunner {
"1 error");
}
+ @Test
+ public void testInferenceExhaustive(Path base) throws Exception {
+ doTest(base,
+ new String[0],
+ """
+ package test;
+ public class Test {
+ sealed interface Opt {}
+ record Some(T t) implements Opt {}
+ final class None implements Opt {}
+
+ void test(Opt optValue) {
+ switch (optValue) {
+ case Some(String s) ->
+ System.out.printf("got string: %s%n", s);
+ case None none ->
+ System.out.println("got none");
+ }
+ }
+ }
+ """);
+ }
+
private void doTest(Path base, String[] libraryCode, String testCode, String... expectedErrors) throws IOException {
Path current = base.resolve(".");
Path libClasses = current.resolve("libClasses");
diff --git a/test/langtools/tools/javac/patterns/GenericRecordDeconstructionPattern.java b/test/langtools/tools/javac/patterns/GenericRecordDeconstructionPattern.java
index 52bbbb781c1..55c8bbd1159 100644
--- a/test/langtools/tools/javac/patterns/GenericRecordDeconstructionPattern.java
+++ b/test/langtools/tools/javac/patterns/GenericRecordDeconstructionPattern.java
@@ -39,6 +39,11 @@ public class GenericRecordDeconstructionPattern {
runTest(this::runIf);
runTest(this::runSwitch);
runTest(this::runSwitchExpression);
+ runTest(this::runSwitchInference1);
+ runTest(this::runSwitchInference2);
+ runTest(this::runSwitchInference3);
+ runTest(this::runSwitchInference4);
+ testInference3();
}
void runTest(Function, Integer> test) {
@@ -65,7 +70,49 @@ public class GenericRecordDeconstructionPattern {
};
}
- record Box(V v) {
+ int runSwitchInference1(I b) {
+ switch (b) {
+ case Box(String s): return s == null ? 1 : s.length();
+ default: return -1;
+ }
+ }
+
+ int runSwitchInference2(I b) {
+ switch (b) {
+ case Box(var s): return s == null ? 1 : s.length();
+ default: return -1;
+ }
+ }
+
+ int runSwitchInference3(I b) {
+ return b instanceof Box(var s) ? s == null ? 1 : s.length()
+ : -1;
+ }
+
+ > int runSwitchInference4(Z b) {
+ return b instanceof Box(var s) ? s == null ? 1 : s.length()
+ : -1;
+ }
+
+ > int runSwitchInference5(Z b) {
+ return b instanceof Box(var s) ? s == null ? 1 : s.length()
+ : -1;
+ }
+
+ void testInference3() {
+ I> b = new Box<>(new Box<>(null));
+ assertEquals(1, runSwitchInferenceNested(b));
+ }
+
+ int runSwitchInferenceNested(I> b) {
+ switch (b) {
+ case Box(Box(var s)): return s == null ? 1 : s.length();
+ default: return -1;
+ }
+ }
+
+ sealed interface I {}
+ record Box(V v) implements I {
}
void assertEquals(Object expected, Object actual) {
diff --git a/test/langtools/tools/javac/patterns/Guards.java b/test/langtools/tools/javac/patterns/Guards.java
index eb9d9826789..f8cffd41655 100644
--- a/test/langtools/tools/javac/patterns/Guards.java
+++ b/test/langtools/tools/javac/patterns/Guards.java
@@ -48,7 +48,6 @@ public class Guards {
runIfTrue(this::typeGuardAfterParenthesizedTrueSwitchStatement);
runIfTrue(this::typeGuardAfterParenthesizedTrueSwitchExpression);
runIfTrue(this::typeGuardAfterParenthesizedTrueIfStatement);
- testGuardNPE();
}
void run(Function