Make computation of arguments for raw types lazy

See how we translate raw types to Kotlin model:
RawType(A) = A<ErasedUpperBound(T1), ...>
ErasedUpperBound(T : G<t>) = G<*> // UpperBound(T) is a type G<t> with arguments
ErasedUpperBound(T : A) = A // UpperBound(T) is a type A without arguments
ErasedUpperBound(T : F) = UpperBound(F) // UB(T) is another type parameter F

Stack overflow happens with the following classes:
class A<X extends B> // NB: raw type B in upper bound
class B<Y extends A> // NB: raw type A in upper bound

when calculating raw type for A, we start calculate ErasedUpperBound(Y),
thus starting calculating raw type for B => ErasedUpperBound(X) => RawType(A),
so we have SOE here.
The problem is that we calculating the arguments for these raw types eagerly,
while from the definition of ErasedUpperBound(Y) we only need a type constructor
of raw type B (and the number of parameters), we don't use its arguments.

The solution is to make arguments calculating for raw types lazy

 #KT-16528 Fixed
This commit is contained in:
Denis Zharkov
2017-03-09 17:14:52 +03:00
parent f2fea9a04a
commit 7173e56393
7 changed files with 90 additions and 2 deletions
@@ -477,6 +477,27 @@ public class BlackBoxAgainstJavaCodegenTestGenerated extends AbstractBlackBoxAga
}
}
@TestMetadata("compiler/testData/codegen/boxAgainstJava/recursiveRawTypes")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class RecursiveRawTypes extends AbstractBlackBoxAgainstJavaCodegenTest {
public void testAllFilesPresentInRecursiveRawTypes() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxAgainstJava/recursiveRawTypes"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("kt16528.kt")
public void testKt16528() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxAgainstJava/recursiveRawTypes/kt16528.kt");
doTest(fileName);
}
@TestMetadata("kt16639.kt")
public void testKt16639() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxAgainstJava/recursiveRawTypes/kt16639.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/codegen/boxAgainstJava/reflection")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)