diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt54411.diag.txt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt54411.diag.txt new file mode 100644 index 00000000000..a1494b08584 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt54411.diag.txt @@ -0,0 +1,9 @@ +/kt54411.kt:5:68: warning: parameter 'createNewSegment' is never used +inline fun > AtomicRef.findSegmentAndMoveForward(createNewSegment: (prev: F?) -> F) = null + ^ +/kt54411.kt:14:14: warning: type argument for a type parameter F has possible incompatible upper bounds: Segment>, OneElementSegment? (final class and non-final class: Segment>, OneElementSegment) + tail.findSegmentAndMoveForward(::createSegment) + ^ +/kt54411.kt:18:31: warning: parameter 'prev' is never used +private fun createSegment(prev: OneElementSegment?) = OneElementSegment() + ^ diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt54411.kt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt54411.kt index ea7eb3b3ac6..1ffeb7ebe99 100644 --- a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt54411.kt +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt54411.kt @@ -1,4 +1,5 @@ // FIR_IDENTICAL +// !RENDER_DIAGNOSTICS_FULL_TEXT class AtomicRef(val value: T) inline fun > AtomicRef.findSegmentAndMoveForward(createNewSegment: (prev: F?) -> F) = null diff --git a/core/compiler.common/src/org/jetbrains/kotlin/resolve/checkers/EmptyIntersectionTypeChecker.kt b/core/compiler.common/src/org/jetbrains/kotlin/resolve/checkers/EmptyIntersectionTypeChecker.kt index 960de7e867e..2aaf1bb2b56 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/resolve/checkers/EmptyIntersectionTypeChecker.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/resolve/checkers/EmptyIntersectionTypeChecker.kt @@ -108,8 +108,9 @@ internal object EmptyIntersectionTypeChecker { when { firstSuperTypeWithSecondConstructor != null && secondSuperTypeByFirstConstructor != null -> { - val argumentsIntersectionKind = - computeByCheckingTypeArguments(firstSuperTypeWithSecondConstructor, secondSuperTypeByFirstConstructor) ?: continue + val argumentsIntersectionKind = computeByCheckingTypeArguments( + firstSuperTypeWithSecondConstructor, secondSuperTypeByFirstConstructor + ) ?: continue if (argumentsIntersectionKind.kind.isDefinitelyEmpty()) return argumentsIntersectionKind @@ -124,8 +125,11 @@ internal object EmptyIntersectionTypeChecker { else -> { // don't have incompatible supertypes so can have a common subtype only if all types are interfaces if (firstTypeConstructor.isFinalClassConstructor() || secondTypeConstructor.isFinalClassConstructor()) { - possibleEmptyIntersectionKind = - EmptyIntersectionTypeInfo(EmptyIntersectionTypeKind.SINGLE_FINAL_CLASS, firstType, secondType) + possibleEmptyIntersectionKind = EmptyIntersectionTypeInfo( + if (atLeastOneInterface) EmptyIntersectionTypeKind.FINAL_CLASS_AND_INTERFACE + else EmptyIntersectionTypeKind.SINGLE_FINAL_CLASS, + firstType, secondType + ) } continue } 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 6671e650a94..09a412b445a 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/types/EmptyIntersectionTypeKind.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/types/EmptyIntersectionTypeKind.kt @@ -9,7 +9,8 @@ enum class EmptyIntersectionTypeKind(val description: String) { MULTIPLE_CLASSES("multiple incompatible classes"), INCOMPATIBLE_SUPERTYPES("incompatible supertypes"), INCOMPATIBLE_TYPE_ARGUMENTS("incompatible type arguments"), - SINGLE_FINAL_CLASS("final class and interface") + FINAL_CLASS_AND_INTERFACE("final class and interface"), + SINGLE_FINAL_CLASS("final class and non-final class") } fun EmptyIntersectionTypeKind.isDefinitelyEmpty(): Boolean = @@ -17,4 +18,5 @@ fun EmptyIntersectionTypeKind.isDefinitelyEmpty(): Boolean = || this == EmptyIntersectionTypeKind.INCOMPATIBLE_SUPERTYPES || this == EmptyIntersectionTypeKind.INCOMPATIBLE_TYPE_ARGUMENTS -fun EmptyIntersectionTypeKind.isPossiblyEmpty(): Boolean = this == EmptyIntersectionTypeKind.SINGLE_FINAL_CLASS +fun EmptyIntersectionTypeKind.isPossiblyEmpty(): Boolean = + this == EmptyIntersectionTypeKind.SINGLE_FINAL_CLASS || this == EmptyIntersectionTypeKind.FINAL_CLASS_AND_INTERFACE