[FIR] Fix bounds check for inner classes of generic outer classes

#KT-61068 Fixed
#KT-35566
This commit is contained in:
Kirill Rakhman
2023-09-06 13:21:33 +02:00
committed by Space Team
parent 5e49b472f8
commit b41e5abcfa
8 changed files with 119 additions and 5 deletions
@@ -13743,6 +13743,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
runTest("compiler/testData/diagnostics/tests/generics/innerClasses/importedInner.kt");
}
@Test
@TestMetadata("innerClassGenericBounds.kt")
public void testInnerClassGenericBounds() throws Exception {
runTest("compiler/testData/diagnostics/tests/generics/innerClasses/innerClassGenericBounds.kt");
}
@Test
@TestMetadata("innerSuperCall.kt")
public void testInnerSuperCall() throws Exception {
@@ -13743,6 +13743,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
runTest("compiler/testData/diagnostics/tests/generics/innerClasses/importedInner.kt");
}
@Test
@TestMetadata("innerClassGenericBounds.kt")
public void testInnerClassGenericBounds() throws Exception {
runTest("compiler/testData/diagnostics/tests/generics/innerClasses/innerClassGenericBounds.kt");
}
@Test
@TestMetadata("innerSuperCall.kt")
public void testInnerSuperCall() throws Exception {
@@ -13743,6 +13743,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
runTest("compiler/testData/diagnostics/tests/generics/innerClasses/importedInner.kt");
}
@Test
@TestMetadata("innerClassGenericBounds.kt")
public void testInnerClassGenericBounds() throws Exception {
runTest("compiler/testData/diagnostics/tests/generics/innerClasses/innerClassGenericBounds.kt");
}
@Test
@TestMetadata("innerSuperCall.kt")
public void testInnerSuperCall() throws Exception {
@@ -13749,6 +13749,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
runTest("compiler/testData/diagnostics/tests/generics/innerClasses/importedInner.kt");
}
@Test
@TestMetadata("innerClassGenericBounds.kt")
public void testInnerClassGenericBounds() throws Exception {
runTest("compiler/testData/diagnostics/tests/generics/innerClasses/innerClassGenericBounds.kt");
}
@Test
@TestMetadata("innerSuperCall.kt")
public void testInnerSuperCall() throws Exception {
@@ -219,13 +219,15 @@ fun ConeClassLikeType.fullyExpandedTypeWithSource(
useSiteSession: FirSession,
): ConeClassLikeType? {
val typeRefAndSourcesForArguments = extractArgumentsTypeRefAndSource(typeRef) ?: return null
// Avoid issues with nested type aliases and context receivers on function types as source information isn't returned.
if (typeRefAndSourcesForArguments.size != typeArguments.size) return null
// Add source information to arguments of non-expanded type, which is preserved during expansion.
val typeArguments =
typeArguments.zip(typeRefAndSourcesForArguments) { projection, source -> projection.withSource(source) }
.toTypedArray()
val typeArguments = typeArguments.mapIndexed { i, projection ->
// typeRefAndSourcesForArguments can have fewer elements than there are type arguments
// because in FIR, inner types of generic outer types have the generic arguments of the outer type added to the end of their list
// of type arguments but there is no source for them.
val source = typeRefAndSourcesForArguments.elementAtOrNull(i) ?: return@mapIndexed projection
projection.withSource(source)
}.toTypedArray()
return withArguments(typeArguments).fullyExpandedType(useSiteSession)
}
@@ -0,0 +1,41 @@
// ISSUE: KT-61068, KT-35566
// FILE: generic.kt
package generic
interface Foo
open class SuperOuter<T> {
open inner class SuperInner<D : Foo>(database: D)
}
class SubOuter : SuperOuter<Unit>() {
inner class SubInner(database: Any?) : SuperInner<<!UPPER_BOUND_VIOLATED!>Any?<!>>(<!ARGUMENT_TYPE_MISMATCH!>database<!>)
}
// FILE: nongeneric.kt
package nongeneric
interface Foo
open class SuperOuter {
open inner class SuperInner<D : Foo>(database: D)
}
class SubOuter : SuperOuter() {
inner class SubInner(database: Any?) : SuperInner<<!UPPER_BOUND_VIOLATED!>Any?<!>>(<!ARGUMENT_TYPE_MISMATCH!>database<!>)
}
// FILE: kt35566.kt
package kt35566
open class Case1<K : Number> {
open inner class Case1_1<L> : Case1<Int>() where L : CharSequence {
var x: L? = null
inner class Case1_2<M>(m: M) : Case1<K>.Case1_1<<!UPPER_BOUND_VIOLATED!>M<!>>() where M : Map<K, L> {
init {
x = m
}
}
}
}
@@ -0,0 +1,41 @@
// ISSUE: KT-61068, KT-35566
// FILE: generic.kt
package generic
interface Foo
open class SuperOuter<T> {
open inner class SuperInner<D : Foo>(database: D)
}
class SubOuter : SuperOuter<Unit>() {
inner class SubInner(database: Any?) : SuperInner<Any?>(database)
}
// FILE: nongeneric.kt
package nongeneric
interface Foo
open class SuperOuter {
open inner class SuperInner<D : Foo>(database: D)
}
class SubOuter : SuperOuter() {
inner class SubInner(database: Any?) : SuperInner<<!UPPER_BOUND_VIOLATED!>Any?<!>>(database)
}
// FILE: kt35566.kt
package kt35566
open class Case1<K : Number> {
open inner class Case1_1<L> : Case1<Int>() where L : CharSequence {
var x: L? = null
inner class Case1_2<M>(m: M) : Case1<K>.Case1_1<M>() where M : Map<K, L> {
init {
x = m
}
}
}
}
@@ -13749,6 +13749,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/generics/innerClasses/importedInner.kt");
}
@Test
@TestMetadata("innerClassGenericBounds.kt")
public void testInnerClassGenericBounds() throws Exception {
runTest("compiler/testData/diagnostics/tests/generics/innerClasses/innerClassGenericBounds.kt");
}
@Test
@TestMetadata("innerSuperCall.kt")
public void testInnerSuperCall() throws Exception {