[FE] Determine intersection type emptiness by looking at supertypes properly: substitute their type arguments

This commit is contained in:
Victor Petukhov
2022-04-26 20:13:56 +03:00
committed by teamcity
parent a0260292ec
commit 20a8e5d742
17 changed files with 315 additions and 17 deletions
@@ -15217,6 +15217,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/compatibilityResolveWhenVariableHasComplexIntersectionType.kt");
}
@Test
@TestMetadata("contravariance.kt")
public void testContravariance() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/contravariance.kt");
}
@Test
@TestMetadata("kt45461.kt")
public void testKt45461() throws Exception {
@@ -15510,6 +15516,18 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
public void testSelectFromCovariantAndContravariantTypes() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/selectFromCovariantAndContravariantTypes.kt");
}
@Test
@TestMetadata("substitutingSuperTypes.kt")
public void testSubstitutingSuperTypes() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/substitutingSuperTypes.kt");
}
@Test
@TestMetadata("substitutingSuperTypes2.kt")
public void testSubstitutingSuperTypes2() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/substitutingSuperTypes2.kt");
}
}
@Nested
@@ -15217,6 +15217,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/compatibilityResolveWhenVariableHasComplexIntersectionType.kt");
}
@Test
@TestMetadata("contravariance.kt")
public void testContravariance() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/contravariance.kt");
}
@Test
@TestMetadata("kt45461.kt")
public void testKt45461() throws Exception {
@@ -15510,6 +15516,18 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
public void testSelectFromCovariantAndContravariantTypes() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/selectFromCovariantAndContravariantTypes.kt");
}
@Test
@TestMetadata("substitutingSuperTypes.kt")
public void testSubstitutingSuperTypes() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/substitutingSuperTypes.kt");
}
@Test
@TestMetadata("substitutingSuperTypes2.kt")
public void testSubstitutingSuperTypes2() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/substitutingSuperTypes2.kt");
}
}
@Nested
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.types
import org.jetbrains.kotlin.fir.diagnostics.ConeIntermediateDiagnostic
import org.jetbrains.kotlin.fir.isPrimitiveNumberOrUnsignedNumberType
import org.jetbrains.kotlin.fir.resolve.createSubstitutionForSupertype
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
@@ -563,4 +564,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
override fun SimpleTypeMarker.createConstraintPartForLowerBoundAndFlexibleTypeVariable(): KotlinTypeMarker =
createFlexibleType(this.makeSimpleTypeDefinitelyNotNullOrNotNull(), this.withNullability(true))
override fun createSubstitutorForSuperTypes(baseType: KotlinTypeMarker): TypeSubstitutorMarker? =
if (baseType is ConeLookupTagBasedType) createSubstitutionForSupertype(baseType, session) else null
}
@@ -0,0 +1,9 @@
// WITH_STDLIB
fun expandMaskConditionsAndUpdateVariableNodes(validOffsets: Collection<Int>) {}
fun main(x: List<Int>, y: Int) {
<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>expandMaskConditionsAndUpdateVariableNodes<!>(
x.mapTo(mutableSetOf()) { y }
)
}
@@ -0,0 +1,9 @@
// WITH_STDLIB
fun expandMaskConditionsAndUpdateVariableNodes(validOffsets: Collection<Int>) {}
fun main(x: List<Int>, y: Int) {
<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION_WARNING!>expandMaskConditionsAndUpdateVariableNodes<!>(
x.mapTo(mutableSetOf()) { y }
)
}
@@ -0,0 +1,5 @@
package
public fun expandMaskConditionsAndUpdateVariableNodes(/*0*/ validOffsets: kotlin.collections.Collection<kotlin.Int>): kotlin.Unit
public fun main(/*0*/ x: kotlin.collections.List<kotlin.Int>, /*1*/ y: kotlin.Int): kotlin.Unit
@@ -0,0 +1,16 @@
class Foo<T>
class Bar<T> {
fun <S : T> takeFoo(foo: Foo<in S>) {}
}
class Out<out P>
interface A<K>
interface B<T> : A<T>
interface C<T> : A<T>
fun <K : C<Int>> main() {
val foo = Foo<K>()
Bar<B<String>>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
}
@@ -0,0 +1,16 @@
class Foo<T>
class Bar<T> {
fun <S : T> takeFoo(foo: Foo<in S>) {}
}
class Out<out P>
interface A<K>
interface B<T> : A<T>
interface C<T> : A<T>
fun <K : C<Int>> main() {
val foo = Foo<K>()
Bar<B<String>>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION_WARNING!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
}
@@ -0,0 +1,43 @@
package
public fun </*0*/ K : C<kotlin.Int>> main(): kotlin.Unit
public interface A</*0*/ K> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface B</*0*/ T> : A<T> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Bar</*0*/ T> {
public constructor Bar</*0*/ T>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final fun </*0*/ S : T> takeFoo(/*0*/ foo: Foo<in S>): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface C</*0*/ T> : A<T> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Foo</*0*/ T> {
public constructor Foo</*0*/ T>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Out</*0*/ out P> {
public constructor Out</*0*/ out P>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,18 @@
class Foo<T>
class Bar<T> {
fun <S : T> takeFoo(foo: Foo<in S>) {}
}
class Out<out P>
interface A<K>
interface B2<T> : A<T>
interface C2<T> : A<T>
interface B<T> : B2<T>
interface C<T> : C2<T>
fun <K : C<Int>> main() {
val foo = Foo<K>()
Bar<B<String>>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
}
@@ -0,0 +1,18 @@
class Foo<T>
class Bar<T> {
fun <S : T> takeFoo(foo: Foo<in S>) {}
}
class Out<out P>
interface A<K>
interface B2<T> : A<T>
interface C2<T> : A<T>
interface B<T> : B2<T>
interface C<T> : C2<T>
fun <K : C<Int>> main() {
val foo = Foo<K>()
Bar<B<String>>().<!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION_WARNING!>takeFoo<!>(foo) // error in 1.3.72, no error in 1.4.31
}
@@ -0,0 +1,55 @@
package
public fun </*0*/ K : C<kotlin.Int>> main(): kotlin.Unit
public interface A</*0*/ K> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface B</*0*/ T> : B2<T> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface B2</*0*/ T> : A<T> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Bar</*0*/ T> {
public constructor Bar</*0*/ T>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final fun </*0*/ S : T> takeFoo(/*0*/ foo: Foo<in S>): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface C</*0*/ T> : C2<T> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface C2</*0*/ T> : A<T> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Foo</*0*/ T> {
public constructor Foo</*0*/ T>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Out</*0*/ out P> {
public constructor Out</*0*/ out P>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -15223,6 +15223,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/compatibilityResolveWhenVariableHasComplexIntersectionType.kt");
}
@Test
@TestMetadata("contravariance.kt")
public void testContravariance() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/contravariance.kt");
}
@Test
@TestMetadata("kt45461.kt")
public void testKt45461() throws Exception {
@@ -15516,6 +15522,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
public void testSelectFromCovariantAndContravariantTypes() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/selectFromCovariantAndContravariantTypes.kt");
}
@Test
@TestMetadata("substitutingSuperTypes.kt")
public void testSubstitutingSuperTypes() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/substitutingSuperTypes.kt");
}
@Test
@TestMetadata("substitutingSuperTypes2.kt")
public void testSubstitutingSuperTypes2() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/substitutingSuperTypes2.kt");
}
}
@Nested