Index: src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java,v retrieving revision 1.42 diff -u -r1.42 AmbiguousMethodTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java 30 Apr 2007 19:03:58 -0000 1.42 +++ src/org/eclipse/jdt/core/tests/compiler/regression/AmbiguousMethodTest.java 14 May 2007 19:34:46 -0000 @@ -1984,4 +1984,22 @@ }, ""); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=186382 +public void test057() { + this.runConformTest( + new String[] { + "X.java", + "public class X extends Y {\n" + + " @Override > T4 foo(G4 g) { return super.foo(g); }\n" + + "}\n" + + "class Y extends Z {\n" + + " @Override > T3 foo(G3 g) { return super.foo(g); }\n" + + "}\n" + + "class Z {\n" + + " > T2 foo(G2 g) { return null; }\n" + + "}\n" + + "interface I {}" + }, + ""); +} } Index: compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java,v retrieving revision 1.91 diff -u -r1.91 MethodBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java 12 Apr 2007 22:39:50 -0000 1.91 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java 14 May 2007 19:34:49 -0000 @@ -299,18 +299,20 @@ return false; } MethodBinding computeSubstitutedMethod(MethodBinding method, LookupEnvironment env) { - TypeVariableBinding[] vars = this.typeVariables; - TypeVariableBinding[] vars2 = method.typeVariables; - if (vars.length != vars2.length) + int length = this.typeVariables.length; + TypeVariableBinding[] vars = method.typeVariables; + if (length != vars.length) return null; - for (int v = vars.length; --v >= 0;) - if (!vars[v].isInterchangeableWith(env, vars2[v])) - return null; // must substitute to detect cases like: // > void dup() {} // > Object dup() {return null;} - return env.createParameterizedGenericMethod(method, vars); + ParameterizedGenericMethodBinding substitute = + env.createParameterizedGenericMethod(method, this.typeVariables); + for (int i = 0; i < length; i++) + if (!this.typeVariables[i].isInterchangeableWith(vars[i], substitute)) + return null; + return substitute; } /* * declaringUniqueKey dot selector genericSignature Index: compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java,v retrieving revision 1.59 diff -u -r1.59 TypeVariableBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java 16 Mar 2007 18:28:58 -0000 1.59 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java 14 May 2007 19:34:49 -0000 @@ -297,41 +297,23 @@ * the same bounds, providing one is substituted with the other: > is interchangeable with >. */ - public boolean isInterchangeableWith(final LookupEnvironment environment, final TypeVariableBinding otherVariable) { + public boolean isInterchangeableWith(TypeVariableBinding otherVariable, ParameterizedGenericMethodBinding substitute) { if (this == otherVariable) return true; int length = this.superInterfaces.length; if (length != otherVariable.superInterfaces.length) return false; - identical: { - if (this.superclass != otherVariable.superclass) { - if (this.superclass.erasure() != otherVariable.superclass.erasure()) - return false; // no way it can match after substitution - break identical; - } - for (int i = 0; i < length; i++) { - if (this.superInterfaces[i] != otherVariable.superInterfaces[i]) { - if (this.superInterfaces[i].erasure() != otherVariable.superInterfaces[i].erasure()) - return false; // no way it can match after substitution - break identical; - } - } - return true; - } - // need substitutions - Substitution subst = new Substitution() { - public LookupEnvironment environment() { return environment; } - public boolean isRawSubstitution() { return false; } - public TypeBinding substitute(TypeVariableBinding typeVariable) { - return typeVariable == otherVariable ? TypeVariableBinding.this : typeVariable; - } - }; - if (this.superclass != Scope.substitute(subst, otherVariable.superclass)) + if (this.superclass != Scope.substitute(substitute, otherVariable.superclass)) return false; - for (int i = 0; i < length; i++) - if (this.superInterfaces[i] != Scope.substitute(subst, otherVariable.superInterfaces[i])) - return false; + + next : for (int i = 0; i < length; i++) { + TypeBinding superType = Scope.substitute(substitute, otherVariable.superInterfaces[i]); + for (int j = 0; j < length; j++) + if (superType == this.superInterfaces[j]) + continue next; + return false; // not a match + } return true; }