From 710659324cc351a812bc44cd74e328bddce33a88 Mon Sep 17 00:00:00 2001 From: Pavel Kirpichenkov Date: Mon, 20 Jul 2020 14:05:58 +0300 Subject: [PATCH] [NI] Fix common supertype of types with error supertypes Enable check for error supertypes during CST calculation in classic type system context. Cyclic upper bound + known type parameters of superclasses may create non-error types with error supertypes. Such types don't have common constructors with other normal types and cause assertion errors during intersection. ^KT-36951 Fixed --- ...irOldFrontendDiagnosticsTestGenerated.java | 5 ++++ ...endDiagnosticsTestWithStdlibGenerated.java | 5 ++++ ...SuperTypeOfTypesWithErrorSupertypes.fir.kt | 15 +++++++++++ ...mmonSuperTypeOfTypesWithErrorSupertypes.kt | 15 +++++++++++ ...monSuperTypeOfTypesWithErrorSupertypes.txt | 19 ++++++++++++++ .../testsWithStdLib/inference/kt36951.fir.kt | 8 ++++++ .../testsWithStdLib/inference/kt36951.kt | 8 ++++++ .../testsWithStdLib/inference/kt36951.txt | 26 +++++++++++++++++++ .../checkers/DiagnosticsTestGenerated.java | 5 ++++ .../DiagnosticsTestWithStdLibGenerated.java | 5 ++++ ...ticsTestWithStdLibUsingJavacGenerated.java | 5 ++++ .../DiagnosticsUsingJavacTestGenerated.java | 5 ++++ .../types/checker/ClassicTypeSystemContext.kt | 8 +++--- .../kotlin/types/model/TypeSystemContext.kt | 3 +-- 14 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/inference/commonSuperTypeOfTypesWithErrorSupertypes.fir.kt create mode 100644 compiler/testData/diagnostics/tests/inference/commonSuperTypeOfTypesWithErrorSupertypes.kt create mode 100644 compiler/testData/diagnostics/tests/inference/commonSuperTypeOfTypesWithErrorSupertypes.txt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/inference/kt36951.fir.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/inference/kt36951.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/inference/kt36951.txt diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java index d0dda40e6c1..af52e823f4e 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java @@ -10109,6 +10109,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte runTest("compiler/testData/diagnostics/tests/inference/commonSuperTypeOfErrorTypes.kt"); } + @TestMetadata("commonSuperTypeOfTypesWithErrorSupertypes.kt") + public void testCommonSuperTypeOfTypesWithErrorSupertypes() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/commonSuperTypeOfTypesWithErrorSupertypes.kt"); + } + @TestMetadata("compatibilityResolveWhenVariableHasComplexIntersectionType.kt") public void testCompatibilityResolveWhenVariableHasComplexIntersectionType() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/compatibilityResolveWhenVariableHasComplexIntersectionType.kt"); diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestWithStdlibGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestWithStdlibGenerated.java index f6b0470a4c3..80d4cf0b94e 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestWithStdlibGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestWithStdlibGenerated.java @@ -2910,6 +2910,11 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt36249.kt"); } + @TestMetadata("kt36951.kt") + public void testKt36951() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt36951.kt"); + } + @TestMetadata("kt37627.kt") public void testKt37627() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt37627.kt"); diff --git a/compiler/testData/diagnostics/tests/inference/commonSuperTypeOfTypesWithErrorSupertypes.fir.kt b/compiler/testData/diagnostics/tests/inference/commonSuperTypeOfTypesWithErrorSupertypes.fir.kt new file mode 100644 index 00000000000..2a170857f27 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/commonSuperTypeOfTypesWithErrorSupertypes.fir.kt @@ -0,0 +1,15 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER + +interface Foo { + fun getSum(): F = TODO() +} + +fun select(vararg args: S): S = TODO() + +class Bar : Foo { + val v = select( + getSum(), + 42 + ) +} diff --git a/compiler/testData/diagnostics/tests/inference/commonSuperTypeOfTypesWithErrorSupertypes.kt b/compiler/testData/diagnostics/tests/inference/commonSuperTypeOfTypesWithErrorSupertypes.kt new file mode 100644 index 00000000000..12e38db8ee4 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/commonSuperTypeOfTypesWithErrorSupertypes.kt @@ -0,0 +1,15 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER + +interface Foo { + fun getSum(): F = TODO() +} + +fun select(vararg args: S): S = TODO() + +class BarB> : Foo { + val v = select( + getSum(), + 42 + ) +} diff --git a/compiler/testData/diagnostics/tests/inference/commonSuperTypeOfTypesWithErrorSupertypes.txt b/compiler/testData/diagnostics/tests/inference/commonSuperTypeOfTypesWithErrorSupertypes.txt new file mode 100644 index 00000000000..57f5d5250f2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/commonSuperTypeOfTypesWithErrorSupertypes.txt @@ -0,0 +1,19 @@ +package + +public fun select(/*0*/ vararg args: S /*kotlin.Array*/): S + +public final class Bar : Foo { + public constructor Bar() + public final val v: [ERROR : from type constructor([ERROR : Cyclic upper bounds])] + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun getSum(): B + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface Foo { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open fun getSum(): F + 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/testsWithStdLib/inference/kt36951.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/kt36951.fir.kt new file mode 100644 index 00000000000..35c35da17b4 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/kt36951.fir.kt @@ -0,0 +1,8 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER + +class Base : HashSet() { + fun foo() { + super.remove("") + } +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/kt36951.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/kt36951.kt new file mode 100644 index 00000000000..76d082ad720 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/kt36951.kt @@ -0,0 +1,8 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER + +class BaseT> : HashSet() { + fun foo() { + super.remove("") + } +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/kt36951.txt b/compiler/testData/diagnostics/testsWithStdLib/inference/kt36951.txt new file mode 100644 index 00000000000..ae626f8ca0c --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/kt36951.txt @@ -0,0 +1,26 @@ +package + +public final class Base : kotlin.collections.HashSet /* = java.util.HashSet */ { + public constructor Base() + invisible_fake final override /*1*/ /*fake_override*/ var map: java.util.HashMap! + public open override /*1*/ /*fake_override*/ val size: kotlin.Int + public open override /*1*/ /*fake_override*/ fun add(/*0*/ element: T): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun addAll(/*0*/ elements: kotlin.collections.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun clear(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public open override /*1*/ /*fake_override*/ fun contains(/*0*/ element: T): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun containsAll(/*0*/ elements: kotlin.collections.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun iterator(): kotlin.collections.MutableIterator + invisible_fake open override /*1*/ /*fake_override*/ fun readObject(/*0*/ s: java.io.ObjectInputStream!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun remove(/*0*/ element: T): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun removeAll(/*0*/ elements: kotlin.collections.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun retainAll(/*0*/ elements: kotlin.collections.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun toArray(): kotlin.Array<(out) kotlin.Any!>! + public open override /*1*/ /*fake_override*/ fun toArray(/*0*/ a: kotlin.Array<(out) T!>!): kotlin.Array<(out) T!>! + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + invisible_fake open override /*1*/ /*fake_override*/ fun writeObject(/*0*/ s: java.io.ObjectOutputStream!): kotlin.Unit +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 2fa7a868e33..365814a5674 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -10116,6 +10116,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali runTest("compiler/testData/diagnostics/tests/inference/commonSuperTypeOfErrorTypes.kt"); } + @TestMetadata("commonSuperTypeOfTypesWithErrorSupertypes.kt") + public void testCommonSuperTypeOfTypesWithErrorSupertypes() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/commonSuperTypeOfTypesWithErrorSupertypes.kt"); + } + @TestMetadata("compatibilityResolveWhenVariableHasComplexIntersectionType.kt") public void testCompatibilityResolveWhenVariableHasComplexIntersectionType() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/compatibilityResolveWhenVariableHasComplexIntersectionType.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java index 560ef787a33..36bfd106d81 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java @@ -3060,6 +3060,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt36249.kt"); } + @TestMetadata("kt36951.kt") + public void testKt36951() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt36951.kt"); + } + @TestMetadata("kt37627.kt") public void testKt37627() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt37627.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java index d3d0ccfefc4..a57fdbee2e7 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java @@ -3060,6 +3060,11 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt36249.kt"); } + @TestMetadata("kt36951.kt") + public void testKt36951() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt36951.kt"); + } + @TestMetadata("kt37627.kt") public void testKt37627() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt37627.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 9cc48fc0a44..1ed2594938d 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -10111,6 +10111,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/inference/commonSuperTypeOfErrorTypes.kt"); } + @TestMetadata("commonSuperTypeOfTypesWithErrorSupertypes.kt") + public void testCommonSuperTypeOfTypesWithErrorSupertypes() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/commonSuperTypeOfTypesWithErrorSupertypes.kt"); + } + @TestMetadata("compatibilityResolveWhenVariableHasComplexIntersectionType.kt") public void testCompatibilityResolveWhenVariableHasComplexIntersectionType() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/compatibilityResolveWhenVariableHasComplexIntersectionType.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt index fb45b2c32f8..5a843347d43 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt @@ -33,7 +33,7 @@ import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSystemCommonBackendContext { - override val isErrorTypeAllowed: Boolean get() = true + override val isErrorTypeAllowed: Boolean get() = false override fun TypeConstructorMarker.isDenotable(): Boolean { require(this is TypeConstructor, this::errorMessage) @@ -62,7 +62,8 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy } override fun TypeConstructorMarker.toErrorType(): SimpleTypeMarker { - throw IllegalStateException("Should not be called") + require(this is TypeConstructor && ErrorUtils.isError(declarationDescriptor), this::errorMessage) + return ErrorUtils.createErrorType("from type constructor(${toString()})") } override fun KotlinTypeMarker.isUninferredParameter(): Boolean { @@ -529,7 +530,8 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy } override fun TypeConstructorMarker.isError(): Boolean { - throw IllegalStateException("Should not be called") + require(this is TypeConstructor, this::errorMessage) + return ErrorUtils.isError(declarationDescriptor) } override fun TypeConstructorMarker.getApproximatedIntegerLiteralType(): KotlinTypeMarker { diff --git a/core/type-system/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt b/core/type-system/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt index d64711b1103..4b43b045002 100644 --- a/core/type-system/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt +++ b/core/type-system/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt @@ -79,8 +79,7 @@ interface TypeCheckerProviderContext { interface TypeSystemCommonSuperTypesContext : TypeSystemContext, TypeSystemTypeFactoryContext, TypeCheckerProviderContext { /* - * If set in false then if there is an error type in input types list of `commonSuperType` it will be return - * That flag is needed for FIR where there are a problems with recursive class hierarchies + * If set in false then if there is an error supertype in input types list of `commonSuperType` it will be returned */ val isErrorTypeAllowed: Boolean