[FIR] Add NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER check

This commit is contained in:
Andrey Zinovyev
2021-04-11 16:18:07 +00:00
committed by Space
parent ea22f4b681
commit 47407c4445
20 changed files with 373 additions and 16 deletions
@@ -1150,6 +1150,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/methodOfAnyImplementedInInterface.kt");
}
@TestMetadata("multipleBounds.kt")
public void testMultipleBounds() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/multipleBounds.kt");
}
@TestMetadata("nonConstValInAnnotationArgument.kt")
public void testNonConstValInAnnotationArgument() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/nonConstValInAnnotationArgument.kt");
@@ -0,0 +1,109 @@
FILE: multipleBounds.kt
public open class A : R|kotlin/Any| {
public constructor(): R|Jet87/A| {
super<R|kotlin/Any|>()
}
public final fun foo(): R|kotlin/Int| {
^foo Int(1)
}
}
public abstract interface B : R|kotlin/Any| {
public open fun bar(): R|kotlin/Double| {
^bar Double(1.0)
}
}
public abstract interface G<X> : R|kotlin/Any| {
public abstract val <X : R|Jet87/A|, R|Jet87/B|> boo: R|kotlin/Double|
public get(): R|kotlin/Double|
public abstract val <A : R|Jet87/B|> bal: R|kotlin/Double|
public get(): R|kotlin/Double|
public abstract val <Y : R|Jet87/B|> bas: R|kotlin/Double|
public get(): R|kotlin/Double|
}
public final class C : R|Jet87/A|, R|Jet87/B| {
public constructor(): R|Jet87/C| {
super<R|Jet87/A|>()
}
}
public final class D : R|kotlin/Any| {
public constructor(): R|Jet87/D| {
super<R|kotlin/Any|>()
}
public final companion object Companion : R|Jet87/A|, R|Jet87/B| {
private constructor(): R|Jet87/D.Companion| {
super<R|Jet87/A|>()
}
}
}
public final class Test1<T : R|Jet87/A|, R|Jet87/B|> : R|kotlin/Any| {
public constructor<T : R|Jet87/A|, R|Jet87/B|>(): R|Jet87/Test1<T>| {
super<R|kotlin/Any|>()
}
public final fun test(t: R|T|): R|kotlin/Unit| {
R|?|.<Unresolved name: foo>#()
R|?|.<Unresolved name: bar>#()
R|<local>/t|.R|Jet87/A.foo|()
R|<local>/t|.R|Jet87/B.bar|()
}
}
public final fun test(): R|kotlin/Unit| {
R|Jet87/Test1.Test1|<R|Jet87/B|>()
R|Jet87/Test1.Test1|<R|Jet87/A|>()
R|Jet87/Test1.Test1|<R|Jet87/C|>()
}
public final class Foo : R|kotlin/Any| {
public constructor(): R|Jet87/Foo| {
super<R|kotlin/Any|>()
}
}
public final class Bar<T : R|Jet87/Foo|> : R|kotlin/Any| {
public constructor<T : R|Jet87/Foo|>(): R|Jet87/Bar<T>| {
super<R|kotlin/Any|>()
}
}
public final class Buzz<T : R|Jet87/Bar<kotlin/Int>|, <ERROR TYPE REF: Symbol not found for nioho>> : R|kotlin/Any| {
public constructor<T : R|Jet87/Bar<kotlin/Int>|, <ERROR TYPE REF: Symbol not found for nioho>>(): R|Jet87/Buzz<T>| {
super<R|kotlin/Any|>()
}
}
public final class X<T : R|Jet87/Foo|> : R|kotlin/Any| {
public constructor<T : R|Jet87/Foo|>(): R|Jet87/X<T>| {
super<R|kotlin/Any|>()
}
}
public final class Y<T : R|Jet87/Foo|, R|Jet87/Bar<Jet87/Foo>|> : R|kotlin/Any| {
public constructor<T : R|Jet87/Foo|, R|Jet87/Bar<Jet87/Foo>|>(): R|Jet87/Y<T>| {
super<R|kotlin/Any|>()
}
}
public final fun <T : R|Jet87/A|, R|Jet87/B|> test2(t: R|T|): R|kotlin/Unit| {
R|?|.<Unresolved name: foo>#()
R|?|.<Unresolved name: bar>#()
R|<local>/t|.R|Jet87/A.foo|()
R|<local>/t|.R|Jet87/B.bar|()
}
public final val t1: R|kotlin/Unit| = <Inapplicable(INAPPLICABLE): Jet87/test2>#<R|Jet87/A|>(R|Jet87/A.A|())
public get(): R|kotlin/Unit|
public final val t2: R|kotlin/Unit| = <Inapplicable(INAPPLICABLE): Jet87/test2>#<R|Jet87/B|>(R|Jet87/C.C|())
public get(): R|kotlin/Unit|
public final val t3: R|kotlin/Unit| = R|Jet87/test2|<R|Jet87/C|>(R|Jet87/C.C|())
public get(): R|kotlin/Unit|
public final val <T, B : R|T|> x: R|kotlin/Int| = Int(0)
public get(): R|kotlin/Int|
@@ -0,0 +1,69 @@
package Jet87
open class A() {
fun foo() : Int = 1
}
interface B {
fun bar() : Double = 1.0;
}
interface G<X> {
val <X> boo: Double where X : A, X : B
val <A> bal: Double where A : B
val <Y> bas: Double where Y : B, <!NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER!>X<!> : B
}
class C() : A(), B
class D() {
companion object : A(), B {}
}
class Test1<T>()
where
T : A,
T : B,
<!NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER!>B<!> : T // error
{
fun test(t : T) {
<!TYPE_PARAMETER_ON_LHS_OF_DOT!>T<!>.<!UNRESOLVED_REFERENCE!>foo<!>()
<!TYPE_PARAMETER_ON_LHS_OF_DOT!>T<!>.<!UNRESOLVED_REFERENCE!>bar<!>()
t.foo()
t.bar()
}
}
fun test() {
Test1<<!UPPER_BOUND_VIOLATED!>B<!>>()
Test1<<!UPPER_BOUND_VIOLATED!>A<!>>()
Test1<C>()
}
class Foo() {}
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<<!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
T : A,
T : B,
<!NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER!>B<!> : T
{
<!TYPE_PARAMETER_ON_LHS_OF_DOT!>T<!>.<!UNRESOLVED_REFERENCE!>foo<!>()
<!TYPE_PARAMETER_ON_LHS_OF_DOT!>T<!>.<!UNRESOLVED_REFERENCE!>bar<!>()
t.foo()
t.bar()
}
val t1 = <!INAPPLICABLE_CANDIDATE!>test2<!><A>(A())
val t2 = <!INAPPLICABLE_CANDIDATE!>test2<!><B>(C())
val t3 = test2<C>(C())
val <T, B : T> x : Int = 0
@@ -1321,6 +1321,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/methodOfAnyImplementedInInterface.kt");
}
@Test
@TestMetadata("multipleBounds.kt")
public void testMultipleBounds() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/multipleBounds.kt");
}
@Test
@TestMetadata("nonConstValInAnnotationArgument.kt")
public void testNonConstValInAnnotationArgument() throws Exception {
@@ -1333,6 +1333,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/methodOfAnyImplementedInInterface.kt");
}
@Test
@TestMetadata("multipleBounds.kt")
public void testMultipleBounds() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/multipleBounds.kt");
}
@Test
@TestMetadata("nonConstValInAnnotationArgument.kt")
public void testNonConstValInAnnotationArgument() throws Exception {
@@ -16,10 +16,7 @@ import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.PrivateForInline
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
@@ -309,6 +306,11 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
val CONFLICTING_UPPER_BOUNDS by error<FirSourceElement, KtNamedDeclaration> {
parameter<FirTypeParameterSymbol>("typeParameter")
}
val NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER by error<FirSourceElement, KtSimpleNameExpression> {
parameter<Name>("typeParameterName")
parameter<FirDeclaration>("typeParametersOwner")
}
}
val REFLECTION by object : DiagnosticGroup("Reflection") {
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.diagnostics.SourceElementPositioningStrategies
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.expressions.FirExpression
@@ -226,6 +227,7 @@ object FirErrors {
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>()
val NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER by error2<FirSourceElement, KtSimpleNameExpression, Name, FirDeclaration>()
// Reflection
val EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED by error1<FirSourceElement, KtExpression, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
@@ -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.checkers.declaration
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
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.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner
import org.jetbrains.kotlin.fir.declarations.getDanglingTypeConstraintsOrEmpty
object FirTypeConstraintsChecker : FirBasicDeclarationChecker() {
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration !is FirTypeParameterRefsOwner) return
//basically we transfer errors, which were discovered in ast parsers
declaration.getDanglingTypeConstraintsOrEmpty().forEach { constraint ->
reporter.reportOn(
constraint.source,
FirErrors.NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER,
constraint.name,
declaration,
context
)
}
}
}
@@ -136,6 +136,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZ
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NAMED_ARGUMENTS_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NAMED_PARAMETER_NOT_FOUND
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NESTED_CLASS_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NONE_APPLICABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY
@@ -474,6 +475,13 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
SYMBOL
)
map.put(
NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER,
"{0} does not refer to a type parameter of {1}",
TO_STRING,
NAME
)
// Reflection
map.put(
EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED,
@@ -18,6 +18,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirModifierChecker,
FirConflictsChecker,
FirConflictingProjectionChecker,
FirTypeConstraintsChecker,
)
override val memberDeclarationCheckers: Set<FirMemberDeclarationChecker> = setOf(
@@ -526,6 +526,7 @@ class DeclarationsConverter(
}
}.also {
it.initContainingClassForLocalAttr()
fillDanglingConstraintsTo(firTypeParameters, typeConstraints, it)
}
}
@@ -1083,6 +1084,8 @@ class DeclarationsConverter(
}
}
annotations += modifiers.annotations
}.also {
fillDanglingConstraintsTo(firTypeParameters, typeConstraints, it)
}
}
@@ -1394,6 +1397,9 @@ class DeclarationsConverter(
context.firFunctionTargets.removeLast()
}.build().also {
target.bind(it)
if (it is FirSimpleFunction) {
fillDanglingConstraintsTo(firTypeParameters, typeConstraints, it)
}
}
}
@@ -1573,17 +1579,21 @@ class DeclarationsConverter(
private fun convertTypeConstraint(typeConstraint: LighterASTNode): TypeConstraint {
lateinit var identifier: String
lateinit var firType: FirTypeRef
lateinit var referenceExpression: LighterASTNode
val annotations = mutableListOf<FirAnnotationCall>()
typeConstraint.forEachChildren {
when (it.tokenType) {
//annotations will be saved later, on mapping stage with type parameters
ANNOTATION, ANNOTATION_ENTRY -> annotations += convertAnnotation(it)
REFERENCE_EXPRESSION -> identifier = it.asText
REFERENCE_EXPRESSION -> {
identifier = it.asText
referenceExpression = it
}
TYPE_REFERENCE -> firType = convertType(it)
}
}
return TypeConstraint(annotations, identifier, firType)
return TypeConstraint(annotations, identifier, firType, referenceExpression.toFirSourceElement())
}
/**
@@ -1867,4 +1877,24 @@ class DeclarationsConverter(
}
calleeReference = FirReferencePlaceholderForResolvedAnnotations
}
private fun <T> fillDanglingConstraintsTo(
typeParameters: List<FirTypeParameter>,
typeConstraints: List<TypeConstraint>,
to: T
) where T : FirDeclaration, T : FirTypeParameterRefsOwner {
val typeParamNames = typeParameters.map { it.name }.toSet()
val result = typeConstraints.mapNotNull { constraint ->
val name = constraint.identifier.nameAsSafeName()
if (!typeParamNames.contains(name)) {
DanglingTypeConstraint(name, constraint.source)
} else {
null
}
}
if (result.isNotEmpty()) {
to.danglingTypeConstraints = result
}
}
}
@@ -5,7 +5,13 @@
package org.jetbrains.kotlin.fir.lightTree.fir
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.types.FirTypeRef
class TypeConstraint(val annotations: List<FirAnnotationCall>, val identifier: String, val firTypeRef: FirTypeRef)
class TypeConstraint(
val annotations: List<FirAnnotationCall>,
val identifier: String,
val firTypeRef: FirTypeRef,
val source: FirSourceElement
)
@@ -500,6 +500,23 @@ open class RawFirBuilder(
}
}
private fun <T> KtTypeParameterListOwner.fillDanglingConstraintsTo(to: T) where T : FirDeclaration, T : FirTypeParameterRefsOwner {
val typeParamNames = typeParameters.mapNotNull { it.nameAsName }.toSet()
val result = typeConstraints.mapNotNull { constraint ->
constraint.subjectTypeParameterName?.getReferencedNameAsName()?.let { name ->
if (!typeParamNames.contains(name)) {
DanglingTypeConstraint(name, constraint.subjectTypeParameterName!!.toFirSourceElement())
} else {
null
}
}
}
if (result.isNotEmpty()) {
to.danglingTypeConstraints = result
}
}
private fun KtDeclarationWithBody.extractValueParametersTo(
container: FirFunctionBuilder,
defaultTypeRef: FirTypeRef? = null,
@@ -898,6 +915,7 @@ open class RawFirBuilder(
}
}.also {
it.initContainingClassForLocalAttr()
classOrObject.fillDanglingConstraintsTo(it)
}
}
@@ -1030,6 +1048,9 @@ open class RawFirBuilder(
context.firFunctionTargets.removeLast()
}.build().also {
target.bind(it)
if (it is FirSimpleFunction) {
function.fillDanglingConstraintsTo(it)
}
}
}
@@ -1308,6 +1329,10 @@ open class RawFirBuilder(
}
}
extractAnnotationsTo(this)
}.also {
if (!isLocal) {
fillDanglingConstraintsTo(it)
}
}
}
@@ -0,0 +1,30 @@
/*
* 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.declarations
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.name.Name
/**
* Constraint without corresponding type argiment
*/
data class DanglingTypeConstraint(val name: Name, val source: FirSourceElement)
private object DanglingTypeConstraintsKey : FirDeclarationDataKey()
var <T> T.danglingTypeConstraints: List<DanglingTypeConstraint>?
where T : FirDeclaration, T : FirTypeParameterRefsOwner
by FirDeclarationDataRegistry.data(DanglingTypeConstraintsKey)
fun FirDeclaration.getDanglingTypeConstraintsOrEmpty(): List<DanglingTypeConstraint> {
val res = when (this) {
is FirRegularClass -> danglingTypeConstraints
is FirSimpleFunction -> danglingTypeConstraints
is FirProperty -> danglingTypeConstraints
else -> null
}
return res ?: emptyList()
}
+3 -3
View File
@@ -11,7 +11,7 @@ interface B {
interface G<X> {
val <X> boo: Double where X : A, X : B
val <A> bal: Double where A : B
val <Y> bas: Double where Y : B, X : B
val <Y> bas: Double where Y : B, <!NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER!>X<!> : B
}
class C() : A(), B
@@ -24,7 +24,7 @@ class Test1<T>()
where
T : A,
T : B,
B : T // error
<!NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER!>B<!> : T // error
{
fun test(t : T) {
@@ -54,7 +54,7 @@ fun <T> test2(t : T)
where
T : A,
T : B,
B : T
<!NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER!>B<!> : T
{
<!TYPE_PARAMETER_ON_LHS_OF_DOT!>T<!>.<!UNRESOLVED_REFERENCE!>foo<!>()
<!TYPE_PARAMETER_ON_LHS_OF_DOT!>T<!>.<!UNRESOLVED_REFERENCE!>bar<!>()
@@ -15,10 +15,7 @@ import org.jetbrains.kotlin.diagnostics.WhenMissingCase
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.DiagnosticData
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.DiagnosticList
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.DiagnosticParameter
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
@@ -183,6 +180,11 @@ private object FirToKtConversionCreator {
KtVariableLikeSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirVariable")
),
FirDeclaration::class to HLFunctionCallConversion(
"firSymbolBuilder.buildSymbol({0})",
KtSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirDeclaration")
),
)
private val allowedTypesWithoutTypeParams = setOf(
@@ -945,6 +945,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER) { firDiagnostic ->
NameInConstraintIsNotATypeParameterImpl(
firDiagnostic.a,
firSymbolBuilder.buildSymbol(firDiagnostic.b),
firDiagnostic as FirPsiDiagnostic<*>,
token,
)
}
add(FirErrors.EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED) { firDiagnostic ->
ExtensionInClassReferenceNotAllowedImpl(
firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a as FirCallableDeclaration),
@@ -673,6 +673,12 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract val typeParameter: KtTypeParameterSymbol
}
abstract class NameInConstraintIsNotATypeParameter : KtFirDiagnostic<KtSimpleNameExpression>() {
override val diagnosticClass get() = NameInConstraintIsNotATypeParameter::class
abstract val typeParameterName: Name
abstract val typeParametersOwner: KtSymbol
}
abstract class ExtensionInClassReferenceNotAllowed : KtFirDiagnostic<KtExpression>() {
override val diagnosticClass get() = ExtensionInClassReferenceNotAllowed::class
abstract val referencedDeclaration: KtCallableSymbol
@@ -1085,6 +1085,15 @@ internal class ConflictingUpperBoundsImpl(
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class NameInConstraintIsNotATypeParameterImpl(
override val typeParameterName: Name,
override val typeParametersOwner: KtSymbol,
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,
) : KtFirDiagnostic.NameInConstraintIsNotATypeParameter(), KtAbstractFirDiagnostic<KtSimpleNameExpression> {
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class ExtensionInClassReferenceNotAllowedImpl(
override val referencedDeclaration: KtCallableSymbol,
firDiagnostic: FirPsiDiagnostic<*>,
+2 -2
View File
@@ -18,7 +18,7 @@ class Test1<T>()
where
T : A,
T : B,
B : T // error
<error descr="[NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER] B does not refer to a type parameter of Test1">B</error> : T // error
{
fun test(t : T) {
@@ -48,7 +48,7 @@ fun <T> test2(t : T)
where
T : A,
T : B,
B : T
<error descr="[NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER] B does not refer to a type parameter of test2">B</error> : T
{
<error descr="[TYPE_PARAMETER_ON_LHS_OF_DOT] Type parameter 'T' cannot have or inherit a companion object, so it cannot be on the left hand side of dot">T</error>.<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: foo">foo</error>()
<error descr="[TYPE_PARAMETER_ON_LHS_OF_DOT] Type parameter 'T' cannot have or inherit a companion object, so it cannot be on the left hand side of dot">T</error>.<error descr="[UNRESOLVED_REFERENCE] Unresolved reference: bar">bar</error>()