Project: JDT
Bug 169608 [Use supertype] refactoring causes infinite loop with self-referential generic types
Reported: 2007-01-04 18:28:59 | Status: verified fixed

Build ID: M20060921-0945 Steps To Reproduce: 1. Create A.java with body public class A<T extends A<T>> {} 2. Create B.java with body public class B<T extends B<T>> extends A<B<T>> {} 3. Create C.java with body: public class C extends B<C> {} 4. While in C.java, attempt the "Use supertype where possible" refactoring, and select B<T> as the "supertype to use instead of C". A dialog box pops up informing that "An unexpected exception occurred while performing the refactoring. See the error log for more details". More information: The error log shows a java.lang.reflect.InvocationTargetException with a root cause of java.lang.StackOverflowError. The stack overflow stems from an infinite loop of the following seven stack frames: at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TypeEnvironment.createParameterizedType(TypeEnvironment.java:365) at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TypeEnvironment.create(TypeEnvironment.java:182) at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.HierarchyType.initialize(HierarchyType.java:37) at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.ParameterizedType.initialize(ParameterizedType.java:31) at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TypeEnvironment.createParameterizedType(TypeEnvironment.java:365) at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TypeEnvironment.create(TypeEnvironment.java:182) at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.ParameterizedType.initialize(ParameterizedType.java:37) Placing a breakpoint at org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types.TypeEnvironment [line: 365] - createParameterizedType(ITypeBinding), and displaying the value of the binding variable, I see it toggling between B<C> and A<B<C>>. It appears that the jdt is getting tripped up because B<C> extends A<B<C>>, which in turn is parameterized by B<C>.

Files changed in fix:
org.eclipse.jdt.ui.tests.refactoring/resources/UseSupertypeWherePossible/testNew39/in/C.java org.eclipse.jdt.ui.tests.refactoring/resources/UseSupertypeWherePossible/testNew39/out/C.java org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/UseSupertypeWherePossibleTests.java org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/types/TType.java org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/types/TypeEnvironment.java