[FIR] Implement ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE diagnostic
#KT-59401 Fixed
This commit is contained in:
committed by
Space Team
parent
d91000e39c
commit
789f886d3c
+6
@@ -2597,6 +2597,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE) { firDiagnostic ->
|
||||||
|
AdaptedCallableReferenceAgainstReflectionTypeImpl(
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.CLASS_LITERAL_LHS_NOT_A_CLASS) { firDiagnostic ->
|
add(FirErrors.CLASS_LITERAL_LHS_NOT_A_CLASS) { firDiagnostic ->
|
||||||
ClassLiteralLhsNotAClassImpl(
|
ClassLiteralLhsNotAClassImpl(
|
||||||
firDiagnostic as KtPsiDiagnostic,
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
|||||||
+4
@@ -1841,6 +1841,10 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = CallableReferenceToAnnotationConstructor::class
|
override val diagnosticClass get() = CallableReferenceToAnnotationConstructor::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface AdaptedCallableReferenceAgainstReflectionType : KtFirDiagnostic<KtExpression> {
|
||||||
|
override val diagnosticClass get() = AdaptedCallableReferenceAgainstReflectionType::class
|
||||||
|
}
|
||||||
|
|
||||||
interface ClassLiteralLhsNotAClass : KtFirDiagnostic<KtExpression> {
|
interface ClassLiteralLhsNotAClass : KtFirDiagnostic<KtExpression> {
|
||||||
override val diagnosticClass get() = ClassLiteralLhsNotAClass::class
|
override val diagnosticClass get() = ClassLiteralLhsNotAClass::class
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -2212,6 +2212,11 @@ internal class CallableReferenceToAnnotationConstructorImpl(
|
|||||||
token: KtLifetimeToken,
|
token: KtLifetimeToken,
|
||||||
) : KtAbstractFirDiagnostic<KtExpression>(firDiagnostic, token), KtFirDiagnostic.CallableReferenceToAnnotationConstructor
|
) : KtAbstractFirDiagnostic<KtExpression>(firDiagnostic, token), KtFirDiagnostic.CallableReferenceToAnnotationConstructor
|
||||||
|
|
||||||
|
internal class AdaptedCallableReferenceAgainstReflectionTypeImpl(
|
||||||
|
firDiagnostic: KtPsiDiagnostic,
|
||||||
|
token: KtLifetimeToken,
|
||||||
|
) : KtAbstractFirDiagnostic<KtExpression>(firDiagnostic, token), KtFirDiagnostic.AdaptedCallableReferenceAgainstReflectionType
|
||||||
|
|
||||||
internal class ClassLiteralLhsNotAClassImpl(
|
internal class ClassLiteralLhsNotAClassImpl(
|
||||||
firDiagnostic: KtPsiDiagnostic,
|
firDiagnostic: KtPsiDiagnostic,
|
||||||
token: KtLifetimeToken,
|
token: KtLifetimeToken,
|
||||||
|
|||||||
+1
@@ -872,6 +872,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
}
|
}
|
||||||
val CALLABLE_REFERENCE_LHS_NOT_A_CLASS by error<KtExpression>()
|
val CALLABLE_REFERENCE_LHS_NOT_A_CLASS by error<KtExpression>()
|
||||||
val CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR by error<KtExpression>(PositioningStrategy.REFERENCE_BY_QUALIFIED)
|
val CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR by error<KtExpression>(PositioningStrategy.REFERENCE_BY_QUALIFIED)
|
||||||
|
val ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE by error<KtExpression>()
|
||||||
|
|
||||||
val CLASS_LITERAL_LHS_NOT_A_CLASS by error<KtExpression>()
|
val CLASS_LITERAL_LHS_NOT_A_CLASS by error<KtExpression>()
|
||||||
val NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error<KtExpression>()
|
val NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error<KtExpression>()
|
||||||
|
|||||||
@@ -488,6 +488,7 @@ object FirErrors {
|
|||||||
val EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED by error1<KtExpression, FirCallableSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
val EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED by error1<KtExpression, FirCallableSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||||
val CALLABLE_REFERENCE_LHS_NOT_A_CLASS by error0<KtExpression>()
|
val CALLABLE_REFERENCE_LHS_NOT_A_CLASS by error0<KtExpression>()
|
||||||
val CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR by error0<KtExpression>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
val CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR by error0<KtExpression>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||||
|
val ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE by error0<KtExpression>()
|
||||||
val CLASS_LITERAL_LHS_NOT_A_CLASS by error0<KtExpression>()
|
val CLASS_LITERAL_LHS_NOT_A_CLASS by error0<KtExpression>()
|
||||||
val NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error0<KtExpression>()
|
val NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error0<KtExpression>()
|
||||||
val EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error1<PsiElement, ConeKotlinType>()
|
val EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS by error1<PsiElement, ConeKotlinType>()
|
||||||
|
|||||||
+1
@@ -319,6 +319,7 @@ val FIR_NON_SUPPRESSIBLE_ERROR_NAMES: Set<String> = setOf(
|
|||||||
"EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED",
|
"EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED",
|
||||||
"CALLABLE_REFERENCE_LHS_NOT_A_CLASS",
|
"CALLABLE_REFERENCE_LHS_NOT_A_CLASS",
|
||||||
"CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR",
|
"CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR",
|
||||||
|
"ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE",
|
||||||
"CLASS_LITERAL_LHS_NOT_A_CLASS",
|
"CLASS_LITERAL_LHS_NOT_A_CLASS",
|
||||||
"NULLABLE_TYPE_IN_CLASS_LITERAL_LHS",
|
"NULLABLE_TYPE_IN_CLASS_LITERAL_LHS",
|
||||||
"EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS",
|
"EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS",
|
||||||
|
|||||||
+5
@@ -72,6 +72,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_TYPE_ALIAS
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_WITHOUT_EXPECT
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_WITHOUT_EXPECT
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_ACTUALS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_ACTUALS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_ALTERED_ASSIGN
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_ALTERED_ASSIGN
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_ANNOTATION_ARGUMENT
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_ANNOTATION_ARGUMENT
|
||||||
@@ -1474,6 +1475,10 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
|||||||
)
|
)
|
||||||
map.put(CALLABLE_REFERENCE_LHS_NOT_A_CLASS, "Left-hand side of callable reference cannot be a type parameter.")
|
map.put(CALLABLE_REFERENCE_LHS_NOT_A_CLASS, "Left-hand side of callable reference cannot be a type parameter.")
|
||||||
map.put(CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR, "Annotation class cannot be instantiated.")
|
map.put(CALLABLE_REFERENCE_TO_ANNOTATION_CONSTRUCTOR, "Annotation class cannot be instantiated.")
|
||||||
|
map.put(
|
||||||
|
ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE,
|
||||||
|
"Adapted callable reference cannot be resolved against reflective types."
|
||||||
|
)
|
||||||
|
|
||||||
map.put(CLASS_LITERAL_LHS_NOT_A_CLASS, "Only classes are allowed on the left-hand side of a class literal.")
|
map.put(CLASS_LITERAL_LHS_NOT_A_CLASS, "Only classes are allowed on the left-hand side of a class literal.")
|
||||||
map.put(NULLABLE_TYPE_IN_CLASS_LITERAL_LHS, "Type in a class literal must not be nullable.")
|
map.put(NULLABLE_TYPE_IN_CLASS_LITERAL_LHS, "Type in a class literal must not be nullable.")
|
||||||
|
|||||||
+2
@@ -358,6 +358,8 @@ private fun mapInapplicableCandidateError(
|
|||||||
isError = rootCause.isError
|
isError = rootCause.isError
|
||||||
)
|
)
|
||||||
|
|
||||||
|
is AdaptedCallableReferenceIsUsedWithReflection -> FirErrors.ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE.createOn(source)
|
||||||
|
|
||||||
else -> genericDiagnostic
|
else -> genericDiagnostic
|
||||||
}
|
}
|
||||||
}.distinct()
|
}.distinct()
|
||||||
|
|||||||
@@ -400,8 +400,9 @@ class FirCallResolver(
|
|||||||
manager = TowerResolveManager(localCollector),
|
manager = TowerResolveManager(localCollector),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val isSuccess = result.currentApplicability.isSuccess
|
|
||||||
val (reducedCandidates, newApplicability) = reduceCandidates(result, callableReferenceAccess.explicitReceiver)
|
val (reducedCandidates, newApplicability) = reduceCandidates(result, callableReferenceAccess.explicitReceiver)
|
||||||
|
val isSuccess = reducedCandidates.isNotEmpty() && reducedCandidates.all { it.isSuccessful }
|
||||||
val applicability = newApplicability ?: result.currentApplicability
|
val applicability = newApplicability ?: result.currentApplicability
|
||||||
|
|
||||||
(callableReferenceAccess.explicitReceiver as? FirResolvedQualifier)?.replaceResolvedToCompanionObject(
|
(callableReferenceAccess.explicitReceiver as? FirResolvedQualifier)?.replaceResolvedToCompanionObject(
|
||||||
|
|||||||
+44
-15
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.name.StandardClassIds
|
|||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.runTransaction
|
import org.jetbrains.kotlin.resolve.calls.inference.runTransaction
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||||
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
import org.jetbrains.kotlin.types.expressions.CoercionStrategy
|
import org.jetbrains.kotlin.types.expressions.CoercionStrategy
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
|
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
|
||||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||||
@@ -47,13 +48,31 @@ internal object CheckCallableReferenceExpectedType : CheckerStage() {
|
|||||||
|
|
||||||
val fir: FirCallableDeclaration = candidate.symbol.fir as FirCallableDeclaration
|
val fir: FirCallableDeclaration = candidate.symbol.fir as FirCallableDeclaration
|
||||||
|
|
||||||
val (rawResultingType, callableReferenceAdaptation) = buildReflectionType(fir, resultingReceiverType, candidate, context)
|
val isExpectedTypeReflectionType = callInfo.expectedType?.isReflectFunctionType(callInfo.session) == true
|
||||||
|
val (rawResultingType, callableReferenceAdaptation) = buildResultingTypeAndAdaptation(
|
||||||
|
fir,
|
||||||
|
resultingReceiverType,
|
||||||
|
candidate,
|
||||||
|
context,
|
||||||
|
// If the input and output types match the expected type but the expected type is a reflection type, and we need an adaptation,
|
||||||
|
// we want to report AdaptedCallableReferenceIsUsedWithReflection but *not* InapplicableCandidate because
|
||||||
|
// AdaptedCallableReferenceIsUsedWithReflection has the higher applicability.
|
||||||
|
// Therefore, we force a reflection type whenever the expected type is a reflection type.
|
||||||
|
//
|
||||||
|
// If the input and output types end up not matching, we'll report InapplicableCandidate, regardless of whether the
|
||||||
|
// expected/actual type is a reflection type.
|
||||||
|
forceReflectionType = isExpectedTypeReflectionType
|
||||||
|
)
|
||||||
val resultingType = candidate.substitutor.substituteOrSelf(rawResultingType)
|
val resultingType = candidate.substitutor.substituteOrSelf(rawResultingType)
|
||||||
|
|
||||||
if (callableReferenceAdaptation.needCompatibilityResolveForCallableReference()) {
|
if (callableReferenceAdaptation != null) {
|
||||||
if (!context.session.languageVersionSettings.supportsFeature(LanguageFeature.DisableCompatibilityModeForNewInference)) {
|
if (!context.session.languageVersionSettings.supportsFeature(LanguageFeature.DisableCompatibilityModeForNewInference)) {
|
||||||
sink.reportDiagnostic(LowerPriorityToPreserveCompatibilityDiagnostic)
|
sink.reportDiagnostic(LowerPriorityToPreserveCompatibilityDiagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isExpectedTypeReflectionType) {
|
||||||
|
sink.reportDiagnostic(AdaptedCallableReferenceIsUsedWithReflection)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
candidate.resultingTypeForCallableReference = resultingType
|
candidate.resultingTypeForCallableReference = resultingType
|
||||||
@@ -88,11 +107,17 @@ internal object CheckCallableReferenceExpectedType : CheckerStage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildReflectionType(
|
/**
|
||||||
|
* The resulting type is a reflection type ([FunctionTypeKind.reflectKind])
|
||||||
|
* iff the adaptation is `null` or [forceReflectionType]` == true`.
|
||||||
|
* Otherwise, it's a non-reflection type ([FunctionTypeKind.nonReflectKind]).
|
||||||
|
*/
|
||||||
|
private fun buildResultingTypeAndAdaptation(
|
||||||
fir: FirCallableDeclaration,
|
fir: FirCallableDeclaration,
|
||||||
receiverType: ConeKotlinType?,
|
receiverType: ConeKotlinType?,
|
||||||
candidate: Candidate,
|
candidate: Candidate,
|
||||||
context: ResolutionContext
|
context: ResolutionContext,
|
||||||
|
forceReflectionType: Boolean,
|
||||||
): Pair<ConeKotlinType, CallableReferenceAdaptation?> {
|
): Pair<ConeKotlinType, CallableReferenceAdaptation?> {
|
||||||
val returnTypeRef = context.bodyResolveComponents.returnTypeCalculator.tryCalculateReturnType(fir)
|
val returnTypeRef = context.bodyResolveComponents.returnTypeCalculator.tryCalculateReturnType(fir)
|
||||||
return when (fir) {
|
return when (fir) {
|
||||||
@@ -128,7 +153,7 @@ private fun buildReflectionType(
|
|||||||
?: FunctionTypeKind.Function
|
?: FunctionTypeKind.Function
|
||||||
|
|
||||||
return createFunctionType(
|
return createFunctionType(
|
||||||
if (callableReferenceAdaptation == null) baseFunctionTypeKind.reflectKind() else baseFunctionTypeKind.nonReflectKind(),
|
if (callableReferenceAdaptation == null || forceReflectionType) baseFunctionTypeKind.reflectKind() else baseFunctionTypeKind.nonReflectKind(),
|
||||||
parameters,
|
parameters,
|
||||||
receiverType = receiverType.takeIf { fir.receiverParameter != null },
|
receiverType = receiverType.takeIf { fir.receiverParameter != null },
|
||||||
rawReturnType = returnType,
|
rawReturnType = returnType,
|
||||||
@@ -145,16 +170,20 @@ internal class CallableReferenceAdaptation(
|
|||||||
val coercionStrategy: CoercionStrategy,
|
val coercionStrategy: CoercionStrategy,
|
||||||
val defaults: Int,
|
val defaults: Int,
|
||||||
val mappedArguments: CallableReferenceMappedArguments,
|
val mappedArguments: CallableReferenceMappedArguments,
|
||||||
val suspendConversionStrategy: CallableReferenceConversionStrategy
|
val suspendConversionStrategy: CallableReferenceConversionStrategy,
|
||||||
)
|
) {
|
||||||
|
init {
|
||||||
private fun CallableReferenceAdaptation?.needCompatibilityResolveForCallableReference(): Boolean {
|
if (AbstractTypeChecker.RUN_SLOW_ASSERTIONS) {
|
||||||
// KT-13934: check containing declaration for companion object
|
require(
|
||||||
if (this == null) return false
|
defaults != 0 ||
|
||||||
return defaults != 0 ||
|
suspendConversionStrategy != CallableReferenceConversionStrategy.NoConversion ||
|
||||||
suspendConversionStrategy != CallableReferenceConversionStrategy.NoConversion ||
|
coercionStrategy != CoercionStrategy.NO_COERCION ||
|
||||||
coercionStrategy != CoercionStrategy.NO_COERCION ||
|
mappedArguments.values.any { it is ResolvedCallArgument.VarargArgument }
|
||||||
mappedArguments.values.any { it is ResolvedCallArgument.VarargArgument }
|
) {
|
||||||
|
"Adaptation must be non-trivial."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun BodyResolveComponents.getCallableReferenceAdaptation(
|
private fun BodyResolveComponents.getCallableReferenceAdaptation(
|
||||||
|
|||||||
+2
@@ -146,3 +146,5 @@ class AmbiguousValuesForContextReceiverParameter(
|
|||||||
) : ResolutionDiagnostic(INAPPLICABLE)
|
) : ResolutionDiagnostic(INAPPLICABLE)
|
||||||
|
|
||||||
object ResolutionResultOverridesOtherToPreserveCompatibility : ResolutionDiagnostic(RESOLVED)
|
object ResolutionResultOverridesOtherToPreserveCompatibility : ResolutionDiagnostic(RESOLVED)
|
||||||
|
|
||||||
|
object AdaptedCallableReferenceIsUsedWithReflection : ResolutionDiagnostic(RESOLVED_WITH_ERROR)
|
||||||
Vendored
+2
-2
@@ -3,12 +3,12 @@ fun foo(x: String = "O"): String = x
|
|||||||
fun bar(x: String = "K"): String = x
|
fun bar(x: String = "K"): String = x
|
||||||
|
|
||||||
fun dump(dumpStrategy: String) {
|
fun dump(dumpStrategy: String) {
|
||||||
val k0: kotlin.reflect.KFunction0<String> = returnAdapter(::<!INAPPLICABLE_CANDIDATE!>foo<!>) // Error: ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE
|
val k0: kotlin.reflect.KFunction0<String> = returnAdapter(<!ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE!>::foo<!>) // Error: ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE
|
||||||
val k1: kotlin.reflect.KFunction0<String> = <!INITIALIZER_TYPE_MISMATCH!>::foo<!>
|
val k1: kotlin.reflect.KFunction0<String> = <!INITIALIZER_TYPE_MISMATCH!>::foo<!>
|
||||||
// Should be error here, too
|
// Should be error here, too
|
||||||
val k2: kotlin.reflect.KFunction0<String> = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>if (dumpStrategy == "KotlinLike") ::foo else ::bar<!>
|
val k2: kotlin.reflect.KFunction0<String> = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>if (dumpStrategy == "KotlinLike") ::foo else ::bar<!>
|
||||||
|
|
||||||
val f0: Function0<String> = returnAdapter(::<!INAPPLICABLE_CANDIDATE!>foo<!>)
|
val f0: Function0<String> = returnAdapter(<!ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE!>::foo<!>)
|
||||||
val f1: Function0<String> = ::foo
|
val f1: Function0<String> = ::foo
|
||||||
val f2: Function0<String> = if (dumpStrategy == "KotlinLike") ::foo else ::bar
|
val f2: Function0<String> = if (dumpStrategy == "KotlinLike") ::foo else ::bar
|
||||||
}
|
}
|
||||||
|
|||||||
-27
@@ -1,27 +0,0 @@
|
|||||||
// !LANGUAGE: -AdaptedCallableReferenceAgainstReflectiveType +DisableCompatibilityModeForNewInference
|
|
||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
|
||||||
|
|
||||||
import kotlin.reflect.KFunction1
|
|
||||||
|
|
||||||
fun foo(x: Int): Unit {} // (1)
|
|
||||||
fun bar(f: KFunction1<Int, Unit>) {}
|
|
||||||
|
|
||||||
fun test() {
|
|
||||||
bar(::foo) // OK, foo resolved to (1)
|
|
||||||
}
|
|
||||||
|
|
||||||
object Scope {
|
|
||||||
fun foo(x: Int, y: Int = 0): Int = 0 // (2)
|
|
||||||
|
|
||||||
fun test() {
|
|
||||||
bar(::foo) // Error and foo should be resolved to (2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object Local {
|
|
||||||
fun baz(x: Int, y: Int = 0): Int = 0
|
|
||||||
|
|
||||||
fun test() {
|
|
||||||
bar(::<!INAPPLICABLE_CANDIDATE!>baz<!>)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+10
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !LANGUAGE: -AdaptedCallableReferenceAgainstReflectiveType +DisableCompatibilityModeForNewInference
|
// !LANGUAGE: -AdaptedCallableReferenceAgainstReflectiveType +DisableCompatibilityModeForNewInference
|
||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
@@ -15,6 +16,7 @@ object Scope {
|
|||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
bar(<!ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE!>::foo<!>) // Error and foo should be resolved to (2)
|
bar(<!ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE!>::foo<!>) // Error and foo should be resolved to (2)
|
||||||
|
bar(<!ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE!>Scope::foo<!>) // Error and foo should be resolved to (2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,3 +27,11 @@ object Local {
|
|||||||
bar(<!ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE!>::baz<!>)
|
bar(<!ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE!>::baz<!>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object WrongType {
|
||||||
|
fun foo(x: String, y: Int = 0) {} // (3)
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
bar(::foo) // Should resolve to (1) because (3) has wrong type on top of being adapted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
-23
@@ -1,23 +0,0 @@
|
|||||||
package
|
|
||||||
|
|
||||||
public fun bar(/*0*/ f: kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit>): kotlin.Unit
|
|
||||||
public fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
|
|
||||||
public fun test(): kotlin.Unit
|
|
||||||
|
|
||||||
public object Local {
|
|
||||||
private constructor Local()
|
|
||||||
public final fun baz(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int = ...): kotlin.Int
|
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
|
||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
|
||||||
public final fun test(): kotlin.Unit
|
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
|
||||||
}
|
|
||||||
|
|
||||||
public object Scope {
|
|
||||||
private constructor Scope()
|
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
|
||||||
public final fun foo(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int = ...): kotlin.Int
|
|
||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
|
||||||
public final fun test(): kotlin.Unit
|
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
|
||||||
}
|
|
||||||
+10
-1
@@ -15,6 +15,7 @@ object Scope {
|
|||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
bar(::foo)
|
bar(::foo)
|
||||||
|
bar(<!ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE!>Scope::foo<!>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,6 +23,14 @@ object Local {
|
|||||||
fun baz(x: Int, y: Int = 0): Int = 0
|
fun baz(x: Int, y: Int = 0): Int = 0
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
bar(::<!INAPPLICABLE_CANDIDATE!>baz<!>)
|
bar(<!ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE!>::baz<!>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object WrongType {
|
||||||
|
fun foo(x: String, y: Int = 0) {} // (3)
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
bar(::foo) // Should resolve to (1) because (3) has wrong type on top of being adapted
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
@@ -15,6 +15,7 @@ object Scope {
|
|||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
bar(<!COMPATIBILITY_WARNING!>::foo<!>)
|
bar(<!COMPATIBILITY_WARNING!>::foo<!>)
|
||||||
|
bar(<!ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE!>Scope::foo<!>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,3 +26,11 @@ object Local {
|
|||||||
bar(<!ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE!>::baz<!>)
|
bar(<!ADAPTED_CALLABLE_REFERENCE_AGAINST_REFLECTION_TYPE!>::baz<!>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object WrongType {
|
||||||
|
fun foo(x: String, y: Int = 0) {} // (3)
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
bar(::foo) // Should resolve to (1) because (3) has wrong type on top of being adapted
|
||||||
|
}
|
||||||
|
}
|
||||||
-23
@@ -1,23 +0,0 @@
|
|||||||
package
|
|
||||||
|
|
||||||
public fun bar(/*0*/ f: kotlin.reflect.KFunction1<kotlin.Int, kotlin.Unit>): kotlin.Unit
|
|
||||||
public fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
|
|
||||||
public fun test(): kotlin.Unit
|
|
||||||
|
|
||||||
public object Local {
|
|
||||||
private constructor Local()
|
|
||||||
public final fun baz(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int = ...): kotlin.Int
|
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
|
||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
|
||||||
public final fun test(): kotlin.Unit
|
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
|
||||||
}
|
|
||||||
|
|
||||||
public object Scope {
|
|
||||||
private constructor Scope()
|
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
|
||||||
public final fun foo(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int = ...): kotlin.Int
|
|
||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
|
||||||
public final fun test(): kotlin.Unit
|
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user