From e8bf8cb18295c67501a232782da8c4eb916e3c26 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Tue, 19 Jul 2022 21:25:48 +0200 Subject: [PATCH] [Analysis API FIR] fix type rendering for type with "Cannot infer type for parameter" error --- .../api/fir/renderer/ConeTypeIdeRenderer.kt | 19 ++++++++++-- .../coneDiagnosticToFirDiagnostic.kt | 1 + .../inference/ConstraintSystemCompleter.kt | 31 +++++++++++++------ .../fir/diagnostics/ConeSimpleDiagnostic.kt | 8 +++++ 4 files changed, 47 insertions(+), 12 deletions(-) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/ConeTypeIdeRenderer.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/ConeTypeIdeRenderer.kt index da2a6b916d1..befce21b90f 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/ConeTypeIdeRenderer.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/renderer/ConeTypeIdeRenderer.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.containingClassForLocal import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.isInner import org.jetbrains.kotlin.fir.declarations.utils.isLocal +import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferParameterType import org.jetbrains.kotlin.fir.renderWithType import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedError import org.jetbrains.kotlin.fir.resolve.toFirRegularClass @@ -96,9 +97,21 @@ internal class ConeTypeIdeRenderer( private fun StringBuilder.renderErrorType(type: ConeErrorType) { val diagnostic = type.diagnostic - if (options.renderUnresolvedTypeAsResolved && diagnostic is ConeUnresolvedError) { - val qualifierRendered = diagnostic.qualifier?.let { FqName(it).render() }.orEmpty() - append(qualifierRendered) + if (options.renderUnresolvedTypeAsResolved) { + when (diagnostic) { + is ConeUnresolvedError -> { + val qualifierRendered = diagnostic.qualifier?.let { FqName(it).render() }.orEmpty() + append(qualifierRendered) + } + + is ConeCannotInferParameterType -> { + append(diagnostic.typeParameter.name.render()) + } + + else -> { + appendError(diagnostic.reason) + } + } } else { appendError(diagnostic.reason) } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt index 78ac4ed364c..6d499d7fe74 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt @@ -105,6 +105,7 @@ private fun ConeDiagnostic.toKtDiagnostic( source.kind is KtFakeSourceElementKind && source.kind != KtFakeSourceElementKind.ReferenceInAtomicQualifiedAccess -> null else -> this.getFactory(source).createOn(qualifiedAccessSource ?: source) } + is ConeCannotInferParameterType -> 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 diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt index 460242933c4..330e55a1b28 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt @@ -7,6 +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.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.expressions.* @@ -18,6 +19,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext import org.jetbrains.kotlin.fir.resolve.inference.model.ConeFixVariableConstraintPosition import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.BodyResolveContext import org.jetbrains.kotlin.fir.returnExpressions +import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.types.ConeErrorType import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeTypeVariable @@ -305,11 +307,16 @@ class ConstraintSystemCompleter(components: BodyResolveComponents, private val c val resultErrorType = when (typeVariable) { is ConeTypeParameterBasedTypeVariable -> createCannotInferErrorType( + typeVariable.typeParameterSymbol, "Cannot infer argument for type parameter ${typeVariable.typeParameterSymbol.name}", isUninferredParameter = true, ) - is ConeTypeVariableForLambdaParameterType -> createCannotInferErrorType("Cannot infer lambda parameter type") - else -> createCannotInferErrorType("Cannot infer type variable $typeVariable") + + is ConeTypeVariableForLambdaParameterType -> createCannotInferErrorType( + typeParameterSymbol = null, + message = "Cannot infer lambda parameter type" + ) + else -> createCannotInferErrorType(typeParameterSymbol = null, "Cannot infer type variable $typeVariable") } fixVariable(typeVariable, resultErrorType, ConeFixVariableConstraintPosition(typeVariable)) @@ -445,14 +452,20 @@ class ConstraintSystemCompleter(components: BodyResolveComponents, private val c return topLevelAtoms.firstNotNullOfOrNull(FirStatement::findFirstAtomContainingVariable) } - private fun createCannotInferErrorType(message: String, isUninferredParameter: Boolean = false) = - ConeErrorType( - ConeSimpleDiagnostic( + private fun createCannotInferErrorType( + typeParameterSymbol: FirTypeParameterSymbol?, + message: String, + isUninferredParameter: Boolean = false + ): ConeErrorType { + val diagnostic = when (typeParameterSymbol) { + null -> ConeSimpleDiagnostic(message, DiagnosticKind.CannotInferParameterType) + else -> ConeCannotInferParameterType( + typeParameterSymbol, message, - DiagnosticKind.CannotInferParameterType, - ), - isUninferredParameter, - ) + ) + } + return ConeErrorType(diagnostic, isUninferredParameter,) + } } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt index a4f75767cf1..b75356d5ffc 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt @@ -6,6 +6,9 @@ package org.jetbrains.kotlin.fir.diagnostics import org.jetbrains.kotlin.KtSourceElement +import org.jetbrains.kotlin.fir.declarations.FirTypeParameter +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 @@ -21,6 +24,11 @@ class ConeUnderscoreIsReserved(source: KtSourceElement) : ConeDiagnosticWithSour override val reason: String get() = "Names _, __, ___, ..., are reserved in Kotlin" } +class ConeCannotInferParameterType( + val typeParameter: FirTypeParameterSymbol, + override val reason: String = "Cannot infer type for parameter ${typeParameter.name}" +) : ConeDiagnostic + class ConeUnderscoreUsageWithoutBackticks(source: KtSourceElement) : ConeDiagnosticWithSource(source) { override val reason: String get() = "Names _, __, ___, ... can be used only in back-ticks (`_`, `__`, `___`, ...)" }