Report warnings on overrides with wrong types nullability
^KT-48899 Fixed
This commit is contained in:
committed by
TeamCityServer
parent
ec97dab6cd
commit
f7ef551f99
@@ -445,9 +445,10 @@ object AbstractTypeChecker {
|
||||
return true
|
||||
}
|
||||
|
||||
@OptIn(ObsoleteTypeKind::class)
|
||||
private fun TypeSystemContext.isCommonDenotableType(type: KotlinTypeMarker): Boolean =
|
||||
type.typeConstructor().isDenotable() &&
|
||||
!type.isDynamic() && !type.isDefinitelyNotNullType() &&
|
||||
!type.isDynamic() && !type.isDefinitelyNotNullType() && !type.isNotNullTypeVariable() &&
|
||||
type.lowerBoundIfFlexible().typeConstructor() == type.upperBoundIfFlexible().typeConstructor()
|
||||
|
||||
fun effectiveVariance(declared: TypeVariance, useSite: TypeVariance): TypeVariance? {
|
||||
@@ -702,7 +703,8 @@ object AbstractNullabilityChecker {
|
||||
if (superType.isMarkedNullable()) return true
|
||||
|
||||
// i.e. subType is definitely not null
|
||||
if (subType.isDefinitelyNotNullType()) return true
|
||||
@OptIn(ObsoleteTypeKind::class)
|
||||
if (subType.isDefinitelyNotNullType() || subType.isNotNullTypeVariable()) return true
|
||||
|
||||
// i.e. subType is captured type, projection of which is marked not-null
|
||||
if (subType is CapturedTypeMarker && subType.isProjectionNotNull()) return true
|
||||
|
||||
@@ -377,6 +377,11 @@ interface TypeSystemContext : TypeSystemOptimizationContext {
|
||||
|
||||
fun KotlinTypeMarker.isDefinitelyNotNullType(): Boolean = asSimpleType()?.asDefinitelyNotNullType() != null
|
||||
|
||||
// This kind of types is obsolete (expected to be removed at 1.7) and shouldn't be used further in a new code
|
||||
// Now, such types are being replaced with definitely non-nullable types
|
||||
@ObsoleteTypeKind
|
||||
fun KotlinTypeMarker.isNotNullTypeVariable(): Boolean = false
|
||||
|
||||
fun KotlinTypeMarker.hasFlexibleNullability() =
|
||||
lowerBoundIfFlexible().isMarkedNullable() != upperBoundIfFlexible().isMarkedNullable()
|
||||
|
||||
@@ -495,3 +500,6 @@ fun requireOrDescribe(condition: Boolean, value: Any?) {
|
||||
"Unexpected: value = '$value'$typeInfo"
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresOptIn("This kinds of type is obsolete and should not be used until you really need it")
|
||||
annotation class ObsoleteTypeKind
|
||||
|
||||
@@ -60,18 +60,23 @@ public class OverridingUtil {
|
||||
};
|
||||
|
||||
static {
|
||||
|
||||
DEFAULT = new OverridingUtil(DEFAULT_TYPE_CONSTRUCTOR_EQUALITY, KotlinTypeRefiner.Default.INSTANCE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static OverridingUtil createWithEqualityAxioms(@NotNull KotlinTypeChecker.TypeConstructorEquality equalityAxioms) {
|
||||
return new OverridingUtil(equalityAxioms, KotlinTypeRefiner.Default.INSTANCE);
|
||||
DEFAULT = new OverridingUtil(
|
||||
DEFAULT_TYPE_CONSTRUCTOR_EQUALITY, KotlinTypeRefiner.Default.INSTANCE, KotlinTypePreparator.Default.INSTANCE,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static OverridingUtil createWithTypeRefiner(@NotNull KotlinTypeRefiner kotlinTypeRefiner) {
|
||||
return new OverridingUtil(DEFAULT_TYPE_CONSTRUCTOR_EQUALITY, kotlinTypeRefiner);
|
||||
return new OverridingUtil(DEFAULT_TYPE_CONSTRUCTOR_EQUALITY, kotlinTypeRefiner, KotlinTypePreparator.Default.INSTANCE, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static OverridingUtil createWithTypePreparatorAndCustomSubtype(
|
||||
@NotNull KotlinTypePreparator kotlinTypePreparator,
|
||||
@NotNull Function2<KotlinType, KotlinType, Boolean> customSubtype
|
||||
) {
|
||||
return new OverridingUtil(DEFAULT_TYPE_CONSTRUCTOR_EQUALITY, KotlinTypeRefiner.Default.INSTANCE, kotlinTypePreparator, customSubtype);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -79,18 +84,24 @@ public class OverridingUtil {
|
||||
@NotNull KotlinTypeRefiner kotlinTypeRefiner,
|
||||
@NotNull KotlinTypeChecker.TypeConstructorEquality equalityAxioms
|
||||
) {
|
||||
return new OverridingUtil(equalityAxioms, kotlinTypeRefiner);
|
||||
return new OverridingUtil(equalityAxioms, kotlinTypeRefiner, KotlinTypePreparator.Default.INSTANCE, null);
|
||||
}
|
||||
|
||||
private final KotlinTypeRefiner kotlinTypeRefiner;
|
||||
private final KotlinTypePreparator kotlinTypePreparator;
|
||||
private final KotlinTypeChecker.TypeConstructorEquality equalityAxioms;
|
||||
private final Function2<KotlinType, KotlinType, Boolean> customSubtype;
|
||||
|
||||
private OverridingUtil(
|
||||
@NotNull KotlinTypeChecker.TypeConstructorEquality axioms,
|
||||
@NotNull KotlinTypeRefiner kotlinTypeRefiner
|
||||
@NotNull KotlinTypeRefiner kotlinTypeRefiner,
|
||||
@NotNull KotlinTypePreparator kotlinTypePreparator,
|
||||
@Nullable Function2<KotlinType, KotlinType, Boolean> customSubtype
|
||||
) {
|
||||
equalityAxioms = axioms;
|
||||
this.kotlinTypeRefiner = kotlinTypeRefiner;
|
||||
this.kotlinTypePreparator = kotlinTypePreparator;
|
||||
this.customSubtype = customSubtype;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -395,8 +406,9 @@ public class OverridingUtil {
|
||||
"Should be the same number of type parameters: " + firstParameters + " vs " + secondParameters;
|
||||
|
||||
if (firstParameters.isEmpty()) {
|
||||
return new OverridingUtilTypeSystemContext(null, equalityAxioms, kotlinTypeRefiner)
|
||||
.newTypeCheckerState(true, true);
|
||||
return new OverridingUtilTypeSystemContext(
|
||||
null, equalityAxioms, kotlinTypeRefiner, kotlinTypePreparator, customSubtype
|
||||
).newTypeCheckerState(true, true);
|
||||
}
|
||||
|
||||
Map<TypeConstructor, TypeConstructor> matchingTypeConstructors = new HashMap<TypeConstructor, TypeConstructor>();
|
||||
@@ -404,8 +416,9 @@ public class OverridingUtil {
|
||||
matchingTypeConstructors.put(firstParameters.get(i).getTypeConstructor(), secondParameters.get(i).getTypeConstructor());
|
||||
}
|
||||
|
||||
return new OverridingUtilTypeSystemContext(matchingTypeConstructors, equalityAxioms, kotlinTypeRefiner)
|
||||
.newTypeCheckerState(true, true);
|
||||
return new OverridingUtilTypeSystemContext(
|
||||
matchingTypeConstructors, equalityAxioms, kotlinTypeRefiner, kotlinTypePreparator, customSubtype
|
||||
).newTypeCheckerState(true, true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+26
-10
@@ -5,18 +5,19 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve
|
||||
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeCheckerState
|
||||
import org.jetbrains.kotlin.types.TypeConstructor
|
||||
import org.jetbrains.kotlin.types.checker.ClassicTypeSystemContext
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
|
||||
import org.jetbrains.kotlin.types.checker.createClassicTypeCheckerState
|
||||
import org.jetbrains.kotlin.types.checker.*
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||
|
||||
class OverridingUtilTypeSystemContext(
|
||||
val matchingTypeConstructors: Map<TypeConstructor, TypeConstructor>?,
|
||||
private val equalityAxioms: KotlinTypeChecker.TypeConstructorEquality,
|
||||
val kotlinTypeRefiner: KotlinTypeRefiner
|
||||
private val kotlinTypeRefiner: KotlinTypeRefiner,
|
||||
private val kotlinTypePreparator: KotlinTypePreparator,
|
||||
private val customSubtype: ((KotlinType, KotlinType) -> Boolean)? = null,
|
||||
) : ClassicTypeSystemContext {
|
||||
|
||||
override fun areEqualTypeConstructors(c1: TypeConstructorMarker, c2: TypeConstructorMarker): Boolean {
|
||||
@@ -29,12 +30,27 @@ class OverridingUtilTypeSystemContext(
|
||||
errorTypesEqualToAnything: Boolean,
|
||||
stubTypesEqualToAnything: Boolean
|
||||
): TypeCheckerState {
|
||||
return createClassicTypeCheckerState(
|
||||
errorTypesEqualToAnything,
|
||||
stubTypesEqualToAnything,
|
||||
if (customSubtype == null) {
|
||||
return createClassicTypeCheckerState(
|
||||
errorTypesEqualToAnything,
|
||||
stubTypesEqualToAnything,
|
||||
typeSystemContext = this,
|
||||
kotlinTypeRefiner = kotlinTypeRefiner,
|
||||
kotlinTypePreparator = kotlinTypePreparator,
|
||||
)
|
||||
}
|
||||
|
||||
return object : TypeCheckerState(
|
||||
errorTypesEqualToAnything, stubTypesEqualToAnything, allowedTypeVariable = true,
|
||||
typeSystemContext = this,
|
||||
kotlinTypeRefiner = kotlinTypeRefiner
|
||||
)
|
||||
kotlinTypePreparator, kotlinTypeRefiner,
|
||||
) {
|
||||
override fun customIsSubtypeOf(subType: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean {
|
||||
require(subType is KotlinType)
|
||||
require(superType is KotlinType)
|
||||
return customSubtype.invoke(subType, superType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun areEqualTypeConstructorsByAxioms(a: TypeConstructor, b: TypeConstructor): Boolean {
|
||||
|
||||
@@ -150,6 +150,9 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
||||
return this as? DefinitelyNotNullType
|
||||
}
|
||||
|
||||
@OptIn(ObsoleteTypeKind::class)
|
||||
override fun KotlinTypeMarker.isNotNullTypeVariable(): Boolean = this is NotNullTypeVariable
|
||||
|
||||
override fun SimpleTypeMarker.isMarkedNullable(): Boolean {
|
||||
require(this is SimpleType, this::errorMessage)
|
||||
return this.isMarkedNullable
|
||||
|
||||
Reference in New Issue
Block a user