FIR: do not leak ConeTypeVariableType via diagnostics

ConeTypeVariableType is an internal part of type inference
and should not be leaked outside it
This commit is contained in:
Ilya Kirillov
2021-09-28 19:16:32 +02:00
committed by TeamCityServer
parent cdde765ad9
commit 451464d635
4 changed files with 52 additions and 12 deletions
@@ -190,12 +190,15 @@ private fun mapInapplicableCandidateError(
rootCause.argument.source,
rootCause.forbiddenNamedArgumentsTarget
)
is ArgumentTypeMismatch -> FirErrors.ARGUMENT_TYPE_MISMATCH.createOn(
rootCause.argument.source ?: source,
rootCause.expectedType,
rootCause.actualType,
rootCause.isMismatchDueToNullability
)
is ArgumentTypeMismatch -> {
val typeContext = diagnostic.candidate.callInfo.session.typeContext
FirErrors.ARGUMENT_TYPE_MISMATCH.createOn(
rootCause.argument.source ?: source,
rootCause.expectedType.removeTypeVariableTypes(typeContext),
rootCause.argument.typeRef.coneType.removeTypeVariableTypes(typeContext),
rootCause.isMismatchDueToNullability
)
}
is NullForNotNullType -> FirErrors.NULL_FOR_NONNULL_TYPE.createOn(
rootCause.argument.source ?: source
)
@@ -299,8 +302,8 @@ private fun ConstraintSystemError.toDiagnostic(
argument?.let {
return FirErrors.ARGUMENT_TYPE_MISMATCH.createOn(
it.source ?: source,
lowerConeType,
upperConeType,
lowerConeType.removeTypeVariableTypes(typeContext),
upperConeType.removeTypeVariableTypes(typeContext),
typeMismatchDueToNullability
)
}
@@ -319,8 +322,8 @@ private fun ConstraintSystemError.toDiagnostic(
FirErrors.TYPE_MISMATCH.createOn(
qualifiedAccessSource ?: source,
upperConeType,
inferredType,
upperConeType.removeTypeVariableTypes(typeContext),
inferredType.removeTypeVariableTypes(typeContext),
typeMismatchDueToNullability
)
}
@@ -0,0 +1,33 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.diagnostics
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnknownLambdaParameterTypeDiagnostic
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
internal fun ConeKotlinType.removeTypeVariableTypes(typeContext: ConeTypeContext): ConeKotlinType {
val substitutor = TypeVariableTypeRemovingSubstitutor(typeContext)
return substitutor.substituteOrSelf(this)
}
private class TypeVariableTypeRemovingSubstitutor(typeContext: ConeTypeContext) : AbstractConeSubstitutor(typeContext) {
override fun substituteType(type: ConeKotlinType): ConeKotlinType? = when (type) {
is ConeTypeVariableType -> convertTypeVariableType(type)
else -> null
}
private fun convertTypeVariableType(type: ConeTypeVariableType): ConeKotlinType {
val originalTypeParameter = type.lookupTag.originalTypeParameter
if (originalTypeParameter != null) {
check(originalTypeParameter is ConeTypeParameterLookupTag)
return ConeTypeParameterTypeImpl(originalTypeParameter, type.isNullable, type.attributes)
}
return ConeClassErrorType(ConeUnknownLambdaParameterTypeDiagnostic())
}
}
@@ -216,6 +216,10 @@ class ConePropertyAsOperator(val symbol: FirPropertySymbol) : ConeDiagnostic {
override val reason: String get() = "Cannot use a property as an operator"
}
class ConeUnknownLambdaParameterTypeDiagnostic : ConeDiagnostic {
override val reason: String get() = "Unknown return lambda parameter type"
}
private fun describeSymbol(symbol: FirBasedSymbol<*>): String {
return when (symbol) {
is FirClassLikeSymbol<*> -> symbol.classId.asString()
@@ -13,10 +13,10 @@ compiler/testData/cli/jvm/instanceAccessBeforeSuperCall.kt:2:74: error: unresolv
compiler/testData/cli/jvm/instanceAccessBeforeSuperCall.kt:7:20: error: 'this' is not defined in this context
class B(other: B = this)
^
compiler/testData/cli/jvm/instanceAccessBeforeSuperCall.kt:10:32: error: argument type mismatch: actual type is kotlin/Int but kotlin/Function0<TypeVariable(_L)> was expected
compiler/testData/cli/jvm/instanceAccessBeforeSuperCall.kt:10:32: error: argument type mismatch: actual type is kotlin/Function0<ERROR CLASS: Cannot access ''<this>'' before superclass constructor has been called> but kotlin/Int was expected
constructor(x: Int) : this({
^
compiler/testData/cli/jvm/instanceAccessBeforeSuperCall.kt:12:9: error: argument type mismatch: actual type is ERROR CLASS: Cannot access ''<this>'' before superclass constructor has been called but TypeVariable(_L) was expected
compiler/testData/cli/jvm/instanceAccessBeforeSuperCall.kt:12:9: error: argument type mismatch: actual type is ERROR CLASS: Cannot access ''<this>'' before superclass constructor has been called but ERROR CLASS: Unknown return lambda parameter type was expected
this
^
compiler/testData/cli/jvm/instanceAccessBeforeSuperCall.kt:12:9: error: cannot access '<this>' before superclass constructor has been called