Fix IllegalStateException in case of recursive T & Any upper bound

^KT-50542 Fixed
This commit is contained in:
Denis.Zharkov
2022-01-11 18:20:19 +03:00
committed by teamcity
parent afc548d5d9
commit 964cf937c3
10 changed files with 96 additions and 2 deletions
@@ -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 {
@@ -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 {
@@ -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)
@@ -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() {}
@@ -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() {}
@@ -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
}
@@ -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 {