diff --git a/compiler/fir/analysis-tests/testData/resolve/typeParameterVsNested.fir.txt b/compiler/fir/analysis-tests/testData/resolve/typeParameterVsNested.fir.txt index 3f336035ba4..848d07d7874 100644 --- a/compiler/fir/analysis-tests/testData/resolve/typeParameterVsNested.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/typeParameterVsNested.fir.txt @@ -24,7 +24,7 @@ FILE: typeParameterVsNested.kt public abstract val z: public get(): - public final class Some : { + public final class Some : { public constructor(): R|test/My.Some| { super|>() } @@ -32,7 +32,7 @@ FILE: typeParameterVsNested.kt } } - public abstract class Your : { + public abstract class Your : { public constructor(): R|test/Your| { super() } diff --git a/compiler/fir/analysis-tests/testData/resolve/typeParameterVsNested.kt b/compiler/fir/analysis-tests/testData/resolve/typeParameterVsNested.kt index ded00ddec29..9126477c414 100644 --- a/compiler/fir/analysis-tests/testData/resolve/typeParameterVsNested.kt +++ b/compiler/fir/analysis-tests/testData/resolve/typeParameterVsNested.kt @@ -13,7 +13,7 @@ abstract class My { abstract val z: test.My.T - class Some : T() + class Some : T() } -abstract class Your : T +abstract class Your : T diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index e3f4e665edf..19d4e6c1d21 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -82,6 +82,9 @@ object DIAGNOSTICS_LIST : DiagnosticList() { val CLASS_IN_SUPERTYPE_FOR_ENUM by error() val SEALED_SUPERTYPE by error() val SEALED_SUPERTYPE_IN_LOCAL_CLASS by error() + val SUPERTYPE_NOT_A_CLASS_OR_INTERFACE by error { + parameter("reason") + } } val CONSTRUCTOR_PROBLEMS by object : DiagnosticGroup("Constructor problems") { diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index e34c9481330..63d73dd4a21 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -90,6 +90,7 @@ object FirErrors { val CLASS_IN_SUPERTYPE_FOR_ENUM by error0() val SEALED_SUPERTYPE by error0() val SEALED_SUPERTYPE_IN_LOCAL_CLASS by error0() + val SUPERTYPE_NOT_A_CLASS_OR_INTERFACE by error1() // Constructor problems val CONSTRUCTOR_IN_OBJECT by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index 02a7a799985..9ab8f8b7901 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -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") 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 440c5992509..b5b953cde2e 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 @@ -47,6 +47,7 @@ fun ConeDiagnostic.toFirDiagnostic(source: FirSourceElement): FirDiagnostic 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}") } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt index 34cb331bcf6..d51ffb8f043 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt @@ -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() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt index 033e05f3a0d..4f4ba4a93f1 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt @@ -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() when { - superTypeRef.coneTypeSafe() != null -> - createErrorTypeRef( - superTypeRef, - "Type parameter cannot be a super-type: ${superTypeRef.coneTypeUnsafe().render()}" - ) + typeParameterType != null -> + buildErrorTypeRef { + source = superTypeRef.source + diagnostic = ConeTypeParameterSupertype(typeParameterType.lookupTag.typeParameterSymbol) + } superTypeRef !is FirResolvedTypeRef -> createErrorTypeRef(superTypeRef, "Unresolved super-type: ${superTypeRef.render()}") else -> diff --git a/compiler/testData/diagnostics/tests/regressions/TypeParameterAsASupertype.fir.kt b/compiler/testData/diagnostics/tests/regressions/TypeParameterAsASupertype.fir.kt deleted file mode 100644 index 6c0c8795e61..00000000000 --- a/compiler/testData/diagnostics/tests/regressions/TypeParameterAsASupertype.fir.kt +++ /dev/null @@ -1 +0,0 @@ -class A : T {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/regressions/TypeParameterAsASupertype.kt b/compiler/testData/diagnostics/tests/regressions/TypeParameterAsASupertype.kt index a5f611397ce..0bf4cef74d1 100644 --- a/compiler/testData/diagnostics/tests/regressions/TypeParameterAsASupertype.kt +++ b/compiler/testData/diagnostics/tests/regressions/TypeParameterAsASupertype.kt @@ -1 +1,2 @@ +// FIR_IDENTICAL class A : T {} \ No newline at end of file