Fix IllegalStateException in case of recursive T & Any upper bound
^KT-50542 Fixed
This commit is contained in:
+6
@@ -10259,6 +10259,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
||||
runTest("compiler/testData/diagnostics/tests/explicitDefinitelyNotNullableViaIntersection/overridesJavaAnnotated.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("recursiveBounds.kt")
|
||||
public void testRecursiveBounds() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/explicitDefinitelyNotNullableViaIntersection/recursiveBounds.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reifiedArguments.kt")
|
||||
public void testReifiedArguments() throws Exception {
|
||||
|
||||
+6
@@ -10259,6 +10259,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/explicitDefinitelyNotNullableViaIntersection/overridesJavaAnnotated.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("recursiveBounds.kt")
|
||||
public void testRecursiveBounds() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/explicitDefinitelyNotNullableViaIntersection/recursiveBounds.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reifiedArguments.kt")
|
||||
public void testReifiedArguments() throws Exception {
|
||||
|
||||
+6
@@ -10259,6 +10259,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/explicitDefinitelyNotNullableViaIntersection/overridesJavaAnnotated.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("recursiveBounds.kt")
|
||||
public void testRecursiveBounds() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/explicitDefinitelyNotNullableViaIntersection/recursiveBounds.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reifiedArguments.kt")
|
||||
public void testReifiedArguments() throws Exception {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve
|
||||
|
||||
import org.jetbrains.kotlin.types.DefinitelyNotNullType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.isNullable
|
||||
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
|
||||
|
||||
fun KotlinType.containsIncorrectExplicitDefinitelyNonNullableType(): Boolean = contains {
|
||||
it is DefinitelyNotNullType && it.original.isTypeParameter() && !it.original.isNullable()
|
||||
}
|
||||
@@ -668,6 +668,9 @@ public class DescriptorResolver {
|
||||
if (FunctionTypesKt.isExtensionFunctionType(upperBoundType)) {
|
||||
trace.report(UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE.on(upperBound));
|
||||
}
|
||||
if (DefinitelyNonNullableTypesKt.containsIncorrectExplicitDefinitelyNonNullableType(upperBoundType)) {
|
||||
trace.report(INCORRECT_LEFT_COMPONENT_OF_INTERSECTION.on(upperBound));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -25,10 +25,10 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.annotations.composeAnnotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.VariableDescriptorImpl
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||
import org.jetbrains.kotlin.types.extensions.TypeAttributeTranslators
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -56,6 +56,7 @@ import org.jetbrains.kotlin.resolve.source.getPsi
|
||||
import org.jetbrains.kotlin.resolve.source.toSourceElement
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.Variance.*
|
||||
import org.jetbrains.kotlin.types.extensions.TypeAttributeTranslators
|
||||
import org.jetbrains.kotlin.types.typeUtil.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import kotlin.math.min
|
||||
@@ -325,7 +326,7 @@ class TypeResolver(
|
||||
return
|
||||
}
|
||||
|
||||
if (!leftType.isTypeParameter() || leftType.isMarkedNullable || !TypeUtils.isNullableType(leftType)) {
|
||||
if (!leftType.isTypeParameter() || leftType.isMarkedNullable || !leftType.isNullableOrUninitializedTypeParameter()) {
|
||||
c.trace.report(INCORRECT_LEFT_COMPONENT_OF_INTERSECTION.on(intersectionType.getLeftTypeRef()!!))
|
||||
return
|
||||
}
|
||||
@@ -348,6 +349,14 @@ class TypeResolver(
|
||||
result = type(definitelyNotNullType)
|
||||
}
|
||||
|
||||
private fun KotlinType.isNullableOrUninitializedTypeParameter(): Boolean {
|
||||
if ((constructor.declarationDescriptor as? TypeParameterDescriptorImpl)?.isInitialized == false) {
|
||||
return true
|
||||
}
|
||||
|
||||
return isNullable()
|
||||
}
|
||||
|
||||
override fun visitFunctionType(type: KtFunctionType) {
|
||||
val receiverTypeRef = type.receiverTypeReference
|
||||
val receiverType = if (receiverTypeRef?.typeElement == null) null else resolveType(c.noBareTypes(), receiverTypeRef)
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// !LANGUAGE: +DefinitelyNonNullableTypes
|
||||
|
||||
fun <T : Comparable<T & Any>> sort1() {}
|
||||
fun <T : Comparable<T & Any>?> sort2() {}
|
||||
|
||||
class A1<K : Comparable<K & Any>>
|
||||
class A2<K : Comparable<K & Any>?>
|
||||
|
||||
fun <R : T & Any, T> bar() {}
|
||||
|
||||
fun <E : E & Any> baz() {}
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
// !LANGUAGE: +DefinitelyNonNullableTypes
|
||||
|
||||
fun <T : <!INCORRECT_LEFT_COMPONENT_OF_INTERSECTION!>Comparable<T & Any><!>> sort1() {}
|
||||
fun <T : Comparable<T & Any>?> sort2() {}
|
||||
|
||||
class A1<K : Comparable<<!INCORRECT_LEFT_COMPONENT_OF_INTERSECTION!>K<!> & Any>>
|
||||
class A2<K : Comparable<<!INCORRECT_LEFT_COMPONENT_OF_INTERSECTION!>K<!> & Any>?>
|
||||
|
||||
fun <R : T & Any, T> bar() {}
|
||||
|
||||
fun <<!CYCLIC_GENERIC_UPPER_BOUND!>E : <!INCORRECT_LEFT_COMPONENT_OF_INTERSECTION!>E & Any<!><!>> baz() {}
|
||||
compiler/testData/diagnostics/tests/explicitDefinitelyNotNullableViaIntersection/recursiveBounds.txt
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
package
|
||||
|
||||
public fun </*0*/ R : T & Any, /*1*/ T> bar(): kotlin.Unit
|
||||
public fun </*0*/ E : [ERROR : Cyclic upper bounds]> baz(): kotlin.Unit
|
||||
public fun </*0*/ T : kotlin.Comparable<T & Any>> sort1(): kotlin.Unit
|
||||
public fun </*0*/ T : kotlin.Comparable<T & Any>?> sort2(): kotlin.Unit
|
||||
|
||||
public final class A1</*0*/ K : kotlin.Comparable<K>> {
|
||||
public constructor A1</*0*/ K : kotlin.Comparable<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 final class A2</*0*/ K : kotlin.Comparable<K>?> {
|
||||
public constructor A2</*0*/ K : kotlin.Comparable<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
|
||||
}
|
||||
Generated
+6
@@ -10265,6 +10265,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/explicitDefinitelyNotNullableViaIntersection/overridesJavaAnnotated.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("recursiveBounds.kt")
|
||||
public void testRecursiveBounds() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/explicitDefinitelyNotNullableViaIntersection/recursiveBounds.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reifiedArguments.kt")
|
||||
public void testReifiedArguments() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user