Index: compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java =================================================================== --- compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java (revision 107) +++ compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java (working copy) @@ -324,7 +324,7 @@ for (int i = 0, length1 = current.length; i < length1; i++) { MethodBinding currentMethod = current[i]; for (int j = 0, length2 = inherited.length; j < length2; j++) { - MethodBinding inheritedMethod = computeSubstituteMethod(inherited[j], currentMethod); + MethodBinding inheritedMethod = computeSubstituteMethod(inherited[j], currentMethod, false); if (inheritedMethod != null) { if (doesMethodOverride(currentMethod, inheritedMethod)) { matchingInherited[++index] = inheritedMethod; @@ -348,7 +348,7 @@ MethodBinding otherInheritedMethod = inherited[j]; if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod)) continue; - otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod); + otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod, false); if (otherInheritedMethod != null) { if (doesMethodOverride(inheritedMethod, otherInheritedMethod)) { matchingInherited[++index] = otherInheritedMethod; @@ -564,7 +564,7 @@ } } } -MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod) { +MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod, boolean eraseIfTypeParametersNbMismatch) { if (inheritedMethod == null) return null; if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; // no match return inheritedMethod; Index: compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java =================================================================== --- compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java (revision 107) +++ compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java (working copy) @@ -20,7 +20,7 @@ super(environment); } boolean areMethodsEqual(MethodBinding one, MethodBinding two) { - MethodBinding sub = computeSubstituteMethod(two, one); + MethodBinding sub = computeSubstituteMethod(two, one, false); return sub != null && doesSubstituteMethodOverride(one, sub) && areReturnTypesEqual(one, sub); } boolean areParametersEqual(MethodBinding one, MethodBinding two) { @@ -128,7 +128,7 @@ MethodBinding compareMethod = inheritedMethod instanceof ParameterizedGenericMethodBinding ? ((ParameterizedGenericMethodBinding) inheritedMethod).originalMethod : inheritedMethod; - MethodBinding substitute = computeSubstituteMethod(otherInheritedMethod, compareMethod); + MethodBinding substitute = computeSubstituteMethod(otherInheritedMethod, compareMethod, false); if (substitute == null || doesSubstituteMethodOverride(compareMethod, substitute)) continue; if (detectInheritedNameClash(originalInherited, otherOriginal)) @@ -211,7 +211,7 @@ while (superType != null && superType.isValidBinding()) { MethodBinding[] methods = superType.getMethods(currentMethod.selector); for (int m = 0, n = methods.length; m < n; m++) { - MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod); + MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod, false); if (substitute != null && !doesSubstituteMethodOverride(currentMethod, substitute) && detectNameClash(currentMethod, substitute)) return; } @@ -239,7 +239,7 @@ if (superType.isValidBinding()) { MethodBinding[] methods = superType.getMethods(currentMethod.selector); for (int m = 0, n = methods.length; m < n; m++){ - MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod); + MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod, false); if (substitute != null && !doesSubstituteMethodOverride(currentMethod, substitute) && detectNameClash(currentMethod, substitute)) return; } @@ -333,7 +333,7 @@ MethodBinding inheritedMethod; if (i != j && (inheritedMethod = methodsToCheck[j]) != null && existingMethod.declaringClass.implementsInterface(inheritedMethod.declaringClass, true)) { - MethodBinding substitute = computeSubstituteMethod(inheritedMethod, existingMethod); + MethodBinding substitute = computeSubstituteMethod(inheritedMethod, existingMethod, false); if (substitute != null && doesSubstituteMethodOverride(existingMethod, substitute) && (existingMethod.returnType.isCompatibleWith(substitute.returnType) || @@ -399,7 +399,7 @@ for (int i = 0, length1 = current.length; i < length1; i++) { MethodBinding currentMethod = current[i]; for (int j = 0, length2 = inherited.length; j < length2; j++) { - MethodBinding inheritedMethod = computeSubstituteMethod(inherited[j], currentMethod); + MethodBinding inheritedMethod = computeSubstituteMethod(inherited[j], currentMethod, true); if (inheritedMethod != null) { if (foundMatch[j] == 0 && doesSubstituteMethodOverride(currentMethod, inheritedMethod)) { matchingInherited[++index] = inheritedMethod; @@ -428,7 +428,7 @@ MethodBinding otherInheritedMethod = inherited[j]; if (foundMatch[j] == 1 || canSkipInheritedMethods(inheritedMethod, otherInheritedMethod)) continue; - otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod); + otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod, false); if (otherInheritedMethod != null) { if (doesSubstituteMethodOverride(inheritedMethod, otherInheritedMethod)) { matchingInherited[++index] = otherInheritedMethod; @@ -466,7 +466,7 @@ MethodBinding otherInheritedMethod = inherited[j]; if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod)) continue; - otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod); + otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod, false); if (otherInheritedMethod != null && doesSubstituteMethodOverride(inheritedMethod, otherInheritedMethod)) { matchingInherited[++index] = otherInheritedMethod; inherited[j] = null; // do not want to find it again @@ -485,7 +485,7 @@ } } } -MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod) { +MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod, boolean eraseIfTypeParametersNbMismatch) { if (inheritedMethod == null) return null; if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; // no match @@ -500,14 +500,21 @@ int inheritedLength = inheritedTypeVariables.length; TypeVariableBinding[] typeVariables = currentMethod.typeVariables; int length = typeVariables.length; - if (length > 0 && inheritedLength != length) return inheritedMethod; + if (length > 0 && inheritedLength != length) return inheritedMethod; // no match JLS 8.4.2 TypeBinding[] arguments = new TypeBinding[inheritedLength]; - if (inheritedLength <= length) { + if (length != 0) { System.arraycopy(typeVariables, 0, arguments, 0, inheritedLength); + } else if (eraseIfTypeParametersNbMismatch) { + // length is null + for (int i = 0; i < inheritedLength; i++) { + arguments[i] = inheritedTypeVariables[i].erasure(); + } + return this.environment.createParameterizedGenericMethod(inheritedMethod, arguments); // erasure } else { - System.arraycopy(typeVariables, 0, arguments, 0, length); - for (int i = length; i < inheritedLength; i++) + // length is null + for (int i = 0; i < inheritedLength; i++) { arguments[i] = inheritedTypeVariables[i].upperBound(); + } } ParameterizedGenericMethodBinding substitute = this.environment.createParameterizedGenericMethod(inheritedMethod, arguments); @@ -562,7 +569,7 @@ return true; } public boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod) { - MethodBinding substitute = computeSubstituteMethod(inheritedMethod, method); + MethodBinding substitute = computeSubstituteMethod(inheritedMethod, method, false); return substitute != null && doesSubstituteMethodOverride(method, substitute); } boolean doesSubstituteMethodOverride(MethodBinding method, MethodBinding substituteMethod) { @@ -600,7 +607,7 @@ if (inheritedMethod.original() != inheritedMethod && existingMethod.declaringClass.isInterface()) return false; // must hold onto ParameterizedMethod to see if a bridge method is necessary - inheritedMethod = computeSubstituteMethod(inheritedMethod, existingMethod); + inheritedMethod = computeSubstituteMethod(inheritedMethod, existingMethod, false); return inheritedMethod != null && inheritedMethod.returnType == existingMethod.returnType && super.isInterfaceMethodImplemented(inheritedMethod, existingMethod, superType);