FIR: report SUPERTYPE_NOT_A_CLASS_OR_INTERFACE on type parameters

This commit is contained in:
Mikhail Glukhikh
2021-02-16 15:28:15 +03:00
parent e67eb0c123
commit 3e9ff3ecda
10 changed files with 25 additions and 13 deletions
@@ -24,7 +24,7 @@ FILE: typeParameterVsNested.kt
public abstract val z: <ERROR TYPE REF: Wrong number of type arguments>
public get(): <ERROR TYPE REF: Wrong number of type arguments>
public final class Some : <ERROR TYPE REF: Type parameter cannot be a super-type: T> {
public final class Some : <ERROR TYPE REF: Type parameter T cannot be a supertype> {
public constructor(): R|test/My.Some| {
super<R|test/My.T<T>|>()
}
@@ -32,7 +32,7 @@ FILE: typeParameterVsNested.kt
}
}
public abstract class Your<T : R|test/Some|> : <ERROR TYPE REF: Type parameter cannot be a super-type: T> {
public abstract class Your<T : R|test/Some|> : <ERROR TYPE REF: Type parameter T cannot be a supertype> {
public constructor<T : R|test/Some|>(): R|test/Your<T>| {
super<R|kotlin/Any|>()
}
@@ -13,7 +13,7 @@ abstract class My<T : Some> {
abstract val z: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>test.My.T<!>
class Some : <!UNRESOLVED_REFERENCE{LT}!><!OTHER_ERROR, UNRESOLVED_REFERENCE{PSI}!>T<!>()<!>
class Some : <!UNRESOLVED_REFERENCE{LT}!><!SUPERTYPE_NOT_A_CLASS_OR_INTERFACE, UNRESOLVED_REFERENCE{PSI}!>T<!>()<!>
}
abstract class Your<T : Some> : <!OTHER_ERROR!>T<!>
abstract class Your<T : Some> : <!SUPERTYPE_NOT_A_CLASS_OR_INTERFACE!>T<!>
@@ -82,6 +82,9 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
val CLASS_IN_SUPERTYPE_FOR_ENUM by error<FirSourceElement, PsiElement>()
val SEALED_SUPERTYPE by error<FirSourceElement, PsiElement>()
val SEALED_SUPERTYPE_IN_LOCAL_CLASS by error<FirSourceElement, PsiElement>()
val SUPERTYPE_NOT_A_CLASS_OR_INTERFACE by error<FirSourceElement, KtElement> {
parameter<String>("reason")
}
}
val CONSTRUCTOR_PROBLEMS by object : DiagnosticGroup("Constructor problems") {
@@ -90,6 +90,7 @@ object FirErrors {
val CLASS_IN_SUPERTYPE_FOR_ENUM by error0<FirSourceElement, PsiElement>()
val SEALED_SUPERTYPE by error0<FirSourceElement, PsiElement>()
val SEALED_SUPERTYPE_IN_LOCAL_CLASS by error0<FirSourceElement, PsiElement>()
val SUPERTYPE_NOT_A_CLASS_OR_INTERFACE by error1<FirSourceElement, KtElement, String>()
// Constructor problems
val CONSTRUCTOR_IN_OBJECT by error0<FirSourceElement, KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
@@ -146,6 +146,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SEALED_SUPERTYPE_
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPE_INITIALIZED_IN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPE_NOT_A_CLASS_OR_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPER_IS_NOT_AN_EXPRESSION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPER_NOT_AVAILABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SYNTAX
@@ -242,6 +243,8 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
map.put(CLASS_IN_SUPERTYPE_FOR_ENUM, "Enum class cannot inherit from classes")
map.put(SEALED_SUPERTYPE, "This type is sealed, so it can be inherited by only its own nested classes or objects")
map.put(SEALED_SUPERTYPE_IN_LOCAL_CLASS, "Local class cannot extend a sealed class")
map.put(SUPERTYPE_NOT_A_CLASS_OR_INTERFACE, "Supertype is not a class or interface", TO_STRING)
// Constructor problems
map.put(CONSTRUCTOR_IN_OBJECT, "Constructors are not allowed for objects")
@@ -47,6 +47,7 @@ fun ConeDiagnostic.toFirDiagnostic(source: FirSourceElement): FirDiagnostic<FirS
is ConeStubDiagnostic -> null
is ConeIntermediateDiagnostic -> null
is ConeContractDescriptionError -> FirErrors.ERROR_IN_CONTRACT_DESCRIPTION.on(source, this.reason)
is ConeTypeParameterSupertype -> FirErrors.SUPERTYPE_NOT_A_CLASS_OR_INTERFACE.on(source, this.reason)
else -> throw IllegalArgumentException("Unsupported diagnostic type: ${this.javaClass}")
}
@@ -9,15 +9,13 @@ import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionDiagnostic
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintSystemError
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
class ConeUnresolvedReferenceError(val name: Name? = null) : ConeDiagnostic() {
@@ -80,6 +78,10 @@ class ConeUnsupportedCallableReferenceTarget(val fir: FirCallableDeclaration<*>)
override val reason: String get() = "Unsupported declaration for callable reference: ${fir.render()}"
}
class ConeTypeParameterSupertype(val symbol: FirTypeParameterSymbol) : ConeDiagnostic() {
override val reason: String get() = "Type parameter ${symbol.fir.name} cannot be a supertype"
}
private fun describeSymbol(symbol: AbstractFirBasedSymbol<*>): String {
return when (symbol) {
is FirClassLikeSymbol<*> -> symbol.classId.asString()
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
import org.jetbrains.kotlin.fir.extensions.supertypeGenerators
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeTypeParameterSupertype
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.LocalClassesNavigationInfo
import org.jetbrains.kotlin.fir.scopes.FirCompositeScope
import org.jetbrains.kotlin.fir.scopes.FirScope
@@ -285,12 +286,13 @@ private class FirSupertypeResolverVisitor(
return resolveSpecificClassLikeSupertypes(classLikeDeclaration) { transformer, scope ->
supertypeRefs.mapTo(mutableListOf()) {
val superTypeRef = transformer.transformTypeRef(it, scope).single
val typeParameterType = superTypeRef.coneTypeSafe<ConeTypeParameterType>()
when {
superTypeRef.coneTypeSafe<ConeTypeParameterType>() != null ->
createErrorTypeRef(
superTypeRef,
"Type parameter cannot be a super-type: ${superTypeRef.coneTypeUnsafe<ConeTypeParameterType>().render()}"
)
typeParameterType != null ->
buildErrorTypeRef {
source = superTypeRef.source
diagnostic = ConeTypeParameterSupertype(typeParameterType.lookupTag.typeParameterSymbol)
}
superTypeRef !is FirResolvedTypeRef ->
createErrorTypeRef(superTypeRef, "Unresolved super-type: ${superTypeRef.render()}")
else ->
@@ -1 +0,0 @@
class A<T> : <!OTHER_ERROR!>T<!> {}
@@ -1 +1,2 @@
// FIR_IDENTICAL
class A<T> : <!SUPERTYPE_NOT_A_CLASS_OR_INTERFACE!>T<!> {}