[FIR] Implement capturing of cone types same as for kotlin types
This commit is contained in:
@@ -14,10 +14,12 @@ object StandardClassIds {
|
||||
|
||||
val BASE_KOTLIN_PACKAGE = FqName("kotlin")
|
||||
val BASE_REFLECT_PACKAGE = BASE_KOTLIN_PACKAGE.child(Name.identifier("reflect"))
|
||||
val BASE_COLLECTIONS_PACKAGE = BASE_KOTLIN_PACKAGE.child(Name.identifier("collections"))
|
||||
private fun String.baseId() = ClassId(BASE_KOTLIN_PACKAGE, Name.identifier(this))
|
||||
private fun ClassId.unsignedId() = ClassId(BASE_KOTLIN_PACKAGE, Name.identifier("U" + shortClassName.identifier))
|
||||
private fun String.reflectId() = ClassId(BASE_REFLECT_PACKAGE, Name.identifier(this))
|
||||
private fun Name.primitiveArrayId() = ClassId(Array.packageFqName, Name.identifier(identifier + Array.shortClassName.identifier))
|
||||
private fun String.collectionsId() = ClassId(BASE_COLLECTIONS_PACKAGE, Name.identifier(this))
|
||||
|
||||
val Nothing = "Nothing".baseId()
|
||||
val Unit = "Unit".baseId()
|
||||
@@ -85,6 +87,25 @@ object StandardClassIds {
|
||||
return "Function$n".baseId()
|
||||
}
|
||||
|
||||
val Iterator = "Iterator".collectionsId()
|
||||
val Iterable = "Iterable".collectionsId()
|
||||
val Collection = "Collection".collectionsId()
|
||||
val List = "List".collectionsId()
|
||||
val ListIterator = "ListIterator".collectionsId()
|
||||
val Set = "Set".collectionsId()
|
||||
val Map = "Map".collectionsId()
|
||||
val MutableIterator = "MutableIterator".collectionsId()
|
||||
|
||||
val MutableIterable = "MutableIterable".collectionsId()
|
||||
val MutableCollection = "MutableCollection".collectionsId()
|
||||
val MutableList = "MutableList".collectionsId()
|
||||
val MutableListIterator = "MutableListIterator".collectionsId()
|
||||
val MutableSet = "MutableSet".collectionsId()
|
||||
val MutableMap = "MutableMap".collectionsId()
|
||||
|
||||
val MapEntry = Map.createNestedClassId(Name.identifier("Entry"))
|
||||
val MutableMapEntry = MutableMap.createNestedClassId(Name.identifier("MutableEntry"))
|
||||
|
||||
val Suppress = "Suppress".baseId()
|
||||
}
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ abstract class LogicSystem<FLOW : Flow>(protected val context: ConeInferenceCont
|
||||
if (types.any { it.isEmpty() }) return mutableSetOf()
|
||||
val intersectedTypes = types.map {
|
||||
if (it.size > 1) {
|
||||
context.intersectTypes(it.toList()) as ConeKotlinType
|
||||
context.intersectTypes(it.toList())
|
||||
} else {
|
||||
assert(it.size == 1) { "We've already checked each set of types is not empty." }
|
||||
it.single()
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.fir.types
|
||||
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
|
||||
object ConeFlexibleTypeBoundsChecker {
|
||||
private val fqNames = StandardNames.FqNames
|
||||
private val baseTypesToMutableEquivalent = mapOf(
|
||||
StandardClassIds.Iterable to StandardClassIds.MutableIterable,
|
||||
StandardClassIds.Iterator to StandardClassIds.MutableIterator,
|
||||
StandardClassIds.ListIterator to StandardClassIds.MutableListIterator,
|
||||
StandardClassIds.List to StandardClassIds.MutableList,
|
||||
StandardClassIds.Collection to StandardClassIds.MutableCollection,
|
||||
StandardClassIds.Set to StandardClassIds.MutableSet,
|
||||
StandardClassIds.Map to StandardClassIds.MutableMap,
|
||||
StandardClassIds.MapEntry to StandardClassIds.MutableMapEntry
|
||||
)
|
||||
private val mutableToBaseMap = baseTypesToMutableEquivalent.entries.associateBy({ it.value }) { it.key }
|
||||
|
||||
fun areTypesMayBeLowerAndUpperBoundsOfSameFlexibleTypeByMutability(a: ConeKotlinType, b: ConeKotlinType): Boolean {
|
||||
val classId = a.classId ?: return false
|
||||
val possiblePairBound = (baseTypesToMutableEquivalent[classId] ?: mutableToBaseMap[classId]) ?: return false
|
||||
|
||||
return possiblePairBound == b.classId
|
||||
}
|
||||
|
||||
// We consider base bounds as not mutable collections
|
||||
fun getBaseBoundFqNameByMutability(a: ConeKotlinType): ClassId? {
|
||||
val classId = a.classId ?: return null
|
||||
|
||||
if (classId in baseTypesToMutableEquivalent) return classId
|
||||
|
||||
return mutableToBaseMap[classId]
|
||||
}
|
||||
}
|
||||
@@ -340,10 +340,6 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
||||
return false
|
||||
}
|
||||
|
||||
override fun captureFromExpression(type: KotlinTypeMarker): KotlinTypeMarker? {
|
||||
return type
|
||||
}
|
||||
|
||||
override fun createErrorType(debugName: String): ConeClassErrorType {
|
||||
return ConeClassErrorType(ConeIntermediateDiagnostic(debugName))
|
||||
}
|
||||
|
||||
@@ -228,9 +228,8 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
|
||||
private fun TypeConstructorMarker.toClassLikeSymbol(): FirClassLikeSymbol<*>? = (this as? ConeClassLikeLookupTag)?.toSymbol(session)
|
||||
|
||||
override fun TypeConstructorMarker.supertypes(): Collection<KotlinTypeMarker> {
|
||||
override fun TypeConstructorMarker.supertypes(): Collection<ConeKotlinType> {
|
||||
if (this is ErrorTypeConstructor) return emptyList()
|
||||
//require(this is ConeSymbol)
|
||||
return when (this) {
|
||||
is ConeTypeVariableTypeConstructor -> emptyList()
|
||||
is ConeTypeParameterLookupTag -> symbol.fir.bounds.map { it.coneType }
|
||||
@@ -307,56 +306,14 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
fir.classKind != ClassKind.ANNOTATION_CLASS
|
||||
}
|
||||
|
||||
override fun captureFromExpression(type: KotlinTypeMarker): KotlinTypeMarker? {
|
||||
require(type is ConeKotlinType)
|
||||
return captureFromExpressionInternal(type)
|
||||
}
|
||||
|
||||
override fun captureFromArguments(type: SimpleTypeMarker, status: CaptureStatus): SimpleTypeMarker? {
|
||||
require(type is ConeKotlinType)
|
||||
val argumentsCount = type.typeArguments.size
|
||||
if (argumentsCount == 0) return null
|
||||
|
||||
val typeConstructor = type.typeConstructor()
|
||||
if (argumentsCount != typeConstructor.parametersCount()) return null
|
||||
|
||||
if (type.typeArguments.all { it !is ConeStarProjection && it.kind == ProjectionKind.INVARIANT }) return null
|
||||
|
||||
val newArguments = Array(argumentsCount) { index ->
|
||||
val argument = type.typeArguments[index]
|
||||
if (argument !is ConeStarProjection && argument.kind == ProjectionKind.INVARIANT) return@Array argument
|
||||
|
||||
val lowerType = if (argument !is ConeStarProjection && argument.getVariance() == TypeVariance.IN) {
|
||||
(argument as ConeKotlinTypeProjection).type
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
ConeCapturedType(status, lowerType, argument, typeConstructor.getParameter(index))
|
||||
}
|
||||
|
||||
val substitutor = substitutorByMap((0 until argumentsCount).map { index ->
|
||||
(typeConstructor.getParameter(index) as ConeTypeParameterLookupTag).symbol to (newArguments[index] as ConeKotlinType)
|
||||
}.toMap())
|
||||
|
||||
for (index in 0 until argumentsCount) {
|
||||
val oldArgument = type.typeArguments[index]
|
||||
val newArgument = newArguments[index]
|
||||
|
||||
if (oldArgument !is ConeStarProjection && oldArgument.kind == ProjectionKind.INVARIANT) continue
|
||||
|
||||
val parameter = typeConstructor.getParameter(index)
|
||||
val upperBounds = (0 until parameter.upperBoundCount()).mapTo(mutableListOf()) { paramIndex ->
|
||||
substitutor.safeSubstitute(
|
||||
this as TypeSystemInferenceExtensionContext, parameter.getUpperBound(paramIndex)
|
||||
)
|
||||
}
|
||||
|
||||
if (!oldArgument.isStarProjection() && oldArgument.getVariance() == TypeVariance.OUT) {
|
||||
upperBounds += oldArgument.getType()
|
||||
}
|
||||
|
||||
require(newArgument is ConeCapturedType)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
newArgument.constructor.supertypes = upperBounds as List<ConeKotlinType>
|
||||
}
|
||||
|
||||
return type.withArguments(newArguments)
|
||||
return captureFromArgumentsInternal(type, status) as SimpleTypeMarker?
|
||||
}
|
||||
|
||||
override fun SimpleTypeMarker.asArgumentList(): TypeArgumentListMarker {
|
||||
@@ -392,10 +349,6 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
typeConstructor is ConeTypeParameterLookupTag
|
||||
}
|
||||
|
||||
override fun captureFromExpression(type: KotlinTypeMarker): KotlinTypeMarker? {
|
||||
TODO("not implemented")
|
||||
}
|
||||
|
||||
override fun SimpleTypeMarker.isPrimitiveType(): Boolean {
|
||||
if (this is ConeClassLikeType) {
|
||||
return StandardClassIds.primitiveTypes.contains(this.lookupTag.classId)
|
||||
@@ -417,7 +370,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
return ConeTypeIntersector.intersectTypes(this as ConeInferenceContext, types as List<ConeKotlinType>) as SimpleTypeMarker
|
||||
}
|
||||
|
||||
override fun intersectTypes(types: List<KotlinTypeMarker>): KotlinTypeMarker {
|
||||
override fun intersectTypes(types: List<KotlinTypeMarker>): ConeKotlinType {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return ConeTypeIntersector.intersectTypes(this as ConeInferenceContext, types as List<ConeKotlinType>)
|
||||
}
|
||||
|
||||
@@ -11,8 +11,10 @@ import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.classId
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
@@ -22,6 +24,7 @@ import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator
|
||||
import org.jetbrains.kotlin.types.AbstractStrictEqualityTypeChecker
|
||||
import org.jetbrains.kotlin.types.AbstractTypeApproximator
|
||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
||||
import org.jetbrains.kotlin.types.model.*
|
||||
|
||||
fun ConeInferenceContext.commonSuperTypeOrNull(types: List<ConeKotlinType>): ConeKotlinType? {
|
||||
return when (types.size) {
|
||||
@@ -322,3 +325,159 @@ private fun FirTypeRef.hideLocalTypeIfNeeded(
|
||||
return this
|
||||
}
|
||||
|
||||
fun ConeTypeContext.captureFromArgumentsInternal(type: ConeKotlinType, status: CaptureStatus): ConeKotlinType? {
|
||||
val capturedArguments = captureArguments(type, status) ?: return null
|
||||
return if (type is ConeFlexibleType) {
|
||||
ConeFlexibleType(
|
||||
type.lowerBound.withArguments(capturedArguments),
|
||||
type.upperBound.withArguments(capturedArguments),
|
||||
)
|
||||
} else {
|
||||
type.withArguments(capturedArguments)
|
||||
}
|
||||
}
|
||||
|
||||
private fun ConeTypeContext.captureArguments(type: ConeKotlinType, status: CaptureStatus): Array<ConeTypeProjection>? {
|
||||
val argumentsCount = type.typeArguments.size
|
||||
if (argumentsCount == 0) return null
|
||||
|
||||
val typeConstructor = type.typeConstructor()
|
||||
if (argumentsCount != typeConstructor.parametersCount()) return null
|
||||
|
||||
if (type.typeArguments.all { it !is ConeStarProjection && it.kind == ProjectionKind.INVARIANT }) return null
|
||||
|
||||
val newArguments = Array(argumentsCount) { index ->
|
||||
val argument = type.typeArguments[index]
|
||||
if (argument !is ConeStarProjection && argument.kind == ProjectionKind.INVARIANT) return@Array argument
|
||||
|
||||
val lowerType = if (argument !is ConeStarProjection && argument.getVariance() == TypeVariance.IN) {
|
||||
(argument as ConeKotlinTypeProjection).type
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
ConeCapturedType(status, lowerType, argument, typeConstructor.getParameter(index))
|
||||
}
|
||||
|
||||
val substitutor = substitutorByMap((0 until argumentsCount).map { index ->
|
||||
(typeConstructor.getParameter(index) as ConeTypeParameterLookupTag).symbol to (newArguments[index] as ConeKotlinType)
|
||||
}.toMap())
|
||||
|
||||
for (index in 0 until argumentsCount) {
|
||||
val oldArgument = type.typeArguments[index]
|
||||
val newArgument = newArguments[index]
|
||||
|
||||
if (oldArgument !is ConeStarProjection && oldArgument.kind == ProjectionKind.INVARIANT) continue
|
||||
|
||||
val parameter = typeConstructor.getParameter(index)
|
||||
val upperBounds = (0 until parameter.upperBoundCount()).mapTo(mutableListOf()) { paramIndex ->
|
||||
substitutor.safeSubstitute(
|
||||
this as TypeSystemInferenceExtensionContext, parameter.getUpperBound(paramIndex)
|
||||
)
|
||||
}
|
||||
|
||||
if (!oldArgument.isStarProjection() && oldArgument.getVariance() == TypeVariance.OUT) {
|
||||
upperBounds += oldArgument.getType()
|
||||
}
|
||||
|
||||
require(newArgument is ConeCapturedType)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
newArgument.constructor.supertypes = upperBounds as List<ConeKotlinType>
|
||||
}
|
||||
return newArguments
|
||||
}
|
||||
|
||||
fun ConeTypeContext.captureFromExpressionInternal(type: ConeKotlinType): ConeKotlinType? {
|
||||
if (type !is ConeIntersectionType && type !is ConeFlexibleType) {
|
||||
return captureFromArgumentsInternal(type, CaptureStatus.FROM_EXPRESSION)
|
||||
}
|
||||
/*
|
||||
* We capture arguments in the intersection types in specific way:
|
||||
* 1) Firstly, we create captured arguments for all type arguments grouped by a type constructor* and a type argument's type.
|
||||
* It means, that we create only one captured argument for two types `Foo<*>` and `Foo<*>?` within a flexible type, for instance.
|
||||
* * In addition to grouping by type constructors, we look at possibility locating of two types in different bounds of the same flexible type.
|
||||
* This is necessary in order to create the same captured arguments,
|
||||
* for example, for `MutableList` in the lower bound of the flexible type and for `List` in the upper one.
|
||||
* Example: MutableList<*>..List<*>? -> MutableList<Captured1(*)>..List<Captured2(*)>?, Captured1(*) and Captured2(*) are the same.
|
||||
* 2) Secondly, we replace type arguments with captured arguments by given a type constructor and type arguments.
|
||||
*/
|
||||
val capturedArgumentsByComponents = captureArgumentsForIntersectionType(type) ?: return null
|
||||
|
||||
// We reuse `TypeToCapture` for some types, suitability to reuse defines by `isSuitableForType`
|
||||
fun findCorrespondingCapturedArgumentsForType(type: ConeKotlinType) =
|
||||
capturedArgumentsByComponents.find { typeToCapture -> typeToCapture.isSuitableForType(type, this) }?.capturedArguments
|
||||
|
||||
fun replaceArgumentsWithCapturedArgumentsByIntersectionComponents(typeToReplace: ConeKotlinType): List<ConeKotlinType> {
|
||||
return if (typeToReplace is ConeIntersectionType) {
|
||||
typeToReplace.intersectedTypes.map { componentType ->
|
||||
val capturedArguments = findCorrespondingCapturedArgumentsForType(componentType)
|
||||
?: return@map componentType
|
||||
componentType.withArguments(capturedArguments)
|
||||
}
|
||||
} else {
|
||||
val capturedArguments = findCorrespondingCapturedArgumentsForType(typeToReplace)
|
||||
?: return listOf(typeToReplace)
|
||||
listOf(typeToReplace.withArguments(capturedArguments))
|
||||
}
|
||||
}
|
||||
|
||||
return if (type is ConeFlexibleType) {
|
||||
val lowerIntersectedType = intersectTypes(replaceArgumentsWithCapturedArgumentsByIntersectionComponents(type.lowerBound))
|
||||
.withNullability(type.lowerBound.isMarkedNullable) as ConeKotlinType
|
||||
val upperIntersectedType = intersectTypes(replaceArgumentsWithCapturedArgumentsByIntersectionComponents(type.upperBound))
|
||||
.withNullability(type.upperBound.isMarkedNullable) as ConeKotlinType
|
||||
|
||||
ConeFlexibleType(lowerIntersectedType, upperIntersectedType)
|
||||
} else {
|
||||
intersectTypes(replaceArgumentsWithCapturedArgumentsByIntersectionComponents(type)).withNullability(type.isMarkedNullable) as ConeKotlinType
|
||||
}
|
||||
}
|
||||
|
||||
private fun ConeTypeContext.captureArgumentsForIntersectionType(type: ConeKotlinType): List<CapturedArguments>? {
|
||||
// It's possible to have one of the bounds as non-intersection type
|
||||
fun getTypesToCapture(type: ConeKotlinType) =
|
||||
if (type is ConeIntersectionType) type.intersectedTypes else listOf(type)
|
||||
|
||||
val filteredTypesToCapture =
|
||||
when (type) {
|
||||
is ConeFlexibleType -> {
|
||||
val typesToCapture = getTypesToCapture(type.lowerBound) + getTypesToCapture(type.upperBound)
|
||||
typesToCapture.distinctBy {
|
||||
(ConeFlexibleTypeBoundsChecker.getBaseBoundFqNameByMutability(it) ?: it.typeConstructor(this)) to it.typeArguments
|
||||
}
|
||||
}
|
||||
is ConeIntersectionType -> type.intersectedTypes
|
||||
else -> error("Should not be here")
|
||||
}
|
||||
|
||||
var changed = false
|
||||
|
||||
val capturedArgumentsByTypes = filteredTypesToCapture.mapNotNull { typeToCapture ->
|
||||
val capturedArguments = captureArguments(typeToCapture, CaptureStatus.FROM_EXPRESSION)
|
||||
?: return@mapNotNull null
|
||||
changed = true
|
||||
CapturedArguments(capturedArguments, originalType = typeToCapture)
|
||||
}
|
||||
|
||||
if (!changed) return null
|
||||
|
||||
return capturedArgumentsByTypes
|
||||
}
|
||||
|
||||
private class CapturedArguments(val capturedArguments: Array<ConeTypeProjection>, private val originalType: ConeKotlinType) {
|
||||
fun isSuitableForType(type: ConeKotlinType, context: ConeTypeContext): Boolean {
|
||||
val areArgumentsMatched = type.typeArguments.withIndex().all { (i, typeArgumentsType) ->
|
||||
originalType.typeArguments.size > i && typeArgumentsType == originalType.typeArguments[i]
|
||||
}
|
||||
|
||||
if (!areArgumentsMatched) return false
|
||||
|
||||
val areConstructorsMatched = originalType.typeConstructor(context) == type.typeConstructor(context)
|
||||
|| ConeFlexibleTypeBoundsChecker.areTypesMayBeLowerAndUpperBoundsOfSameFlexibleTypeByMutability(originalType, type)
|
||||
|
||||
if (!areConstructorsMatched) return false
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -7,4 +7,4 @@ class A<T>
|
||||
fun <T1> A<T1>.foo() = X1
|
||||
fun <T2> A<out T2>.foo() = X2
|
||||
|
||||
fun <T> A<out T>.test() = foo() // TODO fix constraint system
|
||||
fun <T> A<out T>.test() = <!AMBIGUITY!>foo<!>() // TODO fix constraint system
|
||||
|
||||
@@ -10,29 +10,29 @@ fun <T> case_1(x: T) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.<!INAPPLICABLE_CANDIDATE!>equals<!>(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!><!UNSAFE_CALL!>.<!>propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.<!INAPPLICABLE_CANDIDATE!>propAny<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!><!UNSAFE_CALL!>.<!>funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.<!INAPPLICABLE_CANDIDATE!>funAny<!>()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { <!INAPPLICABLE_CANDIDATE!>equals<!>(null) }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { propT }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { <!UNSAFE_CALL!>propAny<!> }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { <!INAPPLICABLE_CANDIDATE!>propAny<!> }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { propNullableT }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { propNullableAny }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { funT() }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { <!UNSAFE_CALL!>funAny<!>() }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { <!INAPPLICABLE_CANDIDATE!>funAny<!>() }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { funNullableT() }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.apply { funNullableAny(); <!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.<!INAPPLICABLE_CANDIDATE!>equals<!>(null) }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.also { <!DEBUG_INFO_EXPRESSION_TYPE("T")!>it<!>.<!INAPPLICABLE_CANDIDATE!>equals<!>(null) }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.also { <!DEBUG_INFO_EXPRESSION_TYPE("T")!>it<!>.propT }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.also { <!DEBUG_INFO_EXPRESSION_TYPE("T")!>it<!><!UNSAFE_CALL!>.<!>propAny }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.also { <!DEBUG_INFO_EXPRESSION_TYPE("T")!>it<!>.<!INAPPLICABLE_CANDIDATE!>propAny<!> }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.also { <!DEBUG_INFO_EXPRESSION_TYPE("T")!>it<!>.propNullableT }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.also { <!DEBUG_INFO_EXPRESSION_TYPE("T")!>it<!>.propNullableAny }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.also { <!DEBUG_INFO_EXPRESSION_TYPE("T")!>it<!>.funT() }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.also { <!DEBUG_INFO_EXPRESSION_TYPE("T")!>it<!><!UNSAFE_CALL!>.<!>funAny() }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.also { <!DEBUG_INFO_EXPRESSION_TYPE("T")!>it<!>.<!INAPPLICABLE_CANDIDATE!>funAny<!>() }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.also { <!DEBUG_INFO_EXPRESSION_TYPE("T")!>it<!>.funNullableT() }
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.also { <!DEBUG_INFO_EXPRESSION_TYPE("T")!>it<!>.funNullableAny() }
|
||||
}
|
||||
|
||||
@@ -246,11 +246,11 @@ fun <T>case_18(x: T, f: Boolean) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.<!INAPPLICABLE_CANDIDATE!>equals<!>(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!><!UNSAFE_CALL!>.<!>propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.<!INAPPLICABLE_CANDIDATE!>propAny<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!><!UNSAFE_CALL!>.<!>funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.<!INAPPLICABLE_CANDIDATE!>funAny<!>()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("T")!>x<!>.funNullableAny()
|
||||
}
|
||||
@@ -263,21 +263,21 @@ fun <K, V>case_19(map: MutableMap<K, V>, y: Nothing?) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K")!>k<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K")!>k<!>.<!INAPPLICABLE_CANDIDATE!>equals<!>(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K")!>k<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K")!>k<!><!UNSAFE_CALL!>.<!>propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K")!>k<!>.<!INAPPLICABLE_CANDIDATE!>propAny<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K")!>k<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K")!>k<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K")!>k<!>.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K")!>k<!><!UNSAFE_CALL!>.<!>funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K")!>k<!>.<!INAPPLICABLE_CANDIDATE!>funAny<!>()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K")!>k<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("K")!>k<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("V")!>v<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("V")!>v<!>.<!INAPPLICABLE_CANDIDATE!>equals<!>(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("V")!>v<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("V")!>v<!><!UNSAFE_CALL!>.<!>propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("V")!>v<!>.<!INAPPLICABLE_CANDIDATE!>propAny<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("V")!>v<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("V")!>v<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("V")!>v<!>.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("V")!>v<!><!UNSAFE_CALL!>.<!>funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("V")!>v<!>.<!INAPPLICABLE_CANDIDATE!>funAny<!>()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("V")!>v<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("V")!>v<!>.funNullableAny()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user