diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeUtils.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeUtils.kt index e2683df9291..7062e884af3 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeUtils.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeUtils.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.types +import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.types.Variance @@ -55,3 +56,22 @@ fun ConeClassLikeType.replaceArgumentsWithStarProjections(): ConeClassLikeType { val newArguments = Array(typeArguments.size) { ConeStarProjection } return withArguments(newArguments) } + +val ConeKotlinType.isAny: Boolean get() = isBuiltinType(StandardClassIds.Any, false) +val ConeKotlinType.isNullableAny: Boolean get() = isBuiltinType(StandardClassIds.Any, true) +val ConeKotlinType.isNothing: Boolean get() = isBuiltinType(StandardClassIds.Nothing, false) +val ConeKotlinType.isNullableNothing: Boolean get() = isBuiltinType(StandardClassIds.Nothing, true) +val ConeKotlinType.isUnit: Boolean get() = isBuiltinType(StandardClassIds.Unit, false) +val ConeKotlinType.isBoolean: Boolean get() = isBuiltinType(StandardClassIds.Boolean, false) +val ConeKotlinType.isEnum: Boolean get() = isBuiltinType(StandardClassIds.Enum, false) +val ConeKotlinType.isArrayType: Boolean + get() { + return isBuiltinType(StandardClassIds.Array, false) || + StandardClassIds.primitiveArrayTypeByElementType.values.any { isBuiltinType(it, false) } + } + +private fun ConeKotlinType.isBuiltinType(classId: ClassId, isNullable: Boolean): Boolean { + + if (this !is ConeClassLikeType) return false + return lookupTag.classId == classId && type.isNullable == isNullable +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallableReferenceResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallableReferenceResolution.kt index 3fcf7709d64..c7c0e2ce9a4 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallableReferenceResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallableReferenceResolution.kt @@ -226,7 +226,7 @@ private fun BodyResolveComponents.getCallableReferenceAdaptation( } } - val coercionStrategy = if (returnExpectedType.isUnit && !function.returnTypeRef.isUnit) + val coercionStrategy = if (returnExpectedType.isUnitOrFlexibleUnit && !function.returnTypeRef.isUnit) CoercionStrategy.COERCION_TO_UNIT else CoercionStrategy.NO_COERCION @@ -288,7 +288,7 @@ private enum class VarargMappingState { private fun FirFunction<*>.indexOf(valueParameter: FirValueParameter): Int = valueParameters.indexOf(valueParameter) -val ConeKotlinType.isUnit: Boolean +val ConeKotlinType.isUnitOrFlexibleUnit: Boolean get() { val type = this.lowerBoundIfFlexible() if (type.isNullable) return false diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt index 5bba7ca49e6..1e5395e994e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt @@ -168,14 +168,14 @@ class PostponedArgumentsAnalyzer( val lastExpression = lambda.atom.body?.statements?.lastOrNull() as? FirExpression var hasExpressionInReturnArguments = false // No constraint for return expressions of lambda if it has Unit return type. - val lambdaReturnType = lambda.returnType.let(substitute).takeUnless { it.isUnit } + val lambdaReturnType = lambda.returnType.let(substitute).takeUnless { it.isUnitOrFlexibleUnit } returnArguments.forEach { if (it !is FirExpression) return@forEach hasExpressionInReturnArguments = true // If it is the last expression, and the expected type is Unit, that expression will be coerced to Unit. // If the last expression is of Unit type, of course it's not coercion-to-Unit case. val lastExpressionCoercedToUnit = - it == lastExpression && expectedReturnType?.isUnit == true && !it.typeRef.coneType.isUnit + it == lastExpression && expectedReturnType?.isUnitOrFlexibleUnit == true && !it.typeRef.coneType.isUnitOrFlexibleUnit // No constraint for the last expression of lambda if it will be coerced to Unit. if (!lastExpressionCoercedToUnit) { candidate.resolveArgumentExpression( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt index 7b2e341b402..b43f0ee261d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt @@ -7,13 +7,12 @@ package org.jetbrains.kotlin.fir.types import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility -import org.jetbrains.kotlin.fir.FirFakeSourceElementKind -import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.classId import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic -import org.jetbrains.kotlin.fir.fakeElement -import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.resolve.fullyExpandedType +import org.jetbrains.kotlin.fir.resolve.toSymbol +import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef @@ -184,6 +183,10 @@ fun ConeKotlinType.isUnsafeVarianceType(session: FirSession): Boolean { return type.attributes.unsafeVarianceType != null } +fun ConeKotlinType.toSymbol(session: FirSession): AbstractFirBasedSymbol<*>? { + return (this as? ConeLookupTagBasedType)?.lookupTag?.toSymbol(session) +} + fun FirTypeRef.isUnsafeVarianceType(session: FirSession): Boolean { return coneTypeSafe()?.isUnsafeVarianceType(session) == true }