Skip to content

Commit

Permalink
Include notional types in the three step algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
biboudis committed Jan 17, 2025
1 parent e861e2d commit a6e8bc9
Show file tree
Hide file tree
Showing 7 changed files with 414 additions and 142 deletions.
283 changes: 154 additions & 129 deletions src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2383,11 +2383,11 @@ public Tag getTag() {
/**
* Pattern matching forms.
*/
public abstract static class JCPattern extends JCTree
public sealed abstract static class JCPattern extends JCTree
implements PatternTree {
}

public static class JCAnyPattern extends JCPattern
public static final class JCAnyPattern extends JCPattern
implements AnyPatternTree {

protected JCAnyPattern() {
Expand Down Expand Up @@ -2415,7 +2415,7 @@ public Tag getTag() {
}
}

public static class JCBindingPattern extends JCPattern
public static final class JCBindingPattern extends JCPattern
implements BindingPatternTree {
public JCVariableDecl var;

Expand Down Expand Up @@ -2554,7 +2554,7 @@ public Tag getTag() {

}

public static class JCRecordPattern extends JCPattern
public static final class JCRecordPattern extends JCPattern
implements DeconstructionPatternTree {
public JCExpression deconstructor;
public List<JCPattern> nested;
Expand Down
2 changes: 1 addition & 1 deletion test/langtools/tools/javac/T8305582.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
* @test
* @bug 8305582
* @summary Compiler crash when compiling record patterns with var
* @compile/fail/ref=T8305582.out -XDrawDiagnostics -XDshould-stop.at=FLOW T8305582.java
* @compile/fail/ref=T8305582.out -XDrawDiagnostics -XDshould-stop.at=FLOW -XDdev T8305582.java
*/

public class T8305582 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ DeconstructionPatternErrors.java:35:37: compiler.err.illegal.start.of.type
DeconstructionPatternErrors.java:37:28: compiler.err.illegal.start.of.type
DeconstructionPatternErrors.java:39:42: compiler.err.expected: ';'
DeconstructionPatternErrors.java:39:43: compiler.err.not.stmt
DeconstructionPatternErrors.java:15:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.util.List<java.lang.String>, java.util.ArrayList<java.lang.Integer>)
DeconstructionPatternErrors.java:15:26: compiler.err.no.compatible.matcher.found
DeconstructionPatternErrors.java:16:29: compiler.err.instanceof.reifiable.not.safe: java.lang.Object, java.util.ArrayList<java.lang.Integer>
DeconstructionPatternErrors.java:17:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, int)
DeconstructionPatternErrors.java:18:28: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: int, java.lang.String)
DeconstructionPatternErrors.java:19:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, DeconstructionPatternErrors.P)
DeconstructionPatternErrors.java:17:26: compiler.err.no.compatible.matcher.found
DeconstructionPatternErrors.java:18:26: compiler.err.no.compatible.matcher.found
DeconstructionPatternErrors.java:19:26: compiler.err.no.compatible.matcher.found
DeconstructionPatternErrors.java:20:26: compiler.err.cant.apply.deconstruction.pattern: DeconstructionPatternErrors.P2
DeconstructionPatternErrors.java:21:26: compiler.err.cant.apply.deconstruction.pattern: DeconstructionPatternErrors.P2
DeconstructionPatternErrors.java:22:26: compiler.err.cant.apply.deconstruction.pattern: DeconstructionPatternErrors.P
Expand All @@ -15,7 +15,7 @@ DeconstructionPatternErrors.java:24:26: compiler.err.cant.apply.deconstruction.p
DeconstructionPatternErrors.java:24:36: compiler.err.cant.resolve.location: kindname.class, Unresolvable, , , (compiler.misc.location: kindname.class, DeconstructionPatternErrors, null)
DeconstructionPatternErrors.java:25:13: compiler.err.instanceof.reifiable.not.safe: java.lang.Object, DeconstructionPatternErrors.GenRecord<java.lang.String>
DeconstructionPatternErrors.java:26:29: compiler.err.instanceof.reifiable.not.safe: java.lang.Object, DeconstructionPatternErrors.GenRecord<java.lang.String>
DeconstructionPatternErrors.java:27:44: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer)
DeconstructionPatternErrors.java:27:26: compiler.err.no.compatible.matcher.found
DeconstructionPatternErrors.java:27:13: compiler.err.instanceof.reifiable.not.safe: java.lang.Object, DeconstructionPatternErrors.GenRecord<java.lang.String>
DeconstructionPatternErrors.java:28:40: compiler.err.match.binding.exists
DeconstructionPatternErrors.java:29:56: compiler.err.already.defined: kindname.variable, v1, kindname.method, meth()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
PrimitivePatternsSwitchErrors.java:15:18: compiler.err.pattern.dominated
PrimitivePatternsSwitchErrors.java:24:18: compiler.err.pattern.dominated
PrimitivePatternsSwitchErrors.java:31:24: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: int, java.lang.Long)
PrimitivePatternsSwitchErrors.java:31:18: compiler.err.no.compatible.matcher.found
PrimitivePatternsSwitchErrors.java:70:18: compiler.err.pattern.dominated
PrimitivePatternsSwitchErrors.java:78:18: compiler.err.pattern.dominated
PrimitivePatternsSwitchErrors.java:84:18: compiler.err.prob.found.req: (compiler.misc.possible.loss.of.precision: long, byte)
Expand Down Expand Up @@ -29,7 +29,6 @@ PrimitivePatternsSwitchErrors.java:248:18: compiler.err.prob.found.req: (compile
PrimitivePatternsSwitchErrors.java:255:18: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Long, int)
PrimitivePatternsSwitchErrors.java:261:18: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Short, char)
PrimitivePatternsSwitchErrors.java:266:16: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: T, byte)
PrimitivePatternsSwitchErrors.java:30:16: compiler.err.not.exhaustive
PrimitivePatternsSwitchErrors.java:37:16: compiler.err.not.exhaustive
PrimitivePatternsSwitchErrors.java:44:16: compiler.err.not.exhaustive
PrimitivePatternsSwitchErrors.java:52:16: compiler.err.not.exhaustive
Expand All @@ -43,4 +42,4 @@ PrimitivePatternsSwitchErrors.java:254:16: compiler.err.not.exhaustive
PrimitivePatternsSwitchErrors.java:260:16: compiler.err.not.exhaustive
- compiler.note.preview.filename: PrimitivePatternsSwitchErrors.java, DEFAULT
- compiler.note.preview.recompile
43 errors
42 errors
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ public void testOne(Path base) throws Exception {
runSingle(base, "A", "C", "B", 2);
runSingle(base, "A", "D", "B", 2);
runSingle(base, "E", "F", "I", 0);

runSingle(base, "A", "B", "var", 1);
}

