Index: ParameterizedGenericMethodBinding.java =================================================================== RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java,v retrieving revision 1.37 diff -u -r1.37 ParameterizedGenericMethodBinding.java --- ParameterizedGenericMethodBinding.java 10 Jun 2005 07:30:26 -0000 1.37 +++ ParameterizedGenericMethodBinding.java 20 Jun 2005 11:56:47 -0000 @@ -68,31 +68,13 @@ // 15.12.2.8 - inferring unresolved type arguments if (hasUnresolvedTypeArgument(substitutes)) { TypeBinding expectedType = null; - // if message invocation has expected type - if (invocationSite instanceof MessageSend) { - MessageSend message = (MessageSend) invocationSite; - expectedType = message.expectedType; - } - TypeBinding upperBound; - TypeBinding substitutedReturnType = methodSubstitute.returnType; - switch (substitutedReturnType.kind()) { - case Binding.TYPE_PARAMETER : - // should be: if no expected type, then assume Object - // actually it rather seems to handle the returned variable case by expecting its erasure instead - upperBound = Scope.substitute(methodSubstitute, ((TypeVariableBinding)substitutedReturnType).upperBound()); - break; - case Binding.BASE_TYPE : - if (substitutedReturnType == VoidBinding) { - upperBound = null; - break; - } - // fallthrough - default: - upperBound = scope.getJavaLangObject(); - } - // Object o = foo(); // where T foo(); - if (expectedType == null || (upperBound != null && upperBound.isCompatibleWith(expectedType))) { - expectedType = upperBound; + if (methodSubstitute.returnType != VoidBinding) { + // if message invocation has expected type + if (invocationSite instanceof MessageSend) { + MessageSend message = (MessageSend) invocationSite; + expectedType = message.expectedType; + } + if (expectedType == null) expectedType = scope.getJavaLangObject(); // assume Object by default } methodSubstitute = methodSubstitute.inferFromExpectedType(scope, expectedType, collectedSubstitutes, substitutes); if (methodSubstitute == null) @@ -208,6 +190,7 @@ for (int j = 0, equalLength = equalSubstitutes.length; j < equalLength; j++) { TypeBinding equalSubstitute = equalSubstitutes[j]; if (equalSubstitute == null) continue nextConstraint; +// if (equalSubstitute == current) continue nextConstraint; if (equalSubstitute == current) { // try to find a better different match if any in subsequent equal candidates for (int k = j+1; k < equalLength; k++) { @@ -387,19 +370,28 @@ computeSubstitutes: { // infer from expected return type if (expectedType != null) { - returnType.collectSubstitutes(scope, expectedType, collectedSubstitutes, CONSTRAINT_SUPER); + this.returnType.collectSubstitutes(scope, expectedType, collectedSubstitutes, CONSTRAINT_SUPER); } // infer from bounds of type parameters for (int i = 0; i < varLength; i++) { TypeVariableBinding originalVariable = originalVariables[i]; TypeBinding argument = this.typeArguments[i]; + boolean argAlreadyInferred = argument != originalVariable; if (originalVariable.firstBound == originalVariable.superclass) { - Scope.substitute(this, originalVariable.firstBound) // substitue original bound with resolved variables - .collectSubstitutes(scope, argument, collectedSubstitutes, CONSTRAINT_EXTENDS); + TypeBinding substitutedBound = Scope.substitute(this, originalVariable.superclass); + argument.collectSubstitutes(scope, substitutedBound, collectedSubstitutes, CONSTRAINT_SUPER); + // JLS 15.12.2.8 claims reverse inference shouldn't occur, however it improves inference + // e.g. given: > S test1(S param) + // invocation: test1(new Vector()) will infer: S=Vector and with code below: E=String + if (argAlreadyInferred) + substitutedBound.collectSubstitutes(scope, argument, collectedSubstitutes, CONSTRAINT_EXTENDS); } for (int j = 0, max = originalVariable.superInterfaces.length; j < max; j++) { - Scope.substitute(this, originalVariable.superInterfaces[j]) // substitue original bound with resolved variables - .collectSubstitutes(scope, argument, collectedSubstitutes, CONSTRAINT_EXTENDS); + TypeBinding substitutedBound = Scope.substitute(this, originalVariable.superInterfaces[j]); + argument.collectSubstitutes(scope, substitutedBound, collectedSubstitutes, CONSTRAINT_SUPER); + // JLS 15.12.2.8 claims reverse inference shouldn't occur, however it improves inference + if (argAlreadyInferred) + substitutedBound.collectSubstitutes(scope, argument, collectedSubstitutes, CONSTRAINT_EXTENDS); } } substitutes = resolveSubstituteConstraints(scope, originalVariables, substitutes, true/*consider Ti<:Uk*/, collectedSubstitutes);