From 73be9d0a20fa693d92380a8c848233dd5cc00625 Mon Sep 17 00:00:00 2001 From: Victor Petukhov Date: Wed, 27 Apr 2022 10:30:09 +0300 Subject: [PATCH] [FE] Don't check intersection emptiness if there were lower constraints --- .../kotlin/fir/resolve/calls/ResolutionStages.kt | 6 +++++- .../kotlin/resolve/calls/components/ResolutionParts.kt | 6 +++++- .../emptyIntersectionTypes/contravariance.fir.kt | 9 --------- .../inference/emptyIntersectionTypes/contravariance.kt | 3 ++- .../jetbrains/kotlin/types/EmptyIntersectionTypeKind.kt | 3 ++- 5 files changed, 14 insertions(+), 13 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/contravariance.fir.kt diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt index b3e9adf12a0..1b1c5661e7d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt @@ -583,7 +583,11 @@ internal object CheckIncompatibleTypeVariableUpperBounds : ResolutionStage() { for (variableWithConstraints in candidate.system.notFixedTypeVariables.values) { val upperTypes = variableWithConstraints.constraints.extractUpperTypesToCheckIntersectionEmptiness() - if (upperTypes.computeEmptyIntersectionTypeKind().isDefinitelyEmpty()) { + // TODO: consider reporting errors on bounded type variables by incompatible types but with other lower constraints + if ( + variableWithConstraints.constraints.none { it.kind.isLower() } + && upperTypes.computeEmptyIntersectionTypeKind().isDefinitelyEmpty() + ) { sink.yieldDiagnostic( @Suppress("UNCHECKED_CAST") InferredEmptyIntersectionDiagnostic( diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt index 4e0dfe4e6dd..b8bd894678a 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt @@ -892,7 +892,11 @@ internal object CheckIncompatibleTypeVariableUpperBounds : ResolutionPart() { for (variableWithConstraints in getSystem().getBuilder().currentStorage().notFixedTypeVariables.values) { val upperTypes = variableWithConstraints.constraints.extractUpperTypesToCheckIntersectionEmptiness() - if (upperTypes.computeEmptyIntersectionTypeKind().isDefinitelyEmpty()) { + // TODO: consider reporting errors on bounded type variables by incompatible types but with other lower constraints + if ( + variableWithConstraints.constraints.none { it.kind.isLower() } + && upperTypes.computeEmptyIntersectionTypeKind().isDefinitelyEmpty() + ) { val isInferredEmptyIntersectionForbidden = callComponents.languageVersionSettings.supportsFeature(LanguageFeature.ForbidInferringTypeVariablesIntoEmptyIntersection) diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/contravariance.fir.kt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/contravariance.fir.kt deleted file mode 100644 index e297233678f..00000000000 --- a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/contravariance.fir.kt +++ /dev/null @@ -1,9 +0,0 @@ -// WITH_STDLIB - -fun expandMaskConditionsAndUpdateVariableNodes(validOffsets: Collection) {} - -fun main(x: List, y: Int) { - expandMaskConditionsAndUpdateVariableNodes( - x.mapTo(mutableSetOf()) { y } - ) -} diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/contravariance.kt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/contravariance.kt index 88f380b2832..73346f7d1e2 100644 --- a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/contravariance.kt +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/contravariance.kt @@ -1,9 +1,10 @@ +// FIR_IDENTICAL // WITH_STDLIB fun expandMaskConditionsAndUpdateVariableNodes(validOffsets: Collection) {} fun main(x: List, y: Int) { - expandMaskConditionsAndUpdateVariableNodes( + expandMaskConditionsAndUpdateVariableNodes( x.mapTo(mutableSetOf()) { y } ) } diff --git a/core/compiler.common/src/org/jetbrains/kotlin/types/EmptyIntersectionTypeKind.kt b/core/compiler.common/src/org/jetbrains/kotlin/types/EmptyIntersectionTypeKind.kt index 9e65ac4d384..e55382668b8 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/types/EmptyIntersectionTypeKind.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/types/EmptyIntersectionTypeKind.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.types -enum class EmptyIntersectionTypeKind { NOT_EMPTY_INTERSECTION, MULTIPLE_CLASSES } // TODO: add `SINGLE_FINAL_CLASS` later +// TODO: add `SINGLE_FINAL_CLASS` later to report warnings +enum class EmptyIntersectionTypeKind { NOT_EMPTY_INTERSECTION, MULTIPLE_CLASSES } fun EmptyIntersectionTypeKind.isDefinitelyEmpty(): Boolean = this == EmptyIntersectionTypeKind.MULTIPLE_CLASSES