[FIR] Fix reporting of CANNOT_INFER_PARAMETER_TYPE on lambda parameters
^KT-56138 Fixed
This commit is contained in:
committed by
Space Team
parent
76d360d793
commit
f479a56f5e
+2
-2
@@ -33,7 +33,7 @@ import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirFieldImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirOuterClassTypeParameterRef
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferParameterType
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferTypeParameterType
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
|
||||
import org.jetbrains.kotlin.fir.originalForSubstitutionOverride
|
||||
@@ -458,7 +458,7 @@ internal class KtSymbolByFirBuilder constructor(
|
||||
is ConeTypeVariableType -> {
|
||||
val diagnostic = when ( val typeParameter = coneType.lookupTag.originalTypeParameter) {
|
||||
null -> ConeSimpleDiagnostic("Cannot infer parameter type for ${coneType.lookupTag.debugName}")
|
||||
else -> ConeCannotInferParameterType((typeParameter as ConeTypeParameterLookupTag).typeParameterSymbol)
|
||||
else -> ConeCannotInferTypeParameterType((typeParameter as ConeTypeParameterLookupTag).typeParameterSymbol)
|
||||
}
|
||||
buildKtType(ConeErrorType(diagnostic, isUninferredParameter = true, attributes = coneType.attributes))
|
||||
}
|
||||
|
||||
+2
-2
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeErrorType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferParameterType
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferTypeParameterType
|
||||
import org.jetbrains.kotlin.fir.types.ConeErrorType
|
||||
import org.jetbrains.kotlin.fir.types.renderForDebugging
|
||||
|
||||
@@ -28,7 +28,7 @@ internal class KtFirTypeErrorType(
|
||||
|
||||
override fun tryRenderAsNonErrorType(): String? = withValidityAssertion {
|
||||
when (val diagnostic = coneType.diagnostic) {
|
||||
is ConeCannotInferParameterType -> diagnostic.typeParameter.name.asString()
|
||||
is ConeCannotInferTypeParameterType -> diagnostic.typeParameter.name.asString()
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -11858,6 +11858,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
||||
runTest("compiler/testData/diagnostics/tests/functionLiterals/kt51317.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt56138.kt")
|
||||
public void testKt56138() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/functionLiterals/kt56138.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt6541_extensionForExtensionFunction.kt")
|
||||
public void testKt6541_extensionForExtensionFunction() throws Exception {
|
||||
|
||||
+6
@@ -11864,6 +11864,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/functionLiterals/kt51317.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt56138.kt")
|
||||
public void testKt56138() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/functionLiterals/kt56138.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt6541_extensionForExtensionFunction.kt")
|
||||
public void testKt6541_extensionForExtensionFunction() throws Exception {
|
||||
|
||||
+6
@@ -11858,6 +11858,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/functionLiterals/kt51317.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt56138.kt")
|
||||
public void testKt56138() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/functionLiterals/kt56138.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt6541_extensionForExtensionFunction.kt")
|
||||
public void testKt6541_extensionForExtensionFunction() throws Exception {
|
||||
|
||||
+2
-2
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.fir.resolve.inference.model.ConeArgumentConstraintPo
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeExpectedTypeConstraintPosition
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeLambdaArgumentConstraintPosition
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
@@ -109,7 +108,8 @@ private fun ConeDiagnostic.toKtDiagnostic(
|
||||
}
|
||||
|
||||
is ConeDestructuringDeclarationsOnTopLevel -> FirSyntaxErrors.SYNTAX.createOn(source)
|
||||
is ConeCannotInferParameterType -> 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 ConeInstanceAccessBeforeSuperCall -> FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL.createOn(source, this.target)
|
||||
is ConeStubDiagnostic -> null
|
||||
is ConeIntermediateDiagnostic -> null
|
||||
|
||||
+5
-1
@@ -2318,16 +2318,20 @@ class DeclarationsConverter(
|
||||
|
||||
val name = convertValueParameterName(identifier.nameAsSafeName(), identifier, valueParameterDeclaration)
|
||||
|
||||
val valueParameterSource = valueParameter.toFirSourceElement()
|
||||
return ValueParameter(
|
||||
isVal = isVal,
|
||||
isVar = isVar,
|
||||
modifiers = modifiers,
|
||||
returnTypeRef = firType
|
||||
?: when {
|
||||
valueParameterDeclaration == ValueParameterDeclaration.LAMBDA -> buildImplicitTypeRef {
|
||||
source = valueParameterSource.fakeElement(KtFakeSourceElementKind.ImplicitReturnTypeOfLambdaValueParameter)
|
||||
}
|
||||
valueParameterDeclaration.shouldExplicitParameterTypeBePresent -> createNoTypeForParameterTypeRef()
|
||||
else -> implicitType
|
||||
},
|
||||
source = valueParameter.toFirSourceElement(),
|
||||
source = valueParameterSource,
|
||||
moduleData = baseModuleData,
|
||||
isFromPrimaryConstructor = valueParameterDeclaration == ValueParameterDeclaration.PRIMARY_CONSTRUCTOR,
|
||||
additionalAnnotations = additionalAnnotations,
|
||||
|
||||
@@ -1583,7 +1583,7 @@ open class RawFirBuilder(
|
||||
multiParameter
|
||||
} else {
|
||||
val typeRef = valueParameter.typeReference?.convertSafe() ?: buildImplicitTypeRef {
|
||||
source = implicitTypeRefSource
|
||||
source = valueParameter.toFirSourceElement().fakeElement(KtFakeSourceElementKind.ImplicitReturnTypeOfLambdaValueParameter)
|
||||
}
|
||||
convertValueParameter(valueParameter, symbol, typeRef, ValueParameterDeclaration.LAMBDA)
|
||||
}
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.inference
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferParameterType
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferTypeParameterType
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
@@ -459,7 +459,7 @@ class ConstraintSystemCompleter(components: BodyResolveComponents, private val c
|
||||
): ConeErrorType {
|
||||
val diagnostic = when (typeParameterSymbol) {
|
||||
null -> ConeSimpleDiagnostic(message, DiagnosticKind.CannotInferParameterType)
|
||||
else -> ConeCannotInferParameterType(
|
||||
else -> ConeCannotInferTypeParameterType(
|
||||
typeParameterSymbol,
|
||||
message,
|
||||
)
|
||||
|
||||
+1
-1
@@ -332,7 +332,7 @@ class FirCallCompleter(
|
||||
lambdaArgument.valueParameters.forEachIndexed { index, parameter ->
|
||||
val newReturnType = parameters[index].approximateLambdaInputType()
|
||||
val newReturnTypeRef = if (parameter.returnTypeRef is FirImplicitTypeRef) {
|
||||
newReturnType.toFirResolvedTypeRef(parameter.source)
|
||||
newReturnType.toFirResolvedTypeRef(parameter.source?.fakeElement(KtFakeSourceElementKind.ImplicitReturnTypeOfLambdaValueParameter))
|
||||
} else parameter.returnTypeRef.resolvedTypeFromPrototype(newReturnType)
|
||||
parameter.replaceReturnTypeRef(newReturnTypeRef)
|
||||
lookupTracker?.recordTypeResolveAsLookup(newReturnTypeRef, parameter.source, fileSource)
|
||||
|
||||
+2
-5
@@ -6,8 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir.resolve.inference
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferValueParameterType
|
||||
import org.jetbrains.kotlin.fir.expressions.FirReturnExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
|
||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||
@@ -85,9 +84,7 @@ fun extractLambdaInfoFromFunctionType(
|
||||
argumentValueParameters.mapIndexed { index, parameter ->
|
||||
parameter.returnTypeRef.coneTypeSafe()
|
||||
?: expectedParameters.getOrNull(index)
|
||||
?: ConeErrorType(
|
||||
ConeSimpleDiagnostic("Cannot infer type for parameter ${parameter.name}", DiagnosticKind.CannotInferParameterType)
|
||||
)
|
||||
?: ConeErrorType(ConeCannotInferValueParameterType(parameter.symbol))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.diagnostics
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionTypeKind
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
@@ -23,11 +24,16 @@ class ConeUnderscoreIsReserved(source: KtSourceElement) : ConeDiagnosticWithSour
|
||||
override val reason: String get() = "Names _, __, ___, ..., are reserved in Kotlin"
|
||||
}
|
||||
|
||||
class ConeCannotInferParameterType(
|
||||
class ConeCannotInferTypeParameterType(
|
||||
val typeParameter: FirTypeParameterSymbol,
|
||||
override val reason: String = "Cannot infer type for parameter ${typeParameter.name}"
|
||||
) : ConeDiagnostic
|
||||
|
||||
class ConeCannotInferValueParameterType(
|
||||
val valueParameter: FirValueParameterSymbol,
|
||||
override val reason: String = "Cannot infer type for parameter ${valueParameter.name}"
|
||||
) : ConeDiagnostic
|
||||
|
||||
class ConeUnderscoreUsageWithoutBackticks(source: KtSourceElement) : ConeDiagnosticWithSource(source) {
|
||||
override val reason: String get() = "Names _, __, ___, ... can be used only in back-ticks (`_`, `__`, `___`, ...)"
|
||||
}
|
||||
@@ -78,7 +84,7 @@ enum class DiagnosticKind {
|
||||
Java,
|
||||
SuperNotAllowed,
|
||||
ValueParameterWithNoTypeAnnotation,
|
||||
CannotInferParameterType,
|
||||
CannotInferParameterType, // TODO: replace this with ConeCannotInferValueParameterType and ConeCannotInferTypeParameterType
|
||||
IllegalProjectionUsage,
|
||||
MissingStdlibClass,
|
||||
NotASupertype,
|
||||
|
||||
@@ -248,6 +248,9 @@ sealed class KtFakeSourceElementKind(final override val shouldSkipErrorTypeRepor
|
||||
|
||||
// for when on the LHS of an assignment an error expression appears
|
||||
object AssignmentLValueError : KtFakeSourceElementKind()
|
||||
|
||||
// for return type of value parameters in lambdas
|
||||
object ImplicitReturnTypeOfLambdaValueParameter : KtFakeSourceElementKind()
|
||||
}
|
||||
|
||||
sealed class AbstractKtSourceElement {
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// SKIP_TXT
|
||||
// ISSUE: KT-56138
|
||||
|
||||
fun takeLambda1(f: String.() -> String) {}
|
||||
fun takeLambda2(f: String.(String) -> String) {}
|
||||
|
||||
fun test_1() {
|
||||
val x1: String.(String) -> String = { str, <!CANNOT_INFER_PARAMETER_TYPE!>str2<!> -> "this" }
|
||||
val x2: String.() -> String = { <!UNRESOLVED_REFERENCE!>it<!> }
|
||||
val x3: String.() -> String = { <!CANNOT_INFER_PARAMETER_TYPE!>x<!> -> "x" }
|
||||
}
|
||||
|
||||
fun test_2() {
|
||||
takeLambda2 <!ARGUMENT_TYPE_MISMATCH!>{ str, <!CANNOT_INFER_PARAMETER_TYPE!>str2<!> -> "this" }<!>
|
||||
takeLambda1 { <!UNRESOLVED_REFERENCE!>it<!> }
|
||||
takeLambda1 <!ARGUMENT_TYPE_MISMATCH!>{ <!CANNOT_INFER_PARAMETER_TYPE!>x<!> -> "x" }<!>
|
||||
}
|
||||
|
||||
fun test_3(b: Boolean) {
|
||||
val x1: String.(String) -> String = if (b) {
|
||||
{ str, <!CANNOT_INFER_PARAMETER_TYPE!>str2<!> -> "this" }
|
||||
} else {
|
||||
{ str, <!CANNOT_INFER_PARAMETER_TYPE!>str2<!> -> "this" }
|
||||
}
|
||||
|
||||
val x2: String.() -> String = if (b) {
|
||||
{ <!UNRESOLVED_REFERENCE!>it<!> }
|
||||
} else {
|
||||
{ <!UNRESOLVED_REFERENCE!>it<!> }
|
||||
}
|
||||
|
||||
val x3: String.() -> String = if (b) {
|
||||
{ <!CANNOT_INFER_PARAMETER_TYPE!>x<!> -> "x" }
|
||||
} else {
|
||||
{ <!CANNOT_INFER_PARAMETER_TYPE!>x<!> -> "x" }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// SKIP_TXT
|
||||
// ISSUE: KT-56138
|
||||
|
||||
fun takeLambda1(f: String.() -> String) {}
|
||||
fun takeLambda2(f: String.(String) -> String) {}
|
||||
|
||||
fun test_1() {
|
||||
val x1: String.(String) -> String = { <!EXPECTED_PARAMETERS_NUMBER_MISMATCH!>str, <!CANNOT_INFER_PARAMETER_TYPE!>str2<!><!> -> "this" }
|
||||
val x2: String.() -> String = { <!UNRESOLVED_REFERENCE!>it<!> }
|
||||
val x3: String.() -> String = { <!CANNOT_INFER_PARAMETER_TYPE, EXPECTED_PARAMETERS_NUMBER_MISMATCH!>x<!> -> "x" }
|
||||
}
|
||||
|
||||
fun test_2() {
|
||||
takeLambda2 <!TYPE_MISMATCH!>{ <!EXPECTED_PARAMETERS_NUMBER_MISMATCH!>str, <!CANNOT_INFER_PARAMETER_TYPE!>str2<!><!> -> "this" }<!>
|
||||
takeLambda1 <!TYPE_MISMATCH!>{ <!UNRESOLVED_REFERENCE!>it<!> }<!>
|
||||
takeLambda1 <!TYPE_MISMATCH!>{ <!CANNOT_INFER_PARAMETER_TYPE, EXPECTED_PARAMETERS_NUMBER_MISMATCH!>x<!> -> "x" }<!>
|
||||
}
|
||||
|
||||
fun test_3(b: Boolean) {
|
||||
val x1: String.(String) -> String = if (b) <!TYPE_MISMATCH!>{
|
||||
{ <!EXPECTED_PARAMETERS_NUMBER_MISMATCH!>str, <!CANNOT_INFER_PARAMETER_TYPE!>str2<!><!> -> "this" }
|
||||
}<!> else <!TYPE_MISMATCH!>{
|
||||
{ <!EXPECTED_PARAMETERS_NUMBER_MISMATCH!>str, <!CANNOT_INFER_PARAMETER_TYPE!>str2<!><!> -> "this" }
|
||||
}<!>
|
||||
|
||||
val x2: String.() -> String = if (b) <!TYPE_MISMATCH!>{
|
||||
{ <!UNRESOLVED_REFERENCE!>it<!> }
|
||||
}<!> else <!TYPE_MISMATCH!>{
|
||||
{ <!UNRESOLVED_REFERENCE!>it<!> }
|
||||
}<!>
|
||||
|
||||
val x3: String.() -> String = if (b) <!TYPE_MISMATCH!>{
|
||||
{ <!CANNOT_INFER_PARAMETER_TYPE, EXPECTED_PARAMETERS_NUMBER_MISMATCH!>x<!> -> "x" }
|
||||
}<!> else <!TYPE_MISMATCH!>{
|
||||
{ <!CANNOT_INFER_PARAMETER_TYPE, EXPECTED_PARAMETERS_NUMBER_MISMATCH!>x<!> -> "x" }
|
||||
}<!>
|
||||
}
|
||||
Generated
+6
@@ -11864,6 +11864,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/functionLiterals/kt51317.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt56138.kt")
|
||||
public void testKt56138() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/functionLiterals/kt56138.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt6541_extensionForExtensionFunction.kt")
|
||||
public void testKt6541_extensionForExtensionFunction() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user