diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 7e58f9a1841..671d156855c 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -15343,12 +15343,48 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_28.kt"); } + @Test + @TestMetadata("kt45461_29.kt") + public void testKt45461_29() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_29.kt"); + } + @Test @TestMetadata("kt45461_3.kt") public void testKt45461_3() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_3.kt"); } + @Test + @TestMetadata("kt45461_30.kt") + public void testKt45461_30() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_30.kt"); + } + + @Test + @TestMetadata("kt45461_31.kt") + public void testKt45461_31() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_31.kt"); + } + + @Test + @TestMetadata("kt45461_32.kt") + public void testKt45461_32() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_32.kt"); + } + + @Test + @TestMetadata("kt45461_33.kt") + public void testKt45461_33() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_33.kt"); + } + + @Test + @TestMetadata("kt45461_34.kt") + public void testKt45461_34() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_34.kt"); + } + @Test @TestMetadata("kt45461_4.kt") public void testKt45461_4() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index ae1b31204ca..e2519c02be6 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -15343,12 +15343,48 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_28.kt"); } + @Test + @TestMetadata("kt45461_29.kt") + public void testKt45461_29() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_29.kt"); + } + @Test @TestMetadata("kt45461_3.kt") public void testKt45461_3() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_3.kt"); } + @Test + @TestMetadata("kt45461_30.kt") + public void testKt45461_30() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_30.kt"); + } + + @Test + @TestMetadata("kt45461_31.kt") + public void testKt45461_31() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_31.kt"); + } + + @Test + @TestMetadata("kt45461_32.kt") + public void testKt45461_32() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_32.kt"); + } + + @Test + @TestMetadata("kt45461_33.kt") + public void testKt45461_33() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_33.kt"); + } + + @Test + @TestMetadata("kt45461_34.kt") + public void testKt45461_34() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_34.kt"); + } + @Test @TestMetadata("kt45461_4.kt") public void testKt45461_4() throws Exception { diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt index 257849a7e35..d7136f7dc8d 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.name.StandardClassIds +import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator.commonSuperType import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeRefiner import org.jetbrains.kotlin.types.TypeCheckerState @@ -502,8 +503,8 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo this else { var functionalSupertype: KotlinTypeMarker? = null - simpleType.anySuperTypeConstructor { typeConstructor -> - simpleType.fastCorrespondingSupertypes(typeConstructor)?.any { superType -> + simpleType.anySuperTypeConstructor { type -> + simpleType.fastCorrespondingSupertypes(type.typeConstructor())?.any { superType -> val isFunctional = superType.cast().isBuiltinFunctionalType(session) if (isFunctional) functionalSupertype = superType diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt index b8fe97e4185..0b47d97e587 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt @@ -631,7 +631,8 @@ internal fun captureFromTypeParameterUpperBoundIfNeeded( private fun ConeKotlinType.hasSupertypeWithGivenClassId(classId: ClassId, context: TypeSystemCommonSuperTypesContext): Boolean { return with(context) { anySuperTypeConstructor { - it is ConeClassLikeLookupTag && it.classId == classId + val typeConstructor = it.typeConstructor() + typeConstructor is ConeClassLikeLookupTag && typeConstructor.classId == classId } } } diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/intersect.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/intersect.kt index 9224ad1ebce..4b92674c263 100644 --- a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/intersect.kt +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/intersect.kt @@ -38,10 +38,10 @@ fun test() { build2 { emit(1) - intersect(this@build.getIn(), getIn()) - intersect(getIn(), Test.foo(this@build.getIn())) - intersect(Test.foo(this@build.getIn()), Test.foo(getIn())) - intersect(Test.foo(getIn()), this@build.getIn()) + intersect(this@build.getIn(), getIn()) + intersect(getIn(), Test.foo(this@build.getIn())) + intersect(Test.foo(this@build.getIn()), Test.foo(getIn())) + intersect(Test.foo(getIn()), this@build.getIn()) "" } "" diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_29.fir.kt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_29.fir.kt new file mode 100644 index 00000000000..98674519815 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_29.fir.kt @@ -0,0 +1,15 @@ +class Foo + +class Bar { + fun takeFoo(foo: Foo) {} +} + +class Inv

+ +interface A +interface B + +fun > main() { + val foo = Foo() + Bar>().takeFoo(foo) // error in 1.3.72, no error in 1.4.31 +} diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_29.kt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_29.kt new file mode 100644 index 00000000000..98674519815 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_29.kt @@ -0,0 +1,15 @@ +class Foo + +class Bar { + fun takeFoo(foo: Foo) {} +} + +class Inv

+ +interface A +interface B + +fun > main() { + val foo = Foo() + Bar>().takeFoo(foo) // error in 1.3.72, no error in 1.4.31 +} diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_29.txt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_29.txt new file mode 100644 index 00000000000..cc53a5edf9c --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_29.txt @@ -0,0 +1,37 @@ +package + +public fun > main(): kotlin.Unit + +public interface A { + 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 { + 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 { + public constructor Bar() + 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 takeFoo(/*0*/ foo: Foo): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Foo { + public constructor Foo() + 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 Inv { + public constructor Inv() + 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 +} diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_30.fir.kt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_30.fir.kt new file mode 100644 index 00000000000..7437993de9d --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_30.fir.kt @@ -0,0 +1,15 @@ +class Foo + +class Bar { + fun takeFoo(foo: Foo) {} +} + +class Out + +interface A +interface B : A + +fun >> main() { + val foo = Foo() + Bar>>().takeFoo(foo) // error in 1.3.72, no error in 1.4.31 +} diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_30.kt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_30.kt new file mode 100644 index 00000000000..7437993de9d --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_30.kt @@ -0,0 +1,15 @@ +class Foo + +class Bar { + fun takeFoo(foo: Foo) {} +} + +class Out + +interface A +interface B : A + +fun >> main() { + val foo = Foo() + Bar>>().takeFoo(foo) // error in 1.3.72, no error in 1.4.31 +} diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_30.txt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_30.txt new file mode 100644 index 00000000000..e7e5408e887 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_30.txt @@ -0,0 +1,37 @@ +package + +public fun >> main(): kotlin.Unit + +public interface A { + 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 : A { + 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 { + public constructor Bar() + 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 takeFoo(/*0*/ foo: Foo): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Foo { + public constructor Foo() + 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 { + public constructor Out() + 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 +} diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_31.fir.kt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_31.fir.kt new file mode 100644 index 00000000000..24364ceab0b --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_31.fir.kt @@ -0,0 +1,15 @@ +class Foo + +class Bar { + fun takeFoo(foo: Foo) {} +} + +class Out + +interface A +interface B : A + +fun >> main() { + val foo = Foo() + Bar>().takeFoo(foo) // error in 1.3.72, no error in 1.4.31 +} diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_31.kt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_31.kt new file mode 100644 index 00000000000..24364ceab0b --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_31.kt @@ -0,0 +1,15 @@ +class Foo + +class Bar { + fun takeFoo(foo: Foo) {} +} + +class Out + +interface A +interface B : A + +fun >> main() { + val foo = Foo() + Bar>().takeFoo(foo) // error in 1.3.72, no error in 1.4.31 +} diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_31.txt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_31.txt new file mode 100644 index 00000000000..89bebb08337 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_31.txt @@ -0,0 +1,37 @@ +package + +public fun >> main(): kotlin.Unit + +public interface A { + 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 : A { + 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 { + public constructor Bar() + 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 takeFoo(/*0*/ foo: Foo): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Foo { + public constructor Foo() + 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 { + public constructor Out() + 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 +} diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_32.fir.kt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_32.fir.kt new file mode 100644 index 00000000000..a1c46761b80 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_32.fir.kt @@ -0,0 +1,16 @@ +class Foo + +class Bar { + fun takeFoo(foo: Foo) {} +} + +class Out + +interface A +interface B : A +interface C : A + +fun > main() { + val foo = Foo() + Bar>().takeFoo(foo) // error in 1.3.72, no error in 1.4.31 +} diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_32.kt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_32.kt new file mode 100644 index 00000000000..a1c46761b80 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_32.kt @@ -0,0 +1,16 @@ +class Foo + +class Bar { + fun takeFoo(foo: Foo) {} +} + +class Out + +interface A +interface B : A +interface C : A + +fun > main() { + val foo = Foo() + Bar>().takeFoo(foo) // error in 1.3.72, no error in 1.4.31 +} diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_32.txt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_32.txt new file mode 100644 index 00000000000..b8e617eba89 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_32.txt @@ -0,0 +1,43 @@ +package + +public fun > main(): kotlin.Unit + +public interface A { + 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 : A { + 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 { + public constructor Bar() + 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 takeFoo(/*0*/ foo: Foo): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface C : A { + 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 { + public constructor Foo() + 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 { + public constructor Out() + 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 +} diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_33.fir.kt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_33.fir.kt new file mode 100644 index 00000000000..0af0f745e3f --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_33.fir.kt @@ -0,0 +1,16 @@ +class Foo + +class Bar { + fun takeFoo(foo: Foo) {} +} + +class Out + +interface A +class B : A +class C : A + +fun Out> main() { + val foo = Foo() + Bar>().takeFoo(foo) // error in 1.3.72, no error in 1.4.31 +} diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_33.kt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_33.kt new file mode 100644 index 00000000000..0af0f745e3f --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_33.kt @@ -0,0 +1,16 @@ +class Foo + +class Bar { + fun takeFoo(foo: Foo) {} +} + +class Out + +interface A +class B : A +class C : A + +fun Out> main() { + val foo = Foo() + Bar>().takeFoo(foo) // error in 1.3.72, no error in 1.4.31 +} diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_33.txt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_33.txt new file mode 100644 index 00000000000..1dc9cd8b415 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_33.txt @@ -0,0 +1,45 @@ +package + +public fun > main(): kotlin.Unit + +public interface A { + 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 B : A { + public constructor B() + 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 { + public constructor Bar() + 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 takeFoo(/*0*/ foo: Foo): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class C : A { + public constructor C() + 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 { + public constructor Foo() + 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 { + public constructor Out() + 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 +} diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_34.fir.kt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_34.fir.kt new file mode 100644 index 00000000000..a3dbc03234e --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_34.fir.kt @@ -0,0 +1,15 @@ +class Foo + +class Bar { + fun takeFoo(foo: Foo) {} +} + +class Out + +interface A +class B : A + +fun >> main() { + val foo = Foo() + Bar>().takeFoo(foo) // error in 1.3.72, no error in 1.4.31 +} diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_34.kt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_34.kt new file mode 100644 index 00000000000..a3dbc03234e --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_34.kt @@ -0,0 +1,15 @@ +class Foo + +class Bar { + fun takeFoo(foo: Foo) {} +} + +class Out + +interface A +class B : A + +fun >> main() { + val foo = Foo() + Bar>().takeFoo(foo) // error in 1.3.72, no error in 1.4.31 +} diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_34.txt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_34.txt new file mode 100644 index 00000000000..27896aa94f5 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_34.txt @@ -0,0 +1,38 @@ +package + +public fun >> main(): kotlin.Unit + +public interface A { + 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 B : A { + public constructor B() + 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 { + public constructor Bar() + 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 takeFoo(/*0*/ foo: Foo): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Foo { + public constructor Foo() + 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 { + public constructor Out() + 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 +} diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt51016.fir.kt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt51016.fir.kt deleted file mode 100644 index 57e9d0eab0c..00000000000 --- a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt51016.fir.kt +++ /dev/null @@ -1,11 +0,0 @@ -interface A -interface B : A - -fun , S : T?> B.foo(t: T) {} -fun , S : T?> A.foo(other: A) {} - -interface C : B, Comparable> - -fun test(x: C) { - x.foo(x) // OVERLOAD_RESOLUTION_AMBIGUITY, shoub be OK -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt51016.kt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt51016.kt index d60d080cff1..90645a094d3 100644 --- a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt51016.kt +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt51016.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL interface A interface B : A @@ -7,5 +8,5 @@ fun , S : T?> A.foo(other: A) {} interface C : B, Comparable> fun test(x: C) { - x.foo(x) // OVERLOAD_RESOLUTION_AMBIGUITY, shoub be OK + x.foo(x) // OVERLOAD_RESOLUTION_AMBIGUITY, shoub be OK } diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/callableReferences.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/callableReferences.kt index 96b52e45bb3..ba831efc6ba 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/callableReferences.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/callableReferences.kt @@ -53,5 +53,5 @@ fun main() { select(id(::foo5), id { x: A -> }, id { x: B -> }, id { it }) - val x2: (Int) -> Unit = selectNumber(id(")!>::foo6), id { x -> & Number}")!>x }, id { & Number}")!>it }) + val x2: (Int) -> Unit = selectNumber(id(::foo6), id { x -> & Number}")!>x }, id { & Number}")!>it }) } diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index bbce687e669..2b50b20167f 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -15349,12 +15349,48 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_28.kt"); } + @Test + @TestMetadata("kt45461_29.kt") + public void testKt45461_29() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_29.kt"); + } + @Test @TestMetadata("kt45461_3.kt") public void testKt45461_3() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_3.kt"); } + @Test + @TestMetadata("kt45461_30.kt") + public void testKt45461_30() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_30.kt"); + } + + @Test + @TestMetadata("kt45461_31.kt") + public void testKt45461_31() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_31.kt"); + } + + @Test + @TestMetadata("kt45461_32.kt") + public void testKt45461_32() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_32.kt"); + } + + @Test + @TestMetadata("kt45461_33.kt") + public void testKt45461_33() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_33.kt"); + } + + @Test + @TestMetadata("kt45461_34.kt") + public void testKt45461_34() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_34.kt"); + } + @Test @TestMetadata("kt45461_4.kt") public void testKt45461_4() throws Exception { diff --git a/core/compiler.common/src/org/jetbrains/kotlin/types/AbstractTypeChecker.kt b/core/compiler.common/src/org/jetbrains/kotlin/types/AbstractTypeChecker.kt index 0c113d96fcf..170013ec5a6 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/types/AbstractTypeChecker.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/types/AbstractTypeChecker.kt @@ -205,6 +205,16 @@ object AbstractTypeChecker { return isSubtypeOf(context.newTypeCheckerState(true, stubTypesEqualToAnything), subType, superType) } + fun areRelatedBySubtyping( + context: TypeCheckerProviderContext, + subType: KotlinTypeMarker, + superType: KotlinTypeMarker, + stubTypesEqualToAnything: Boolean = true + ): Boolean { + val typeCheckerContext = context.newTypeCheckerState(true, stubTypesEqualToAnything) + return isSubtypeOf(typeCheckerContext, subType, superType) || isSubtypeOf(typeCheckerContext, superType, subType) + } + fun isSubtypeOfClass( state: TypeCheckerState, typeConstructor: TypeConstructorMarker, diff --git a/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt b/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt index f6bd55ac53f..a651bd1723d 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt @@ -105,11 +105,11 @@ interface TypeCheckerProviderContext { */ interface TypeSystemCommonSuperTypesContext : TypeSystemContext, TypeSystemTypeFactoryContext, TypeCheckerProviderContext { - fun KotlinTypeMarker.anySuperTypeConstructor(predicate: (TypeConstructorMarker) -> Boolean) = + fun KotlinTypeMarker.anySuperTypeConstructor(predicate: (SimpleTypeMarker) -> Boolean) = newTypeCheckerState(errorTypesEqualToAnything = false, stubTypesEqualToAnything = true) .anySupertype( lowerBoundIfFlexible(), - { predicate(it.typeConstructor()) }, + { predicate(it) }, { TypeCheckerState.SupertypesPolicy.LowerIfFlexible } ) @@ -325,13 +325,13 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui for (i in 0 until types.size) { val firstType = types[i] - if (!firstType.typeConstructor().mayCauseEmptyIntersection()) continue + if (!firstType.mayCauseEmptyIntersection()) continue val firstSubstitutedType by lazy { firstType.eraseContainingTypeParameters() } for (j in i + 1 until types.size) { val secondType = types[j] - if (!secondType.typeConstructor().mayCauseEmptyIntersection()) continue + if (!secondType.mayCauseEmptyIntersection()) continue val secondSubstitutedType = secondType.eraseContainingTypeParameters() @@ -343,6 +343,30 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui return EmptyIntersectionTypeKind.NOT_EMPTY_INTERSECTION } + private fun canHaveCommonSubtypeWithInterface(firstType: KotlinTypeMarker, secondType: KotlinTypeMarker): Boolean { + require(firstType.typeConstructor().isInterface() || secondType.typeConstructor().isInterface()) { + "One of the passed type should be an interface" + } + @Suppress("NAME_SHADOWING") + val firstType = firstType.withNullability(false) + + @Suppress("NAME_SHADOWING") + val secondType = secondType.withNullability(false) + + // interface A + // interface B: A + // interface C: A + // B & C can't have common subtype due to having incompatible supertypes: A and A + val haveIncompatibleSupertypes = firstType.anySuperTypeConstructor { superTypeOfFirst -> + secondType.anySuperTypeConstructor { superTypeOfSecond -> + superTypeOfFirst.typeConstructor() == superTypeOfSecond.typeConstructor() + && !AbstractTypeChecker.equalTypes(this, superTypeOfFirst, superTypeOfSecond) + } + } + + return !haveIncompatibleSupertypes + } + private fun canHaveCommonSubtype(first: KotlinTypeMarker, second: KotlinTypeMarker): Boolean { fun extractIntersectionComponentsIfNeeded(type: KotlinTypeMarker) = if (type.typeConstructor() is IntersectionTypeConstructorMarker) { @@ -350,26 +374,28 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui } else listOf(type) val expandedTypes = extractIntersectionComponentsIfNeeded(first) + extractIntersectionComponentsIfNeeded(second) - val typeCheckerState = newTypeCheckerState(errorTypesEqualToAnything = true, stubTypesEqualToAnything = true) - for (i in 0 until expandedTypes.size) { + for (i in expandedTypes.indices) { val firstType = expandedTypes[i] val firstTypeConstructor = firstType.typeConstructor() - if (!firstTypeConstructor.mayCauseEmptyIntersection()) + if (!firstType.mayCauseEmptyIntersection()) continue for (j in i + 1 until expandedTypes.size) { val secondType = expandedTypes[j] val secondTypeConstructor = secondType.typeConstructor() - if (!secondTypeConstructor.mayCauseEmptyIntersection()) + if (!secondType.mayCauseEmptyIntersection()) continue if (areEqualTypeConstructors(firstTypeConstructor, secondTypeConstructor) && secondTypeConstructor.parametersCount() == 0) continue + if (AbstractTypeChecker.areRelatedBySubtyping(this, firstType, secondType)) + continue + val superTypeByFirstConstructor = AbstractTypeChecker.findCorrespondingSupertypes( typeCheckerState, firstType.lowerBoundIfFlexible(), secondTypeConstructor ).singleOrNull() @@ -377,15 +403,20 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui typeCheckerState, secondType.lowerBoundIfFlexible(), firstTypeConstructor ).singleOrNull() - if (superTypeByFirstConstructor == null && superTypeBySecondConstructor == null) + val anyInference = firstTypeConstructor.isInterface() || secondTypeConstructor.isInterface() + + // Two classes can't have a common subtype if neither is a subtype of another + if (superTypeByFirstConstructor == null && superTypeBySecondConstructor == null && !anyInference) + return false + + if (anyInference && !canHaveCommonSubtypeWithInterface(firstType, secondType)) return false if (superTypeByFirstConstructor == null || superTypeBySecondConstructor == null) continue // first or second is actually subtype of another - if (!checkArgumentsOfTypesToBeAbleToHaveCommonSubtype(superTypeByFirstConstructor, superTypeBySecondConstructor)) { + if (!checkArgumentsOfTypesToBeAbleToHaveCommonSubtype(superTypeByFirstConstructor, superTypeBySecondConstructor)) return false - } } } @@ -400,8 +431,19 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui private fun computeEffectiveVariance(parameter: TypeParameterMarker, argument: TypeArgumentMarker): TypeVariance? = AbstractTypeChecker.effectiveVariance(parameter.getVariance(), argument.getVariance()) - private fun TypeConstructorMarker.mayCauseEmptyIntersection(): Boolean = - (isClassTypeConstructor() || isTypeParameterTypeConstructor()) && !isInterface() && !isAnyConstructor() && !isNothingConstructor() + private fun KotlinTypeMarker.mayCauseEmptyIntersection(): Boolean { + val typeConstructor = typeConstructor() + + if (!typeConstructor.isClassTypeConstructor() && !typeConstructor.isTypeParameterTypeConstructor()) + return false + + // Even two interfaces may be an empty intersection type: + // interface Inv + // interface B : Inv + // `Inv & B` or `Inv & Inv` are empty + // So we don't filter out interfaces here + return !typeConstructor.isAnyConstructor() && !typeConstructor.isNothingConstructor() + } private fun areArgumentsOfSpecifiedVariances( firstType: KotlinTypeMarker, @@ -431,6 +473,9 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui fun isSubtypeOf(firstType: KotlinTypeMarker, secondType: KotlinTypeMarker) = AbstractTypeChecker.isSubtypeOf(this, firstType, secondType) + fun areEqualTypes(firstType: KotlinTypeMarker, secondType: KotlinTypeMarker) = + AbstractTypeChecker.equalTypes(this, firstType, secondType) + for ((i, argumentOfFirst) in firstType.getArguments().withIndex()) { @Suppress("NAME_SHADOWING") val argumentOfFirst = argumentOfFirst.uncaptureIfNeeded() @@ -444,31 +489,27 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui when { areArgumentsOfSpecifiedVariances(firstType, secondType, i, TypeVariance.INV, TypeVariance.INV) -> - return false + return areEqualTypes(argumentTypeOfFirst, argumentTypeOfSecond) areArgumentsOfSpecifiedVariances(firstType, secondType, i, TypeVariance.INV, TypeVariance.OUT) -> { - if (!isSubtypeOf(argumentTypeOfFirst, argumentTypeOfSecond)) { + if (!isSubtypeOf(argumentTypeOfFirst, argumentTypeOfSecond)) return false - } } areArgumentsOfSpecifiedVariances(firstType, secondType, i, TypeVariance.INV, TypeVariance.IN) -> { - if (!isSubtypeOf(argumentTypeOfSecond, argumentTypeOfFirst)) { + if (!isSubtypeOf(argumentTypeOfSecond, argumentTypeOfFirst)) return false - } } areArgumentsOfSpecifiedVariances(firstType, secondType, i, TypeVariance.IN, TypeVariance.OUT) -> { if (argumentTypeOfFirst.argumentsCount() == 0 && argumentTypeOfSecond.argumentsCount() == 0) { - if (!isSubtypeOf(argumentTypeOfFirst, argumentTypeOfSecond)) { + if (!isSubtypeOf(argumentTypeOfFirst, argumentTypeOfSecond)) return false - } } else if (!canHaveCommonSubtype(argumentTypeOfFirst, argumentTypeOfSecond)) { return false } } areArgumentsOfSpecifiedVariances(firstType, secondType, i, TypeVariance.OUT, TypeVariance.OUT) || areArgumentsOfSpecifiedVariances(firstType, secondType, i, TypeVariance.IN, TypeVariance.IN) -> { - if (!canHaveCommonSubtype(argumentTypeOfFirst, argumentTypeOfSecond)) { + if (!canHaveCommonSubtype(argumentTypeOfFirst, argumentTypeOfSecond)) return false - } } } }