FIR: Support type aliases to function types in resolution
This commit is contained in:
@@ -12,6 +12,8 @@ import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
|||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.inferenceContext
|
import org.jetbrains.kotlin.fir.inferenceContext
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||||
import org.jetbrains.kotlin.fir.resolve.withNullability
|
import org.jetbrains.kotlin.fir.resolve.withNullability
|
||||||
@@ -19,11 +21,13 @@ import org.jetbrains.kotlin.fir.returnExpressions
|
|||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirILTTypeRefPlaceHolder
|
import org.jetbrains.kotlin.fir.scopes.impl.FirILTTypeRefPlaceHolder
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperator
|
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperator
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall
|
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
|
import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
|
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
|
||||||
import org.jetbrains.kotlin.types.model.CaptureStatus
|
import org.jetbrains.kotlin.types.model.CaptureStatus
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
|
|
||||||
fun Candidate.resolveArgumentExpression(
|
fun Candidate.resolveArgumentExpression(
|
||||||
@@ -299,14 +303,14 @@ private fun Candidate.getExpectedTypeWithSAMConversion(
|
|||||||
argument: FirExpression,
|
argument: FirExpression,
|
||||||
candidateExpectedType: ConeKotlinType
|
candidateExpectedType: ConeKotlinType
|
||||||
): ConeKotlinType? {
|
): ConeKotlinType? {
|
||||||
if (candidateExpectedType.isBuiltinFunctionalType) return null
|
if (candidateExpectedType.isBuiltinFunctionalType(session)) return null
|
||||||
// TODO: if (!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.SamConversionPerArgument)) return null
|
// TODO: if (!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.SamConversionPerArgument)) return null
|
||||||
val firNamedFunction = symbol.fir as? FirSimpleFunction ?: return null
|
val firNamedFunction = symbol.fir as? FirSimpleFunction ?: return null
|
||||||
if (!samResolver.shouldRunSamConversionForFunction(firNamedFunction)) return null
|
if (!samResolver.shouldRunSamConversionForFunction(firNamedFunction)) return null
|
||||||
|
|
||||||
val argumentIsFunctional = when ((argument as? FirWrappedArgumentExpression)?.expression ?: argument) {
|
val argumentIsFunctional = when ((argument as? FirWrappedArgumentExpression)?.expression ?: argument) {
|
||||||
is FirAnonymousFunction, is FirCallableReferenceAccess -> true
|
is FirAnonymousFunction, is FirCallableReferenceAccess -> true
|
||||||
else -> argument.typeRef.coneTypeSafe<ConeKotlinType>()?.isBuiltinFunctionalType == true
|
else -> argument.typeRef.coneTypeSafe<ConeKotlinType>()?.isBuiltinFunctionalType(session) == true
|
||||||
}
|
}
|
||||||
if (!argumentIsFunctional) return null
|
if (!argumentIsFunctional) return null
|
||||||
|
|
||||||
@@ -335,3 +339,19 @@ internal fun FirExpression.getExpectedType(
|
|||||||
private fun ConeKotlinType.varargElementType(session: FirSession): ConeKotlinType {
|
private fun ConeKotlinType.varargElementType(session: FirSession): ConeKotlinType {
|
||||||
return this.arrayElementType(session) ?: error("Failed to extract! ${this.render()}!")
|
return this.arrayElementType(session) ?: error("Failed to extract! ${this.render()}!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun FirTypeRef.isExtensionFunctionType(session: FirSession): Boolean {
|
||||||
|
if (annotations.any(FirAnnotationCall::isExtensionFunctionAnnotationCall)) return true
|
||||||
|
|
||||||
|
if (this !is FirResolvedTypeRef) return false
|
||||||
|
val type = type as? ConeClassLikeType ?: return false
|
||||||
|
if (type.fullyExpandedType(session) === type) return false
|
||||||
|
|
||||||
|
val typeAlias = type.lookupTag
|
||||||
|
.toSymbol(session)
|
||||||
|
?.safeAs<FirTypeAliasSymbol>()?.fir ?: return false
|
||||||
|
|
||||||
|
if (typeAlias.expandedTypeRef.annotations.any(FirAnnotationCall::isExtensionFunctionAnnotationCall)) return true
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
+77
-60
@@ -5,11 +5,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.calls
|
package org.jetbrains.kotlin.fir.resolve.calls
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
|
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||||
import org.jetbrains.kotlin.fir.resolve.DoubleColonLHS
|
import org.jetbrains.kotlin.fir.resolve.DoubleColonLHS
|
||||||
import org.jetbrains.kotlin.fir.resolve.createFunctionalType
|
import org.jetbrains.kotlin.fir.resolve.createFunctionalType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
@@ -31,8 +33,8 @@ fun Candidate.preprocessLambdaArgument(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val resolvedArgument =
|
val resolvedArgument =
|
||||||
extractLambdaInfoFromFunctionalType(expectedType, expectedTypeRef, argument)
|
extractLambdaInfoFromFunctionalType(expectedType, expectedTypeRef, argument, bodyResolveComponents.session)
|
||||||
?: extraLambdaInfo(expectedType, expectedTypeRef, argument, csBuilder)
|
?: extraLambdaInfo(expectedType, expectedTypeRef, argument, csBuilder, bodyResolveComponents.session)
|
||||||
|
|
||||||
if (expectedType != null) {
|
if (expectedType != null) {
|
||||||
// TODO: add SAM conversion processing
|
// TODO: add SAM conversion processing
|
||||||
@@ -53,51 +55,45 @@ fun Candidate.preprocessCallableReference(
|
|||||||
expectedType: ConeKotlinType
|
expectedType: ConeKotlinType
|
||||||
) {
|
) {
|
||||||
val lhs = bodyResolveComponents.doubleColonExpressionResolver.resolveDoubleColonLHS(argument)
|
val lhs = bodyResolveComponents.doubleColonExpressionResolver.resolveDoubleColonLHS(argument)
|
||||||
postponedAtoms += ResolvedCallableReferenceAtom(argument, expectedType, lhs)
|
postponedAtoms += ResolvedCallableReferenceAtom(argument, expectedType, lhs, bodyResolveComponents.session)
|
||||||
}
|
}
|
||||||
|
|
||||||
val ConeKotlinType.isBuiltinFunctionalType: Boolean
|
fun ConeKotlinType.isBuiltinFunctionalType(session: FirSession): Boolean {
|
||||||
get() {
|
return when (this) {
|
||||||
return when (this) {
|
is ConeClassLikeType -> fullyExpandedType(session).lookupTag.classId.asString().startsWith("kotlin/Function")
|
||||||
is ConeClassLikeType -> this.lookupTag.classId.asString().startsWith("kotlin/Function")
|
else -> false
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ConeKotlinType.isSuspendFunctionType(session: FirSession): Boolean {
|
||||||
private val ConeKotlinType.isSuspendFunctionType: Boolean
|
return when (val type = this) {
|
||||||
get() {
|
is ConeClassLikeType -> {
|
||||||
val type = this
|
val classId = type.fullyExpandedType(session).lookupTag.classId
|
||||||
return when (type) {
|
classId.packageFqName.asString() == "kotlin" && classId.relativeClassName.asString().startsWith("SuspendFunction")
|
||||||
is ConeClassLikeType -> {
|
|
||||||
val classId = type.lookupTag.classId
|
|
||||||
classId.packageFqName.asString() == "kotlin" && classId.relativeClassName.asString().startsWith("SuspendFunction")
|
|
||||||
}
|
|
||||||
else -> false
|
|
||||||
}
|
}
|
||||||
|
else -> false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun ConeKotlinType.receiverType(expectedTypeRef: FirTypeRef): ConeKotlinType? {
|
fun ConeKotlinType.receiverType(expectedTypeRef: FirTypeRef, session: FirSession): ConeKotlinType? {
|
||||||
if (expectedTypeRef.isExtensionFunctionType()) {
|
if (isBuiltinFunctionalType(session) && expectedTypeRef.isExtensionFunctionType(session)) {
|
||||||
return (this.typeArguments.first() as ConeTypedProjection).type
|
return ((this as ConeClassLikeType).fullyExpandedType(session).typeArguments.first() as ConeTypedProjection).type
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
val ConeKotlinType.returnType: ConeKotlinType?
|
fun ConeKotlinType.returnType(session: FirSession): ConeKotlinType? {
|
||||||
get() {
|
require(this is ConeClassLikeType)
|
||||||
require(this is ConeClassLikeType)
|
val projection = fullyExpandedType(session).typeArguments.last()
|
||||||
val projection = typeArguments.last()
|
return (projection as? ConeTypedProjection)?.type
|
||||||
return (projection as? ConeTypedProjection)?.type
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val ConeKotlinType.valueParameterTypes: List<ConeKotlinType?>
|
private fun ConeKotlinType.valueParameterTypes(session: FirSession): List<ConeKotlinType?> {
|
||||||
get() {
|
require(this is ConeClassLikeType)
|
||||||
require(this is ConeClassLikeType)
|
return fullyExpandedType(session).typeArguments.dropLast(1).map {
|
||||||
return typeArguments.dropLast(1).map {
|
(it as? ConeTypedProjection)?.type
|
||||||
(it as? ConeTypedProjection)?.type
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val FirAnonymousFunction.returnType get() = returnTypeRef.coneTypeSafe<ConeKotlinType>()
|
private val FirAnonymousFunction.returnType get() = returnTypeRef.coneTypeSafe<ConeKotlinType>()
|
||||||
private val FirAnonymousFunction.receiverType get() = receiverTypeRef?.coneTypeSafe<ConeKotlinType>()
|
private val FirAnonymousFunction.receiverType get() = receiverTypeRef?.coneTypeSafe<ConeKotlinType>()
|
||||||
@@ -107,13 +103,15 @@ private fun extraLambdaInfo(
|
|||||||
expectedType: ConeKotlinType?,
|
expectedType: ConeKotlinType?,
|
||||||
expectedTypeRef: FirTypeRef,
|
expectedTypeRef: FirTypeRef,
|
||||||
argument: FirAnonymousFunction,
|
argument: FirAnonymousFunction,
|
||||||
csBuilder: ConstraintSystemBuilder
|
csBuilder: ConstraintSystemBuilder,
|
||||||
|
session: FirSession
|
||||||
): ResolvedLambdaAtom {
|
): ResolvedLambdaAtom {
|
||||||
// val builtIns = csBuilder.builtIns
|
// val builtIns = csBuilder.builtIns
|
||||||
val isSuspend = expectedType?.isSuspendFunctionType ?: false
|
val isSuspend = expectedType?.isSuspendFunctionType(session) ?: false
|
||||||
|
|
||||||
val isFunctionSupertype =
|
val isFunctionSupertype =
|
||||||
expectedType != null && expectedType.lowerBoundIfFlexible().isBuiltinFunctionalType//isNotNullOrNullableFunctionSupertype(expectedType)
|
expectedType != null && expectedType.lowerBoundIfFlexible()
|
||||||
|
.isBuiltinFunctionalType(session)//isNotNullOrNullableFunctionSupertype(expectedType)
|
||||||
val argumentAsFunctionExpression = argument//.safeAs<FunctionExpression>()
|
val argumentAsFunctionExpression = argument//.safeAs<FunctionExpression>()
|
||||||
|
|
||||||
val typeVariable = TypeVariableForLambdaReturnType(argument, "_L")
|
val typeVariable = TypeVariableForLambdaReturnType(argument, "_L")
|
||||||
@@ -124,7 +122,8 @@ private fun extraLambdaInfo(
|
|||||||
?: expectedType?.typeArguments?.singleOrNull()?.safeAs<ConeTypedProjection>()?.type?.takeIf { isFunctionSupertype }
|
?: expectedType?.typeArguments?.singleOrNull()?.safeAs<ConeTypedProjection>()?.type?.takeIf { isFunctionSupertype }
|
||||||
?: typeVariable.defaultType
|
?: typeVariable.defaultType
|
||||||
|
|
||||||
val nothingType = argument.session.builtinTypes.nothingType.type //StandardClassIds.Nothing(argument.session.firSymbolProvider).constructType(emptyArray(), false)
|
val nothingType = argument.session.builtinTypes.nothingType
|
||||||
|
.type //StandardClassIds.Nothing(argument.session.firSymbolProvider).constructType(emptyArray(), false)
|
||||||
val parameters = argument.valueParameters?.map {
|
val parameters = argument.valueParameters?.map {
|
||||||
it.returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: nothingType
|
it.returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: nothingType
|
||||||
} ?: emptyList()
|
} ?: emptyList()
|
||||||
@@ -138,20 +137,23 @@ private fun extraLambdaInfo(
|
|||||||
internal fun extractLambdaInfoFromFunctionalType(
|
internal fun extractLambdaInfoFromFunctionalType(
|
||||||
expectedType: ConeKotlinType?,
|
expectedType: ConeKotlinType?,
|
||||||
expectedTypeRef: FirTypeRef,
|
expectedTypeRef: FirTypeRef,
|
||||||
argument: FirAnonymousFunction
|
argument: FirAnonymousFunction,
|
||||||
|
session: FirSession
|
||||||
): ResolvedLambdaAtom? {
|
): ResolvedLambdaAtom? {
|
||||||
if (expectedType == null) return null
|
if (expectedType == null) return null
|
||||||
if (expectedType is ConeFlexibleType) return extractLambdaInfoFromFunctionalType(expectedType.lowerBound, expectedTypeRef, argument)
|
if (expectedType is ConeFlexibleType) {
|
||||||
if (!expectedType.isBuiltinFunctionalType) return null
|
return extractLambdaInfoFromFunctionalType(expectedType.lowerBound, expectedTypeRef, argument, session)
|
||||||
|
}
|
||||||
|
if (!expectedType.isBuiltinFunctionalType(session)) return null
|
||||||
|
|
||||||
val argumentAsFunctionExpression = argument//.safeAs<FunctionExpression>()
|
val argumentAsFunctionExpression = argument//.safeAs<FunctionExpression>()
|
||||||
val receiverType = argumentAsFunctionExpression.receiverType ?: expectedType.receiverType(expectedTypeRef)
|
val receiverType = argumentAsFunctionExpression.receiverType ?: expectedType.receiverType(expectedTypeRef, session)
|
||||||
val returnType = argumentAsFunctionExpression.returnType ?: expectedType.returnType ?: return null
|
val returnType = argumentAsFunctionExpression.returnType ?: expectedType.returnType(session) ?: return null
|
||||||
val parameters = extractLambdaParameters(expectedType, argument, expectedTypeRef.isExtensionFunctionType())
|
val parameters = extractLambdaParameters(expectedType, argument, expectedTypeRef.isExtensionFunctionType(session), session)
|
||||||
|
|
||||||
return ResolvedLambdaAtom(
|
return ResolvedLambdaAtom(
|
||||||
argument,
|
argument,
|
||||||
expectedType.isSuspendFunctionType,
|
expectedType.isSuspendFunctionType(session),
|
||||||
receiverType,
|
receiverType,
|
||||||
parameters,
|
parameters,
|
||||||
returnType,
|
returnType,
|
||||||
@@ -159,12 +161,16 @@ internal fun extractLambdaInfoFromFunctionalType(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun extractLambdaParameters(expectedType: ConeKotlinType, argument: FirAnonymousFunction, expectedTypeIsExtensionFunctionType: Boolean): List<ConeKotlinType> {
|
private fun extractLambdaParameters(
|
||||||
|
expectedType: ConeKotlinType,
|
||||||
|
argument: FirAnonymousFunction,
|
||||||
|
expectedTypeIsExtensionFunctionType: Boolean,
|
||||||
|
session: FirSession
|
||||||
|
): List<ConeKotlinType> {
|
||||||
val parameters = argument.valueParameters
|
val parameters = argument.valueParameters
|
||||||
val expectedParameters = expectedType.extractParametersForFunctionalType(expectedTypeIsExtensionFunctionType)
|
val expectedParameters = expectedType.extractParametersForFunctionalType(expectedTypeIsExtensionFunctionType, session)
|
||||||
|
|
||||||
val nullableAnyType = argument.session.builtinTypes.nullableAnyType.type //StandardClassIds.Any(argument.session.firSymbolProvider).constructType(emptyArray(), true)
|
|
||||||
|
|
||||||
|
val nullableAnyType = argument.session.builtinTypes.nullableAnyType.type
|
||||||
if (parameters.isEmpty()) {
|
if (parameters.isEmpty()) {
|
||||||
return expectedParameters.map { it?.type ?: nullableAnyType }
|
return expectedParameters.map { it?.type ?: nullableAnyType }
|
||||||
}
|
}
|
||||||
@@ -175,8 +181,11 @@ private fun extractLambdaParameters(expectedType: ConeKotlinType, argument: FirA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeKotlinType.extractParametersForFunctionalType(isExtensionFunctionType: Boolean): List<ConeKotlinType?> {
|
private fun ConeKotlinType.extractParametersForFunctionalType(
|
||||||
return valueParameterTypes.let {
|
isExtensionFunctionType: Boolean,
|
||||||
|
session: FirSession
|
||||||
|
): List<ConeKotlinType?> {
|
||||||
|
return valueParameterTypes(session).let {
|
||||||
if (isExtensionFunctionType) {
|
if (isExtensionFunctionType) {
|
||||||
it.drop(1)
|
it.drop(1)
|
||||||
} else {
|
} else {
|
||||||
@@ -217,7 +226,8 @@ class ResolvedLambdaAtom(
|
|||||||
class ResolvedCallableReferenceAtom(
|
class ResolvedCallableReferenceAtom(
|
||||||
val reference: FirCallableReferenceAccess,
|
val reference: FirCallableReferenceAccess,
|
||||||
val expectedType: ConeKotlinType?,
|
val expectedType: ConeKotlinType?,
|
||||||
val lhs: DoubleColonLHS?
|
val lhs: DoubleColonLHS?,
|
||||||
|
private val session: FirSession
|
||||||
) : PostponedResolvedAtomMarker {
|
) : PostponedResolvedAtomMarker {
|
||||||
override var analyzed: Boolean = false
|
override var analyzed: Boolean = false
|
||||||
var postponed: Boolean = false
|
var postponed: Boolean = false
|
||||||
@@ -227,23 +237,27 @@ class ResolvedCallableReferenceAtom(
|
|||||||
override val inputTypes: Collection<ConeKotlinType>
|
override val inputTypes: Collection<ConeKotlinType>
|
||||||
get() {
|
get() {
|
||||||
if (!postponed) return emptyList()
|
if (!postponed) return emptyList()
|
||||||
return extractInputOutputTypesFromCallableReferenceExpectedType(expectedType)?.inputTypes ?: listOfNotNull(expectedType)
|
return extractInputOutputTypesFromCallableReferenceExpectedType(expectedType, session)?.inputTypes
|
||||||
|
?: listOfNotNull(expectedType)
|
||||||
}
|
}
|
||||||
override val outputType: ConeKotlinType?
|
override val outputType: ConeKotlinType?
|
||||||
get() {
|
get() {
|
||||||
if (!postponed) return null
|
if (!postponed) return null
|
||||||
return extractInputOutputTypesFromCallableReferenceExpectedType(expectedType)?.outputType
|
return extractInputOutputTypesFromCallableReferenceExpectedType(expectedType, session)?.outputType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class InputOutputTypes(val inputTypes: List<ConeKotlinType>, val outputType: ConeKotlinType)
|
private data class InputOutputTypes(val inputTypes: List<ConeKotlinType>, val outputType: ConeKotlinType)
|
||||||
|
|
||||||
private fun extractInputOutputTypesFromCallableReferenceExpectedType(expectedType: ConeKotlinType?): InputOutputTypes? {
|
private fun extractInputOutputTypesFromCallableReferenceExpectedType(
|
||||||
|
expectedType: ConeKotlinType?,
|
||||||
|
session: FirSession
|
||||||
|
): InputOutputTypes? {
|
||||||
if (expectedType == null) return null
|
if (expectedType == null) return null
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
expectedType.isBuiltinFunctionalType || expectedType.isSuspendFunctionType ->
|
expectedType.isBuiltinFunctionalType(session) || expectedType.isSuspendFunctionType(session) ->
|
||||||
extractInputOutputTypesFromFunctionType(expectedType)
|
extractInputOutputTypesFromFunctionType(expectedType, session)
|
||||||
|
|
||||||
// ReflectionTypes.isBaseTypeForNumberedReferenceTypes(expectedType) ->
|
// ReflectionTypes.isBaseTypeForNumberedReferenceTypes(expectedType) ->
|
||||||
// InputOutputTypes(emptyList(), expectedType.arguments.single().type.unwrap())
|
// InputOutputTypes(emptyList(), expectedType.arguments.single().type.unwrap())
|
||||||
@@ -267,9 +281,12 @@ private fun extractInputOutputTypesFromCallableReferenceExpectedType(expectedTyp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun extractInputOutputTypesFromFunctionType(functionType: ConeKotlinType): InputOutputTypes {
|
private fun extractInputOutputTypesFromFunctionType(
|
||||||
|
functionType: ConeKotlinType,
|
||||||
|
session: FirSession
|
||||||
|
): InputOutputTypes {
|
||||||
val receiver = null// TODO: functionType.receiverType()
|
val receiver = null// TODO: functionType.receiverType()
|
||||||
val parameters = functionType.valueParameterTypes.map {
|
val parameters = functionType.valueParameterTypes(session).map {
|
||||||
it ?: ConeClassLikeTypeImpl(
|
it ?: ConeClassLikeTypeImpl(
|
||||||
ConeClassLikeLookupTagImpl(StandardClassIds.Nothing), emptyArray(),
|
ConeClassLikeLookupTagImpl(StandardClassIds.Nothing), emptyArray(),
|
||||||
isNullable = false
|
isNullable = false
|
||||||
@@ -277,7 +294,7 @@ private fun extractInputOutputTypesFromFunctionType(functionType: ConeKotlinType
|
|||||||
}
|
}
|
||||||
|
|
||||||
val inputTypes = /*listOfNotNull(receiver) +*/ parameters
|
val inputTypes = /*listOfNotNull(receiver) +*/ parameters
|
||||||
val outputType = functionType.returnType ?: ConeClassLikeTypeImpl(
|
val outputType = functionType.returnType(session) ?: ConeClassLikeTypeImpl(
|
||||||
ConeClassLikeLookupTagImpl(StandardClassIds.Any), emptyArray(),
|
ConeClassLikeLookupTagImpl(StandardClassIds.Any), emptyArray(),
|
||||||
isNullable = true
|
isNullable = true
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -99,8 +99,7 @@ internal sealed class CheckReceivers : ResolutionStage() {
|
|||||||
val receiverType = (callable.receiverTypeRef as FirResolvedTypeRef?)?.type
|
val receiverType = (callable.receiverTypeRef as FirResolvedTypeRef?)?.type
|
||||||
if (receiverType != null) return receiverType
|
if (receiverType != null) return receiverType
|
||||||
val returnTypeRef = callable.returnTypeRef as? FirResolvedTypeRef ?: return null
|
val returnTypeRef = callable.returnTypeRef as? FirResolvedTypeRef ?: return null
|
||||||
if (!returnTypeRef.isExtensionFunctionType()) return null
|
return returnTypeRef.type.receiverType(returnTypeRef, bodyResolveComponents.session)
|
||||||
return (returnTypeRef.type.typeArguments.firstOrNull() as? ConeTypedProjection)?.type
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -168,7 +168,7 @@ class TowerResolveManager internal constructor(private val towerResolver: FirTow
|
|||||||
for (invokeReceiverCandidate in invokeReceiverCollector.bestCandidates()) {
|
for (invokeReceiverCandidate in invokeReceiverCollector.bestCandidates()) {
|
||||||
|
|
||||||
val symbol = invokeReceiverCandidate.symbol as FirCallableSymbol<*>
|
val symbol = invokeReceiverCandidate.symbol as FirCallableSymbol<*>
|
||||||
val isExtensionFunctionType = symbol.fir.returnTypeRef.isExtensionFunctionType()
|
val isExtensionFunctionType = symbol.fir.returnTypeRef.isExtensionFunctionType(towerResolver.components.session)
|
||||||
if (invokeBuiltinExtensionMode && !isExtensionFunctionType) {
|
if (invokeBuiltinExtensionMode && !isExtensionFunctionType) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-7
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.references.impl.FirResolvedNamedReferenceImpl
|
|||||||
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.isBuiltinFunctionalType
|
import org.jetbrains.kotlin.fir.resolve.calls.isBuiltinFunctionalType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.returnType
|
||||||
import org.jetbrains.kotlin.fir.resolve.constructFunctionalTypeRef
|
import org.jetbrains.kotlin.fir.resolve.constructFunctionalTypeRef
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substituteOrNull
|
import org.jetbrains.kotlin.fir.resolve.substitution.substituteOrNull
|
||||||
@@ -187,7 +188,8 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
result = when (result) {
|
result = when (result) {
|
||||||
is FirIntegerOperatorCall -> {
|
is FirIntegerOperatorCall -> {
|
||||||
val expectedType = data?.getExpectedType(functionCall)
|
val expectedType = data?.getExpectedType(functionCall)
|
||||||
resultType = typeRef.resolvedTypeFromPrototype(typeRef.coneTypeUnsafe<ConeIntegerLiteralType>().getApproximatedType(expectedType))
|
resultType =
|
||||||
|
typeRef.resolvedTypeFromPrototype(typeRef.coneTypeUnsafe<ConeIntegerLiteralType>().getApproximatedType(expectedType))
|
||||||
result.transformArguments(this, expectedType?.toExpectedType()).transformSingle(integerApproximator, expectedType)
|
result.transformArguments(this, expectedType?.toExpectedType()).transformSingle(integerApproximator, expectedType)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
@@ -238,9 +240,9 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
|
|
||||||
private fun Candidate.createArgumentsMapping(): ExpectedArgumentType? {
|
private fun Candidate.createArgumentsMapping(): ExpectedArgumentType? {
|
||||||
return argumentMapping?.map { (argument, valueParameter) ->
|
return argumentMapping?.map { (argument, valueParameter) ->
|
||||||
val expectedType = valueParameter.returnTypeRef.substitute(this)
|
val expectedType = valueParameter.returnTypeRef.substitute(this)
|
||||||
argument.unwrapArgument() to expectedType
|
argument.unwrapArgument() to expectedType
|
||||||
}
|
}
|
||||||
?.toMap()?.toExpectedType()
|
?.toMap()?.toExpectedType()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,7 +250,8 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
delegatedConstructorCall: FirDelegatedConstructorCall,
|
delegatedConstructorCall: FirDelegatedConstructorCall,
|
||||||
data: ExpectedArgumentType?
|
data: ExpectedArgumentType?
|
||||||
): CompositeTransformResult<FirStatement> {
|
): CompositeTransformResult<FirStatement> {
|
||||||
val calleeReference = delegatedConstructorCall.calleeReference as? FirNamedReferenceWithCandidate ?: return delegatedConstructorCall.compose()
|
val calleeReference =
|
||||||
|
delegatedConstructorCall.calleeReference as? FirNamedReferenceWithCandidate ?: return delegatedConstructorCall.compose()
|
||||||
|
|
||||||
val result = delegatedConstructorCall.transformArguments(this, calleeReference.candidate.createArgumentsMapping())
|
val result = delegatedConstructorCall.transformArguments(this, calleeReference.candidate.createArgumentsMapping())
|
||||||
return result.transformCalleeReference(
|
return result.transformCalleeReference(
|
||||||
@@ -276,8 +279,8 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
data: ExpectedArgumentType?
|
data: ExpectedArgumentType?
|
||||||
): CompositeTransformResult<FirStatement> {
|
): CompositeTransformResult<FirStatement> {
|
||||||
val expectedReturnType = data?.getExpectedType(anonymousFunction)
|
val expectedReturnType = data?.getExpectedType(anonymousFunction)
|
||||||
?.takeIf { it.isBuiltinFunctionalType }
|
?.takeIf { it.isBuiltinFunctionalType(session) }
|
||||||
?.let { it.typeArguments.last() as? ConeClassLikeType }
|
?.returnType(session) as? ConeClassLikeType
|
||||||
|
|
||||||
val initialType = anonymousFunction.returnTypeRef.coneTypeSafe<ConeKotlinType>()
|
val initialType = anonymousFunction.returnTypeRef.coneTypeSafe<ConeKotlinType>()
|
||||||
if (initialType != null) {
|
if (initialType != null) {
|
||||||
|
|||||||
+1
-1
@@ -416,7 +416,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
|
|||||||
val expectedTypeRef = (data as? ResolutionMode.WithExpectedType)?.expectedTypeRef ?: FirImplicitTypeRefImpl(null)
|
val expectedTypeRef = (data as? ResolutionMode.WithExpectedType)?.expectedTypeRef ?: FirImplicitTypeRefImpl(null)
|
||||||
val resolvedLambdaAtom = (expectedTypeRef as? FirResolvedTypeRef)?.let {
|
val resolvedLambdaAtom = (expectedTypeRef as? FirResolvedTypeRef)?.let {
|
||||||
extractLambdaInfoFromFunctionalType(
|
extractLambdaInfoFromFunctionalType(
|
||||||
it.type, it, anonymousFunction
|
it.type, it, anonymousFunction, session
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
var af = anonymousFunction
|
var af = anonymousFunction
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
private typealias A = String.(Int) -> Int
|
||||||
|
|
||||||
|
private fun b(a: A) {
|
||||||
|
"b".a(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
b {
|
||||||
|
length + it
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
FILE: functionTypeAlias.kt
|
||||||
|
private final typealias A = R|kotlin/String.(kotlin/Int) -> kotlin/Int|
|
||||||
|
private final fun b(a: R|A|): R|kotlin/Unit| {
|
||||||
|
R|<local>/a|.R|FakeOverride<kotlin/Function2.invoke: R|kotlin/Int|>|(String(b), Int(1))
|
||||||
|
}
|
||||||
|
public final fun main(): R|kotlin/Unit| {
|
||||||
|
R|/b|(<L> = b@fun R|kotlin/String|.<anonymous>(it: R|kotlin/Int|): R|kotlin/Int| {
|
||||||
|
this@R|special/anonymous|.R|kotlin/String.length|.R|kotlin/Int.plus|(R|<local>/it|)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
+5
@@ -128,6 +128,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/ft.kt");
|
runTest("compiler/fir/resolve/testData/resolve/ft.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("functionTypeAlias.kt")
|
||||||
|
public void testFunctionTypeAlias() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/functionTypeAlias.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("functionTypes.kt")
|
@TestMetadata("functionTypes.kt")
|
||||||
public void testFunctionTypes() throws Exception {
|
public void testFunctionTypes() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/functionTypes.kt");
|
runTest("compiler/fir/resolve/testData/resolve/functionTypes.kt");
|
||||||
|
|||||||
Generated
+5
@@ -128,6 +128,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
runTest("compiler/fir/resolve/testData/resolve/ft.kt");
|
runTest("compiler/fir/resolve/testData/resolve/ft.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("functionTypeAlias.kt")
|
||||||
|
public void testFunctionTypeAlias() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/resolve/functionTypeAlias.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("functionTypes.kt")
|
@TestMetadata("functionTypes.kt")
|
||||||
public void testFunctionTypes() throws Exception {
|
public void testFunctionTypes() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/functionTypes.kt");
|
runTest("compiler/fir/resolve/testData/resolve/functionTypes.kt");
|
||||||
|
|||||||
@@ -769,7 +769,9 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
|
|||||||
annotations.renderAnnotations()
|
annotations.renderAnnotations()
|
||||||
print("R|")
|
print("R|")
|
||||||
val coneType = resolvedTypeRef.type
|
val coneType = resolvedTypeRef.type
|
||||||
print(coneType.renderFunctionType(kind, resolvedTypeRef.isExtensionFunctionType()))
|
print(coneType.renderFunctionType(kind, resolvedTypeRef.annotations.any {
|
||||||
|
it.isExtensionFunctionAnnotationCall
|
||||||
|
}))
|
||||||
print("|")
|
print("|")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.types
|
package org.jetbrains.kotlin.fir.types
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirConstKind
|
import org.jetbrains.kotlin.fir.expressions.FirConstKind
|
||||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||||
@@ -38,12 +39,6 @@ val FirFunctionTypeRef.parametersCount: Int
|
|||||||
|
|
||||||
const val EXTENSION_FUNCTION_ANNOTATION = "kotlin/ExtensionFunctionType"
|
const val EXTENSION_FUNCTION_ANNOTATION = "kotlin/ExtensionFunctionType"
|
||||||
|
|
||||||
fun FirTypeRef.isExtensionFunctionType(): Boolean {
|
|
||||||
return annotations.any {
|
|
||||||
it.isExtensionFunctionAnnotationCall
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val FirAnnotationCall.isExtensionFunctionAnnotationCall: Boolean
|
val FirAnnotationCall.isExtensionFunctionAnnotationCall: Boolean
|
||||||
get() = (this as? FirAnnotationCall)?.let {
|
get() = (this as? FirAnnotationCall)?.let {
|
||||||
(it.annotationTypeRef as? FirResolvedTypeRef)?.let {
|
(it.annotationTypeRef as? FirResolvedTypeRef)?.let {
|
||||||
|
|||||||
+3
-3
@@ -16,9 +16,9 @@ fun buildB() {
|
|||||||
val a2 = applyRestrictions2()
|
val a2 = applyRestrictions2()
|
||||||
val a3 = applyRestrictions3("foo")
|
val a3 = applyRestrictions3("foo")
|
||||||
|
|
||||||
B.Builder().<!UNRESOLVED_REFERENCE!>a1<!>()
|
B.Builder().a1()
|
||||||
B.Builder().<!UNRESOLVED_REFERENCE!>a2<!>()
|
B.Builder().a2()
|
||||||
B.Builder().<!UNRESOLVED_REFERENCE!>a3<!>()
|
B.Builder().a3()
|
||||||
}
|
}
|
||||||
|
|
||||||
// additional example from #KT-34820
|
// additional example from #KT-34820
|
||||||
|
|||||||
+3
-3
@@ -16,7 +16,7 @@ fun buildB() {
|
|||||||
val a2 = applyRestrictions2()
|
val a2 = applyRestrictions2()
|
||||||
val a3 = applyRestrictions3("foo")
|
val a3 = applyRestrictions3("foo")
|
||||||
|
|
||||||
B.Builder().<!UNRESOLVED_REFERENCE!>a1<!>()
|
B.Builder().a1()
|
||||||
B.Builder().<!UNRESOLVED_REFERENCE!>a2<!>()
|
B.Builder().a2()
|
||||||
B.Builder().<!UNRESOLVED_REFERENCE!>a3<!>()
|
B.Builder().a3()
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-15
@@ -36,13 +36,13 @@ class W4(val f: L2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test1() { // to extension lambda 0
|
fun test1() { // to extension lambda 0
|
||||||
val w10 = <!INAPPLICABLE_CANDIDATE!>W1<!> { this } // oi+ ni+
|
val w10 = W1 { this } // oi+ ni+
|
||||||
val i10: E0 = id { this } // o1- ni+
|
val i10: E0 = id { this } // o1- ni+
|
||||||
val j10 = <!INAPPLICABLE_CANDIDATE!>id<!><E0> { this } // oi+ ni+
|
val j10 = <!INAPPLICABLE_CANDIDATE!>id<!><E0> { this } // oi+ ni+
|
||||||
val f10 = W1(fun Int.(): Int = this) // oi+ ni+
|
val f10 = W1(fun Int.(): Int = this) // oi+ ni+
|
||||||
val g10: E0 = id(fun Int.(): Int = this) // oi+ ni+
|
val g10: E0 = id(fun Int.(): Int = this) // oi+ ni+
|
||||||
|
|
||||||
val w11 = W1 { i: Int -> i } // oi- ni-
|
val w11 = <!INAPPLICABLE_CANDIDATE!>W1<!> { i: Int -> i } // oi- ni-
|
||||||
val i11: E0 = id { i: Int -> i } // o1+ ni+
|
val i11: E0 = id { i: Int -> i } // o1+ ni+
|
||||||
val w12 = <!INAPPLICABLE_CANDIDATE!>W1<!> { i -> i } // oi- ni-
|
val w12 = <!INAPPLICABLE_CANDIDATE!>W1<!> { i -> i } // oi- ni-
|
||||||
val i12: E0 = id { i -> i } // oi- ni-
|
val i12: E0 = id { i -> i } // oi- ni-
|
||||||
@@ -53,23 +53,23 @@ fun test1() { // to extension lambda 0
|
|||||||
// val i13: E0 = id { it } // this or it: oi- ni-
|
// val i13: E0 = id { it } // this or it: oi- ni-
|
||||||
// val j13 = id<E0> { it } // this or it: oi- ni-
|
// val j13 = id<E0> { it } // this or it: oi- ni-
|
||||||
|
|
||||||
val o14 = <!INAPPLICABLE_CANDIDATE!>W1<!> { -> 0 } // oi+ ni+
|
val o14 = W1 { -> 0 } // oi+ ni+
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test2() { // to extension lambda 1
|
fun test2() { // to extension lambda 1
|
||||||
val w20 = <!INAPPLICABLE_CANDIDATE!>W2<!> { this + <!UNRESOLVED_REFERENCE!>it<!>.<!UNRESOLVED_REFERENCE!>length<!> } // oi+ ni+
|
val w20 = W2 { this + it.length } // oi+ ni+
|
||||||
val i20: E1 = id { this + <!UNRESOLVED_REFERENCE!>it<!>.<!UNRESOLVED_REFERENCE!>length<!> } // oi- ni+
|
val i20: E1 = id { this + <!UNRESOLVED_REFERENCE!>it<!>.<!UNRESOLVED_REFERENCE!>length<!> } // oi- ni+
|
||||||
val w21 = <!INAPPLICABLE_CANDIDATE!>W2<!> { this } // oi+ ni+
|
val w21 = W2 { this } // oi+ ni+
|
||||||
val i21: E1 = id { this } // oi- ni+
|
val i21: E1 = id { this } // oi- ni+
|
||||||
val f21 = <!INAPPLICABLE_CANDIDATE!>W2<!>(fun Int.(String): Int = this) // oi+ ni+
|
val f21 = W2(fun Int.(String): Int = this) // oi+ ni+
|
||||||
val g21: E1 = id(fun Int.(String): Int = this) // oi+ ni+
|
val g21: E1 = id(fun Int.(String): Int = this) // oi+ ni+
|
||||||
val w22 = <!INAPPLICABLE_CANDIDATE!>W2<!> { s -> this + s.<!UNRESOLVED_REFERENCE!>length<!> } // oi+ ni+
|
val w22 = W2 { s -> this + s.length } // oi+ ni+
|
||||||
val i22: E1 = id { s -> this + s.<!UNRESOLVED_REFERENCE!>length<!> } // oi+ ni+
|
val i22: E1 = id { s -> this + s.<!UNRESOLVED_REFERENCE!>length<!> } // oi+ ni+
|
||||||
val w23 = <!INAPPLICABLE_CANDIDATE!>W2<!> { s -> s.<!UNRESOLVED_REFERENCE!>length<!> } // oi+ ni+
|
val w23 = W2 { s -> s.length } // oi+ ni+
|
||||||
val i23: E1 = id { s -> s.<!UNRESOLVED_REFERENCE!>length<!> } // oi+ ni+
|
val i23: E1 = id { s -> s.<!UNRESOLVED_REFERENCE!>length<!> } // oi+ ni+
|
||||||
val w24 = <!INAPPLICABLE_CANDIDATE!>W2<!> { s: String -> this + s.length } // oi+ ni+
|
val w24 = W2 { s: String -> this + s.length } // oi+ ni+
|
||||||
// val i24: E1 = id { s: String -> this + s.length } //oi- ni-
|
// val i24: E1 = id { s: String -> this + s.length } //oi- ni-
|
||||||
val w25 = <!INAPPLICABLE_CANDIDATE!>W2<!> { s: String -> s.length } // oi+ ni+
|
val w25 = W2 { s: String -> s.length } // oi+ ni+
|
||||||
// val i25: E1 = id { s: String -> s.length } // oi- ni-
|
// val i25: E1 = id { s: String -> s.length } // oi- ni-
|
||||||
|
|
||||||
// yet unsupported cases with ambiguity for the lambda conversion (commented constructors in wrappers above)
|
// yet unsupported cases with ambiguity for the lambda conversion (commented constructors in wrappers above)
|
||||||
@@ -80,7 +80,7 @@ fun test2() { // to extension lambda 1
|
|||||||
|
|
||||||
val w28 = <!INAPPLICABLE_CANDIDATE!>W2<!> { i: Int, s -> i <!AMBIGUITY!>+<!> s.<!UNRESOLVED_REFERENCE!>length<!> } // oi- ni-
|
val w28 = <!INAPPLICABLE_CANDIDATE!>W2<!> { i: Int, s -> i <!AMBIGUITY!>+<!> s.<!UNRESOLVED_REFERENCE!>length<!> } // oi- ni-
|
||||||
val i28: E1 = id { i: Int, s -> i <!AMBIGUITY!>+<!> s.<!UNRESOLVED_REFERENCE!>length<!> } // oi- ni-
|
val i28: E1 = id { i: Int, s -> i <!AMBIGUITY!>+<!> s.<!UNRESOLVED_REFERENCE!>length<!> } // oi- ni-
|
||||||
val w29 = W2 { i: Int, s: String -> i + s.length } // oi- ni-
|
val w29 = <!INAPPLICABLE_CANDIDATE!>W2<!> { i: Int, s: String -> i + s.length } // oi- ni-
|
||||||
val i29: E1 = id { i: Int, s: String -> i + s.length } // oi+ ni+
|
val i29: E1 = id { i: Int, s: String -> i + s.length } // oi+ ni+
|
||||||
|
|
||||||
// yet unsupported cases with ambiguity for the lambda conversion (commented constructors in wrappers above)
|
// yet unsupported cases with ambiguity for the lambda conversion (commented constructors in wrappers above)
|
||||||
@@ -89,9 +89,9 @@ fun test2() { // to extension lambda 1
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test3() { // to non-extension lambda 1
|
fun test3() { // to non-extension lambda 1
|
||||||
val w30 = <!INAPPLICABLE_CANDIDATE!>W3<!> { i -> i } // oi+ ni+
|
val w30 = W3 { i -> i } // oi+ ni+
|
||||||
val i30: L1 = id { i -> i } // oi+ ni+
|
val i30: L1 = id { i -> i } // oi+ ni+
|
||||||
val w31 = <!INAPPLICABLE_CANDIDATE!>W3<!> { <!UNRESOLVED_REFERENCE!>it<!> } // oi+ ni+
|
val w31 = W3 { it } // oi+ ni+
|
||||||
val i31: L1 = id { <!UNRESOLVED_REFERENCE!>it<!> } // oi- ni+
|
val i31: L1 = id { <!UNRESOLVED_REFERENCE!>it<!> } // oi- ni+
|
||||||
val j31 = <!INAPPLICABLE_CANDIDATE!>id<!><L1> { <!UNRESOLVED_REFERENCE!>it<!> } // oi+ ni+
|
val j31 = <!INAPPLICABLE_CANDIDATE!>id<!><L1> { <!UNRESOLVED_REFERENCE!>it<!> } // oi+ ni+
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ fun test3() { // to non-extension lambda 1
|
|||||||
// val i32: L1 = id { this } // this or it: oi- ni-
|
// val i32: L1 = id { this } // this or it: oi- ni-
|
||||||
// val j32 = id<L1> { this } // this or it: oi- ni-
|
// val j32 = id<L1> { this } // this or it: oi- ni-
|
||||||
|
|
||||||
val w33 = W3(fun Int.(): Int = this) // oi- ni+
|
val w33 = <!INAPPLICABLE_CANDIDATE!>W3<!>(fun Int.(): Int = this) // oi- ni+
|
||||||
val i33: L1 = id(fun Int.(): Int = this) // oi+ ni+
|
val i33: L1 = id(fun Int.(): Int = this) // oi+ ni+
|
||||||
|
|
||||||
// yet unsupported cases with ambiguity for the lambda conversion (commented constructors in wrappers above)
|
// yet unsupported cases with ambiguity for the lambda conversion (commented constructors in wrappers above)
|
||||||
@@ -108,7 +108,7 @@ fun test3() { // to non-extension lambda 1
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test4() { // to non-extension lambda 2
|
fun test4() { // to non-extension lambda 2
|
||||||
val w30 = <!INAPPLICABLE_CANDIDATE!>W4<!> { i, s -> i } // oi+ ni+
|
val w30 = W4 { i, s -> i } // oi+ ni+
|
||||||
val i30: L2 = id { i, s -> i } // oi+ ni+
|
val i30: L2 = id { i, s -> i } // oi+ ni+
|
||||||
|
|
||||||
// yet unsupported cases with ambiguity for the lambda conversion (commented constructors in wrappers above)
|
// yet unsupported cases with ambiguity for the lambda conversion (commented constructors in wrappers above)
|
||||||
|
|||||||
Reference in New Issue
Block a user