From c928ff1c8670edb568146b0c6ec0e27f1eb03693 Mon Sep 17 00:00:00 2001 From: Stephan Herrmann Date: Sun, 5 Jan 2025 17:35:17 +0100 Subject: [PATCH] Incorrect overload resolution ends in type error. (#3515) + record when Poly*Method is part of a set of overloads + in that case don't propagate premature bounds inner -> outer Fixes https://github.com/eclipse-jdt/eclipse.jdt.core/issues/2941 --- .../compiler/lookup/InferenceContext18.java | 2 + ...PolyParameterizedGenericMethodBinding.java | 2 + .../compiler/lookup/ProblemMethodBinding.java | 23 ++++--- .../regression/OverloadResolutionTest8.java | 64 +++++++++++++++++++ 4 files changed, 82 insertions(+), 9 deletions(-) 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 7df0a5f58bf..75ce057fccf 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 @@ -691,6 +691,8 @@ private boolean addConstraintsToC_OneExpr(Expression expri, Set proceed with no new C set elements. + if (innerMethod instanceof PolyParameterizedGenericMethodBinding poly && poly.hasOverloads) + return true; // don't let ambiguous inner method influence outer inference Expression[] arguments = invocation.arguments(); TypeBinding[] argumentTypes = arguments == null ? Binding.NO_PARAMETERS : new TypeBinding[arguments.length]; diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/PolyParameterizedGenericMethodBinding.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/PolyParameterizedGenericMethodBinding.java index 3f41a87f3f6..5177290c14a 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/PolyParameterizedGenericMethodBinding.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/PolyParameterizedGenericMethodBinding.java @@ -15,6 +15,8 @@ public class PolyParameterizedGenericMethodBinding extends ParameterizedGenericMethodBinding { // confused citizen. + public boolean hasOverloads; + private final ParameterizedGenericMethodBinding wrappedBinding; public PolyParameterizedGenericMethodBinding(ParameterizedGenericMethodBinding applicableMethod) { super(applicableMethod.originalMethod, applicableMethod.typeArguments, applicableMethod.environment, applicableMethod.inferredWithUncheckedConversion, false, applicableMethod.targetType); diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ProblemMethodBinding.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ProblemMethodBinding.java index 9c1a8ffb272..ddf05c8cf5f 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ProblemMethodBinding.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ProblemMethodBinding.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -38,14 +38,19 @@ public ProblemMethodBinding(char[] selector, TypeBinding[] args, ReferenceBindin public ProblemMethodBinding(MethodBinding closestMatch, char[] selector, TypeBinding[] args, int problemReason) { this(selector, args, problemReason); this.closestMatch = closestMatch; - if (closestMatch != null && problemReason != ProblemReasons.Ambiguous) { - this.declaringClass = closestMatch.declaringClass; - this.returnType = closestMatch.returnType; - if (problemReason == ProblemReasons.InvocationTypeInferenceFailure || problemReason == ProblemReasons.ContradictoryNullAnnotations) { - this.thrownExceptions = closestMatch.thrownExceptions; - this.typeVariables = closestMatch.typeVariables; - this.modifiers = closestMatch.modifiers; - this.tagBits = closestMatch.tagBits; + if (problemReason == ProblemReasons.Ambiguous) { + if (closestMatch instanceof PolyParameterizedGenericMethodBinding poly) + poly.hasOverloads = true; + } else { + if (closestMatch != null) { + this.declaringClass = closestMatch.declaringClass; + this.returnType = closestMatch.returnType; + if (problemReason == ProblemReasons.InvocationTypeInferenceFailure || problemReason == ProblemReasons.ContradictoryNullAnnotations) { + this.thrownExceptions = closestMatch.thrownExceptions; + this.typeVariables = closestMatch.typeVariables; + this.modifiers = closestMatch.modifiers; + this.tagBits = closestMatch.tagBits; + } } } } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/OverloadResolutionTest8.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/OverloadResolutionTest8.java index 7216da2bf8b..dd998a668b1 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/OverloadResolutionTest8.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/OverloadResolutionTest8.java @@ -2722,4 +2722,68 @@ public void test482440b() { "}\n" }); } +public void testGH2941_a() { + runConformTest( + new String[] { + "BiStream.java", + """ + import static java.util.stream.Collectors.collectingAndThen; + + import java.util.function.Function; + import java.util.stream.Collector; + import java.util.stream.Stream; + + public abstract class BiStream { + public static Collector> toBiStream( + Function toKey, Function toValue) { + return collectingAndThen(toStream(), stream -> from(stream)); + } + + private static Collector> toStream() { + return null; + } + + public static BiStream from(Iterable elements) { + return null; + } + + public static BiStream from(Stream stream) { + return null; + } + } + """ + }); +} +public void testGH2941_b() { + runConformTest( + new String[] { + "BiStream.java", + """ + import static java.util.stream.Collectors.collectingAndThen; + + import java.util.function.Function; + import java.util.stream.Collector; + import java.util.stream.Stream; + + public abstract class BiStream { + public static Collector> toBiStream( + Function toKey, Function toValue) { + return collectingAndThen(toStream(), stream -> from(stream)); + } + + private static Collector> toStream() { + return null; + } + + public static BiStream from(Stream stream) { + return null; + } + + public static BiStream from(Iterable elements) { + return null; + } + } + """ + }); +} }