From 7d256e3f4334bd92625e8c5d3706b6fd9eda93c9 Mon Sep 17 00:00:00 2001 From: Stephan Herrmann Date: Sat, 13 Apr 2024 11:50:01 +0200 Subject: [PATCH] move test to new class DubiousOutcomeTest improved debug output --- .../internal/compiler/lookup/BoundSet.java | 41 ++++++++-- .../lookup/ConstraintTypeFormula.java | 6 +- .../compiler/lookup/InferenceContext18.java | 3 +- .../regression/DubiousOutcomeTest.java | 74 +++++++++++++++++++ .../GenericsRegressionTest_1_8.java | 21 ------ .../tests/compiler/regression/TestAll.java | 1 + 6 files changed, 113 insertions(+), 33 deletions(-) create mode 100644 org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/DubiousOutcomeTest.java diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java index 48e1d05021c..4952f0a93fe 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java @@ -393,6 +393,9 @@ public BoundSet copy() { } public void addBound(TypeBound bound, LookupEnvironment environment) { + if (InferenceContext18.DEBUG) { + System.out.println("Adding "+bound); //$NON-NLS-1$ + } if (bound.relation == ReductionResult.SUBTYPE && bound.right.id == TypeIds.T_JavaLangObject) return; @@ -719,6 +722,15 @@ protected TypeBinding getP(int i) { } } } + if (InferenceContext18.DEBUG) { + if (!this.captures.isEmpty()) { + for (Entry entry : this.captures.entrySet()) { + System.out.println("Dropping capture bound " + //$NON-NLS-1$ + String.valueOf(entry.getKey().shortReadableName()) + + "=capture("+String.valueOf(entry.getKey().shortReadableName())+")"); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + } this.captures.clear(); return true; } @@ -770,8 +782,12 @@ private ConstraintTypeFormula combineSameSameWithProperType(TypeBound boundLeft, InferenceVariable alpha = boundLeft.left; TypeBinding left = boundRight.left; // no substitution since S inference variable and (S != α) per precondition TypeBinding right = boundRight.right.substituteInferenceVariable(alpha, u); - if (TypeBinding.equalsEquals(right, boundRight.right)) - return null; // no new information + // FIXME: the following looks good by common sense, be it for performance reasons, + // but it creates regressions in GenericTypeTest (4), GenericsRegressionTest (1), GenericsRegressionTest_1_8 (1) + // Note that it would "fix" DubiousOutcomeTest.testGH1591 + // See also the 'speculative addition' in ConstraintTypeFormula.reduce() +// if (TypeBinding.equalsEquals(right, boundRight.right)) +// return null; // no new information return ConstraintTypeFormula.create(left, right, ReductionResult.SAME, boundLeft.isSoft||boundRight.isSoft); } return null; @@ -975,9 +991,13 @@ private ConstraintTypeFormula[] typeArgumentEqualityConstraints(TypeBinding s, T */ public boolean reduceOneConstraint(InferenceContext18 context, ConstraintFormula currentConstraint) throws InferenceFailureException { Object result = currentConstraint.reduce(context); + if (InferenceContext18.DEBUG_FINE) { + System.out.println("Reduced\t"+currentConstraint+"\n to \t"+result); //$NON-NLS-1$ //$NON-NLS-2$ + } if (result == ReductionResult.FALSE) { if (InferenceContext18.DEBUG) { - System.out.println("Couldn't reduce constraint "+currentConstraint+ " in\n"+context); //$NON-NLS-1$ //$NON-NLS-2$ + if (!InferenceContext18.DEBUG_FINE) + System.out.println("Couldn't reduce constraint "+currentConstraint+ " in\n"+context); //$NON-NLS-1$ //$NON-NLS-2$ } return false; } @@ -1139,11 +1159,16 @@ public String toString() { for (TypeBound bound : flattened) { buf.append('\t').append(bound.toString()).append('\n'); } - buf.append("Capture Bounds:\n"); //$NON-NLS-1$ - for (Entry entry : this.captures.entrySet()) { - String lhs = String.valueOf(((TypeBinding)entry.getKey()).shortReadableName()); - String rhs = String.valueOf(((TypeBinding)entry.getValue()).shortReadableName()); - buf.append('\t').append(lhs).append(" = capt(").append(rhs).append(")\n"); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append("Capture Bounds:"); //$NON-NLS-1$ + if (this.captures.isEmpty()) { + buf.append(" \n"); //$NON-NLS-1$ + } else { + buf.append('\n'); + for (Entry entry : this.captures.entrySet()) { + String lhs = String.valueOf(((TypeBinding)entry.getKey()).shortReadableName()); + String rhs = String.valueOf(((TypeBinding)entry.getValue()).shortReadableName()); + buf.append('\t').append(lhs).append(" = capt(").append(rhs).append(")\n"); //$NON-NLS-1$ //$NON-NLS-2$ + } } return buf.toString(); } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ConstraintTypeFormula.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ConstraintTypeFormula.java index 02ce30f5032..3149d02f0d1 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ConstraintTypeFormula.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ConstraintTypeFormula.java @@ -112,8 +112,8 @@ public Object reduce(InferenceContext18 inferenceContext) { if (this.left.kind() != Binding.WILDCARD_TYPE) { return ConstraintTypeFormula.create(this.left, this.right, SAME, this.isSoft); } else { - // FIXME: with the pending change in BoundSet, removing this might actually help: // TODO: speculative addition: + // see also note in BoundSet.combineSameSameWithProperType(..) if (this.right instanceof InferenceVariable) return new TypeBound((InferenceVariable) this.right, this.left, SAME, this.isSoft); return FALSE; @@ -424,8 +424,8 @@ public boolean applySubstitution(BoundSet solutionSet, InferenceVariable[] varia // debugging @Override public String toString() { - StringBuilder buf = new StringBuilder("Type Constraint:\n"); //$NON-NLS-1$ - buf.append('\t').append(LEFT_ANGLE_BRACKET); + StringBuilder buf = new StringBuilder(); + buf.append(LEFT_ANGLE_BRACKET); appendTypeName(buf, this.left); buf.append(relationToString(this.relation)); appendTypeName(buf, this.right); diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java index 5adcf8395d5..3eaea0a2de5 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java @@ -112,6 +112,7 @@ public class InferenceContext18 { public final static boolean DEBUG = false; + public final static boolean DEBUG_FINE = false; /** to conform with javac regarding https://bugs.openjdk.java.net/browse/JDK-8026527 */ static final boolean SIMULATE_BUG_JDK_8026527 = true; @@ -1094,7 +1095,7 @@ private boolean reduce() throws InferenceFailureException { } this.initialConstraints = null; if (DEBUG) { - System.out.println("reduced to\n"+this); //$NON-NLS-1$ + System.out.println("Reduced all to:\n"+this); //$NON-NLS-1$ } return true; } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/DubiousOutcomeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/DubiousOutcomeTest.java new file mode 100644 index 00000000000..f668e54eac5 --- /dev/null +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/DubiousOutcomeTest.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2024 GK Software SE, and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Stephan Herrmann - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.tests.compiler.regression; + +import junit.framework.Test; + +/** + * README: this class captures the actual outcome of examples were we doubt if the outcome is correct, + * (e.g., because javac behaves differently). Still the current outcome is expected in tests, in order + * to alert us when their behavior changes due to some other fix. If such change occurs, we should decide: + *
    + *
  1. if the new outcome is worse, try to improve the code change + *
  2. if the new outcome is equally dubious, just change the test expectation + *
  3. if the new outcome is good, thus removing the doubt, then move the test to a 'regular' suite class + *
+ */ +public class DubiousOutcomeTest extends AbstractRegressionTest { + + static { +// TESTS_NAMES = new String[] { "testGH1591" }; +// TESTS_NUMBERS = new int[] { 40, 41, 43, 45, 63, 64 }; +// TESTS_RANGE = new int[] { 11, -1 }; + } + + public DubiousOutcomeTest(String name) { + super(name); + } + public static Class testClass() { + return DubiousOutcomeTest.class; + } + public static Test suite() { + return buildMinimalComplianceTestSuite(testClass(), F_1_8); + } + + public void testGH1591() { + // javac accepts + runNegativeTest( + new String[] { + "Outer.java", + """ + import java.io.Serializable; + import java.util.List; + import java.util.function.Supplier; + + public class Outer { + public void test() { + Supplier> supplier = () -> null; + error(supplier.get(), ""); + } + + public void error(List v2, T t) {} + + } + """ + }, + "----------\n" + + "1. ERROR in Outer.java (at line 8)\n" + + " error(supplier.get(), \"\");\n" + + " ^^^^^\n" + + "The method error(List, T) in the type Outer is not applicable for the arguments (capture#1-of ? extends List, String)\n" + + "----------\n"); + } +} diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java index c086250740a..4edc27eb36c 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java @@ -10682,25 +10682,4 @@ public int getWeaveCount() { "----------\n", null, true, customOptions); } - public void testGH1591() { - runConformTest( - new String[] { - "Outer.java", - """ - import java.io.Serializable; - import java.util.List; - import java.util.function.Supplier; - - public class Outer { - public void test() { - Supplier> supplier = () -> null; - error(supplier.get(), ""); - } - - public void error(List v2, T t) {} - - } - """ - }); - } } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java index e9871a7be2b..ac6d0745976 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java @@ -164,6 +164,7 @@ public static Test suite() { since_1_8.add(LambdaShapeTests.class); since_1_8.add(StringConcatTest.class); since_1_8.add(UseOfUnderscoreTest.class); + since_1_8.add(DubiousOutcomeTest.class); ArrayList since_9 = new ArrayList(); since_9.add(Unicode9Test.class);