Bug 467776 [compiler][implementation] decouple method
verification from bridge method generation

- test & fix for a regression

Change-Id: I639ba788fa9dd8a35ec0993fa79db2e8c7ed8c3a
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
index a4c90fe..300af03 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
@@ -14271,4 +14271,33 @@
 			"public abstract class ChildFoo extends Foo {}\n"
 		});
 }
+public void testBug467776_regression() {
+	if (this.complianceLevel < ClassFileConstants.JDK1_6) return;
+	Map compilerOptions = getCompilerOptions();
+	compilerOptions.put(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION, JavaCore.ERROR);
+	runConformTest(
+		new String[] {
+			"ITeam.java",
+			"public interface ITeam {\n" + 
+			"        <T> T getRole(Object o, Class<T> clazz);\n" + 
+			"}\n",
+			"Team.java",
+			"public class Team implements ITeam {\n" + 
+			"\n" + 
+			"        @Override\n" + 
+			"        public <T> T getRole(Object o, Class<T> clazz) {\n" + 
+			"                return null;\n" + 
+			"        }\n" + 
+			"}\n",
+			"MyTeam.java",
+			"public class MyTeam extends Team {\n" + 
+			"        @Override\n" + 
+			"        public <T> T getRole(Object o, Class<T> clazz) {\n" + 
+			"                return super.getRole(o, clazz);\n" + 
+			"        }\n" + 
+			"}\n"
+			
+		},
+		compilerOptions);
+}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
index 62df9d3..7010058 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
@@ -556,7 +556,7 @@
 									continue existing; // may need to record incompatible return type
 							}
 						}
-						if (TypeBinding.notEquals(inheritedMethod.returnType, existingMethod.returnType) &&
+						if (TypeBinding.notEquals(inheritedMethod.returnType.erasure(), existingMethod.returnType.erasure()) &&
 								areReturnTypesCompatible(existingMethod, inheritedMethod)) {
 							addBridgeMethodCandidate(inheritedMethod);
 						}
@@ -645,7 +645,7 @@
 					// in a subclass is guaranteed to have the same erasure as an existing method.
 					for (int e = 0; e < length; e++) {
 						if (isInterfaceMethodImplemented(inheritedMethod, existingMethods[e], superType)) {
-							if (TypeBinding.notEquals(inheritedMethod.returnType, existingMethods[e].returnType)) {
+							if (TypeBinding.notEquals(inheritedMethod.returnType.erasure(), existingMethods[e].returnType.erasure())) {
 								// overridden, but with different return type, need to check
 								// for bridge method
 								addBridgeMethodCandidate(inheritedMethod);