FIR: Replace fir.bounds with resolvedBounds where it is appropriate
If there is a `coneType` call immediately after the `fir.bounds` call, it means that the fully resolved type is expected, hence `resolvedBounds` should be used
This commit is contained in:
+1
-1
@@ -256,7 +256,7 @@ internal class FirIdeRenderer private constructor(
|
|||||||
|
|
||||||
for (typeParameter in declaration.typeParameters) {
|
for (typeParameter in declaration.typeParameters) {
|
||||||
if (typeParameter !is FirTypeParameter) continue
|
if (typeParameter !is FirTypeParameter) continue
|
||||||
typeParameter.bounds
|
typeParameter.symbol.resolvedBounds
|
||||||
.drop(1) // first parameter is rendered by renderTypeParameter
|
.drop(1) // first parameter is rendered by renderTypeParameter
|
||||||
.mapTo(upperBoundStrings) { typeParameter.name.render() + " : " + renderTypeToString(it.coneType) }
|
.mapTo(upperBoundStrings) { typeParameter.name.render() + " : " + renderTypeToString(it.coneType) }
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.fir.types.isArrayType
|
|||||||
object FirUpperBoundsChecker : FirTypeParameterChecker() {
|
object FirUpperBoundsChecker : FirTypeParameterChecker() {
|
||||||
|
|
||||||
override fun check(declaration: FirTypeParameter, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(declaration: FirTypeParameter, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
if (declaration.bounds.any { it.coneType.isArrayType }) {
|
if (declaration.symbol.resolvedBounds.any { it.coneType.isArrayType }) {
|
||||||
reporter.reportOn(declaration.source, FirJvmErrors.UPPER_BOUND_CANNOT_BE_ARRAY, context)
|
reporter.reportOn(declaration.source, FirJvmErrors.UPPER_BOUND_CANNOT_BE_ARRAY, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -84,7 +84,7 @@ object FirClassVarianceChecker : FirClassChecker() {
|
|||||||
) {
|
) {
|
||||||
for (typeParameter in typeParameters) {
|
for (typeParameter in typeParameters) {
|
||||||
if (typeParameter is FirTypeParameter) {
|
if (typeParameter is FirTypeParameter) {
|
||||||
for (bound in typeParameter.bounds) {
|
for (bound in typeParameter.symbol.resolvedBounds) {
|
||||||
checkVarianceConflict(bound, variance, context, reporter)
|
checkVarianceConflict(bound, variance, context, reporter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.fir.types.type
|
|||||||
object FirPropertyTypeParametersChecker : FirPropertyChecker() {
|
object FirPropertyTypeParametersChecker : FirPropertyChecker() {
|
||||||
|
|
||||||
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
val boundsByName = declaration.typeParameters.associate { it.name to it.bounds }
|
val boundsByName = declaration.typeParameters.associate { it.name to it.symbol.resolvedBounds }
|
||||||
val usedTypes = HashSet<ConeKotlinType>()
|
val usedTypes = HashSet<ConeKotlinType>()
|
||||||
fun collectAllTypes(type: ConeKotlinType) {
|
fun collectAllTypes(type: ConeKotlinType) {
|
||||||
if (usedTypes.add(type)) {
|
if (usedTypes.add(type)) {
|
||||||
|
|||||||
+4
-4
@@ -84,7 +84,7 @@ object FirTypeParameterBoundsChecker : FirTypeParameterChecker() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun checkOnlyOneTypeParameterBound(declaration: FirTypeParameter, context: CheckerContext, reporter: DiagnosticReporter) {
|
private fun checkOnlyOneTypeParameterBound(declaration: FirTypeParameter, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
val bounds = declaration.bounds.distinctBy { it.coneType }
|
val bounds = declaration.symbol.resolvedBounds.distinctBy { it.coneType }
|
||||||
val (boundWithParam, otherBounds) = bounds.partition { it.coneType is ConeTypeParameterType }
|
val (boundWithParam, otherBounds) = bounds.partition { it.coneType is ConeTypeParameterType }
|
||||||
if (boundWithParam.size > 1 || (boundWithParam.size == 1 && otherBounds.isNotEmpty())) {
|
if (boundWithParam.size > 1 || (boundWithParam.size == 1 && otherBounds.isNotEmpty())) {
|
||||||
// If there's only one problematic bound (either 2 type parameter bounds, or 1 type parameter bound + 1 other bound),
|
// If there's only one problematic bound (either 2 type parameter bounds, or 1 type parameter bound + 1 other bound),
|
||||||
@@ -108,7 +108,7 @@ object FirTypeParameterBoundsChecker : FirTypeParameterChecker() {
|
|||||||
|
|
||||||
private fun checkBoundUniqueness(declaration: FirTypeParameter, context: CheckerContext, reporter: DiagnosticReporter) {
|
private fun checkBoundUniqueness(declaration: FirTypeParameter, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
val seenClasses = mutableSetOf<FirRegularClassSymbol>()
|
val seenClasses = mutableSetOf<FirRegularClassSymbol>()
|
||||||
val allNonErrorBounds = declaration.bounds.filter { it !is FirErrorTypeRef }
|
val allNonErrorBounds = declaration.symbol.resolvedBounds.filter { it !is FirErrorTypeRef }
|
||||||
val uniqueBounds = allNonErrorBounds.distinctBy { it.coneType.classId ?: it.coneType }
|
val uniqueBounds = allNonErrorBounds.distinctBy { it.coneType.classId ?: it.coneType }
|
||||||
|
|
||||||
uniqueBounds.forEach { bound ->
|
uniqueBounds.forEach { bound ->
|
||||||
@@ -140,7 +140,7 @@ object FirTypeParameterBoundsChecker : FirTypeParameterChecker() {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anyConflictingTypes(declaration.bounds.map { it.coneType })) {
|
if (anyConflictingTypes(declaration.symbol.resolvedBounds.map { it.coneType })) {
|
||||||
reporter.reportOn(declaration.source, FirErrors.CONFLICTING_UPPER_BOUNDS, declaration.symbol, context)
|
reporter.reportOn(declaration.source, FirErrors.CONFLICTING_UPPER_BOUNDS, declaration.symbol, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -166,7 +166,7 @@ object FirTypeParameterBoundsChecker : FirTypeParameterChecker() {
|
|||||||
val firTypeRefClasses = mutableListOf<Pair<FirTypeRef, FirRegularClassSymbol>>()
|
val firTypeRefClasses = mutableListOf<Pair<FirTypeRef, FirRegularClassSymbol>>()
|
||||||
val firRegularClassesSet = mutableSetOf<FirRegularClassSymbol>()
|
val firRegularClassesSet = mutableSetOf<FirRegularClassSymbol>()
|
||||||
|
|
||||||
for (bound in declaration.bounds) {
|
for (bound in declaration.symbol.resolvedBounds) {
|
||||||
val classSymbol = bound.toRegularClassSymbol(context.session)
|
val classSymbol = bound.toRegularClassSymbol(context.session)
|
||||||
if (firRegularClassesSet.contains(classSymbol)) {
|
if (firRegularClassesSet.contains(classSymbol)) {
|
||||||
// no need to throw INCONSISTENT_TYPE_PARAMETER_BOUNDS diagnostics here because REPEATED_BOUNDS diagnostic is already exist
|
// no need to throw INCONSISTENT_TYPE_PARAMETER_BOUNDS diagnostics here because REPEATED_BOUNDS diagnostic is already exist
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ private fun FirTypeParameter.eraseToUpperBound(session: FirSession, cache: Mutab
|
|||||||
// Mark to avoid loops.
|
// Mark to avoid loops.
|
||||||
cache[this] = ConeKotlinErrorType(ConeIntermediateDiagnostic("self-recursive type parameter $name"))
|
cache[this] = ConeKotlinErrorType(ConeIntermediateDiagnostic("self-recursive type parameter $name"))
|
||||||
// We can assume that Java type parameter bounds are already converted.
|
// We can assume that Java type parameter bounds are already converted.
|
||||||
bounds.first().coneType.eraseAsUpperBound(session, cache)
|
symbol.resolvedBounds.first().coneType.eraseAsUpperBound(session, cache)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ private fun ConeTypeParameterLookupTag.findClassRepresentationThatIsSubtypeOf(
|
|||||||
supertype: ConeKotlinType,
|
supertype: ConeKotlinType,
|
||||||
session: FirSession
|
session: FirSession
|
||||||
): ConeClassLikeLookupTag? =
|
): ConeClassLikeLookupTag? =
|
||||||
typeParameterSymbol.fir.bounds.map { it.coneType }.findClassRepresentationThatIsSubtypeOf(supertype, session)
|
typeParameterSymbol.resolvedBounds.map { it.coneType }.findClassRepresentationThatIsSubtypeOf(supertype, session)
|
||||||
|
|
||||||
private fun Collection<ConeKotlinType>.findClassRepresentationThatIsSubtypeOf(
|
private fun Collection<ConeKotlinType>.findClassRepresentationThatIsSubtypeOf(
|
||||||
supertype: ConeKotlinType,
|
supertype: ConeKotlinType,
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ private fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: Scope
|
|||||||
scopeSession.getOrBuild(symbol, TYPE_PARAMETER_SCOPE_KEY) {
|
scopeSession.getOrBuild(symbol, TYPE_PARAMETER_SCOPE_KEY) {
|
||||||
val intersectionType = ConeTypeIntersector.intersectTypes(
|
val intersectionType = ConeTypeIntersector.intersectTypes(
|
||||||
useSiteSession.typeContext,
|
useSiteSession.typeContext,
|
||||||
symbol.fir.bounds.map { it.coneType }
|
symbol.resolvedBounds.map { it.coneType }
|
||||||
)
|
)
|
||||||
intersectionType.scope(useSiteSession, scopeSession, requiredPhase) ?: FirTypeScope.Empty
|
intersectionType.scope(useSiteSession, scopeSession, requiredPhase) ?: FirTypeScope.Empty
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ fun createSubstitution(
|
|||||||
else /* StarProjection */ -> {
|
else /* StarProjection */ -> {
|
||||||
ConeTypeIntersector.intersectTypes(
|
ConeTypeIntersector.intersectTypes(
|
||||||
session.typeContext,
|
session.typeContext,
|
||||||
typeParameterSymbol.fir.bounds.map { it.coneType }
|
typeParameterSymbol.resolvedBounds.map { it.coneType }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -503,7 +503,7 @@ object FirFakeOverrideGenerator {
|
|||||||
var wereChangesInTypeParameters = forceTypeParametersRecreation
|
var wereChangesInTypeParameters = forceTypeParametersRecreation
|
||||||
for ((newTypeParameter, oldTypeParameter) in newTypeParameters.zip(member.typeParameters)) {
|
for ((newTypeParameter, oldTypeParameter) in newTypeParameters.zip(member.typeParameters)) {
|
||||||
val original = oldTypeParameter.symbol.fir
|
val original = oldTypeParameter.symbol.fir
|
||||||
for (boundTypeRef in original.bounds) {
|
for (boundTypeRef in original.symbol.resolvedBounds) {
|
||||||
val typeForBound = boundTypeRef.coneType
|
val typeForBound = boundTypeRef.coneType
|
||||||
val substitutedBound = substitutor.substituteOrNull(typeForBound)
|
val substitutedBound = substitutor.substituteOrNull(typeForBound)
|
||||||
if (substitutedBound != null) {
|
if (substitutedBound != null) {
|
||||||
|
|||||||
+3
-3
@@ -82,8 +82,8 @@ class FirStandardOverrideChecker(private val session: FirSession) : FirAbstractO
|
|||||||
|
|
||||||
if (isEqualTypes(substitutedOverrideType, substitutedBaseType)) return true
|
if (isEqualTypes(substitutedOverrideType, substitutedBaseType)) return true
|
||||||
|
|
||||||
return overrideTypeParameter.bounds.any { bound -> isEqualTypes(bound.coneType, substitutedBaseType, substitutor) } &&
|
return overrideTypeParameter.symbol.resolvedBounds.any { bound -> isEqualTypes(bound.coneType, substitutedBaseType, substitutor) } &&
|
||||||
baseTypeParameter.bounds.any { bound -> isEqualTypes(bound.coneType, substitutedOverrideType, substitutor) }
|
baseTypeParameter.symbol.resolvedBounds.any { bound -> isEqualTypes(bound.coneType, substitutedOverrideType, substitutor) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isCompatibleTypeParameters(
|
private fun isCompatibleTypeParameters(
|
||||||
@@ -94,7 +94,7 @@ class FirStandardOverrideChecker(private val session: FirSession) : FirAbstractO
|
|||||||
if (overrideCandidate.symbol == baseDeclaration.symbol) return true
|
if (overrideCandidate.symbol == baseDeclaration.symbol) return true
|
||||||
if (overrideCandidate !is FirTypeParameter || baseDeclaration !is FirTypeParameter) return false
|
if (overrideCandidate !is FirTypeParameter || baseDeclaration !is FirTypeParameter) return false
|
||||||
if (overrideCandidate.bounds.size != baseDeclaration.bounds.size) return false
|
if (overrideCandidate.bounds.size != baseDeclaration.bounds.size) return false
|
||||||
return overrideCandidate.bounds.zip(baseDeclaration.bounds)
|
return overrideCandidate.symbol.resolvedBounds.zip(baseDeclaration.symbol.resolvedBounds)
|
||||||
.all { (aBound, bBound) -> isEqualBound(aBound, bBound, overrideCandidate, baseDeclaration, substitutor) }
|
.all { (aBound, bBound) -> isEqualBound(aBound, bBound, overrideCandidate, baseDeclaration, substitutor) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ fun ConeKotlinType.findSubtypeOfNonSuspendFunctionalType(session: FirSession, ex
|
|||||||
intersectedTypes.find { it.findSubtypeOfNonSuspendFunctionalType(session, expectedFunctionalType) != null }
|
intersectedTypes.find { it.findSubtypeOfNonSuspendFunctionalType(session, expectedFunctionalType) != null }
|
||||||
}
|
}
|
||||||
is ConeTypeParameterType -> {
|
is ConeTypeParameterType -> {
|
||||||
val bounds = lookupTag.typeParameterSymbol.fir.bounds.map { it.coneType }
|
val bounds = lookupTag.typeParameterSymbol.resolvedBounds.map { it.coneType }
|
||||||
if (bounds.any { it.isSuspendFunctionType(session) })
|
if (bounds.any { it.isSuspendFunctionType(session) })
|
||||||
null
|
null
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ class FirSamResolverImpl(
|
|||||||
|
|
||||||
for ((newTypeParameter, oldTypeParameter) in newTypeParameters.zip(firRegularClass.typeParameters)) {
|
for ((newTypeParameter, oldTypeParameter) in newTypeParameters.zip(firRegularClass.typeParameters)) {
|
||||||
val declared = oldTypeParameter.symbol.fir // TODO: or really declared?
|
val declared = oldTypeParameter.symbol.fir // TODO: or really declared?
|
||||||
newTypeParameter.bounds += declared.bounds.map { typeRef ->
|
newTypeParameter.bounds += declared.symbol.resolvedBounds.map { typeRef ->
|
||||||
buildResolvedTypeRef {
|
buildResolvedTypeRef {
|
||||||
source = typeRef.source
|
source = typeRef.source
|
||||||
type = substitutor.substituteOrSelf(typeRef.coneType)
|
type = substitutor.substituteOrSelf(typeRef.coneType)
|
||||||
|
|||||||
@@ -608,7 +608,7 @@ internal fun captureFromTypeParameterUpperBoundIfNeeded(
|
|||||||
|
|
||||||
val context = session.typeContext
|
val context = session.typeContext
|
||||||
|
|
||||||
val chosenSupertype = typeParameter.bounds.map { it.coneType }
|
val chosenSupertype = typeParameter.symbol.resolvedBounds.map { it.coneType }
|
||||||
.singleOrNull { it.hasSupertypeWithGivenClassId(expectedTypeClassId, context) } ?: return argumentType
|
.singleOrNull { it.hasSupertypeWithGivenClassId(expectedTypeClassId, context) } ?: return argumentType
|
||||||
|
|
||||||
val capturedType = context.captureFromExpression(chosenSupertype) as ConeKotlinType? ?: return argumentType
|
val capturedType = context.captureFromExpression(chosenSupertype) as ConeKotlinType? ?: return argumentType
|
||||||
|
|||||||
+1
-1
@@ -208,7 +208,7 @@ class ConeSimpleConstraintSystemImpl(val system: NewConstraintSystemImpl, val se
|
|||||||
val substitutor = substitutorByMap(substitutionMap, session)
|
val substitutor = substitutorByMap(substitutionMap, session)
|
||||||
for (typeParameter in typeParameters) {
|
for (typeParameter in typeParameters) {
|
||||||
require(typeParameter is ConeTypeParameterLookupTag)
|
require(typeParameter is ConeTypeParameterLookupTag)
|
||||||
for (upperBound in typeParameter.symbol.fir.bounds) {
|
for (upperBound in typeParameter.symbol.resolvedBounds) {
|
||||||
addSubtypeConstraint(
|
addSubtypeConstraint(
|
||||||
substitutionMap[typeParameter.typeParameterSymbol]
|
substitutionMap[typeParameter.typeParameterSymbol]
|
||||||
?: error("No ${typeParameter.symbol.fir.render()} in substitution map"),
|
?: error("No ${typeParameter.symbol.fir.render()} in substitution map"),
|
||||||
|
|||||||
+3
-3
@@ -75,7 +75,7 @@ internal object CreateFreshTypeVariableSubstitutorStage : ResolutionStage() {
|
|||||||
)
|
)
|
||||||
is FirStarProjection -> csBuilder.addEqualityConstraint(
|
is FirStarProjection -> csBuilder.addEqualityConstraint(
|
||||||
freshVariable.defaultType,
|
freshVariable.defaultType,
|
||||||
typeParameter.symbol.fir.bounds.firstOrNull()?.coneType
|
typeParameter.symbol.resolvedBounds.firstOrNull()?.coneType
|
||||||
?: context.session.builtinTypes.nullableAnyType.type,
|
?: context.session.builtinTypes.nullableAnyType.type,
|
||||||
SimpleConstraintSystemConstraintPosition
|
SimpleConstraintSystemConstraintPosition
|
||||||
)
|
)
|
||||||
@@ -100,7 +100,7 @@ internal object CreateFreshTypeVariableSubstitutorStage : ResolutionStage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun FirTypeParameterRef.shouldBeFlexible(context: ConeTypeContext): Boolean {
|
private fun FirTypeParameterRef.shouldBeFlexible(context: ConeTypeContext): Boolean {
|
||||||
return symbol.fir.bounds.any {
|
return symbol.resolvedBounds.any {
|
||||||
val type = it.coneType
|
val type = it.coneType
|
||||||
type is ConeFlexibleType || with(context) {
|
type is ConeFlexibleType || with(context) {
|
||||||
(type.typeConstructor() as? ConeTypeParameterLookupTag)?.symbol?.fir?.shouldBeFlexible(context) ?: false
|
(type.typeConstructor() as? ConeTypeParameterLookupTag)?.symbol?.fir?.shouldBeFlexible(context) ?: false
|
||||||
@@ -149,7 +149,7 @@ private fun createToFreshVariableSubstitutorAndAddInitialConstraints(
|
|||||||
|
|
||||||
val parameterSymbolFromExpandedClass = typeParameter.symbol.fir.getTypeParameterFromExpandedClass(index, session)
|
val parameterSymbolFromExpandedClass = typeParameter.symbol.fir.getTypeParameterFromExpandedClass(index, session)
|
||||||
|
|
||||||
for (upperBound in parameterSymbolFromExpandedClass.bounds) {
|
for (upperBound in parameterSymbolFromExpandedClass.symbol.resolvedBounds) {
|
||||||
freshVariable.addSubtypeConstraint(upperBound.coneType/*, position*/)
|
freshVariable.addSubtypeConstraint(upperBound.coneType/*, position*/)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ fun FirTypeProjection.toConeTypeProjection(): ConeTypeProjection =
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeTypeParameterType.hasNotNullUpperBound(): Boolean {
|
private fun ConeTypeParameterType.hasNotNullUpperBound(): Boolean {
|
||||||
return lookupTag.typeParameterSymbol.fir.bounds.any {
|
return lookupTag.typeParameterSymbol.resolvedBounds.any {
|
||||||
val boundType = it.coneType
|
val boundType = it.coneType
|
||||||
if (boundType is ConeTypeParameterType) {
|
if (boundType is ConeTypeParameterType) {
|
||||||
boundType.hasNotNullUpperBound()
|
boundType.hasNotNullUpperBound()
|
||||||
@@ -175,7 +175,7 @@ val ConeKotlinType.canBeNull: Boolean
|
|||||||
return when (this) {
|
return when (this) {
|
||||||
is ConeFlexibleType -> upperBound.canBeNull
|
is ConeFlexibleType -> upperBound.canBeNull
|
||||||
is ConeDefinitelyNotNullType -> false
|
is ConeDefinitelyNotNullType -> false
|
||||||
is ConeTypeParameterType -> this.lookupTag.typeParameterSymbol.fir.bounds.all { it.coneType.canBeNull }
|
is ConeTypeParameterType -> this.lookupTag.typeParameterSymbol.resolvedBounds.all { it.coneType.canBeNull }
|
||||||
is ConeIntersectionType -> intersectedTypes.all { it.canBeNull }
|
is ConeIntersectionType -> intersectedTypes.all { it.canBeNull }
|
||||||
else -> isNullable
|
else -> isNullable
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user