[FIR] Replace type variable types with error types in lambda completion
#KT-54568 Fixed #KT-59882
This commit is contained in:
committed by
Space Team
parent
48433bf9fd
commit
80200fc3c5
+1
@@ -125,6 +125,7 @@ private fun ConeDiagnostic.toKtDiagnostic(
|
|||||||
is ConeDestructuringDeclarationsOnTopLevel -> null // TODO Currently a parsing error. Would be better to report here instead KT-58563
|
is ConeDestructuringDeclarationsOnTopLevel -> null // TODO Currently a parsing error. Would be better to report here instead KT-58563
|
||||||
is ConeCannotInferTypeParameterType -> FirErrors.CANNOT_INFER_PARAMETER_TYPE.createOn(source)
|
is ConeCannotInferTypeParameterType -> FirErrors.CANNOT_INFER_PARAMETER_TYPE.createOn(source)
|
||||||
is ConeCannotInferValueParameterType -> FirErrors.CANNOT_INFER_PARAMETER_TYPE.createOn(source)
|
is ConeCannotInferValueParameterType -> FirErrors.CANNOT_INFER_PARAMETER_TYPE.createOn(source)
|
||||||
|
is ConeCannotInferReceiverParameterType -> FirErrors.CANNOT_INFER_PARAMETER_TYPE.createOn(source)
|
||||||
is ConeTypeVariableTypeIsNotInferred -> FirErrors.INFERENCE_ERROR.createOn(callOrAssignmentSource ?: source)
|
is ConeTypeVariableTypeIsNotInferred -> FirErrors.INFERENCE_ERROR.createOn(callOrAssignmentSource ?: source)
|
||||||
is ConeInstanceAccessBeforeSuperCall -> FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL.createOn(source, this.target)
|
is ConeInstanceAccessBeforeSuperCall -> FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL.createOn(source, this.target)
|
||||||
is ConeStubDiagnostic -> null
|
is ConeStubDiagnostic -> null
|
||||||
|
|||||||
+16
-5
@@ -15,6 +15,8 @@ import org.jetbrains.kotlin.fir.declarations.FirFunction
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildContextReceiver
|
import org.jetbrains.kotlin.fir.declarations.builder.buildContextReceiver
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
|
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
|
||||||
|
import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferReceiverParameterType
|
||||||
|
import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferValueParameterType
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||||
@@ -263,9 +265,9 @@ class FirCallCompleter(
|
|||||||
containingFunctionSymbol = lambdaArgument.symbol
|
containingFunctionSymbol = lambdaArgument.symbol
|
||||||
moduleData = session.moduleData
|
moduleData = session.moduleData
|
||||||
origin = FirDeclarationOrigin.Source
|
origin = FirDeclarationOrigin.Source
|
||||||
returnTypeRef = itType.approximateLambdaInputType().toFirResolvedTypeRef()
|
|
||||||
this.name = name
|
this.name = name
|
||||||
symbol = FirValueParameterSymbol(name)
|
symbol = FirValueParameterSymbol(name)
|
||||||
|
returnTypeRef = itType.approximateLambdaInputType(symbol).toFirResolvedTypeRef()
|
||||||
defaultValue = null
|
defaultValue = null
|
||||||
isCrossinline = false
|
isCrossinline = false
|
||||||
isNoinline = false
|
isNoinline = false
|
||||||
@@ -281,7 +283,7 @@ class FirCallCompleter(
|
|||||||
receiverType == null -> lambdaArgument.replaceReceiverParameter(null)
|
receiverType == null -> lambdaArgument.replaceReceiverParameter(null)
|
||||||
!lambdaAtom.coerceFirstParameterToExtensionReceiver -> {
|
!lambdaAtom.coerceFirstParameterToExtensionReceiver -> {
|
||||||
lambdaArgument.receiverParameter?.apply {
|
lambdaArgument.receiverParameter?.apply {
|
||||||
val type = receiverType.approximateLambdaInputType()
|
val type = receiverType.approximateLambdaInputType(valueParameter = null)
|
||||||
val source = source?.fakeElement(KtFakeSourceElementKind.ImplicitTypeRef)
|
val source = source?.fakeElement(KtFakeSourceElementKind.ImplicitTypeRef)
|
||||||
replaceTypeRef(typeRef.resolvedTypeFromPrototype(type, source))
|
replaceTypeRef(typeRef.resolvedTypeFromPrototype(type, source))
|
||||||
}
|
}
|
||||||
@@ -311,7 +313,7 @@ class FirCallCompleter(
|
|||||||
else -> parameters
|
else -> parameters
|
||||||
}
|
}
|
||||||
lambdaArgument.valueParameters.forEachIndexed { index, parameter ->
|
lambdaArgument.valueParameters.forEachIndexed { index, parameter ->
|
||||||
val newReturnType = theParameters[index].approximateLambdaInputType()
|
val newReturnType = theParameters[index].approximateLambdaInputType(parameter.symbol)
|
||||||
val newReturnTypeRef = if (parameter.returnTypeRef is FirImplicitTypeRef) {
|
val newReturnTypeRef = if (parameter.returnTypeRef is FirImplicitTypeRef) {
|
||||||
newReturnType.toFirResolvedTypeRef(parameter.source?.fakeElement(KtFakeSourceElementKind.ImplicitReturnTypeOfLambdaValueParameter))
|
newReturnType.toFirResolvedTypeRef(parameter.source?.fakeElement(KtFakeSourceElementKind.ImplicitReturnTypeOfLambdaValueParameter))
|
||||||
} else parameter.returnTypeRef.resolvedTypeFromPrototype(newReturnType)
|
} else parameter.returnTypeRef.resolvedTypeFromPrototype(newReturnType)
|
||||||
@@ -352,10 +354,19 @@ class FirCallCompleter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeKotlinType.approximateLambdaInputType(): ConeKotlinType =
|
private fun ConeKotlinType.approximateLambdaInputType(valueParameter: FirValueParameterSymbol?): ConeKotlinType {
|
||||||
session.typeApproximator.approximateToSuperType(
|
// We only run lambda completion from ConstraintSystemCompletionContext.analyzeRemainingNotAnalyzedPostponedArgument when they are
|
||||||
|
// left uninferred.
|
||||||
|
// Currently, we use stub types for builder inference, so CANNOT_INFER_PARAMETER_TYPE is the only possible result here.
|
||||||
|
if (this is ConeTypeVariableType) {
|
||||||
|
val diagnostic = valueParameter?.let(::ConeCannotInferValueParameterType) ?: ConeCannotInferReceiverParameterType()
|
||||||
|
return ConeErrorType(diagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
|
return session.typeApproximator.approximateToSuperType(
|
||||||
this, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
|
this, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
|
||||||
) ?: this
|
) ?: this
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Candidate.isFunctionForExpectTypeFromCastFeature(): Boolean {
|
private fun Candidate.isFunctionForExpectTypeFromCastFeature(): Boolean {
|
||||||
|
|||||||
@@ -37,6 +37,10 @@ class ConeCannotInferValueParameterType(
|
|||||||
override val reason: String = "Cannot infer type for parameter ${valueParameter.name}"
|
override val reason: String = "Cannot infer type for parameter ${valueParameter.name}"
|
||||||
) : ConeDiagnostic
|
) : ConeDiagnostic
|
||||||
|
|
||||||
|
class ConeCannotInferReceiverParameterType(
|
||||||
|
override val reason: String = "Cannot infer type for receiver parameter"
|
||||||
|
) : ConeDiagnostic
|
||||||
|
|
||||||
class ConeTypeVariableTypeIsNotInferred(
|
class ConeTypeVariableTypeIsNotInferred(
|
||||||
val typeVariableType: ConeTypeVariableType,
|
val typeVariableType: ConeTypeVariableType,
|
||||||
override val reason: String = "Type for ${typeVariableType.lookupTag.debugName} is not inferred"
|
override val reason: String = "Type for ${typeVariableType.lookupTag.debugName} is not inferred"
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568
|
|
||||||
fun test1() {
|
|
||||||
try {
|
|
||||||
{ toDouble ->
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun test2() {
|
|
||||||
try {
|
|
||||||
|
|
||||||
} catch (e: Exception) {
|
|
||||||
{ toDouble ->
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun box(): String {
|
|
||||||
test1()
|
|
||||||
test2()
|
|
||||||
return "OK"
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568
|
// FIR_IDENTICAL
|
||||||
fun test1() {
|
fun test1() {
|
||||||
try {
|
try {
|
||||||
{ <!CANNOT_INFER_PARAMETER_TYPE!>toDouble<!> ->
|
{ <!CANNOT_INFER_PARAMETER_TYPE!>toDouble<!> ->
|
||||||
|
|||||||
+3
-4
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568
|
|
||||||
// !DIAGNOSTICS: -UNUSED_ANONYMOUS_PARAMETER -UNUSED_VARIABLE
|
// !DIAGNOSTICS: -UNUSED_ANONYMOUS_PARAMETER -UNUSED_VARIABLE
|
||||||
|
|
||||||
fun <T> select(vararg x: <!CANNOT_INFER_PARAMETER_TYPE, CANNOT_INFER_PARAMETER_TYPE!>T<!>) = x[0]
|
fun <T> select(vararg x: <!CANNOT_INFER_PARAMETER_TYPE, CANNOT_INFER_PARAMETER_TYPE!>T<!>) = x[0]
|
||||||
@@ -6,12 +5,12 @@ fun <K> id(x: K) = x
|
|||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
val x1 = select<Any?>(id { x, y -> }, { x: Int, y -> })
|
val x1 = select<Any?>(id { x, y -> }, { x: Int, y -> })
|
||||||
val x2 = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>select<!>(id { x, y -> }, { x: Int, y -> })
|
val x2 = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>select<!>(id { x, <!CANNOT_INFER_PARAMETER_TYPE!>y<!> -> }, { x: Int, <!CANNOT_INFER_PARAMETER_TYPE!>y<!> -> })
|
||||||
|
|
||||||
val x3 = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>select<!>(id(fun (x, y) {}), fun (x: Int, y) {})
|
val x3 = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>select<!>(id(fun (x, <!CANNOT_INFER_PARAMETER_TYPE!>y<!>) {}), fun (x: Int, <!CANNOT_INFER_PARAMETER_TYPE!>y<!>) {})
|
||||||
|
|
||||||
val x4 = select<Any?>((fun (x, y) {}), fun (x: Int, y) {})
|
val x4 = select<Any?>((fun (x, y) {}), fun (x: Int, y) {})
|
||||||
val x5 = select<Any?>(id(fun (x, y) {}), fun (x: Int, y) {})
|
val x5 = select<Any?>(id(fun (<!CANNOT_INFER_PARAMETER_TYPE!>x<!>, <!CANNOT_INFER_PARAMETER_TYPE!>y<!>) {}), fun (x: Int, y) {})
|
||||||
val x6 = id<Any?>(fun (x) {})
|
val x6 = id<Any?>(fun (x) {})
|
||||||
|
|
||||||
select<Any?>(fun (x) {}, fun (x) {})
|
select<Any?>(fun (x) {}, fun (x) {})
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568
|
|
||||||
// !DIAGNOSTICS: -UNUSED_ANONYMOUS_PARAMETER -UNUSED_VARIABLE
|
// !DIAGNOSTICS: -UNUSED_ANONYMOUS_PARAMETER -UNUSED_VARIABLE
|
||||||
|
|
||||||
fun <T> select(vararg x: T) = x[0]
|
fun <T> select(vararg x: T) = x[0]
|
||||||
|
|||||||
Vendored
+3
-4
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568
|
|
||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
fun callAny(arg: Any?) {}
|
fun callAny(arg: Any?) {}
|
||||||
@@ -20,14 +19,14 @@ fun testAnyCall() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun testParam() {
|
fun testParam() {
|
||||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>callParam<!> {
|
callParam {
|
||||||
param -> param
|
<!CANNOT_INFER_PARAMETER_TYPE!>param<!> -> param
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testParamCall() {
|
fun testParamCall() {
|
||||||
callParam {
|
callParam {
|
||||||
param -> <!UNRESOLVED_REFERENCE!>param<!>()
|
<!CANNOT_INFER_PARAMETER_TYPE!>param<!> -> <!UNRESOLVED_REFERENCE!>param<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568
|
|
||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
fun callAny(arg: Any?) {}
|
fun callAny(arg: Any?) {}
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568
|
|
||||||
// !LANGUAGE: +PartiallySpecifiedTypeArguments
|
// !LANGUAGE: +PartiallySpecifiedTypeArguments
|
||||||
// !DIAGNOSTICS: -UNCHECKED_CAST
|
// !DIAGNOSTICS: -UNCHECKED_CAST
|
||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568
|
|
||||||
// !LANGUAGE: +PartiallySpecifiedTypeArguments
|
// !LANGUAGE: +PartiallySpecifiedTypeArguments
|
||||||
// !DIAGNOSTICS: -UNCHECKED_CAST
|
// !DIAGNOSTICS: -UNCHECKED_CAST
|
||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
|
|||||||
+6
-2
@@ -1,3 +1,7 @@
|
|||||||
// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568
|
|
||||||
fun <K> foo(x: K) {}
|
fun <K> foo(x: K) {}
|
||||||
val x = foo<(<!UNRESOLVED_REFERENCE!>unresolved<!>) -> Float> { it.<!UNRESOLVED_REFERENCE!>toFloat<!>() }
|
val x1 = foo<(<!UNRESOLVED_REFERENCE!>unresolved<!>) -> Float> { it.<!UNRESOLVED_REFERENCE!>toFloat<!>() }
|
||||||
|
val x2 = foo<(<!UNRESOLVED_REFERENCE!>unresolved<!>) -> Float> { <!CANNOT_INFER_PARAMETER_TYPE!>it<!> -> it.<!UNRESOLVED_REFERENCE!>toFloat<!>() }
|
||||||
|
val x3 = foo<<!UNRESOLVED_REFERENCE!>unresolved<!>.() -> Float> { this.<!UNRESOLVED_REFERENCE!>toFloat<!>() }
|
||||||
|
val x4 = foo<(Array<<!UNRESOLVED_REFERENCE!>unresolved<!>>) -> Int> { it.size }
|
||||||
|
|
||||||
|
fun <T> bar() = foo<(T) -> String> { it.toString() }
|
||||||
|
|||||||
+6
-2
@@ -1,3 +1,7 @@
|
|||||||
// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568
|
|
||||||
fun <K> foo(x: K) {}
|
fun <K> foo(x: K) {}
|
||||||
val x = foo<(<!UNRESOLVED_REFERENCE!>unresolved<!>) -> Float> { <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>it<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>toFloat<!>() }
|
val x1 = foo<(<!UNRESOLVED_REFERENCE!>unresolved<!>) -> Float> { <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>it<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>toFloat<!>() }
|
||||||
|
val x2 = foo<(<!UNRESOLVED_REFERENCE!>unresolved<!>) -> Float> { <!CANNOT_INFER_PARAMETER_TYPE!>it<!> -> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>it<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>toFloat<!>() }
|
||||||
|
val x3 = foo<<!UNRESOLVED_REFERENCE!>unresolved<!>.() -> Float> { this.<!DEBUG_INFO_MISSING_UNRESOLVED!>toFloat<!>() }
|
||||||
|
val x4 = foo<(Array<<!UNRESOLVED_REFERENCE!>unresolved<!>>) -> Int> { <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>it<!>.size }
|
||||||
|
|
||||||
|
fun <T> bar() = foo<(T) -> String> { it.toString() }
|
||||||
|
|||||||
+5
-1
@@ -1,4 +1,8 @@
|
|||||||
package
|
package
|
||||||
|
|
||||||
public val x: kotlin.Unit
|
public val x1: kotlin.Unit
|
||||||
|
public val x2: kotlin.Unit
|
||||||
|
public val x3: kotlin.Unit
|
||||||
|
public val x4: kotlin.Unit
|
||||||
|
public fun </*0*/ T> bar(): kotlin.Unit
|
||||||
public fun </*0*/ K> foo(/*0*/ x: K): kotlin.Unit
|
public fun </*0*/ K> foo(/*0*/ x: K): kotlin.Unit
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568
|
|
||||||
// NI_EXPECTED_FILE
|
// NI_EXPECTED_FILE
|
||||||
// See EA-76890 / KT-10843: NPE during analysis
|
// See EA-76890 / KT-10843: NPE during analysis
|
||||||
fun lambda(x : Int?) = x?.<!FUNCTION_CALL_EXPECTED!>let<!> <!UNRESOLVED_REFERENCE!>l<!> {
|
fun lambda(x : Int?) = x?.<!FUNCTION_CALL_EXPECTED!>let<!> <!UNRESOLVED_REFERENCE!>l<!> {
|
||||||
y ->
|
<!CANNOT_INFER_PARAMETER_TYPE!>y<!> ->
|
||||||
if (y <!UNRESOLVED_REFERENCE!>><!> 0) return@l x
|
if (y <!UNRESOLVED_REFERENCE!>><!> 0) return@l x
|
||||||
y
|
y
|
||||||
}<!NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION!>!!<!>
|
}<!NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION!>!!<!>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568
|
|
||||||
// NI_EXPECTED_FILE
|
// NI_EXPECTED_FILE
|
||||||
// See EA-76890 / KT-10843: NPE during analysis
|
// See EA-76890 / KT-10843: NPE during analysis
|
||||||
fun lambda(x : Int?) = x?.<!FUNCTION_CALL_EXPECTED, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NO_VALUE_FOR_PARAMETER!>let<!> <!DEBUG_INFO_MISSING_UNRESOLVED!>l<!> {
|
fun lambda(x : Int?) = x?.<!FUNCTION_CALL_EXPECTED, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NO_VALUE_FOR_PARAMETER!>let<!> <!DEBUG_INFO_MISSING_UNRESOLVED!>l<!> {
|
||||||
|
|||||||
Reference in New Issue
Block a user