void runSingle(Path base, String bt_1, String bt_2, String t1, Integer selected) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
/*
* Copyright (c) 2024, 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.
*/

import toolbox.*;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
* @test
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* jdk.jdeps/com.sun.tools.javap
* @enablePreview
* @build toolbox.ToolBox toolbox.JavapTask
* @run main OverloadedPatternDeclarationsNonTemplated
*/
public class OverloadedPatternDeclarationsNonTemplated extends TestRunner {
private ToolBox tb;
private static final String SOURCE_VERSION = System.getProperty("java.specification.version");

OverloadedPatternDeclarationsNonTemplated() {
super(System.err);
tb = new ToolBox();
}

public static void main(String... args) throws Exception {
new OverloadedPatternDeclarationsNonTemplated().runTests();
}

public void runTests() throws Exception {
runTests(m -> new Object[] { Paths.get(m.getName()) });
}

@Test
public void test1(Path base) throws Exception {
String source =
"""
package test;
class Test {
public static void main(String... args) {
Top t = new Top();
switch (t) {
case Top(NestedB(A a)) -> {}
default -> {}
}
}
static class A {}
static class B extends A {}
static class C extends B {}
static class NestedA {
public pattern NestedA(A a) { System.out.println("NestedA1"); match NestedA(new A());}
public pattern NestedA(B b) { System.out.println("NestedA2"); match NestedA(new B());}
// public pattern NestedA(C c) { System.out.println("NestedA3"); match NestedA(new C());}
}
static class NestedB extends NestedA {
// public pattern NestedB(A a) { System.out.println("NestedB1"); match NestedB(new A());}
public pattern NestedB(B b) { System.out.println("NestedB2"); match NestedB(new B());}
public pattern NestedB(C c) { System.out.println("NestedB3"); match NestedB(new C());}
}
static class NestedC extends NestedB {
// public pattern NestedC(A a) { System.out.println("NestedC1"); match NestedC(new A());}
public pattern NestedC(B b) { System.out.println("NestedC2"); match NestedC(new B());}
public pattern NestedC(C c) { System.out.println("NestedC3"); match NestedC(new C());}
}
static class Top {
// public pattern Top(NestedA na) { System.out.println("Top1"); match Top(new NestedA());}
// public pattern Top(NestedB nb) { System.out.println("Top2"); match Top(new NestedB());}
public pattern Top(NestedC nc) { System.out.println("Top3"); match Top(new NestedC());}
}
}
""";

compileAndRun(base, source, """
Top3
NestedB2
""", Task.Expect.SUCCESS);
}

@Test
public void test2(Path base) throws Exception {
String source =
"""
package test;
class Test {
public static void main(String... args) {
R r = new R();
switch (r) {
case R(A1 a1) -> {} // R:A1
default -> {}
}
switch (r) {
case R(A1(String s)) -> {} // R:A1, A1
default -> {}
}
}
static class A1 {
pattern A1(String s) {
System.out.println("A1");
match A1("A1");
}
}
static class A2 extends A1 {
pattern A2(String s) {
System.out.println("A2");
match A2("A2");
}
}
static class R {
pattern R(A1 a1) {
System.out.println("R:A1");
match R(new A1());
}
pattern R(A2 a2) {
System.out.println("R:A2");
match R(new A2());
}
}
}
""";

compileAndRun(base, source, """
R:A1
R:A1
A1
""",
Task.Expect.SUCCESS);
}

@Test
public void test3(Path base) throws Exception {
String source =
"""
package test;
class Test {
public static void main(String... args) {
R r = new R();
switch (r) {
case R(I i, String s) -> {}
default -> {}
}
}
sealed interface I {}
sealed static interface E extends I {}
sealed static interface F extends I {}
static final class EF implements E, F {}
static class R {
pattern R(E e, String s) {
System.out.println("R:E");
match R(new EF(), "");
}
pattern R(F f, String s) {
System.out.println("R:F");
match R(new EF(), "");
}
pattern R(EF ef, Object o) {
System.out.println("R:EF");
match R(new EF(), "");
}
}
}
""";

compileAndRun(base, source, """
compiler.err.matcher.overloading.ambiguity
""", Task.Expect.FAIL);
}

private void compileAndRun(Path base, String source, String expected, Task.Expect compilationExpectation) throws IOException {
Path current = base.resolve(".");
Path src = current.resolve("src");
Path classes = current.resolve("classes");

tb.writeJavaFiles(src, source);

Files.createDirectories(classes);

{
String javacOut = new JavacTask(tb)
.options("-XDrawDiagnostics", "--enable-preview", "--release", SOURCE_VERSION)
.outdir(classes)
.files(tb.findJavaFiles(src))
.run(compilationExpectation)
.writeAll()
.getOutput(Task.OutputKind.DIRECT);

if (compilationExpectation == Task.Expect.SUCCESS) {
String javaOut = new JavaTask(tb)
.vmOptions("--enable-preview")
.classpath(classes.toString())
.className("test.Test")
.run()
.writeAll()
.getOutput(Task.OutputKind.STDOUT);

if (!javaOut.contains(expected.toString()))
throw new AssertionError("Wrong overload pattern execution:\n" + javaOut);
}
else {
if (!javacOut.contains(expected.toString()))
throw new AssertionError("Wrong overload pattern compilation:\n" + javacOut);
}
}
}
}

0 comments on commit a6e8bc9

Please sign in to comment.