Fix incorrect handling of @NotNull type parameters
^KT-36770 In progress ^KT-40114 Relates ^KT-28785 Relates
This commit is contained in:
+10
@@ -14111,6 +14111,16 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
|||||||
runTest("compiler/testData/diagnostics/tests/j+k/types/arrayList.kt");
|
runTest("compiler/testData/diagnostics/tests/j+k/types/arrayList.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("notNullTypeParameterWithKotlinNullable.kt")
|
||||||
|
public void testNotNullTypeParameterWithKotlinNullable() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/j+k/types/notNullTypeParameterWithKotlinNullable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("notNullTypeParameterWithKotlinNullableWarnings.kt")
|
||||||
|
public void testNotNullTypeParameterWithKotlinNullableWarnings() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/j+k/types/notNullTypeParameterWithKotlinNullableWarnings.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("returnCollection.kt")
|
@TestMetadata("returnCollection.kt")
|
||||||
public void testReturnCollection() throws Exception {
|
public void testReturnCollection() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/j+k/types/returnCollection.kt");
|
runTest("compiler/testData/diagnostics/tests/j+k/types/returnCollection.kt");
|
||||||
|
|||||||
@@ -41,8 +41,10 @@ import org.jetbrains.kotlin.load.kotlin.DeserializationComponentsForJava
|
|||||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
|
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
import org.jetbrains.kotlin.resolve.*
|
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||||
|
import org.jetbrains.kotlin.resolve.TargetEnvironment
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitsExtensionsResolutionFilter
|
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitsExtensionsResolutionFilter
|
||||||
|
import org.jetbrains.kotlin.resolve.createContainer
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver
|
import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmDiagnosticComponents
|
import org.jetbrains.kotlin.resolve.jvm.JvmDiagnosticComponents
|
||||||
import org.jetbrains.kotlin.resolve.jvm.multiplatform.OptionalAnnotationPackageFragmentProvider
|
import org.jetbrains.kotlin.resolve.jvm.multiplatform.OptionalAnnotationPackageFragmentProvider
|
||||||
@@ -129,7 +131,10 @@ fun StorageComponentContainer.configureJavaSpecificComponents(
|
|||||||
|
|
||||||
useInstance(javaClassTracker ?: JavaClassesTracker.Default)
|
useInstance(javaClassTracker ?: JavaClassesTracker.Default)
|
||||||
useInstance(
|
useInstance(
|
||||||
JavaResolverSettings.create(isReleaseCoroutines = languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines))
|
JavaResolverSettings.create(
|
||||||
|
isReleaseCoroutines = languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines),
|
||||||
|
correctNullabilityForNotNullTypeParameter = languageVersionSettings.supportsFeature(LanguageFeature.ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated),
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
useImpl<FilesByFacadeFqNameIndexer>()
|
useImpl<FilesByFacadeFqNameIndexer>()
|
||||||
|
|||||||
+57
-2
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.resolve.jvm.checkers
|
package org.jetbrains.kotlin.resolve.jvm.checkers
|
||||||
|
|
||||||
import org.jetbrains.kotlin.cfg.WhenChecker
|
import org.jetbrains.kotlin.cfg.WhenChecker
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
@@ -35,15 +36,30 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
|
import org.jetbrains.kotlin.types.checker.ClassicTypeCheckerContext
|
||||||
import org.jetbrains.kotlin.types.expressions.SenselessComparisonChecker
|
import org.jetbrains.kotlin.types.expressions.SenselessComparisonChecker
|
||||||
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
|
|
||||||
class JavaNullabilityChecker : AdditionalTypeChecker {
|
class JavaNullabilityChecker : AdditionalTypeChecker {
|
||||||
|
|
||||||
override fun checkType(expression: KtExpression, expressionType: KotlinType, expressionTypeWithSmartCast: KotlinType, c: ResolutionContext<*>) {
|
override fun checkType(
|
||||||
|
expression: KtExpression,
|
||||||
|
expressionType: KotlinType,
|
||||||
|
expressionTypeWithSmartCast: KotlinType,
|
||||||
|
c: ResolutionContext<*>
|
||||||
|
) {
|
||||||
|
val dataFlowValue by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
|
c.dataFlowValueFactory.createDataFlowValue(expression, expressionType, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isWrongTypeParameterNullabilityForSubtyping(expressionType, c) { dataFlowValue }) {
|
||||||
|
c.trace.report(ErrorsJvm.NULLABLE_TYPE_PARAMETER_AGAINST_NOT_NULL_TYPE_PARAMETER.on(expression, c.expectedType, expressionType))
|
||||||
|
}
|
||||||
|
|
||||||
doCheckType(
|
doCheckType(
|
||||||
expressionType,
|
expressionType,
|
||||||
c.expectedType,
|
c.expectedType,
|
||||||
{ c.dataFlowValueFactory.createDataFlowValue(expression, expressionType, c) },
|
{ dataFlowValue },
|
||||||
c.dataFlowInfo
|
c.dataFlowInfo
|
||||||
) { expectedType, actualType ->
|
) { expectedType, actualType ->
|
||||||
c.trace.report(ErrorsJvm.NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS.on(expression, expectedType, actualType))
|
c.trace.report(ErrorsJvm.NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS.on(expression, expectedType, actualType))
|
||||||
@@ -103,6 +119,45 @@ class JavaNullabilityChecker : AdditionalTypeChecker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isWrongTypeParameterNullabilityForSubtyping(
|
||||||
|
expressionType: KotlinType,
|
||||||
|
c: ResolutionContext<*>,
|
||||||
|
dataFlowValueForWholeExpression: () -> DataFlowValue
|
||||||
|
): Boolean {
|
||||||
|
if (c.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated)) return false
|
||||||
|
if (TypeUtils.noExpectedType(c.expectedType)) return false
|
||||||
|
|
||||||
|
var metWrongNullabilityInsideArguments = false
|
||||||
|
|
||||||
|
val typeContext: AbstractTypeCheckerContext = object : ClassicTypeCheckerContext(errorTypeEqualsToAnything = true) {
|
||||||
|
private var expectsTypeArgument = false
|
||||||
|
override fun customIsSubtypeOf(subType: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean {
|
||||||
|
|
||||||
|
if (isNullableTypeAgainstNotNullTypeParameter(subType as KotlinType, superType as KotlinType)) {
|
||||||
|
// data flow value is only checked for top-level types
|
||||||
|
if (expectsTypeArgument || c.dataFlowInfo.getStableNullability(dataFlowValueForWholeExpression()) != Nullability.NOT_NULL) {
|
||||||
|
metWrongNullabilityInsideArguments = true
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!expectsTypeArgument) {
|
||||||
|
expectsTypeArgument = true
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractTypeChecker.isSubtypeOf(typeContext, expressionType, c.expectedType)
|
||||||
|
|
||||||
|
return metWrongNullabilityInsideArguments
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isNullableTypeAgainstNotNullTypeParameter(
|
||||||
|
subType: KotlinType,
|
||||||
|
superType: KotlinType
|
||||||
|
) = superType is NotNullTypeVariable && subType.isNullable()
|
||||||
|
|
||||||
override fun checkReceiver(
|
override fun checkReceiver(
|
||||||
receiverParameter: ReceiverParameterDescriptor,
|
receiverParameter: ReceiverParameterDescriptor,
|
||||||
receiverArgument: ReceiverValue,
|
receiverArgument: ReceiverValue,
|
||||||
|
|||||||
+4
@@ -82,6 +82,10 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
|
|||||||
MAP.put(SUBCLASS_CANT_CALL_COMPANION_PROTECTED_NON_STATIC, "Using non-JVM static members protected in the superclass companion is unsupported yet");
|
MAP.put(SUBCLASS_CANT_CALL_COMPANION_PROTECTED_NON_STATIC, "Using non-JVM static members protected in the superclass companion is unsupported yet");
|
||||||
|
|
||||||
MAP.put(NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS, "Type mismatch: inferred type is {1} but {0} was expected", RENDER_TYPE, RENDER_TYPE);
|
MAP.put(NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS, "Type mismatch: inferred type is {1} but {0} was expected", RENDER_TYPE, RENDER_TYPE);
|
||||||
|
MAP.put(NULLABLE_TYPE_PARAMETER_AGAINST_NOT_NULL_TYPE_PARAMETER,
|
||||||
|
"Type mismatch: type parameter with nullable bounds is used {1} is used where {0} was expected. This warning will become an error soon",
|
||||||
|
RENDER_TYPE, RENDER_TYPE
|
||||||
|
);
|
||||||
MAP.put(RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS,
|
MAP.put(RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS,
|
||||||
"Unsafe use of a nullable receiver of type {0}", RENDER_TYPE);
|
"Unsafe use of a nullable receiver of type {0}", RENDER_TYPE);
|
||||||
|
|
||||||
|
|||||||
@@ -121,6 +121,9 @@ public interface ErrorsJvm {
|
|||||||
DiagnosticFactory2<KtElement, KotlinType, KotlinType> NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS
|
DiagnosticFactory2<KtElement, KotlinType, KotlinType> NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS
|
||||||
= DiagnosticFactory2.create(WARNING);
|
= DiagnosticFactory2.create(WARNING);
|
||||||
|
|
||||||
|
DiagnosticFactory2<KtElement, KotlinType, KotlinType> NULLABLE_TYPE_PARAMETER_AGAINST_NOT_NULL_TYPE_PARAMETER
|
||||||
|
= DiagnosticFactory2.create(WARNING);
|
||||||
|
|
||||||
DiagnosticFactory1<KtElement, KotlinType> RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS
|
DiagnosticFactory1<KtElement, KotlinType> RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS
|
||||||
= DiagnosticFactory1.create(WARNING);
|
= DiagnosticFactory1.create(WARNING);
|
||||||
|
|
||||||
|
|||||||
Vendored
+28
@@ -0,0 +1,28 @@
|
|||||||
|
// FILE: SLRUMap.java
|
||||||
|
// !LANGUAGE: +ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface SLRUMap<V> {
|
||||||
|
void takeV(@NotNull V value);
|
||||||
|
<E> void takeE(@NotNull E value);
|
||||||
|
|
||||||
|
void takeVList(@NotNull List<@NotNull V> value);
|
||||||
|
<E> void takeEList(@NotNull List<@NotNull E> value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun <V> SLRUMap<V>.getOrPut(value: V, l: List<V>) {
|
||||||
|
<!INAPPLICABLE_CANDIDATE!>takeV<!>(value)
|
||||||
|
takeVList(l)
|
||||||
|
|
||||||
|
takeE(value)
|
||||||
|
takeEList(l)
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
takeV(value)
|
||||||
|
takeE(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
// FILE: SLRUMap.java
|
||||||
|
// !LANGUAGE: +ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface SLRUMap<V> {
|
||||||
|
void takeV(@NotNull V value);
|
||||||
|
<E> void takeE(@NotNull E value);
|
||||||
|
|
||||||
|
void takeVList(@NotNull List<@NotNull V> value);
|
||||||
|
<E> void takeEList(@NotNull List<@NotNull E> value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun <V> SLRUMap<V>.getOrPut(value: V, l: List<V>) {
|
||||||
|
takeV(<!TYPE_MISMATCH!>value<!>)
|
||||||
|
takeVList(<!TYPE_MISMATCH!>l<!>)
|
||||||
|
|
||||||
|
takeE(<!TYPE_MISMATCH!>value<!>)
|
||||||
|
takeEList(<!TYPE_MISMATCH!>l<!>)
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
takeV(<!DEBUG_INFO_SMARTCAST!>value<!>)
|
||||||
|
takeE(<!DEBUG_INFO_SMARTCAST!>value<!>)
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun </*0*/ V> SLRUMap<V>.getOrPut(/*0*/ value: V, /*1*/ l: kotlin.collections.List<V>): kotlin.Unit
|
||||||
|
|
||||||
|
public interface SLRUMap</*0*/ V : kotlin.Any!> {
|
||||||
|
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 abstract fun </*0*/ E : kotlin.Any!> takeE(/*0*/ @org.jetbrains.annotations.NotNull value: E!!): kotlin.Unit
|
||||||
|
public abstract fun </*0*/ E : kotlin.Any!> takeEList(/*0*/ @org.jetbrains.annotations.NotNull value: kotlin.collections.(Mutable)List<@org.jetbrains.annotations.NotNull E!!>): kotlin.Unit
|
||||||
|
public abstract fun takeV(/*0*/ @org.jetbrains.annotations.NotNull value: V!!): kotlin.Unit
|
||||||
|
public abstract fun takeVList(/*0*/ @org.jetbrains.annotations.NotNull value: kotlin.collections.(Mutable)List<@org.jetbrains.annotations.NotNull V!!>): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
Vendored
+28
@@ -0,0 +1,28 @@
|
|||||||
|
// FILE: SLRUMap.java
|
||||||
|
// !LANGUAGE: -ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface SLRUMap<V> {
|
||||||
|
void takeV(@NotNull V value);
|
||||||
|
<E> void takeE(@NotNull E value);
|
||||||
|
|
||||||
|
void takeVList(@NotNull List<@NotNull V> value);
|
||||||
|
<E> void takeEList(@NotNull List<@NotNull E> value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun <V> SLRUMap<V>.getOrPut(value: V, l: List<V>) {
|
||||||
|
<!INAPPLICABLE_CANDIDATE!>takeV<!>(value)
|
||||||
|
takeVList(l)
|
||||||
|
|
||||||
|
takeE(value)
|
||||||
|
takeEList(l)
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
takeV(value)
|
||||||
|
takeE(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+28
@@ -0,0 +1,28 @@
|
|||||||
|
// FILE: SLRUMap.java
|
||||||
|
// !LANGUAGE: -ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface SLRUMap<V> {
|
||||||
|
void takeV(@NotNull V value);
|
||||||
|
<E> void takeE(@NotNull E value);
|
||||||
|
|
||||||
|
void takeVList(@NotNull List<@NotNull V> value);
|
||||||
|
<E> void takeEList(@NotNull List<@NotNull E> value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
fun <V> SLRUMap<V>.getOrPut(value: V, l: List<V>) {
|
||||||
|
takeV(<!NULLABLE_TYPE_PARAMETER_AGAINST_NOT_NULL_TYPE_PARAMETER!>value<!>)
|
||||||
|
takeVList(<!NULLABLE_TYPE_PARAMETER_AGAINST_NOT_NULL_TYPE_PARAMETER!>l<!>)
|
||||||
|
|
||||||
|
takeE(<!NULLABLE_TYPE_PARAMETER_AGAINST_NOT_NULL_TYPE_PARAMETER!>value<!>)
|
||||||
|
takeEList(<!NULLABLE_TYPE_PARAMETER_AGAINST_NOT_NULL_TYPE_PARAMETER!>l<!>)
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
|
takeV(value)
|
||||||
|
takeE(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun </*0*/ V> SLRUMap<V>.getOrPut(/*0*/ value: V, /*1*/ l: kotlin.collections.List<V>): kotlin.Unit
|
||||||
|
|
||||||
|
public interface SLRUMap</*0*/ V : kotlin.Any!> {
|
||||||
|
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 abstract fun </*0*/ E : kotlin.Any!> takeE(/*0*/ @org.jetbrains.annotations.NotNull value: E): kotlin.Unit
|
||||||
|
public abstract fun </*0*/ E : kotlin.Any!> takeEList(/*0*/ @org.jetbrains.annotations.NotNull value: kotlin.collections.(Mutable)List<@org.jetbrains.annotations.NotNull E>): kotlin.Unit
|
||||||
|
public abstract fun takeV(/*0*/ @org.jetbrains.annotations.NotNull value: V): kotlin.Unit
|
||||||
|
public abstract fun takeVList(/*0*/ @org.jetbrains.annotations.NotNull value: kotlin.collections.(Mutable)List<@org.jetbrains.annotations.NotNull V>): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
Vendored
+1
-1
@@ -22,5 +22,5 @@ interface TypePredicate : (KotlinType) -> Boolean {
|
|||||||
|
|
||||||
fun <T : Any?> TypePredicate.expectedTypeFor(keys: Iterable<T>): Map<T, TypePredicate> =
|
fun <T : Any?> TypePredicate.expectedTypeFor(keys: Iterable<T>): Map<T, TypePredicate> =
|
||||||
keys.fold(SmartFMap.emptyMap<T, TypePredicate>()) { map, key ->
|
keys.fold(SmartFMap.emptyMap<T, TypePredicate>()) { map, key ->
|
||||||
map.plus(key, this)
|
map.plus(<!NULLABLE_TYPE_PARAMETER_AGAINST_NOT_NULL_TYPE_PARAMETER!>key<!>, this)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14118,6 +14118,16 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali
|
|||||||
runTest("compiler/testData/diagnostics/tests/j+k/types/arrayList.kt");
|
runTest("compiler/testData/diagnostics/tests/j+k/types/arrayList.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("notNullTypeParameterWithKotlinNullable.kt")
|
||||||
|
public void testNotNullTypeParameterWithKotlinNullable() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/j+k/types/notNullTypeParameterWithKotlinNullable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("notNullTypeParameterWithKotlinNullableWarnings.kt")
|
||||||
|
public void testNotNullTypeParameterWithKotlinNullableWarnings() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/j+k/types/notNullTypeParameterWithKotlinNullableWarnings.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("returnCollection.kt")
|
@TestMetadata("returnCollection.kt")
|
||||||
public void testReturnCollection() throws Exception {
|
public void testReturnCollection() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/j+k/types/returnCollection.kt");
|
runTest("compiler/testData/diagnostics/tests/j+k/types/returnCollection.kt");
|
||||||
|
|||||||
Generated
+10
@@ -14113,6 +14113,16 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
|||||||
runTest("compiler/testData/diagnostics/tests/j+k/types/arrayList.kt");
|
runTest("compiler/testData/diagnostics/tests/j+k/types/arrayList.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("notNullTypeParameterWithKotlinNullable.kt")
|
||||||
|
public void testNotNullTypeParameterWithKotlinNullable() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/j+k/types/notNullTypeParameterWithKotlinNullable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("notNullTypeParameterWithKotlinNullableWarnings.kt")
|
||||||
|
public void testNotNullTypeParameterWithKotlinNullableWarnings() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/j+k/types/notNullTypeParameterWithKotlinNullableWarnings.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("returnCollection.kt")
|
@TestMetadata("returnCollection.kt")
|
||||||
public void testReturnCollection() throws Exception {
|
public void testReturnCollection() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/j+k/types/returnCollection.kt");
|
runTest("compiler/testData/diagnostics/tests/j+k/types/returnCollection.kt");
|
||||||
|
|||||||
@@ -134,6 +134,7 @@ enum class LanguageFeature(
|
|||||||
ProperArrayConventionSetterWithDefaultCalls(KOTLIN_1_5, kind = OTHER),
|
ProperArrayConventionSetterWithDefaultCalls(KOTLIN_1_5, kind = OTHER),
|
||||||
DisableCompatibilityModeForNewInference(KOTLIN_1_5, defaultState = LanguageFeature.State.DISABLED),
|
DisableCompatibilityModeForNewInference(KOTLIN_1_5, defaultState = LanguageFeature.State.DISABLED),
|
||||||
AdaptedCallableReferenceAgainstReflectiveType(KOTLIN_1_5, defaultState = LanguageFeature.State.DISABLED),
|
AdaptedCallableReferenceAgainstReflectiveType(KOTLIN_1_5, defaultState = LanguageFeature.State.DISABLED),
|
||||||
|
ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated(KOTLIN_1_5, kind = BUG_FIX),
|
||||||
|
|
||||||
// Temporarily disabled, see KT-27084/KT-22379
|
// Temporarily disabled, see KT-27084/KT-22379
|
||||||
SoundSmartcastFromLoopConditionForLoopAssignedVariables(sinceVersion = null, kind = BUG_FIX),
|
SoundSmartcastFromLoopConditionForLoopAssignedVariables(sinceVersion = null, kind = BUG_FIX),
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.load.java.JavaClassFinder
|
|||||||
import org.jetbrains.kotlin.load.java.JavaClassesTracker
|
import org.jetbrains.kotlin.load.java.JavaClassesTracker
|
||||||
import org.jetbrains.kotlin.load.java.components.JavaPropertyInitializerEvaluator
|
import org.jetbrains.kotlin.load.java.components.JavaPropertyInitializerEvaluator
|
||||||
import org.jetbrains.kotlin.load.java.components.JavaResolverCache
|
import org.jetbrains.kotlin.load.java.components.JavaResolverCache
|
||||||
import org.jetbrains.kotlin.resolve.sam.SamConversionResolver
|
|
||||||
import org.jetbrains.kotlin.load.java.components.SignaturePropagator
|
import org.jetbrains.kotlin.load.java.components.SignaturePropagator
|
||||||
import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeResolver
|
import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeResolver
|
||||||
import org.jetbrains.kotlin.load.java.sources.JavaSourceElementFactory
|
import org.jetbrains.kotlin.load.java.sources.JavaSourceElementFactory
|
||||||
@@ -40,6 +39,7 @@ import org.jetbrains.kotlin.load.java.typeEnhancement.SignatureEnhancement
|
|||||||
import org.jetbrains.kotlin.load.kotlin.DeserializedDescriptorResolver
|
import org.jetbrains.kotlin.load.kotlin.DeserializedDescriptorResolver
|
||||||
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
|
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||||
|
import org.jetbrains.kotlin.resolve.sam.SamConversionResolver
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
|
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
|
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
|
||||||
@@ -82,16 +82,24 @@ class JavaResolverComponents(
|
|||||||
|
|
||||||
interface JavaResolverSettings {
|
interface JavaResolverSettings {
|
||||||
val isReleaseCoroutines: Boolean
|
val isReleaseCoroutines: Boolean
|
||||||
|
val correctNullabilityForNotNullTypeParameter: Boolean
|
||||||
|
|
||||||
object Default : JavaResolverSettings {
|
object Default : JavaResolverSettings {
|
||||||
override val isReleaseCoroutines: Boolean
|
override val isReleaseCoroutines: Boolean
|
||||||
get() = false
|
get() = false
|
||||||
|
|
||||||
|
override val correctNullabilityForNotNullTypeParameter: Boolean
|
||||||
|
get() = false
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun create(isReleaseCoroutines: Boolean): JavaResolverSettings =
|
fun create(
|
||||||
|
isReleaseCoroutines: Boolean,
|
||||||
|
correctNullabilityForNotNullTypeParameter: Boolean
|
||||||
|
): JavaResolverSettings =
|
||||||
object : JavaResolverSettings {
|
object : JavaResolverSettings {
|
||||||
override val isReleaseCoroutines get() = isReleaseCoroutines
|
override val isReleaseCoroutines get() = isReleaseCoroutines
|
||||||
|
override val correctNullabilityForNotNullTypeParameter get() = correctNullabilityForNotNullTypeParameter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-2
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations
|
import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||||
|
import org.jetbrains.kotlin.load.java.lazy.JavaResolverSettings
|
||||||
import org.jetbrains.kotlin.load.java.lazy.types.RawTypeImpl
|
import org.jetbrains.kotlin.load.java.lazy.types.RawTypeImpl
|
||||||
import org.jetbrains.kotlin.load.java.typeEnhancement.MutabilityQualifier.MUTABLE
|
import org.jetbrains.kotlin.load.java.typeEnhancement.MutabilityQualifier.MUTABLE
|
||||||
import org.jetbrains.kotlin.load.java.typeEnhancement.MutabilityQualifier.READ_ONLY
|
import org.jetbrains.kotlin.load.java.typeEnhancement.MutabilityQualifier.READ_ONLY
|
||||||
@@ -51,7 +52,7 @@ enum class TypeComponentPosition {
|
|||||||
INFLEXIBLE
|
INFLEXIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
class JavaTypeEnhancement {
|
class JavaTypeEnhancement(private val javaResolverSettings: JavaResolverSettings) {
|
||||||
|
|
||||||
private open class Result(open val type: KotlinType, val subtreeSize: Int, val wereChanges: Boolean) {
|
private open class Result(open val type: KotlinType, val subtreeSize: Int, val wereChanges: Boolean) {
|
||||||
val typeIfChanged: KotlinType? get() = type.takeIf { wereChanges }
|
val typeIfChanged: KotlinType? get() = type.takeIf { wereChanges }
|
||||||
@@ -144,12 +145,18 @@ class JavaTypeEnhancement {
|
|||||||
enhancedNullability
|
enhancedNullability
|
||||||
)
|
)
|
||||||
|
|
||||||
val enhancement = if (effectiveQualifiers.isNotNullTypeParameter) NotNullTypeParameter(enhancedType) else enhancedType
|
val enhancement = if (effectiveQualifiers.isNotNullTypeParameter) notNullTypeParameter(enhancedType) else enhancedType
|
||||||
val nullabilityForWarning = enhancedNullabilityAnnotations != null && effectiveQualifiers.isNullabilityQualifierForWarning
|
val nullabilityForWarning = enhancedNullabilityAnnotations != null && effectiveQualifiers.isNullabilityQualifierForWarning
|
||||||
val result = if (nullabilityForWarning) wrapEnhancement(enhancement) else enhancement
|
val result = if (nullabilityForWarning) wrapEnhancement(enhancement) else enhancement
|
||||||
|
|
||||||
return SimpleResult(result as SimpleType, subtreeSize, wereChanges = true)
|
return SimpleResult(result as SimpleType, subtreeSize, wereChanges = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun notNullTypeParameter(enhancedType: SimpleType) =
|
||||||
|
if (javaResolverSettings.correctNullabilityForNotNullTypeParameter)
|
||||||
|
enhancedType.makeSimpleTypeDefinitelyNotNullOrNotNull(useCorrectedNullabilityForTypeParameters = true)
|
||||||
|
else
|
||||||
|
NotNullTypeParameter(enhancedType)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun List<Annotations>.compositeAnnotationsOrSingle() = when (size) {
|
private fun List<Annotations>.compositeAnnotationsOrSingle() = when (size) {
|
||||||
|
|||||||
+3
-2
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.load.java.components.JavaPropertyInitializerEvaluato
|
|||||||
import org.jetbrains.kotlin.load.java.components.JavaResolverCache
|
import org.jetbrains.kotlin.load.java.components.JavaResolverCache
|
||||||
import org.jetbrains.kotlin.load.java.components.SignaturePropagator
|
import org.jetbrains.kotlin.load.java.components.SignaturePropagator
|
||||||
import org.jetbrains.kotlin.load.java.lazy.*
|
import org.jetbrains.kotlin.load.java.lazy.*
|
||||||
|
import org.jetbrains.kotlin.load.java.typeEnhancement.JavaTypeEnhancement
|
||||||
import org.jetbrains.kotlin.load.java.typeEnhancement.SignatureEnhancement
|
import org.jetbrains.kotlin.load.java.typeEnhancement.SignatureEnhancement
|
||||||
import org.jetbrains.kotlin.load.kotlin.*
|
import org.jetbrains.kotlin.load.kotlin.*
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -116,7 +117,7 @@ fun makeLazyJavaPackageFragmentFromClassLoaderProvider(
|
|||||||
JavaPropertyInitializerEvaluator.DoNothing, SamConversionResolverImpl(storageManager, emptyList()), RuntimeSourceElementFactory,
|
JavaPropertyInitializerEvaluator.DoNothing, SamConversionResolverImpl(storageManager, emptyList()), RuntimeSourceElementFactory,
|
||||||
singleModuleClassResolver, packagePartProvider, SupertypeLoopChecker.EMPTY, LookupTracker.DO_NOTHING, module,
|
singleModuleClassResolver, packagePartProvider, SupertypeLoopChecker.EMPTY, LookupTracker.DO_NOTHING, module,
|
||||||
ReflectionTypes(module, notFoundClasses), annotationTypeQualifierResolver,
|
ReflectionTypes(module, notFoundClasses), annotationTypeQualifierResolver,
|
||||||
SignatureEnhancement(annotationTypeQualifierResolver, Jsr305State.DISABLED),
|
SignatureEnhancement(annotationTypeQualifierResolver, Jsr305State.DISABLED, JavaTypeEnhancement(JavaResolverSettings.Default)),
|
||||||
JavaClassesTracker.Default, JavaResolverSettings.Default, NewKotlinTypeChecker.Default
|
JavaClassesTracker.Default, JavaResolverSettings.Default, NewKotlinTypeChecker.Default
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -140,4 +141,4 @@ fun makeDeserializationComponentsForJava(
|
|||||||
binaryClassAnnotationAndConstantLoader, lazyJavaPackageFragmentProvider, notFoundClasses,
|
binaryClassAnnotationAndConstantLoader, lazyJavaPackageFragmentProvider, notFoundClasses,
|
||||||
RuntimeErrorReporter, LookupTracker.DO_NOTHING, ContractDeserializer.DEFAULT, NewKotlinTypeChecker.Default
|
RuntimeErrorReporter, LookupTracker.DO_NOTHING, ContractDeserializer.DEFAULT, NewKotlinTypeChecker.Default
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.types.checker.NewTypeVariableConstructor
|
|||||||
import org.jetbrains.kotlin.types.checker.NullabilityChecker
|
import org.jetbrains.kotlin.types.checker.NullabilityChecker
|
||||||
import org.jetbrains.kotlin.types.model.DefinitelyNotNullTypeMarker
|
import org.jetbrains.kotlin.types.model.DefinitelyNotNullTypeMarker
|
||||||
import org.jetbrains.kotlin.types.refinement.TypeRefinement
|
import org.jetbrains.kotlin.types.refinement.TypeRefinement
|
||||||
import org.jetbrains.kotlin.types.typeUtil.canHaveUndefinedNullability
|
|
||||||
|
|
||||||
abstract class DelegatingSimpleType : SimpleType() {
|
abstract class DelegatingSimpleType : SimpleType() {
|
||||||
protected abstract val delegate: SimpleType
|
protected abstract val delegate: SimpleType
|
||||||
@@ -91,15 +90,21 @@ class LazyWrappedType(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DefinitelyNotNullType private constructor(val original: SimpleType) : DelegatingSimpleType(), CustomTypeVariable,
|
class DefinitelyNotNullType private constructor(
|
||||||
|
val original: SimpleType,
|
||||||
|
private val useCorrectedNullabilityForTypeParameters: Boolean
|
||||||
|
) : DelegatingSimpleType(), CustomTypeVariable,
|
||||||
DefinitelyNotNullTypeMarker {
|
DefinitelyNotNullTypeMarker {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
internal fun makeDefinitelyNotNull(type: UnwrappedType): DefinitelyNotNullType? {
|
internal fun makeDefinitelyNotNull(
|
||||||
|
type: UnwrappedType,
|
||||||
|
useCorrectedNullabilityForTypeParameters: Boolean = false
|
||||||
|
): DefinitelyNotNullType? {
|
||||||
return when {
|
return when {
|
||||||
type is DefinitelyNotNullType -> type
|
type is DefinitelyNotNullType -> type
|
||||||
|
|
||||||
makesSenseToBeDefinitelyNotNull(type) -> {
|
makesSenseToBeDefinitelyNotNull(type, useCorrectedNullabilityForTypeParameters) -> {
|
||||||
if (type is FlexibleType) {
|
if (type is FlexibleType) {
|
||||||
assert(type.lowerBound.constructor == type.upperBound.constructor) {
|
assert(type.lowerBound.constructor == type.upperBound.constructor) {
|
||||||
"DefinitelyNotNullType for flexible type ($type) can be created only from type variable with the same constructor for bounds"
|
"DefinitelyNotNullType for flexible type ($type) can be created only from type variable with the same constructor for bounds"
|
||||||
@@ -107,15 +112,40 @@ class DefinitelyNotNullType private constructor(val original: SimpleType) : Dele
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DefinitelyNotNullType(type.lowerIfFlexible())
|
DefinitelyNotNullType(type.lowerIfFlexible(), useCorrectedNullabilityForTypeParameters)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun makesSenseToBeDefinitelyNotNull(type: UnwrappedType): Boolean =
|
private fun makesSenseToBeDefinitelyNotNull(
|
||||||
type.canHaveUndefinedNullability() && !NullabilityChecker.isSubtypeOfAny(type)
|
type: UnwrappedType,
|
||||||
|
useCorrectedNullabilityForFlexibleTypeParameters: Boolean
|
||||||
|
): Boolean {
|
||||||
|
if (!type.canHaveUndefinedNullability()) return false
|
||||||
|
|
||||||
|
// Replacing `useCorrectedNullabilityForFlexibleTypeParameters` with true for all call-sites seems to be correct
|
||||||
|
// But it seems that it should be a new feature: KT-28785 would be automatically fixed then
|
||||||
|
// (see the tests org.jetbrains.kotlin.spec.checkers.DiagnosticsTestSpecGenerated.NotLinked.Dfa.Pos.test12/13)
|
||||||
|
// So it should be a language feature, but it's hard correctly identify language version settings for all call sites
|
||||||
|
// Thus, we have non-trivial value at org.jetbrains.kotlin.load.java.typeEnhancement.JavaTypeEnhancement.notNullTypeParameter
|
||||||
|
// that run under related language-feature only
|
||||||
|
if (useCorrectedNullabilityForFlexibleTypeParameters && type.constructor.declarationDescriptor is TypeParameterDescriptor) {
|
||||||
|
// Effectively checks if the type is flexible or has nullable bound
|
||||||
|
return TypeUtils.isNullableType(type)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actually, this code should work for type parameters as well, but it breaks some cases
|
||||||
|
// See KT-40114
|
||||||
|
return !NullabilityChecker.isSubtypeOfAny(type)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun UnwrappedType.canHaveUndefinedNullability(): Boolean =
|
||||||
|
constructor is NewTypeVariableConstructor ||
|
||||||
|
constructor.declarationDescriptor is TypeParameterDescriptor ||
|
||||||
|
this is NewCapturedType
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override val delegate: SimpleType
|
override val delegate: SimpleType
|
||||||
@@ -129,10 +159,10 @@ class DefinitelyNotNullType private constructor(val original: SimpleType) : Dele
|
|||||||
delegate.constructor.declarationDescriptor is TypeParameterDescriptor
|
delegate.constructor.declarationDescriptor is TypeParameterDescriptor
|
||||||
|
|
||||||
override fun substitutionResult(replacement: KotlinType): KotlinType =
|
override fun substitutionResult(replacement: KotlinType): KotlinType =
|
||||||
replacement.unwrap().makeDefinitelyNotNullOrNotNull()
|
replacement.unwrap().makeDefinitelyNotNullOrNotNull(useCorrectedNullabilityForTypeParameters)
|
||||||
|
|
||||||
override fun replaceAnnotations(newAnnotations: Annotations): DefinitelyNotNullType =
|
override fun replaceAnnotations(newAnnotations: Annotations): DefinitelyNotNullType =
|
||||||
DefinitelyNotNullType(delegate.replaceAnnotations(newAnnotations))
|
DefinitelyNotNullType(delegate.replaceAnnotations(newAnnotations), useCorrectedNullabilityForTypeParameters)
|
||||||
|
|
||||||
override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType =
|
override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType =
|
||||||
if (newNullability) delegate.makeNullableAsSpecified(newNullability) else this
|
if (newNullability) delegate.makeNullableAsSpecified(newNullability) else this
|
||||||
@@ -140,22 +170,22 @@ class DefinitelyNotNullType private constructor(val original: SimpleType) : Dele
|
|||||||
override fun toString(): String = "$delegate!!"
|
override fun toString(): String = "$delegate!!"
|
||||||
|
|
||||||
@TypeRefinement
|
@TypeRefinement
|
||||||
override fun replaceDelegate(delegate: SimpleType) = DefinitelyNotNullType(delegate)
|
override fun replaceDelegate(delegate: SimpleType) = DefinitelyNotNullType(delegate, useCorrectedNullabilityForTypeParameters)
|
||||||
}
|
}
|
||||||
|
|
||||||
val KotlinType.isDefinitelyNotNullType: Boolean
|
val KotlinType.isDefinitelyNotNullType: Boolean
|
||||||
get() = unwrap() is DefinitelyNotNullType
|
get() = unwrap() is DefinitelyNotNullType
|
||||||
|
|
||||||
fun SimpleType.makeSimpleTypeDefinitelyNotNullOrNotNull(): SimpleType =
|
fun SimpleType.makeSimpleTypeDefinitelyNotNullOrNotNull(useCorrectedNullabilityForTypeParameters: Boolean = false): SimpleType =
|
||||||
DefinitelyNotNullType.makeDefinitelyNotNull(this)
|
DefinitelyNotNullType.makeDefinitelyNotNull(this, useCorrectedNullabilityForTypeParameters)
|
||||||
?: makeIntersectionTypeDefinitelyNotNullOrNotNull()
|
?: makeIntersectionTypeDefinitelyNotNullOrNotNull()
|
||||||
?: makeNullableAsSpecified(false)
|
?: makeNullableAsSpecified(false)
|
||||||
|
|
||||||
fun NewCapturedType.withNotNullProjection() =
|
fun NewCapturedType.withNotNullProjection() =
|
||||||
NewCapturedType(captureStatus, constructor, lowerType, annotations, isMarkedNullable, isProjectionNotNull = true)
|
NewCapturedType(captureStatus, constructor, lowerType, annotations, isMarkedNullable, isProjectionNotNull = true)
|
||||||
|
|
||||||
fun UnwrappedType.makeDefinitelyNotNullOrNotNull(): UnwrappedType =
|
fun UnwrappedType.makeDefinitelyNotNullOrNotNull(useCorrectedNullabilityForTypeParameters: Boolean = false): UnwrappedType =
|
||||||
DefinitelyNotNullType.makeDefinitelyNotNull(this)
|
DefinitelyNotNullType.makeDefinitelyNotNull(this, useCorrectedNullabilityForTypeParameters)
|
||||||
?: makeIntersectionTypeDefinitelyNotNullOrNotNull()
|
?: makeIntersectionTypeDefinitelyNotNullOrNotNull()
|
||||||
?: makeNullableAsSpecified(false)
|
?: makeNullableAsSpecified(false)
|
||||||
|
|
||||||
|
|||||||
@@ -227,11 +227,6 @@ fun KotlinType.containsTypeProjectionsInTopLevelArguments(): Boolean {
|
|||||||
return possiblyInnerType.arguments.any { it.isStarProjection || it.projectionKind != Variance.INVARIANT }
|
return possiblyInnerType.arguments.any { it.isStarProjection || it.projectionKind != Variance.INVARIANT }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun UnwrappedType.canHaveUndefinedNullability(): Boolean =
|
|
||||||
constructor is NewTypeVariableConstructor ||
|
|
||||||
constructor.declarationDescriptor is TypeParameterDescriptor ||
|
|
||||||
this is NewCapturedType
|
|
||||||
|
|
||||||
val TypeParameterDescriptor.representativeUpperBound: KotlinType
|
val TypeParameterDescriptor.representativeUpperBound: KotlinType
|
||||||
get() {
|
get() {
|
||||||
assert(upperBounds.isNotEmpty()) { "Upper bounds should not be empty: $this" }
|
assert(upperBounds.isNotEmpty()) { "Upper bounds should not be empty: $this" }
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ abstract class AbstractTypeCheckerContext : TypeSystemContext {
|
|||||||
return type
|
return type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open fun customIsSubtypeOf(subType: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean = true
|
||||||
|
|
||||||
abstract val isErrorTypeEqualsToAnything: Boolean
|
abstract val isErrorTypeEqualsToAnything: Boolean
|
||||||
|
|
||||||
abstract val isStubTypeEqualsToAnything: Boolean
|
abstract val isStubTypeEqualsToAnything: Boolean
|
||||||
@@ -175,6 +177,8 @@ object AbstractTypeChecker {
|
|||||||
): Boolean {
|
): Boolean {
|
||||||
if (subType === superType) return true
|
if (subType === superType) return true
|
||||||
|
|
||||||
|
if (!context.customIsSubtypeOf(subType, superType)) return false
|
||||||
|
|
||||||
return with(context) {
|
return with(context) {
|
||||||
completeIsSubTypeOf(prepareType(refineType(subType)), prepareType(refineType(superType)), isFromNullabilityConstraint)
|
completeIsSubTypeOf(prepareType(refineType(subType)), prepareType(refineType(superType)), isFromNullabilityConstraint)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user