FIR: Refine makesSenseToBeDefinitelyNotNull
Make it work just the same as the analogue from FE 1.0 This change is necessary since many tests start failing after we began reporting diagnostics after call completion
This commit is contained in:
committed by
teamcityserver
parent
a700fdc312
commit
42d387925d
+2
-1
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.typeContext
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||||
@@ -137,7 +138,7 @@ class FirTypeDeserializer(
|
|||||||
if (constructor is ConeTypeParameterLookupTag) {
|
if (constructor is ConeTypeParameterLookupTag) {
|
||||||
return ConeTypeParameterTypeImpl(constructor, isNullable = proto.nullable).let {
|
return ConeTypeParameterTypeImpl(constructor, isNullable = proto.nullable).let {
|
||||||
if (Flags.DEFINITELY_NOT_NULL_TYPE.get(proto.flags))
|
if (Flags.DEFINITELY_NOT_NULL_TYPE.get(proto.flags))
|
||||||
ConeDefinitelyNotNullType.create(it)
|
ConeDefinitelyNotNullType.create(it, moduleData.session.typeContext)
|
||||||
else
|
else
|
||||||
it
|
it
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -233,7 +233,10 @@ class ConeTypeSystemCommonBackendContextForTypeMapping(
|
|||||||
require(it is ConeKotlinType)
|
require(it is ConeKotlinType)
|
||||||
}
|
}
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return defaultType().withArguments((arguments as List<ConeKotlinType>).toTypedArray())
|
return defaultType().withArguments(
|
||||||
|
(arguments as List<ConeKotlinType>).toTypedArray(),
|
||||||
|
session.typeContext,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun TypeParameterMarker.representativeUpperBound(): ConeKotlinType {
|
override fun TypeParameterMarker.representativeUpperBound(): ConeKotlinType {
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
|||||||
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.typeContext
|
import org.jetbrains.kotlin.fir.typeContext
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.impl.*
|
import org.jetbrains.kotlin.fir.types.impl.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||||
@@ -24,6 +23,7 @@ import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
|||||||
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
|
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
|
||||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
@@ -230,10 +230,7 @@ class Fir2IrTypeConverter(
|
|||||||
|
|
||||||
private fun approximateType(type: ConeKotlinType): ConeKotlinType {
|
private fun approximateType(type: ConeKotlinType): ConeKotlinType {
|
||||||
if (type is ConeClassLikeType && type.typeArguments.isEmpty()) return type
|
if (type is ConeClassLikeType && type.typeArguments.isEmpty()) return type
|
||||||
val substitutor = object : AbstractConeSubstitutor() {
|
val substitutor = object : AbstractConeSubstitutor(session.typeContext) {
|
||||||
override val typeInferenceContext: ConeInferenceContext
|
|
||||||
get() = session.inferenceComponents.ctx
|
|
||||||
|
|
||||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||||
return if (type is ConeIntersectionType) {
|
return if (type is ConeIntersectionType) {
|
||||||
type.alternativeType?.let { substituteOrSelf(it) }
|
type.alternativeType?.let { substituteOrSelf(it) }
|
||||||
|
|||||||
+1
-4
@@ -664,10 +664,7 @@ class CallAndReferenceGenerator(
|
|||||||
return IrTypeOperatorCallImpl(this.startOffset, this.endOffset, samType, IrTypeOperator.SAM_CONVERSION, samType, this)
|
return IrTypeOperatorCallImpl(this.startOffset, this.endOffset, samType, IrTypeOperator.SAM_CONVERSION, samType, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val starProjectionApproximator = object : AbstractConeSubstitutor() {
|
private val starProjectionApproximator = object : AbstractConeSubstitutor(session.typeContext) {
|
||||||
override val typeInferenceContext: ConeInferenceContext
|
|
||||||
get() = session.inferenceComponents.ctx
|
|
||||||
|
|
||||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||||
if (type !is ConeClassLikeType || type.typeArguments.none { it == ConeStarProjection }) return null
|
if (type !is ConeClassLikeType || type.typeArguments.none { it == ConeStarProjection }) return null
|
||||||
val fir = type.lookupTag.toSymbol(session)?.fir as? FirTypeParameterRefsOwner ?: return null
|
val fir = type.lookupTag.toSymbol(session)?.fir as? FirTypeParameterRefsOwner ?: return null
|
||||||
|
|||||||
@@ -128,7 +128,11 @@ private fun coneFlexibleOrSimpleType(
|
|||||||
type is ConeTypeParameterType || type.isNullable
|
type is ConeTypeParameterType || type.isNullable
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
return ConeDefinitelyNotNullType.create(lowerBound) ?: lowerBound
|
return ConeDefinitelyNotNullType.create(
|
||||||
|
lowerBound,
|
||||||
|
session.typeContext,
|
||||||
|
useCorrectedNullabilityForFlexibleTypeParameters = true
|
||||||
|
) ?: lowerBound
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return lowerBound
|
return lowerBound
|
||||||
|
|||||||
@@ -34,12 +34,8 @@ import org.jetbrains.kotlin.fir.types.*
|
|||||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
|
||||||
import org.jetbrains.kotlin.name.*
|
import org.jetbrains.kotlin.name.*
|
||||||
|
import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
||||||
|
|
||||||
fun List<FirQualifierPart>.toTypeProjections(): Array<ConeTypeProjection> =
|
fun List<FirQualifierPart>.toTypeProjections(): Array<ConeTypeProjection> =
|
||||||
asReversed().flatMap { it.typeArgumentList.typeArguments.map { typeArgument -> typeArgument.toConeTypeProjection() } }.toTypedArray()
|
asReversed().flatMap { it.typeArgumentList.typeArguments.map { typeArgument -> typeArgument.toConeTypeProjection() } }.toTypedArray()
|
||||||
@@ -326,9 +322,8 @@ fun FirCheckedSafeCallSubject.propagateTypeFromOriginalReceiver(nullableReceiver
|
|||||||
|
|
||||||
val expandedReceiverType = if (receiverType is ConeClassLikeType) receiverType.fullyExpandedType(session) else receiverType
|
val expandedReceiverType = if (receiverType is ConeClassLikeType) receiverType.fullyExpandedType(session) else receiverType
|
||||||
|
|
||||||
val resolvedTypeRef = typeRef.resolvedTypeFromPrototype(
|
val resolvedTypeRef =
|
||||||
expandedReceiverType.makeConeTypeDefinitelyNotNullOrNotNull(session.inferenceComponents.ctx)
|
typeRef.resolvedTypeFromPrototype(expandedReceiverType.makeConeTypeDefinitelyNotNullOrNotNull(session.typeContext))
|
||||||
)
|
|
||||||
replaceTypeRef(resolvedTypeRef)
|
replaceTypeRef(resolvedTypeRef)
|
||||||
session.lookupTracker?.recordTypeResolveAsLookup(resolvedTypeRef, source, null)
|
session.lookupTracker?.recordTypeResolveAsLookup(resolvedTypeRef, source, null)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.fir.resolve
|
|||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
|
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
|
||||||
import org.jetbrains.kotlin.fir.declarations.expandedConeType
|
import org.jetbrains.kotlin.fir.declarations.expandedConeType
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||||
import org.jetbrains.kotlin.fir.typeContext
|
import org.jetbrains.kotlin.fir.typeContext
|
||||||
@@ -85,10 +84,7 @@ private fun mapTypeAliasArguments(
|
|||||||
}
|
}
|
||||||
val typeAliasMap = typeAlias.typeParameters.map { it.symbol }.zip(abbreviatedType.typeArguments).toMap()
|
val typeAliasMap = typeAlias.typeParameters.map { it.symbol }.zip(abbreviatedType.typeArguments).toMap()
|
||||||
|
|
||||||
val substitutor = object : AbstractConeSubstitutor() {
|
val substitutor = object : AbstractConeSubstitutor(useSiteSession.typeContext) {
|
||||||
override val typeInferenceContext: ConeInferenceContext
|
|
||||||
get() = useSiteSession.inferenceComponents.ctx
|
|
||||||
|
|
||||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -600,7 +600,7 @@ internal fun captureFromTypeParameterUpperBoundIfNeeded(
|
|||||||
|
|
||||||
val capturedType = context.captureFromExpression(chosenSupertype) as ConeKotlinType? ?: return argumentType
|
val capturedType = context.captureFromExpression(chosenSupertype) as ConeKotlinType? ?: return argumentType
|
||||||
return if (argumentType is ConeDefinitelyNotNullType) {
|
return if (argumentType is ConeDefinitelyNotNullType) {
|
||||||
ConeDefinitelyNotNullType.create(capturedType) ?: capturedType
|
ConeDefinitelyNotNullType.create(capturedType, session.typeContext) ?: capturedType
|
||||||
} else {
|
} else {
|
||||||
capturedType
|
capturedType
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-16
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.substitution
|
|||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.typeContext
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
||||||
@@ -15,9 +16,7 @@ import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
|||||||
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
||||||
import org.jetbrains.kotlin.types.model.typeConstructor
|
import org.jetbrains.kotlin.types.model.typeConstructor
|
||||||
|
|
||||||
abstract class AbstractConeSubstitutor : ConeSubstitutor() {
|
abstract class AbstractConeSubstitutor(private val typeContext: ConeTypeContext) : ConeSubstitutor() {
|
||||||
abstract val typeInferenceContext: ConeInferenceContext
|
|
||||||
|
|
||||||
private fun wrapProjection(old: ConeTypeProjection, newType: ConeKotlinType): ConeTypeProjection {
|
private fun wrapProjection(old: ConeTypeProjection, newType: ConeKotlinType): ConeTypeProjection {
|
||||||
return when (old) {
|
return when (old) {
|
||||||
is ConeStarProjection -> old
|
is ConeStarProjection -> old
|
||||||
@@ -37,8 +36,8 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
|
|||||||
|
|
||||||
fun ConeKotlinType?.updateNullabilityIfNeeded(originalType: ConeKotlinType): ConeKotlinType? {
|
fun ConeKotlinType?.updateNullabilityIfNeeded(originalType: ConeKotlinType): ConeKotlinType? {
|
||||||
return when {
|
return when {
|
||||||
originalType is ConeDefinitelyNotNullType -> this?.withNullability(ConeNullability.NOT_NULL, typeInferenceContext)
|
originalType is ConeDefinitelyNotNullType -> this?.withNullability(ConeNullability.NOT_NULL, typeContext)
|
||||||
originalType.isMarkedNullable -> this?.withNullability(ConeNullability.NULLABLE, typeInferenceContext)
|
originalType.isMarkedNullable -> this?.withNullability(ConeNullability.NULLABLE, typeContext)
|
||||||
else -> this
|
else -> this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,7 +45,7 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
|
|||||||
override fun substituteOrNull(type: ConeKotlinType): ConeKotlinType? {
|
override fun substituteOrNull(type: ConeKotlinType): ConeKotlinType? {
|
||||||
val newType = substituteType(type)
|
val newType = substituteType(type)
|
||||||
if (newType != null && type is ConeDefinitelyNotNullType) {
|
if (newType != null && type is ConeDefinitelyNotNullType) {
|
||||||
return newType.makeConeTypeDefinitelyNotNullOrNotNull(typeInferenceContext)
|
return newType.makeConeTypeDefinitelyNotNullOrNotNull(typeContext)
|
||||||
}
|
}
|
||||||
return (newType ?: type.substituteRecursive())
|
return (newType ?: type.substituteRecursive())
|
||||||
}
|
}
|
||||||
@@ -84,8 +83,8 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeDefinitelyNotNullType.substituteOriginal(): ConeKotlinType? {
|
private fun ConeDefinitelyNotNullType.substituteOriginal(): ConeKotlinType? {
|
||||||
val substituted = substituteOrNull(original)?.withNullability(ConeNullability.NOT_NULL, typeInferenceContext) ?: return null
|
val substituted = substituteOrNull(original)?.withNullability(ConeNullability.NOT_NULL, typeContext) ?: return null
|
||||||
return ConeDefinitelyNotNullType.create(substituted) ?: substituted
|
return ConeDefinitelyNotNullType.create(substituted, typeContext) ?: substituted
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeFlexibleType.substituteBounds(): ConeFlexibleType? {
|
private fun ConeFlexibleType.substituteBounds(): ConeFlexibleType? {
|
||||||
@@ -158,10 +157,7 @@ fun ConeSubstitutor.chain(other: ConeSubstitutor): ConeSubstitutor {
|
|||||||
data class ConeSubstitutorByMap(
|
data class ConeSubstitutorByMap(
|
||||||
val substitution: Map<FirTypeParameterSymbol, ConeKotlinType>,
|
val substitution: Map<FirTypeParameterSymbol, ConeKotlinType>,
|
||||||
val useSiteSession: FirSession
|
val useSiteSession: FirSession
|
||||||
) : AbstractConeSubstitutor() {
|
) : AbstractConeSubstitutor(useSiteSession.typeContext) {
|
||||||
override val typeInferenceContext: ConeInferenceContext
|
|
||||||
get() = useSiteSession.inferenceComponents.ctx
|
|
||||||
|
|
||||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||||
if (type !is ConeTypeParameterType) return null
|
if (type !is ConeTypeParameterType) return null
|
||||||
val result = substitution[type.lookupTag.symbol].updateNullabilityIfNeeded(type) ?: return null
|
val result = substitution[type.lookupTag.symbol].updateNullabilityIfNeeded(type) ?: return null
|
||||||
@@ -176,10 +172,7 @@ data class ConeSubstitutorByMap(
|
|||||||
|
|
||||||
fun createTypeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, ConeKotlinType>, context: ConeTypeContext): ConeSubstitutor {
|
fun createTypeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, ConeKotlinType>, context: ConeTypeContext): ConeSubstitutor {
|
||||||
if (map.isEmpty()) return ConeSubstitutor.Empty
|
if (map.isEmpty()) return ConeSubstitutor.Empty
|
||||||
return object : AbstractConeSubstitutor(), TypeSubstitutorMarker {
|
return object : AbstractConeSubstitutor(context), TypeSubstitutorMarker {
|
||||||
override val typeInferenceContext: ConeInferenceContext
|
|
||||||
get() = context.session.inferenceComponents.ctx
|
|
||||||
|
|
||||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||||
if (type !is ConeLookupTagBasedType && type !is ConeStubType) return null
|
if (type !is ConeLookupTagBasedType && type !is ConeStubType) return null
|
||||||
val new = map[type.typeConstructor(context)] ?: return null
|
val new = map[type.typeConstructor(context)] ?: return null
|
||||||
|
|||||||
+2
-1
@@ -298,7 +298,8 @@ class FirSyntheticCallGenerator(
|
|||||||
|
|
||||||
val returnType = rightArgumentType.resolvedTypeFromPrototype(
|
val returnType = rightArgumentType.resolvedTypeFromPrototype(
|
||||||
rightArgumentType.type.withAttributes(
|
rightArgumentType.type.withAttributes(
|
||||||
ConeAttributes.create(listOf(CompilerConeAttributes.Exact))
|
ConeAttributes.create(listOf(CompilerConeAttributes.Exact)),
|
||||||
|
session.typeContext,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -517,6 +517,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
returnExpression.resultType.approximatedIfNeededOrSelf(
|
returnExpression.resultType.approximatedIfNeededOrSelf(
|
||||||
inferenceComponents.approximator,
|
inferenceComponents.approximator,
|
||||||
simpleFunction?.visibilityForApproximation(),
|
simpleFunction?.visibilityForApproximation(),
|
||||||
|
transformer.session.typeContext,
|
||||||
simpleFunction?.isInline == true
|
simpleFunction?.isInline == true
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -843,7 +844,8 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
withExpectedType(
|
withExpectedType(
|
||||||
expectedType.approximatedIfNeededOrSelf(
|
expectedType.approximatedIfNeededOrSelf(
|
||||||
inferenceComponents.approximator,
|
inferenceComponents.approximator,
|
||||||
variable.visibilityForApproximation()
|
variable.visibilityForApproximation(),
|
||||||
|
inferenceComponents.session.typeContext,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
|||||||
import org.jetbrains.kotlin.fir.resolve.substitution.createTypeSubstitutorByTypeConstructor
|
import org.jetbrains.kotlin.fir.resolve.substitution.createTypeSubstitutorByTypeConstructor
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||||
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
import org.jetbrains.kotlin.types.model.*
|
import org.jetbrains.kotlin.types.model.*
|
||||||
import org.jetbrains.kotlin.utils.DFS
|
import org.jetbrains.kotlin.utils.DFS
|
||||||
@@ -258,12 +258,12 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
|||||||
|
|
||||||
override fun KotlinTypeMarker.removeAnnotations(): KotlinTypeMarker {
|
override fun KotlinTypeMarker.removeAnnotations(): KotlinTypeMarker {
|
||||||
require(this is ConeKotlinType)
|
require(this is ConeKotlinType)
|
||||||
return withAttributes(ConeAttributes.Empty)
|
return withAttributes(ConeAttributes.Empty, this@ConeInferenceContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun SimpleTypeMarker.replaceArguments(newArguments: List<TypeArgumentMarker>): SimpleTypeMarker {
|
override fun SimpleTypeMarker.replaceArguments(newArguments: List<TypeArgumentMarker>): SimpleTypeMarker {
|
||||||
require(this is ConeKotlinType)
|
require(this is ConeKotlinType)
|
||||||
return this.withArguments(newArguments.cast<List<ConeTypeProjection>>().toTypedArray())
|
return this.withArguments(newArguments.cast<List<ConeTypeProjection>>().toTypedArray(), this@ConeInferenceContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun KotlinTypeMarker.hasExactAnnotation(): Boolean {
|
override fun KotlinTypeMarker.hasExactAnnotation(): Boolean {
|
||||||
@@ -364,7 +364,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
|||||||
|
|
||||||
override fun KotlinTypeMarker.removeExactAnnotation(): KotlinTypeMarker {
|
override fun KotlinTypeMarker.removeExactAnnotation(): KotlinTypeMarker {
|
||||||
require(this is ConeKotlinType)
|
require(this is ConeKotlinType)
|
||||||
return withAttributes(attributes.remove(CompilerConeAttributes.Exact))
|
return withAttributes(attributes.remove(CompilerConeAttributes.Exact), this@ConeInferenceContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun TypeConstructorMarker.toErrorType(): SimpleTypeMarker {
|
override fun TypeConstructorMarker.toErrorType(): SimpleTypeMarker {
|
||||||
|
|||||||
@@ -415,7 +415,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun FirTypeParameterSymbol.allBoundsAreNullable(): Boolean {
|
private fun FirTypeParameterSymbol.allBoundsAreNullable(): Boolean {
|
||||||
return fir.bounds.all { it.coneType.isMarkedNullable }
|
return fir.bounds.all { it.coneType.isNullableType() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun TypeConstructorMarker.toFirRegularClass(): FirRegularClass? {
|
private fun TypeConstructorMarker.toFirRegularClass(): FirRegularClass? {
|
||||||
|
|||||||
@@ -47,23 +47,32 @@ fun ConeInferenceContext.intersectTypesOrNull(types: List<ConeKotlinType>): Cone
|
|||||||
fun TypeCheckerProviderContext.equalTypes(a: ConeKotlinType, b: ConeKotlinType): Boolean =
|
fun TypeCheckerProviderContext.equalTypes(a: ConeKotlinType, b: ConeKotlinType): Boolean =
|
||||||
AbstractTypeChecker.equalTypes(this, a, b)
|
AbstractTypeChecker.equalTypes(this, a, b)
|
||||||
|
|
||||||
fun ConeDefinitelyNotNullType.Companion.create(original: ConeKotlinType): ConeDefinitelyNotNullType? {
|
fun ConeDefinitelyNotNullType.Companion.create(
|
||||||
|
original: ConeKotlinType,
|
||||||
|
typeContext: ConeTypeContext,
|
||||||
|
useCorrectedNullabilityForFlexibleTypeParameters: Boolean = false,
|
||||||
|
): ConeDefinitelyNotNullType? {
|
||||||
return when {
|
return when {
|
||||||
original is ConeDefinitelyNotNullType -> original
|
original is ConeDefinitelyNotNullType -> original
|
||||||
makesSenseToBeDefinitelyNotNull(original) ->
|
typeContext
|
||||||
ConeDefinitelyNotNullType(original.lowerBoundIfFlexible())
|
.newBaseTypeCheckerContext(errorTypesEqualToAnything = false, stubTypesEqualToAnything = false)
|
||||||
|
.makesSenseToBeDefinitelyNotNull(original, useCorrectedNullabilityForFlexibleTypeParameters) ->
|
||||||
|
|
||||||
|
ConeDefinitelyNotNullType(
|
||||||
|
original.lowerBoundIfFlexible()
|
||||||
|
)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ConeKotlinType.makeConeTypeDefinitelyNotNullOrNotNull(typeContext: ConeInferenceContext): ConeKotlinType {
|
fun ConeKotlinType.makeConeTypeDefinitelyNotNullOrNotNull(typeContext: ConeTypeContext): ConeKotlinType {
|
||||||
if (this is ConeIntersectionType) {
|
if (this is ConeIntersectionType) {
|
||||||
return ConeIntersectionType(intersectedTypes.map { it.makeConeTypeDefinitelyNotNullOrNotNull(typeContext) })
|
return ConeIntersectionType(intersectedTypes.map { it.makeConeTypeDefinitelyNotNullOrNotNull(typeContext) })
|
||||||
}
|
}
|
||||||
return ConeDefinitelyNotNullType.create(this) ?: this.withNullability(ConeNullability.NOT_NULL, typeContext)
|
return ConeDefinitelyNotNullType.create(this, typeContext) ?: this.withNullability(ConeNullability.NOT_NULL, typeContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T : ConeKotlinType> T.withArguments(arguments: Array<out ConeTypeProjection>): T {
|
fun <T : ConeKotlinType> T.withArguments(arguments: Array<out ConeTypeProjection>, typeSystemContext: ConeTypeContext): T {
|
||||||
if (this.typeArguments === arguments) {
|
if (this.typeArguments === arguments) {
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
@@ -72,12 +81,15 @@ fun <T : ConeKotlinType> T.withArguments(arguments: Array<out ConeTypeProjection
|
|||||||
return when (this) {
|
return when (this) {
|
||||||
is ConeClassErrorType -> this
|
is ConeClassErrorType -> this
|
||||||
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, arguments, nullability.isNullable) as T
|
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, arguments, nullability.isNullable) as T
|
||||||
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType.create(original.withArguments(arguments))!! as T
|
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType.create(
|
||||||
|
original.withArguments(arguments, typeSystemContext),
|
||||||
|
typeSystemContext
|
||||||
|
)!! as T
|
||||||
else -> error("Not supported: $this: ${this.render()}")
|
else -> error("Not supported: $this: ${this.render()}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T : ConeKotlinType> T.withAttributes(attributes: ConeAttributes): T {
|
fun <T : ConeKotlinType> T.withAttributes(attributes: ConeAttributes, typeSystemContext: ConeTypeContext): T {
|
||||||
if (this.attributes == attributes) {
|
if (this.attributes == attributes) {
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
@@ -86,16 +98,22 @@ fun <T : ConeKotlinType> T.withAttributes(attributes: ConeAttributes): T {
|
|||||||
return when (this) {
|
return when (this) {
|
||||||
is ConeClassErrorType -> this
|
is ConeClassErrorType -> this
|
||||||
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, typeArguments, nullability.isNullable, attributes)
|
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, typeArguments, nullability.isNullable, attributes)
|
||||||
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType.create(original.withAttributes(attributes))!!
|
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType.create(
|
||||||
|
original.withAttributes(attributes, typeSystemContext),
|
||||||
|
typeSystemContext
|
||||||
|
)!!
|
||||||
is ConeTypeParameterTypeImpl -> ConeTypeParameterTypeImpl(lookupTag, nullability.isNullable, attributes)
|
is ConeTypeParameterTypeImpl -> ConeTypeParameterTypeImpl(lookupTag, nullability.isNullable, attributes)
|
||||||
is ConeFlexibleType -> ConeFlexibleType(lowerBound.withAttributes(attributes), upperBound.withAttributes(attributes))
|
is ConeFlexibleType -> ConeFlexibleType(
|
||||||
|
lowerBound.withAttributes(attributes, typeSystemContext),
|
||||||
|
upperBound.withAttributes(attributes, typeSystemContext)
|
||||||
|
)
|
||||||
else -> error("Not supported: $this: ${this.render()}")
|
else -> error("Not supported: $this: ${this.render()}")
|
||||||
} as T
|
} as T
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T : ConeKotlinType> T.withNullability(
|
fun <T : ConeKotlinType> T.withNullability(
|
||||||
nullability: ConeNullability,
|
nullability: ConeNullability,
|
||||||
typeContext: ConeInferenceContext,
|
typeContext: ConeTypeContext,
|
||||||
attributes: ConeAttributes = this.attributes,
|
attributes: ConeAttributes = this.attributes,
|
||||||
): T {
|
): T {
|
||||||
if (this.nullability == nullability && this.attributes == attributes) {
|
if (this.nullability == nullability && this.attributes == attributes) {
|
||||||
@@ -140,7 +158,7 @@ fun <T : ConeKotlinType> T.withNullability(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun coneFlexibleOrSimpleType(
|
fun coneFlexibleOrSimpleType(
|
||||||
typeContext: ConeInferenceContext,
|
typeContext: ConeTypeContext,
|
||||||
lowerBound: ConeKotlinType,
|
lowerBound: ConeKotlinType,
|
||||||
upperBound: ConeKotlinType,
|
upperBound: ConeKotlinType,
|
||||||
): ConeKotlinType {
|
): ConeKotlinType {
|
||||||
@@ -197,7 +215,7 @@ fun FirTypeRef.isUnsafeVarianceType(session: FirSession): Boolean {
|
|||||||
fun FirTypeRef.hasEnhancedNullability(): Boolean =
|
fun FirTypeRef.hasEnhancedNullability(): Boolean =
|
||||||
coneTypeSafe<ConeKotlinType>()?.hasEnhancedNullability == true
|
coneTypeSafe<ConeKotlinType>()?.hasEnhancedNullability == true
|
||||||
|
|
||||||
fun FirTypeRef.withoutEnhancedNullability(): FirTypeRef {
|
fun FirTypeRef.withoutEnhancedNullability(typeSystemContext: ConeTypeContext): FirTypeRef {
|
||||||
require(this is FirResolvedTypeRef)
|
require(this is FirResolvedTypeRef)
|
||||||
if (!hasEnhancedNullability()) return this
|
if (!hasEnhancedNullability()) return this
|
||||||
return buildResolvedTypeRef {
|
return buildResolvedTypeRef {
|
||||||
@@ -205,7 +223,8 @@ fun FirTypeRef.withoutEnhancedNullability(): FirTypeRef {
|
|||||||
type = this@withoutEnhancedNullability.type.withAttributes(
|
type = this@withoutEnhancedNullability.type.withAttributes(
|
||||||
ConeAttributes.create(
|
ConeAttributes.create(
|
||||||
this@withoutEnhancedNullability.type.attributes.filter { it != CompilerConeAttributes.EnhancedNullability }
|
this@withoutEnhancedNullability.type.attributes.filter { it != CompilerConeAttributes.EnhancedNullability }
|
||||||
)
|
),
|
||||||
|
typeSystemContext,
|
||||||
)
|
)
|
||||||
annotations += this@withoutEnhancedNullability.annotations
|
annotations += this@withoutEnhancedNullability.annotations
|
||||||
}
|
}
|
||||||
@@ -263,13 +282,14 @@ fun FirTypeRef.approximated(
|
|||||||
fun FirTypeRef.approximatedIfNeededOrSelf(
|
fun FirTypeRef.approximatedIfNeededOrSelf(
|
||||||
approximator: ConeTypeApproximator,
|
approximator: ConeTypeApproximator,
|
||||||
containingCallableVisibility: Visibility?,
|
containingCallableVisibility: Visibility?,
|
||||||
isInlineFunction: Boolean = false
|
typeSystemContext: ConeTypeContext,
|
||||||
|
isInlineFunction: Boolean = false,
|
||||||
): FirTypeRef {
|
): FirTypeRef {
|
||||||
val approximated = if (containingCallableVisibility == Visibilities.Public || containingCallableVisibility == Visibilities.Protected)
|
val approximated = if (containingCallableVisibility == Visibilities.Public || containingCallableVisibility == Visibilities.Protected)
|
||||||
approximatedForPublicPosition(approximator)
|
approximatedForPublicPosition(approximator)
|
||||||
else
|
else
|
||||||
this
|
this
|
||||||
return approximated.hideLocalTypeIfNeeded(containingCallableVisibility, isInlineFunction).withoutEnhancedNullability()
|
return approximated.hideLocalTypeIfNeeded(containingCallableVisibility, isInlineFunction).withoutEnhancedNullability(typeSystemContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirTypeRef.approximatedForPublicPosition(approximator: ConeTypeApproximator): FirTypeRef =
|
fun FirTypeRef.approximatedForPublicPosition(approximator: ConeTypeApproximator): FirTypeRef =
|
||||||
@@ -334,11 +354,11 @@ fun ConeTypeContext.captureFromArgumentsInternal(type: ConeKotlinType, status: C
|
|||||||
val capturedArguments = captureArguments(type, status) ?: return null
|
val capturedArguments = captureArguments(type, status) ?: return null
|
||||||
return if (type is ConeFlexibleType) {
|
return if (type is ConeFlexibleType) {
|
||||||
ConeFlexibleType(
|
ConeFlexibleType(
|
||||||
type.lowerBound.withArguments(capturedArguments),
|
type.lowerBound.withArguments(capturedArguments, this),
|
||||||
type.upperBound.withArguments(capturedArguments),
|
type.upperBound.withArguments(capturedArguments, this),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
type.withArguments(capturedArguments)
|
type.withArguments(capturedArguments, this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,12 +438,12 @@ fun ConeTypeContext.captureFromExpressionInternal(type: ConeKotlinType): ConeKot
|
|||||||
typeToReplace.intersectedTypes.map { componentType ->
|
typeToReplace.intersectedTypes.map { componentType ->
|
||||||
val capturedArguments = findCorrespondingCapturedArgumentsForType(componentType)
|
val capturedArguments = findCorrespondingCapturedArgumentsForType(componentType)
|
||||||
?: return@map componentType
|
?: return@map componentType
|
||||||
componentType.withArguments(capturedArguments)
|
componentType.withArguments(capturedArguments, this)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val capturedArguments = findCorrespondingCapturedArgumentsForType(typeToReplace)
|
val capturedArguments = findCorrespondingCapturedArgumentsForType(typeToReplace)
|
||||||
?: return listOf(typeToReplace)
|
?: return listOf(typeToReplace)
|
||||||
listOf(typeToReplace.withArguments(capturedArguments))
|
listOf(typeToReplace.withArguments(capturedArguments, this))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,11 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
|
import org.jetbrains.kotlin.types.AbstractNullabilityChecker
|
||||||
|
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
|
||||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||||
import kotlin.contracts.ExperimentalContracts
|
import kotlin.contracts.ExperimentalContracts
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
@@ -137,15 +139,37 @@ fun FirTypeProjection.toConeTypeProjection(): ConeTypeProjection =
|
|||||||
else -> error("!")
|
else -> error("!")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun makesSenseToBeDefinitelyNotNull(type: ConeKotlinType): Boolean =
|
fun AbstractTypeCheckerContext.makesSenseToBeDefinitelyNotNull(
|
||||||
type.canHaveUndefinedNullability() // TODO: also check nullability
|
type: ConeKotlinType,
|
||||||
|
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 is ConeTypeParameterType) {
|
||||||
|
// Effectively checks if the type is flexible or has nullable bound
|
||||||
|
return with(typeSystemContext) {
|
||||||
|
type.isNullableType()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actually, this code should work for type parameters as well, but it breaks some cases
|
||||||
|
// See KT-40114
|
||||||
|
|
||||||
|
return !AbstractNullabilityChecker.isSubtypeOfAny(this, type)
|
||||||
|
}
|
||||||
|
|
||||||
fun ConeKotlinType.canHaveUndefinedNullability(): Boolean {
|
fun ConeKotlinType.canHaveUndefinedNullability(): Boolean {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is ConeTypeVariableType,
|
is ConeTypeVariableType,
|
||||||
is ConeCapturedType
|
is ConeCapturedType,
|
||||||
|
is ConeTypeParameterType
|
||||||
-> true
|
-> true
|
||||||
is ConeTypeParameterType -> type.isMarkedNullable || !hasNotNullUpperBound()
|
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
|||||||
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.typeContext
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
|
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.api.withFirDeclaration
|
import org.jetbrains.kotlin.idea.fir.low.level.api.api.withFirDeclaration
|
||||||
@@ -79,11 +80,8 @@ internal fun KtNamedClassOrObjectSymbol.typeForClassSymbol(psiElement: PsiElemen
|
|||||||
|
|
||||||
private class AnonymousTypesSubstitutor(
|
private class AnonymousTypesSubstitutor(
|
||||||
private val session: FirSession,
|
private val session: FirSession,
|
||||||
private val state: FirModuleResolveState
|
private val state: FirModuleResolveState,
|
||||||
) : AbstractConeSubstitutor() {
|
) : AbstractConeSubstitutor(session.typeContext) {
|
||||||
override val typeInferenceContext: ConeInferenceContext
|
|
||||||
get() = session.inferenceComponents.ctx
|
|
||||||
|
|
||||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||||
|
|
||||||
if (type !is ConeClassLikeType) return null
|
if (type !is ConeClassLikeType) return null
|
||||||
|
|||||||
Reference in New Issue
Block a user