diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java index 137dfa7c3c5..f5e9bfcd7a8 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java @@ -206,7 +206,11 @@ public class Infer { //propagate outwards if needed if (shouldPropagate) { //propagate inference context outwards and exit - minContext.dupTo(resultInfo.checkContext.inferenceContext()); + InferenceContext duppedTo = resultInfo.checkContext.inferenceContext(); + minContext.dupTo(duppedTo); + if (minContext != inferenceContext) { + duppedTo.parentIC = inferenceContext; + } deferredAttrContext.complete(); return mt; } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java index ea7806ef032..8fc316c8ff6 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java @@ -83,6 +83,14 @@ public class InferenceContext { Types types; Infer infer; + /* when an inference context (IC) is minimized, the minimized inference context (MIC) contains a + * proper subset of IC's inference vars (IC_IV). In other words there will be at least one inference variable T + * that belongs to IC_IV which doesn't belong to MIC_IV. We need the field below to, among other things, + * check for set membership for cases where the minimized context or any other context derived from it + * needs to deal with an inference variable that has been eliminated from IC_IV while minimizing it + */ + InferenceContext parentIC; + public InferenceContext(Infer infer, List inferencevars) { this(infer, inferencevars, inferencevars.map(infer.fromTypeVarFun)); } @@ -243,7 +251,17 @@ public class InferenceContext { * fully instantiated, it will still be available in the resulting type. */ Type asInstType(Type t) { - return types.subst(t, inferencevars, instTypes()); + ListBuffer from = new ListBuffer<>(); + ListBuffer to = new ListBuffer<>(); + from.addAll(inferencevars); + to.addAll(instTypes()); + InferenceContext next = parentIC; + while (next != null) { + from.addAll(next.inferencevars); + to.addAll(next.instTypes()); + next = next.parentIC; + } + return types.subst(t, from.toList(), to.toList()); } List asInstTypes(List ts) { @@ -551,8 +569,12 @@ public class InferenceContext { @Override public String toString() { - return "Inference vars: " + inferencevars + '\n' + - "Undet vars: " + undetvars; + String result = "Inference vars: " + inferencevars + '\n' + + "Undet vars: " + undetvars + '\n'; + if (parentIC != null) { + result += "\nParent : " + parentIC.toString(); + } + return result; } /* Method Types.capture() generates a new type every time it's applied diff --git a/test/langtools/tools/javac/inference_context_min/SupplementaryInferenceContextTest.java b/test/langtools/tools/javac/inference_context_min/SupplementaryInferenceContextTest.java new file mode 100644 index 00000000000..25605d71c96 --- /dev/null +++ b/test/langtools/tools/javac/inference_context_min/SupplementaryInferenceContextTest.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2025, 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 8325859 + * @summary potential information loss during type inference + * @modules jdk.compiler/com.sun.tools.javac.util + */ + +import com.sun.tools.javac.util.Assert; + +public class SupplementaryInferenceContextTest { + static String result; + public static void main(String... args) { + runT(() -> supplyNull(Integer.valueOf(1))); + Assert.check(result.equals("class java.lang.Integer")); + } + + static R supplyNull(X... varargs) { + result = varargs.getClass().getComponentType().toString(); + System.err.println("result is =" + result); + return null; + } + + static void runT(Runnable runnable) { runnable.run(); } +}