[FIR] Add REPEATED_BOUND, CONFLICTING_UPPER_BOUNDS diagnostics
This commit is contained in:
+4
-4
@@ -38,15 +38,15 @@ fun test(z: Int, c: Char) {}
|
||||
|
||||
typealias BA = A
|
||||
|
||||
fun <T> kek(t: T) where T : (String) -> Any?, T : <!FINAL_UPPER_BOUND!>Char<!> {}
|
||||
fun <T> kek(t: T) where T : () -> Boolean, T : <!FINAL_UPPER_BOUND!>String<!> {}
|
||||
fun <<!CONFLICTING_UPPER_BOUNDS!>T<!>> kek(t: T) where T : (String) -> Any?, T : <!FINAL_UPPER_BOUND!>Char<!> {}
|
||||
fun <<!CONFLICTING_UPPER_BOUNDS!>T<!>> kek(t: T) where T : () -> Boolean, T : <!FINAL_UPPER_BOUND!>String<!> {}
|
||||
fun <T : <!FINAL_UPPER_BOUND!>Int<!>> kek(t: T) {}
|
||||
|
||||
fun lol(a: Array<Int>) {}
|
||||
fun lol(a: Array<Boolean>) {}
|
||||
|
||||
<!CONFLICTING_OVERLOADS!>fun <T> mem(t: T)<!> where T : () -> Boolean, T : <!FINAL_UPPER_BOUND!>String<!> {}
|
||||
<!CONFLICTING_OVERLOADS!>fun <T> mem(t: T)<!> where T : <!FINAL_UPPER_BOUND!>String<!>, T : () -> Boolean {}
|
||||
<!CONFLICTING_OVERLOADS!>fun <<!CONFLICTING_UPPER_BOUNDS!>T<!>> mem(t: T)<!> where T : () -> Boolean, T : <!FINAL_UPPER_BOUND!>String<!> {}
|
||||
<!CONFLICTING_OVERLOADS!>fun <<!CONFLICTING_UPPER_BOUNDS!>T<!>> mem(t: T)<!> where T : <!FINAL_UPPER_BOUND!>String<!>, T : () -> Boolean {}
|
||||
|
||||
class M {
|
||||
companion <!REDECLARATION!>object<!> {}
|
||||
|
||||
+10
-4
@@ -294,15 +294,21 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
parameter<FirTypeParameterSymbol>("typeParameter")
|
||||
}
|
||||
|
||||
val FINAL_UPPER_BOUND by warning<FirSourceElement, PsiElement> {
|
||||
val FINAL_UPPER_BOUND by warning<FirSourceElement, KtTypeReference> {
|
||||
parameter<ConeKotlinType>("type")
|
||||
}
|
||||
|
||||
val UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE by error<FirSourceElement, PsiElement>()
|
||||
val UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE by error<FirSourceElement, KtTypeReference>()
|
||||
|
||||
val BOUNDS_NOT_ALLOWED_IF_BOUNDED_BY_TYPE_PARAMETER by error<FirSourceElement, PsiElement>()
|
||||
val BOUNDS_NOT_ALLOWED_IF_BOUNDED_BY_TYPE_PARAMETER by error<FirSourceElement, KtElement>()
|
||||
|
||||
val ONLY_ONE_CLASS_BOUND_ALLOWED by error<FirSourceElement, PsiElement>()
|
||||
val ONLY_ONE_CLASS_BOUND_ALLOWED by error<FirSourceElement, KtTypeReference>()
|
||||
|
||||
val REPEATED_BOUND by error<FirSourceElement, KtTypeReference>()
|
||||
|
||||
val CONFLICTING_UPPER_BOUNDS by error<FirSourceElement, KtNamedDeclaration> {
|
||||
parameter<FirTypeParameterSymbol>("typeParameter")
|
||||
}
|
||||
}
|
||||
|
||||
val REFLECTION by object : DiagnosticGroup("Reflection") {
|
||||
|
||||
+6
-4
@@ -220,10 +220,12 @@ object FirErrors {
|
||||
val INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS by error0<FirSourceElement, KtClassOrObject>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||
val KCLASS_WITH_NULLABLE_TYPE_PARAMETER_IN_SIGNATURE by error1<FirSourceElement, KtNamedDeclaration, FirTypeParameterSymbol>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||
val TYPE_PARAMETER_AS_REIFIED by error1<FirSourceElement, PsiElement, FirTypeParameterSymbol>()
|
||||
val FINAL_UPPER_BOUND by warning1<FirSourceElement, PsiElement, ConeKotlinType>()
|
||||
val UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE by error0<FirSourceElement, PsiElement>()
|
||||
val BOUNDS_NOT_ALLOWED_IF_BOUNDED_BY_TYPE_PARAMETER by error0<FirSourceElement, PsiElement>()
|
||||
val ONLY_ONE_CLASS_BOUND_ALLOWED by error0<FirSourceElement, PsiElement>()
|
||||
val FINAL_UPPER_BOUND by warning1<FirSourceElement, KtTypeReference, ConeKotlinType>()
|
||||
val UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE by error0<FirSourceElement, KtTypeReference>()
|
||||
val BOUNDS_NOT_ALLOWED_IF_BOUNDED_BY_TYPE_PARAMETER by error0<FirSourceElement, KtElement>()
|
||||
val ONLY_ONE_CLASS_BOUND_ALLOWED by error0<FirSourceElement, KtTypeReference>()
|
||||
val REPEATED_BOUND by error0<FirSourceElement, KtTypeReference>()
|
||||
val CONFLICTING_UPPER_BOUNDS by error1<FirSourceElement, KtNamedDeclaration, FirTypeParameterSymbol>()
|
||||
|
||||
// Reflection
|
||||
val EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED by error1<FirSourceElement, KtExpression, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
|
||||
+42
-11
@@ -7,18 +7,16 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.canHaveSubtypes
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.*
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.isInlineOnly
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClass
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeTypeParameterType
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.isExtensionFunctionType
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeCheckerProviderContext
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
object FirTypeParameterBoundsChecker : FirTypeParameterChecker() {
|
||||
@@ -48,7 +46,8 @@ object FirTypeParameterBoundsChecker : FirTypeParameterChecker() {
|
||||
checkOnlyOneTypeParameterBound(declaration, context, reporter)
|
||||
}
|
||||
|
||||
checkOnlyOneClassBound(declaration, context, reporter)
|
||||
checkBoundUniqueness(declaration, context, reporter)
|
||||
checkConflictingBounds(declaration, context, reporter)
|
||||
}
|
||||
|
||||
private fun checkOnlyOneTypeParameterBound(declaration: FirTypeParameter, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
@@ -78,15 +77,47 @@ object FirTypeParameterBoundsChecker : FirTypeParameterChecker() {
|
||||
}
|
||||
|
||||
|
||||
private fun checkOnlyOneClassBound(declaration: FirTypeParameter, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
private fun checkBoundUniqueness(declaration: FirTypeParameter, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val seenClasses = mutableSetOf<FirRegularClass>()
|
||||
val bounds = declaration.bounds.distinctBy { it.coneType }
|
||||
bounds.forEach { bound ->
|
||||
val allNonErrorBounds = declaration.bounds.filter { it !is FirErrorTypeRef }
|
||||
val uniqueBounds = allNonErrorBounds.distinctBy { it.coneType.classId ?: it.coneType }
|
||||
|
||||
uniqueBounds.forEach { bound ->
|
||||
bound.coneType.toRegularClass(context.session)?.let { clazz ->
|
||||
if (classKinds.contains(clazz.classKind) && seenClasses.add(clazz) && seenClasses.size > 1) {
|
||||
reporter.reportOn(bound.source, FirErrors.ONLY_ONE_CLASS_BOUND_ALLOWED, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allNonErrorBounds.minus(uniqueBounds).forEach { bound ->
|
||||
reporter.reportOn(bound.source, FirErrors.REPEATED_BOUND, context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkConflictingBounds(declaration: FirTypeParameter, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (declaration.bounds.size < 2) return
|
||||
|
||||
fun anyConflictingTypes(types: List<ConeKotlinType>): Boolean {
|
||||
types.forEach { type ->
|
||||
if (!type.canHaveSubtypes(context.session)) {
|
||||
types.forEach { otherType ->
|
||||
if (type != otherType && !type.isRelated(context.session.typeContext, otherType)){
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if (anyConflictingTypes(declaration.bounds.map { it.coneType })) {
|
||||
reporter.reportOn(declaration.source, FirErrors.CONFLICTING_UPPER_BOUNDS, declaration.symbol, context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun KotlinTypeMarker.isRelated(context: TypeCheckerProviderContext, type: KotlinTypeMarker?): Boolean =
|
||||
isSubtypeOf(context, type) || isSupertypeOf(context, type)
|
||||
|
||||
|
||||
}
|
||||
|
||||
+10
-1
@@ -58,6 +58,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.COMPONENT_FUNCTIO
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.COMPONENT_FUNCTION_ON_NULLABLE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONFLICTING_OVERLOADS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONFLICTING_PROJECTION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONFLICTING_UPPER_BOUNDS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONSTRUCTOR_IN_INTERFACE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONSTRUCTOR_IN_OBJECT
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_CONSTRUCTOR_DELEGATION_CALL
|
||||
@@ -184,6 +185,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_SETTER_
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_VISIBILITY_MODIFIER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REIFIED_TYPE_IN_CATCH_CLAUSE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REPEATED_BOUND
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REPEATED_MODIFIER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RESERVED_MEMBER_INSIDE_INLINE_CLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY
|
||||
@@ -457,7 +459,14 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
||||
"Type parameter cannot have any other bounds if it's bounded by another type parameter"
|
||||
)
|
||||
|
||||
map.put(ONLY_ONE_CLASS_BOUND_ALLOWED,"Only one of the upper bounds can be a class")
|
||||
map.put(ONLY_ONE_CLASS_BOUND_ALLOWED, "Only one of the upper bounds can be a class")
|
||||
map.put(REPEATED_BOUND, "Type parameter already has this bound")
|
||||
|
||||
map.put(
|
||||
CONFLICTING_UPPER_BOUNDS,
|
||||
"Upper bounds of {0} have empty intersection",
|
||||
SYMBOL
|
||||
)
|
||||
|
||||
// Reflection
|
||||
map.put(
|
||||
|
||||
@@ -48,7 +48,7 @@ class Bar<T : <!FINAL_UPPER_BOUND!>Foo<!>>
|
||||
class Buzz<T> where T : <!FINAL_UPPER_BOUND!>Bar<Int><!>, T : <!UNRESOLVED_REFERENCE!>nioho<!>
|
||||
|
||||
class X<T : <!FINAL_UPPER_BOUND!>Foo<!>>
|
||||
class Y<T> where T : <!FINAL_UPPER_BOUND!>Foo<!>, T : <!FINAL_UPPER_BOUND, ONLY_ONE_CLASS_BOUND_ALLOWED!>Bar<Foo><!>
|
||||
class Y<<!CONFLICTING_UPPER_BOUNDS!>T<!>> where T : <!FINAL_UPPER_BOUND!>Foo<!>, T : <!FINAL_UPPER_BOUND, ONLY_ONE_CLASS_BOUND_ALLOWED!>Bar<Foo><!>
|
||||
|
||||
fun <T> test2(t : T)
|
||||
where
|
||||
|
||||
@@ -6,18 +6,18 @@ interface B
|
||||
|
||||
interface D<T>
|
||||
|
||||
interface IncorrectF<T : D<A>> where T : D<B>
|
||||
interface IncorrectF<T : D<A>> where T : <!REPEATED_BOUND!>D<B><!>
|
||||
|
||||
interface CorrectF<T> where T : D<A>, T : D<B>
|
||||
interface CorrectF<T> where T : D<A>, T : <!REPEATED_BOUND!>D<B><!>
|
||||
|
||||
interface G<T>
|
||||
|
||||
interface IncorrectH<T : G<D<A>>> where T : G<D<T>>
|
||||
interface IncorrectH<T : G<D<A>>> where T : <!REPEATED_BOUND!>G<D<T>><!>
|
||||
|
||||
interface CorrectH<T> where T : G<D<A>>, T : G<D<B>>
|
||||
interface CorrectH<T> where T : G<D<A>>, T : <!REPEATED_BOUND!>G<D<B>><!>
|
||||
|
||||
interface incorrectJ<T: G<D<T>>> where T : G<D<T?>>
|
||||
interface incorrectJ<T: G<D<T>>> where T : <!REPEATED_BOUND!>G<D<T?>><!>
|
||||
|
||||
interface correctJ<T> where T : G<D<T>>, T : G<D<T?>>
|
||||
interface correctJ<T> where T : G<D<T>>, T : <!REPEATED_BOUND!>G<D<T?>><!>
|
||||
|
||||
fun <T> bar() where T : D<A>, T : D<B> {}
|
||||
fun <T> bar() where T : D<A>, T : <!REPEATED_BOUND!>D<B><!> {}
|
||||
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
interface I1
|
||||
interface I2
|
||||
open class C
|
||||
|
||||
interface A1<K, V> where V : K, V : K
|
||||
interface A2<K, V, W> where W : K, W : <!BOUNDS_NOT_ALLOWED_IF_BOUNDED_BY_TYPE_PARAMETER!>V<!>
|
||||
interface A3<K, <!BOUNDS_NOT_ALLOWED_IF_BOUNDED_BY_TYPE_PARAMETER!>V<!>> where V : I1, V : K, V : I2
|
||||
interface A4<<!BOUNDS_NOT_ALLOWED_IF_BOUNDED_BY_TYPE_PARAMETER!>K<!>, V> where K : I1, K : I2, K : C, K : V, V : I2, V : I1
|
||||
|
||||
fun <K, V> f1() where V : K, V : K {}
|
||||
fun <K, V, W> f2() where W : K, W : <!BOUNDS_NOT_ALLOWED_IF_BOUNDED_BY_TYPE_PARAMETER!>V<!> {
|
||||
fun <T> f3() where T : K, T : <!BOUNDS_NOT_ALLOWED_IF_BOUNDED_BY_TYPE_PARAMETER!>V<!> {}
|
||||
fun <T> f4() where T : K, T : K {}
|
||||
}
|
||||
fun <K, V, <!BOUNDS_NOT_ALLOWED_IF_BOUNDED_BY_TYPE_PARAMETER!>W<!>> f3() where W : K, W : V, W : Any {}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
interface I1
|
||||
interface I2
|
||||
open class C
|
||||
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
open class C1
|
||||
open class C2
|
||||
open class C3 : C2()
|
||||
|
||||
class A1<T> where T : C1, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>C2<!>
|
||||
class A2<T> where T : C1, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>C2<!>, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>C3<!>
|
||||
class A3<T> where T : C2, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>C3<!>
|
||||
class A4<T> where T : C3, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>C2<!>
|
||||
|
||||
fun <T> f1() where T : C1, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>C2<!>, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>C3<!> {}
|
||||
fun <T> f2() where T : C2, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>C3<!> {}
|
||||
fun <T> f3() where T : C3, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>C2<!> {}
|
||||
|
||||
enum class E1
|
||||
class A5<T> where T : C1, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>E1<!>
|
||||
|
||||
object O1
|
||||
class A6<T> where T : <!FINAL_UPPER_BOUND!>O1<!>, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>C2<!>
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
open class C1
|
||||
open class C2
|
||||
open class C3 : C2()
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
interface I1
|
||||
|
||||
class A1<T> where T : I1, T : I1
|
||||
class A2<T> where T : I1, T : I1?
|
||||
class A3<K, V> where K : V, K : V
|
||||
|
||||
fun <T> f1() where T : I1, T : I1 {}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
interface I1
|
||||
|
||||
class A1<T> where T : I1, T : <!REPEATED_BOUND!>I1<!>
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
fun <A : Array<Any>> f1() {}
|
||||
fun <T, A : Array<out T>> f2() {}
|
||||
fun <S, T : S, A> f3() where A : Array<out S>, A : Array<out T> {}
|
||||
fun <S, T : S, A> f3() where A : Array<out S>, A : <!REPEATED_BOUND!>Array<out T><!> {}
|
||||
|
||||
fun <T : <!FINAL_UPPER_BOUND!>IntArray<!>> f4() {}
|
||||
|
||||
@@ -9,7 +9,7 @@ fun <T> f5() where T : Array<Any> {}
|
||||
val <T : Array<Any?>> T.v: String get() = ""
|
||||
|
||||
class C2<T, A : Array<out T>>
|
||||
interface C3<S, T : S, A> where A : Array<out S>, A : Array<out T>
|
||||
interface C3<S, T : S, A> where A : Array<out S>, A : <!REPEATED_BOUND!>Array<out T><!>
|
||||
|
||||
fun foo() {
|
||||
class C1<A : Array<Any>> {
|
||||
|
||||
+13
@@ -932,6 +932,19 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.REPEATED_BOUND) { firDiagnostic ->
|
||||
RepeatedBoundImpl(
|
||||
firDiagnostic as FirPsiDiagnostic<*>,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.CONFLICTING_UPPER_BOUNDS) { firDiagnostic ->
|
||||
ConflictingUpperBoundsImpl(
|
||||
firSymbolBuilder.classifierBuilder.buildTypeParameterSymbol(firDiagnostic.a.fir),
|
||||
firDiagnostic as FirPsiDiagnostic<*>,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED) { firDiagnostic ->
|
||||
ExtensionInClassReferenceNotAllowedImpl(
|
||||
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration),
|
||||
|
||||
+13
-4
@@ -647,23 +647,32 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
abstract val typeParameter: KtTypeParameterSymbol
|
||||
}
|
||||
|
||||
abstract class FinalUpperBound : KtFirDiagnostic<PsiElement>() {
|
||||
abstract class FinalUpperBound : KtFirDiagnostic<KtTypeReference>() {
|
||||
override val diagnosticClass get() = FinalUpperBound::class
|
||||
abstract val type: KtType
|
||||
}
|
||||
|
||||
abstract class UpperBoundIsExtensionFunctionType : KtFirDiagnostic<PsiElement>() {
|
||||
abstract class UpperBoundIsExtensionFunctionType : KtFirDiagnostic<KtTypeReference>() {
|
||||
override val diagnosticClass get() = UpperBoundIsExtensionFunctionType::class
|
||||
}
|
||||
|
||||
abstract class BoundsNotAllowedIfBoundedByTypeParameter : KtFirDiagnostic<PsiElement>() {
|
||||
abstract class BoundsNotAllowedIfBoundedByTypeParameter : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = BoundsNotAllowedIfBoundedByTypeParameter::class
|
||||
}
|
||||
|
||||
abstract class OnlyOneClassBoundAllowed : KtFirDiagnostic<PsiElement>() {
|
||||
abstract class OnlyOneClassBoundAllowed : KtFirDiagnostic<KtTypeReference>() {
|
||||
override val diagnosticClass get() = OnlyOneClassBoundAllowed::class
|
||||
}
|
||||
|
||||
abstract class RepeatedBound : KtFirDiagnostic<KtTypeReference>() {
|
||||
override val diagnosticClass get() = RepeatedBound::class
|
||||
}
|
||||
|
||||
abstract class ConflictingUpperBounds : KtFirDiagnostic<KtNamedDeclaration>() {
|
||||
override val diagnosticClass get() = ConflictingUpperBounds::class
|
||||
abstract val typeParameter: KtTypeParameterSymbol
|
||||
}
|
||||
|
||||
abstract class ExtensionInClassReferenceNotAllowed : KtFirDiagnostic<KtExpression>() {
|
||||
override val diagnosticClass get() = ExtensionInClassReferenceNotAllowed::class
|
||||
abstract val referencedDeclaration: KtCallableSymbol
|
||||
|
||||
+19
-4
@@ -1045,28 +1045,43 @@ internal class FinalUpperBoundImpl(
|
||||
override val type: KtType,
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.FinalUpperBound(), KtAbstractFirDiagnostic<PsiElement> {
|
||||
) : KtFirDiagnostic.FinalUpperBound(), KtAbstractFirDiagnostic<KtTypeReference> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class UpperBoundIsExtensionFunctionTypeImpl(
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.UpperBoundIsExtensionFunctionType(), KtAbstractFirDiagnostic<PsiElement> {
|
||||
) : KtFirDiagnostic.UpperBoundIsExtensionFunctionType(), KtAbstractFirDiagnostic<KtTypeReference> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class BoundsNotAllowedIfBoundedByTypeParameterImpl(
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.BoundsNotAllowedIfBoundedByTypeParameter(), KtAbstractFirDiagnostic<PsiElement> {
|
||||
) : KtFirDiagnostic.BoundsNotAllowedIfBoundedByTypeParameter(), KtAbstractFirDiagnostic<KtElement> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class OnlyOneClassBoundAllowedImpl(
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.OnlyOneClassBoundAllowed(), KtAbstractFirDiagnostic<PsiElement> {
|
||||
) : KtFirDiagnostic.OnlyOneClassBoundAllowed(), KtAbstractFirDiagnostic<KtTypeReference> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class RepeatedBoundImpl(
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.RepeatedBound(), KtAbstractFirDiagnostic<KtTypeReference> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class ConflictingUpperBoundsImpl(
|
||||
override val typeParameter: KtTypeParameterSymbol,
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.ConflictingUpperBounds(), KtAbstractFirDiagnostic<KtNamedDeclaration> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ class Bar<T : Foo>
|
||||
class Buzz<T> where T : Bar<Int>, T : <error descr="[UNRESOLVED_REFERENCE] Unresolved reference: nioho">nioho</error>
|
||||
|
||||
class X<T : Foo>
|
||||
class Y<T> where T : Foo, T : <error descr="[ONLY_ONE_CLASS_BOUND_ALLOWED] Only one of the upper bounds can be a class">Bar<Foo></error>
|
||||
class Y<<error descr="[CONFLICTING_UPPER_BOUNDS] Upper bounds of T have empty intersection">T</error>> where T : Foo, T : <error descr="[ONLY_ONE_CLASS_BOUND_ALLOWED] Only one of the upper bounds can be a class">Bar<Foo></error>
|
||||
|
||||
fun <T> test2(t : T)
|
||||
where
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
// See KT-9438: Enforce the Single Instantiation Inheritance Rule for type parameters
|
||||
|
||||
interface A
|
||||
|
||||
interface B
|
||||
|
||||
interface D<T>
|
||||
|
||||
interface CorrectF<T> where T : D<A>, T : D<B>
|
||||
|
||||
fun <T> bar() where T : D<A>, T : D<B> {}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// See KT-9438: Enforce the Single Instantiation Inheritance Rule for type parameters
|
||||
|
||||
interface A
|
||||
|
||||
Reference in New Issue
Block a user