FIR: Implement more precise reporting diagnostics from new inference

This commit is contained in:
Denis.Zharkov
2021-04-27 15:19:18 +03:00
committed by teamcityserver
parent c67ae8a0a3
commit c46d049394
11 changed files with 150 additions and 16 deletions
@@ -13,13 +13,14 @@ import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.inference.ConeTypeParameterBasedTypeVariable
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeDeclaredUpperBoundConstraintPosition
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeExplicitTypeParameterConstraintPosition
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.FirTypePlaceholderProjection
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
@@ -71,7 +72,7 @@ internal object CreateFreshTypeVariableSubstitutorStage : ResolutionStage() {
typeParameter,
context.session
).fullyExpandedType(context.session),
SimpleConstraintSystemConstraintPosition // TODO
ConeExplicitTypeParameterConstraintPosition(typeArgument)
)
is FirStarProjection -> csBuilder.addEqualityConstraint(
freshVariable.defaultType,
@@ -50,6 +50,12 @@ class ConeInapplicableCandidateError(
override val reason: String get() = "Inapplicable($applicability): ${describeSymbol(candidate.symbol)}"
}
class ConeConstraintSystemHasContradiction(
val candidate: Candidate,
) : ConeDiagnostic() {
override val reason: String get() = "CS errors: ${describeSymbol(candidate.symbol)}"
}
class ConeArgumentTypeMismatchCandidateError(
val expectedType: ConeKotlinType, val actualType: ConeKotlinType
) : ConeDiagnostic() {
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.resolve.inference
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
@@ -12,10 +13,10 @@ import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.references.FirNamedReference
import org.jetbrains.kotlin.fir.resolve.DoubleColonLHS
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeTypeVariable
import org.jetbrains.kotlin.fir.types.ConeTypeVariableType
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.resolve.calls.model.LambdaWithTypeVariableAsExpectedTypeMarker
import org.jetbrains.kotlin.resolve.calls.model.PostponedCallableReferenceMarker
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
@@ -29,6 +30,7 @@ class ConeTypeVariableForPostponedAtom(name: String) : ConeTypeVariable(name)
// -------------------------- Atoms --------------------------
sealed class PostponedResolvedAtom : PostponedResolvedAtomMarker {
abstract val atom: FirElement
abstract override val inputTypes: Collection<ConeKotlinType>
abstract override val outputType: ConeKotlinType?
override var analyzed: Boolean = false
@@ -38,7 +40,7 @@ sealed class PostponedResolvedAtom : PostponedResolvedAtomMarker {
// ------------- Lambdas -------------
class ResolvedLambdaAtom(
val atom: FirAnonymousFunction,
override val atom: FirAnonymousFunction,
expectedType: ConeKotlinType?,
val isSuspend: Boolean,
val receiver: ConeKotlinType?,
@@ -75,7 +77,7 @@ class ResolvedLambdaAtom(
}
class LambdaWithTypeVariableAsExpectedTypeAtom(
val atom: FirAnonymousFunction,
override val atom: FirAnonymousFunction,
private val initialExpectedTypeType: ConeKotlinType,
val expectedTypeRef: FirTypeRef,
val candidateOfOuterCall: Candidate,
@@ -116,6 +118,9 @@ class ResolvedCallableReferenceAtom(
private val session: FirSession
) : PostponedResolvedAtom(), PostponedCallableReferenceMarker {
override val atom: FirCallableReferenceAccess
get() = reference
var hasBeenResolvedOnce: Boolean = false
var hasBeenPostponed: Boolean = false
@@ -5,13 +5,24 @@
package org.jetbrains.kotlin.fir.resolve.inference.model
import org.jetbrains.kotlin.resolve.calls.inference.model.ArgumentConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.DeclaredUpperBoundConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.FixVariableConstraintPosition
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
import org.jetbrains.kotlin.fir.types.FirTypeProjection
import org.jetbrains.kotlin.resolve.calls.inference.model.*
import org.jetbrains.kotlin.types.model.TypeVariableMarker
class ConeDeclaredUpperBoundConstraintPosition : DeclaredUpperBoundConstraintPosition<Nothing?>(null)
class ConeFixVariableConstraintPosition(variable: TypeVariableMarker) : FixVariableConstraintPosition<Nothing?>(variable, null)
class ConeArgumentConstraintPosition : ArgumentConstraintPosition<Nothing?>(null)
class ConeArgumentConstraintPosition(argument: FirElement) : ArgumentConstraintPosition<FirElement>(argument)
class ConeExpectedTypeConstraintPosition : ExpectedTypeConstraintPosition<Nothing?>(null)
class ConeExplicitTypeParameterConstraintPosition(
typeArgument: FirTypeProjection,
) : ExplicitTypeParameterConstraintPosition<FirTypeProjection>(typeArgument)
class ConeLambdaArgumentConstraintPosition(
anonymousFunction: FirAnonymousFunction
) : LambdaArgumentConstraintPosition<FirAnonymousFunction>(anonymousFunction)
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.calls.*
import org.jetbrains.kotlin.fir.resolve.dfa.FirDataFlowAnalyzer
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeConstraintSystemHasContradiction
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableCandidateError
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeTypeParameterInQualifiedAccess
import org.jetbrains.kotlin.fir.resolve.inference.*
@@ -37,6 +38,7 @@ import org.jetbrains.kotlin.fir.types.builder.buildStarProjection
import org.jetbrains.kotlin.fir.types.builder.buildTypeProjectionWithVariance
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.fir.visitors.*
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.addToStdlib.runIf
@@ -739,7 +741,14 @@ class FirCallCompletionResultsWriterTransformer(
private fun FirNamedReferenceWithCandidate.toResolvedReference(): FirNamedReference {
val errorDiagnostic = when {
this is FirErrorReferenceWithCandidate -> this.diagnostic
!candidate.isSuccessful -> ConeInapplicableCandidateError(candidate.currentApplicability, candidate)
!candidate.currentApplicability.isSuccess -> ConeInapplicableCandidateError(candidate.currentApplicability, candidate)
!candidate.isSuccessful -> {
require(candidate.system.hasContradiction) {
"Candidate is not successful, but system has no contradiction"
}
ConeConstraintSystemHasContradiction(candidate)
}
else -> null
}