[FIR] Report UPPER_BOUND_VIOLATED only on checkers stage, fix detection of missing cases and testData
This commit is contained in:
committed by
teamcityserver
parent
ada14413e0
commit
5741374883
@@ -45,7 +45,7 @@ class Foo() {}
|
|||||||
|
|
||||||
class Bar<T : <!FINAL_UPPER_BOUND!>Foo<!>>
|
class Bar<T : <!FINAL_UPPER_BOUND!>Foo<!>>
|
||||||
|
|
||||||
class Buzz<T> where T : <!FINAL_UPPER_BOUND!>Bar<Int><!>, T : <!UNRESOLVED_REFERENCE!>nioho<!>
|
class Buzz<T> where T : <!FINAL_UPPER_BOUND!>Bar<<!UPPER_BOUND_VIOLATED!>Int<!>><!>, T : <!UNRESOLVED_REFERENCE!>nioho<!>
|
||||||
|
|
||||||
class X<T : <!FINAL_UPPER_BOUND!>Foo<!>>
|
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><!>
|
class Y<<!CONFLICTING_UPPER_BOUNDS!>T<!>> where T : <!FINAL_UPPER_BOUND!>Foo<!>, T : <!FINAL_UPPER_BOUND, ONLY_ONE_CLASS_BOUND_ALLOWED!>Bar<Foo><!>
|
||||||
@@ -62,8 +62,8 @@ fun <T> test2(t : T)
|
|||||||
t.bar()
|
t.bar()
|
||||||
}
|
}
|
||||||
|
|
||||||
val t1 = test2<A>(<!ARGUMENT_TYPE_MISMATCH!>A()<!>)
|
val t1 = test2<<!UPPER_BOUND_VIOLATED!>A<!>>(<!ARGUMENT_TYPE_MISMATCH!>A()<!>)
|
||||||
val t2 = test2<B>(<!ARGUMENT_TYPE_MISMATCH!>C()<!>)
|
val t2 = test2<<!UPPER_BOUND_VIOLATED!>B<!>>(<!ARGUMENT_TYPE_MISMATCH!>C()<!>)
|
||||||
val t3 = test2<C>(C())
|
val t3 = test2<C>(C())
|
||||||
|
|
||||||
val <<!TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER!>T<!>, <!TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER!>B : T<!>> x : Int = 0
|
val <<!TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER!>T<!>, <!TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER!>B : T<!>> x : Int = 0
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@ class G<E : <!FINAL_UPPER_BOUND!>Double<!>>(val balue: E) : F<E>(balue) {
|
|||||||
override var rest: E = balue
|
override var rest: E = balue
|
||||||
}
|
}
|
||||||
|
|
||||||
class H<E : <!FINAL_UPPER_BOUND!>String<!>>(val balue: E) : F<E>(<!ARGUMENT_TYPE_MISMATCH!>balue<!>) {
|
class H<E : <!FINAL_UPPER_BOUND!>String<!>>(val balue: E) : F<<!UPPER_BOUND_VIOLATED!>E<!>>(<!ARGUMENT_TYPE_MISMATCH!>balue<!>) {
|
||||||
override var rest: E = balue // no report because of INAPPLICABLE_CANDIDATE
|
override var rest: E = balue // no report because of INAPPLICABLE_CANDIDATE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -27,7 +27,7 @@ class G<E : <!FINAL_UPPER_BOUND!>Double<!>>(val balue: E) : F<E>(balue) {
|
|||||||
override fun rest(): E = balue
|
override fun rest(): E = balue
|
||||||
}
|
}
|
||||||
|
|
||||||
class H<E : <!FINAL_UPPER_BOUND!>String<!>>(val balue: E) : F<E>(<!ARGUMENT_TYPE_MISMATCH!>balue<!>) {
|
class H<E : <!FINAL_UPPER_BOUND!>String<!>>(val balue: E) : F<<!UPPER_BOUND_VIOLATED!>E<!>>(<!ARGUMENT_TYPE_MISMATCH!>balue<!>) {
|
||||||
override fun rest(): E = balue // no report because of INAPPLICABLE_CANDIDATE
|
override fun rest(): E = balue // no report because of INAPPLICABLE_CANDIDATE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -41,14 +41,14 @@ FILE: upperBoundViolated.kt
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
public final class P<T> : R|kotlin/Any| {
|
public final class P<T0 : R|kotlin/Number|, T1> : R|kotlin/Any| {
|
||||||
public constructor<T>(): R|P<T>| {
|
public constructor<T0 : R|kotlin/Number|, T1>(): R|P<T0, T1>| {
|
||||||
super<R|kotlin/Any|>()
|
super<R|kotlin/Any|>()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
public final class P1<T1 : R|kotlin/Number|, T2 : R|kotlin/Number|> : R|kotlin/Any| {
|
public final class P1<T2 : R|kotlin/Number|, T3 : R|kotlin/Number|> : R|kotlin/Any| {
|
||||||
public constructor<T1 : R|kotlin/Number|, T2 : R|kotlin/Number|>(): R|P1<T1, T2>| {
|
public constructor<T2 : R|kotlin/Number|, T3 : R|kotlin/Number|>(): R|P1<T2, T3>| {
|
||||||
super<R|kotlin/Any|>()
|
super<R|kotlin/Any|>()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ FILE: upperBoundViolated.kt
|
|||||||
lval o5: R|S<S<L, L>, T<K, L>>| = <CS errors: /S.S>#<R|S<L, L>|, R|T<K, L>|>()
|
lval o5: R|S<S<L, L>, T<K, L>>| = <CS errors: /S.S>#<R|S<L, L>|, R|T<K, L>|>()
|
||||||
lval o6: R|S<kotlin/Any, T<S<K, L>, kotlin/String>>| = R|/S.S|<R|kotlin/Any|, R|T<S<K, L>, kotlin/String>|>()
|
lval o6: R|S<kotlin/Any, T<S<K, L>, kotlin/String>>| = R|/S.S|<R|kotlin/Any|, R|T<S<K, L>, kotlin/String>|>()
|
||||||
lval o7: R|S<kotlin/Any, T<S<K, L>, kotlin/Nothing>>| = R|/S.S|<R|kotlin/Any|, R|T<S<K, L>, kotlin/Nothing>|>()
|
lval o7: R|S<kotlin/Any, T<S<K, L>, kotlin/Nothing>>| = R|/S.S|<R|kotlin/Any|, R|T<S<K, L>, kotlin/Nothing>|>()
|
||||||
lval o8: R|P<P1<kotlin/String, kotlin/String>>| = R|/P.P|<R|P1<kotlin/String, kotlin/String>|>()
|
lval o8: R|P<kotlin/String, P1<kotlin/String, kotlin/String>>| = <CS errors: /P.P>#<R|kotlin/String|, R|P1<kotlin/String, kotlin/String>|>()
|
||||||
}
|
}
|
||||||
public final class NumColl<T : R|kotlin/collections/Collection<kotlin/Number>|> : R|kotlin/Any| {
|
public final class NumColl<T : R|kotlin/collections/Collection<kotlin/Number>|> : R|kotlin/Any| {
|
||||||
public constructor<T : R|kotlin/collections/Collection<kotlin/Number>|>(): R|NumColl<T>| {
|
public constructor<T : R|kotlin/collections/Collection<kotlin/Number>|>(): R|NumColl<T>| {
|
||||||
|
|||||||
+3
-3
@@ -24,8 +24,8 @@ fun test() {
|
|||||||
|
|
||||||
open class S<F, G : F>
|
open class S<F, G : F>
|
||||||
class T<U, Y : U> : S<U, Y>()
|
class T<U, Y : U> : S<U, Y>()
|
||||||
class P<T>
|
class P<T0: Number, T1>
|
||||||
class P1<T1: Number, T2: Number>
|
class P1<T2 : Number, T3 : Number>
|
||||||
|
|
||||||
|
|
||||||
fun <K, L : K> rest() {
|
fun <K, L : K> rest() {
|
||||||
@@ -39,7 +39,7 @@ fun <K, L : K> rest() {
|
|||||||
|
|
||||||
val o6 = S<Any, T<S<K, L>, <!UPPER_BOUND_VIOLATED!>String<!>>>()
|
val o6 = S<Any, T<S<K, L>, <!UPPER_BOUND_VIOLATED!>String<!>>>()
|
||||||
val o7 = S<Any, T<S<K, L>, Nothing>>()
|
val o7 = S<Any, T<S<K, L>, Nothing>>()
|
||||||
val o8 = P<P1<<!UPPER_BOUND_VIOLATED!>String<!>, <!UPPER_BOUND_VIOLATED!>String<!>>>()
|
val o8 = P<<!UPPER_BOUND_VIOLATED!>String<!>, P1<<!UPPER_BOUND_VIOLATED!>String<!>, <!UPPER_BOUND_VIOLATED!>String<!>>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
class NumColl<T : Collection<Number>>
|
class NumColl<T : Collection<Number>>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
interface FirDeclaration
|
interface FirDeclaration
|
||||||
|
|
||||||
interface FirSymbolOwner<E : FirSymbolOwner<E>> {
|
interface FirSymbolOwner<E : FirSymbolOwner<E>> {
|
||||||
val symbol: AbstractFirBasedSymbol<E>
|
val symbol: AbstractFirBasedSymbol<<!UPPER_BOUND_VIOLATED!>E<!>>
|
||||||
}
|
}
|
||||||
interface FirFunction<F : FirFunction<F>> : FirSymbolOwner<F>, FirDeclaration
|
interface FirFunction<F : FirFunction<F>> : FirSymbolOwner<F>, FirDeclaration
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirDelegationInInterfac
|
|||||||
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirFunctionTypeParametersSyntaxChecker
|
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirFunctionTypeParametersSyntaxChecker
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirTypeParameterSyntaxChecker
|
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirTypeParameterSyntaxChecker
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirReservedUnderscoreDeclarationChecker
|
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirReservedUnderscoreDeclarationChecker
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirUpperBoundViolatedClassChecker
|
||||||
|
|
||||||
object CommonDeclarationCheckers : DeclarationCheckers() {
|
object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||||
override val basicDeclarationCheckers: Set<FirBasicDeclarationChecker>
|
override val basicDeclarationCheckers: Set<FirBasicDeclarationChecker>
|
||||||
@@ -23,7 +24,8 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
|||||||
FirConflictsChecker,
|
FirConflictsChecker,
|
||||||
FirProjectionRelationChecker,
|
FirProjectionRelationChecker,
|
||||||
FirTypeConstraintsChecker,
|
FirTypeConstraintsChecker,
|
||||||
FirReservedUnderscoreDeclarationChecker
|
FirReservedUnderscoreDeclarationChecker,
|
||||||
|
FirUpperBoundViolatedClassChecker
|
||||||
)
|
)
|
||||||
|
|
||||||
override val memberDeclarationCheckers: Set<FirMemberDeclarationChecker>
|
override val memberDeclarationCheckers: Set<FirMemberDeclarationChecker>
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
|
|||||||
FirAbstractSuperCallChecker,
|
FirAbstractSuperCallChecker,
|
||||||
FirQualifiedSupertypeExtendedByOtherSupertypeChecker,
|
FirQualifiedSupertypeExtendedByOtherSupertypeChecker,
|
||||||
FirProjectionsOnNonClassTypeArgumentChecker,
|
FirProjectionsOnNonClassTypeArgumentChecker,
|
||||||
FirUpperBoundViolatedChecker,
|
FirUpperBoundViolatedExpressionChecker,
|
||||||
FirTypeArgumentsNotAllowedExpressionChecker,
|
FirTypeArgumentsNotAllowedExpressionChecker,
|
||||||
FirTypeParameterInQualifiedAccessChecker,
|
FirTypeParameterInQualifiedAccessChecker,
|
||||||
FirSealedClassConstructorCallChecker,
|
FirSealedClassConstructorCallChecker,
|
||||||
|
|||||||
+127
-98
@@ -7,142 +7,171 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.extractTypeRefAndSourceFromTypeArgument
|
import org.jetbrains.kotlin.fir.analysis.checkers.extractTypeRefAndSourceFromTypeArgument
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableCandidateError
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.fir.typeContext
|
import org.jetbrains.kotlin.fir.typeContext
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
object FirUpperBoundViolatedChecker : FirQualifiedAccessExpressionChecker() {
|
object FirUpperBoundViolatedClassChecker : FirBasicDeclarationChecker() {
|
||||||
|
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
if (declaration is FirClass<*>) {
|
||||||
|
for (typeParameter in declaration.typeParameters) {
|
||||||
|
if (typeParameter is FirTypeParameter) {
|
||||||
|
for (bound in typeParameter.bounds) {
|
||||||
|
analyzeTypeParameters(bound, context, reporter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (superTypeRef in declaration.superTypeRefs) {
|
||||||
|
analyzeTypeParameters(superTypeRef, context, reporter)
|
||||||
|
}
|
||||||
|
} else if (declaration is FirCallableDeclaration<*>) {
|
||||||
|
analyzeTypeParameters(declaration.returnTypeRef, context, reporter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object FirUpperBoundViolatedExpressionChecker : FirQualifiedAccessExpressionChecker() {
|
||||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
// something that contains the type parameters
|
// something that contains the type parameters
|
||||||
// declarations with their declared bounds.
|
// declarations with their declared bounds.
|
||||||
// it may be the called function declaration
|
// it may be the called function declaration
|
||||||
// or the class declaration
|
// or the class declaration
|
||||||
val calleeFir = expression.calleeReference.safeAs<FirResolvedNamedReference>()
|
val calleReference = expression.calleeReference
|
||||||
?.resolvedSymbol
|
var calleeFir: FirTypeParameterRefsOwner? = null
|
||||||
?.fir.safeAs<FirTypeParameterRefsOwner>()
|
if (calleReference is FirResolvedNamedReference) {
|
||||||
?: return
|
calleeFir = calleReference.safeAs<FirResolvedNamedReference>()?.resolvedSymbol?.fir.safeAs()
|
||||||
|
} else if (calleReference is FirErrorNamedReference) {
|
||||||
val coneType = expression.typeRef.coneType
|
val diagnostic = calleReference.diagnostic
|
||||||
if (coneType is ConeClassLikeType) {
|
if (diagnostic is ConeInapplicableCandidateError &&
|
||||||
analyzeTypeParameters(
|
diagnostic.applicability == CandidateApplicability.INAPPLICABLE_WRONG_RECEIVER
|
||||||
coneType,
|
) {
|
||||||
expression.typeRef,
|
return
|
||||||
calleeFir.typeParameters.map { it.symbol },
|
}
|
||||||
expression.typeArguments,
|
calleeFir = calleReference.candidateSymbol?.fir.safeAs()
|
||||||
context,
|
|
||||||
reporter
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
analyzeTypeParameters(
|
||||||
|
expression.typeRef,
|
||||||
|
context,
|
||||||
|
reporter,
|
||||||
|
calleeFir?.typeParameters?.map { it.symbol },
|
||||||
|
expression.typeArguments
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively analyzes type parameters and reports the diagnostic on the given source calculated using typeRef
|
||||||
|
* Returns true if an error occurred
|
||||||
|
*/
|
||||||
|
private fun analyzeTypeParameters(
|
||||||
|
typeRef: FirTypeRef?,
|
||||||
|
context: CheckerContext,
|
||||||
|
reporter: DiagnosticReporter,
|
||||||
|
typeParameters: List<FirTypeParameterSymbol>? = null,
|
||||||
|
typeArguments: List<FirTypeProjection>? = null
|
||||||
|
) {
|
||||||
|
val type = when (typeRef) {
|
||||||
|
is ConeKotlinType -> typeRef
|
||||||
|
is FirResolvedTypeRef -> typeRef.type
|
||||||
|
else -> return
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
val typeArgumentsCount = typeArguments?.size ?: type.typeArguments.size
|
||||||
* Recursively analyzes type parameters and reports the diagnostic on the given source calculated using typeRef
|
if (typeArgumentsCount == 0) {
|
||||||
* Returns true if an error occurred
|
return
|
||||||
*/
|
}
|
||||||
private fun analyzeTypeParameters(
|
|
||||||
type: ConeClassLikeType,
|
|
||||||
typeRef: FirTypeRef?,
|
|
||||||
typeParameters: List<FirTypeParameterSymbol>?,
|
|
||||||
typeArguments: List<FirTypeProjection>?,
|
|
||||||
context: CheckerContext,
|
|
||||||
reporter: DiagnosticReporter
|
|
||||||
) {
|
|
||||||
fun getTypeArgument(index: Int): Any {
|
|
||||||
return typeArguments?.elementAt(index) ?: type.typeArguments[index]
|
|
||||||
}
|
|
||||||
|
|
||||||
val typeArgumentsCount = typeArguments?.size ?: type.typeArguments.size
|
val typeParameterSymbols = typeParameters
|
||||||
if (typeArgumentsCount == 0) {
|
?: if (type is ConeClassLikeType) {
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val typeParameterSymbols = if (typeParameters != null) {
|
|
||||||
typeParameters
|
|
||||||
} else {
|
|
||||||
val prototypeClass = type.lookupTag.toSymbol(context.session)
|
val prototypeClass = type.lookupTag.toSymbol(context.session)
|
||||||
?.fir.safeAs<FirRegularClass>()
|
?.fir.safeAs<FirRegularClass>()
|
||||||
?: return
|
?: return
|
||||||
|
|
||||||
prototypeClass.typeParameters.map { it.symbol }
|
prototypeClass.typeParameters.map { it.symbol }
|
||||||
|
} else {
|
||||||
|
listOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeParameterSymbols.isEmpty()) {
|
if (typeParameterSymbols.isEmpty()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val count = minOf(typeParameterSymbols.size, typeArgumentsCount)
|
val count = minOf(typeParameterSymbols.size, typeArgumentsCount)
|
||||||
val substitution = mutableMapOf<FirTypeParameterSymbol, ConeKotlinType>()
|
val substitution = mutableMapOf<FirTypeParameterSymbol, ConeKotlinType>()
|
||||||
|
|
||||||
for (index in 0 until count) {
|
for (index in 0 until count) {
|
||||||
val typeArgument = getTypeArgument(index)
|
val typeArgument = typeArguments?.elementAt(index) ?: type.typeArguments[index]
|
||||||
val typeParameterSymbol = typeParameterSymbols[index]
|
val typeParameterSymbol = typeParameterSymbols[index]
|
||||||
|
|
||||||
if (typeArgument is FirTypeProjectionWithVariance) {
|
if (typeArgument is FirTypeProjectionWithVariance) {
|
||||||
substitution[typeParameterSymbol] = typeArgument.typeRef.coneType
|
substitution[typeParameterSymbol] = typeArgument.typeRef.coneType
|
||||||
} else if (typeArgument is ConeClassLikeType) {
|
} else if (typeArgument is ConeKotlinType) {
|
||||||
substitution[typeParameterSymbol] = typeArgument.type
|
substitution[typeParameterSymbol] = typeArgument.type
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val substitutor = substitutorByMap(substitution, context.session)
|
|
||||||
val typeSystemContext = context.session.typeContext
|
|
||||||
|
|
||||||
for (index in 0 until count) {
|
|
||||||
var typeArgument: ConeClassLikeType? = null
|
|
||||||
var typeArgumentTypeRef: FirTypeRef? = null
|
|
||||||
var typeArgumentSource: FirSourceElement? = null
|
|
||||||
|
|
||||||
if (typeArguments != null) {
|
|
||||||
val localTypeArgument = typeArguments[index]
|
|
||||||
if (localTypeArgument is FirTypeProjectionWithVariance) {
|
|
||||||
typeArgumentTypeRef = localTypeArgument.typeRef
|
|
||||||
typeArgument = typeArgumentTypeRef.coneType as? ConeClassLikeType
|
|
||||||
typeArgumentSource = localTypeArgument.source
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
typeArgument = type.typeArguments[index] as? ConeClassLikeType
|
|
||||||
val argTypeRefSource = extractTypeRefAndSourceFromTypeArgument(typeRef, index)
|
|
||||||
typeArgumentTypeRef = argTypeRefSource?.first
|
|
||||||
typeArgumentSource = argTypeRefSource?.second
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeArgument != null && typeArgumentSource != null) {
|
|
||||||
val upperBound = getSubstitutedUpperBound(typeParameterSymbols[index], substitutor, typeSystemContext)
|
|
||||||
if (upperBound != null && !satisfiesBounds(upperBound, typeArgument.type, typeSystemContext)) {
|
|
||||||
reporter.reportOn(typeArgumentSource, FirErrors.UPPER_BOUND_VIOLATED, upperBound, context)
|
|
||||||
} else {
|
|
||||||
analyzeTypeParameters(typeArgument, typeArgumentTypeRef, null, null, context, reporter)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSubstitutedUpperBound(
|
val substitutor = substitutorByMap(substitution, context.session)
|
||||||
prototypeSymbol: FirTypeParameterSymbol,
|
val typeSystemContext = context.session.typeContext
|
||||||
substitutor: ConeSubstitutor,
|
|
||||||
typeSystemContext: ConeTypeContext
|
|
||||||
): ConeKotlinType? {
|
|
||||||
val intersection = typeSystemContext.intersectTypes(
|
|
||||||
prototypeSymbol.fir.bounds.map { it.coneType }
|
|
||||||
).safeAs<ConeKotlinType>() ?: return null
|
|
||||||
|
|
||||||
return substitutor.substituteOrSelf(intersection)
|
for (index in 0 until count) {
|
||||||
}
|
var typeArgument: ConeKotlinType? = null
|
||||||
|
var typeArgumentTypeRef: FirTypeRef? = null
|
||||||
|
var typeArgumentSource: FirSourceElement? = null
|
||||||
|
|
||||||
private fun satisfiesBounds(upperBound: ConeKotlinType, target: ConeKotlinType, typeSystemContext: ConeTypeContext): Boolean {
|
if (typeArguments != null) {
|
||||||
return AbstractTypeChecker.isSubtypeOf(typeSystemContext, target, upperBound, stubTypesEqualToAnything = false)
|
val localTypeArgument = typeArguments[index]
|
||||||
|
if (localTypeArgument is FirTypeProjectionWithVariance) {
|
||||||
|
typeArgumentTypeRef = localTypeArgument.typeRef
|
||||||
|
typeArgument = typeArgumentTypeRef.coneType
|
||||||
|
typeArgumentSource = localTypeArgument.source
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
typeArgument = type.typeArguments[index] as? ConeKotlinType
|
||||||
|
val argTypeRefSource = extractTypeRefAndSourceFromTypeArgument(typeRef, index)
|
||||||
|
if (argTypeRefSource != null) {
|
||||||
|
typeArgumentTypeRef = argTypeRefSource.first
|
||||||
|
typeArgumentSource = argTypeRefSource.second
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeArgument != null && typeArgumentSource != null) {
|
||||||
|
val upperBound = getSubstitutedUpperBound(typeParameterSymbols[index], substitutor, typeSystemContext)
|
||||||
|
if (upperBound != null && !satisfiesBounds(upperBound, typeArgument.type, typeSystemContext)) {
|
||||||
|
reporter.reportOn(typeArgumentSource, FirErrors.UPPER_BOUND_VIOLATED, upperBound, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
analyzeTypeParameters(typeArgumentTypeRef, context, reporter)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getSubstitutedUpperBound(
|
||||||
|
prototypeSymbol: FirTypeParameterSymbol,
|
||||||
|
substitutor: ConeSubstitutor,
|
||||||
|
typeSystemContext: ConeTypeContext
|
||||||
|
): ConeKotlinType? {
|
||||||
|
val intersection = typeSystemContext.intersectTypes(prototypeSymbol.fir.bounds.map { it.coneType }) as? ConeKotlinType ?: return null
|
||||||
|
return substitutor.substituteOrSelf(intersection)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun satisfiesBounds(upperBound: ConeKotlinType, target: ConeKotlinType, typeSystemContext: ConeTypeContext): Boolean {
|
||||||
|
return AbstractTypeChecker.isSubtypeOf(typeSystemContext, target, upperBound, stubTypesEqualToAnything = false)
|
||||||
|
}
|
||||||
|
|||||||
+1
-9
@@ -286,15 +286,7 @@ private fun ConstraintSystemError.toDiagnostic(
|
|||||||
|
|
||||||
FirErrors.TYPE_MISMATCH.createOn(qualifiedAccessSource ?: source, upperConeType, inferredType)
|
FirErrors.TYPE_MISMATCH.createOn(qualifiedAccessSource ?: source, upperConeType, inferredType)
|
||||||
}
|
}
|
||||||
is ExplicitTypeParameterConstraintPosition<*> -> {
|
is ExplicitTypeParameterConstraintPosition<*>,
|
||||||
val conePosition = position as ConeExplicitTypeParameterConstraintPosition
|
|
||||||
val typeArgument = conePosition.typeArgument
|
|
||||||
|
|
||||||
FirErrors.UPPER_BOUND_VIOLATED.createOn(
|
|
||||||
typeArgument.source ?: qualifiedAccessSource ?: source,
|
|
||||||
upperConeType,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
is DelegatedPropertyConstraintPosition<*> -> {
|
is DelegatedPropertyConstraintPosition<*> -> {
|
||||||
errorsToIgnore.add(this)
|
errorsToIgnore.add(this)
|
||||||
return null
|
return null
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_FIR_DIAGNOSTICS
|
|
||||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_FIR_DIAGNOSTICS
|
|
||||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
// WITH_REFLECT
|
// WITH_REFLECT
|
||||||
// KJS_WITH_FULL_RUNTIME
|
// KJS_WITH_FULL_RUNTIME
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// MODULE: lib
|
// MODULE: lib
|
||||||
// FILE: A.java
|
// FILE: A.java
|
||||||
|
|||||||
+2
-2
@@ -20,10 +20,10 @@ package boundsWithSubstitutors
|
|||||||
|
|
||||||
class Pair<A, B>
|
class Pair<A, B>
|
||||||
|
|
||||||
abstract class C<T : B<Int>, X : (B<Char>) -> Pair<B<Any>, B<A>>>() : <!UPPER_BOUND_VIOLATED!>B<Any><!>() { // 2 errors
|
abstract class C<T : B<<!UPPER_BOUND_VIOLATED!>Int<!>>, X : (B<<!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Char<!>>) -> Pair<B<<!UPPER_BOUND_VIOLATED!>Any<!>>, B<A>>>() : B<<!UPPER_BOUND_VIOLATED!>Any<!>>() { // 2 errors
|
||||||
val a = B<<!UPPER_BOUND_VIOLATED!>Char<!>>() // error
|
val a = B<<!UPPER_BOUND_VIOLATED!>Char<!>>() // error
|
||||||
|
|
||||||
abstract val x : (B<Char>) -> B<Any>
|
abstract val x : (B<<!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Char<!>>) -> B<<!UPPER_BOUND_VIOLATED!>Any<!>>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class Foo() {}
|
|||||||
|
|
||||||
class Bar<T : <!FINAL_UPPER_BOUND!>Foo<!>>
|
class Bar<T : <!FINAL_UPPER_BOUND!>Foo<!>>
|
||||||
|
|
||||||
class Buzz<T> where T : <!FINAL_UPPER_BOUND!>Bar<Int><!>, T : <!UNRESOLVED_REFERENCE!>nioho<!>
|
class Buzz<T> where T : <!FINAL_UPPER_BOUND!>Bar<<!UPPER_BOUND_VIOLATED!>Int<!>><!>, T : <!UNRESOLVED_REFERENCE!>nioho<!>
|
||||||
|
|
||||||
class X<T : <!FINAL_UPPER_BOUND!>Foo<!>>
|
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><!>
|
class Y<<!CONFLICTING_UPPER_BOUNDS!>T<!>> where T : <!FINAL_UPPER_BOUND!>Foo<!>, T : <!FINAL_UPPER_BOUND, ONLY_ONE_CLASS_BOUND_ALLOWED!>Bar<Foo><!>
|
||||||
@@ -62,8 +62,8 @@ fun <T> test2(t : T)
|
|||||||
t.bar()
|
t.bar()
|
||||||
}
|
}
|
||||||
|
|
||||||
val t1 = test2<A>(<!ARGUMENT_TYPE_MISMATCH!>A()<!>)
|
val t1 = test2<<!UPPER_BOUND_VIOLATED!>A<!>>(<!ARGUMENT_TYPE_MISMATCH!>A()<!>)
|
||||||
val t2 = test2<B>(<!ARGUMENT_TYPE_MISMATCH!>C()<!>)
|
val t2 = test2<<!UPPER_BOUND_VIOLATED!>B<!>>(<!ARGUMENT_TYPE_MISMATCH!>C()<!>)
|
||||||
val t3 = test2<C>(C())
|
val t3 = test2<C>(C())
|
||||||
|
|
||||||
val <<!TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER!>T<!>, <!TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER!>B : T<!>> x : Int = 0
|
val <<!TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER!>T<!>, <!TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER!>B : T<!>> x : Int = 0
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ val <T> <!KCLASS_WITH_NULLABLE_TYPE_PARAMETER_IN_SIGNATURE!>test4<!> get() = T::
|
|||||||
|
|
||||||
fun <T> test5() = listOf(T::class)
|
fun <T> test5() = listOf(T::class)
|
||||||
|
|
||||||
fun <T> test6(): kotlin.reflect.KClass<T> = <!TYPE_MISMATCH!>T<!>::class
|
fun <T> test6(): kotlin.reflect.KClass<<!UPPER_BOUND_VIOLATED!>T<!>> = <!TYPE_MISMATCH!>T<!>::class
|
||||||
fun <T> test7(): kotlin.reflect.KClass<*> = <!TYPE_MISMATCH!>T<!>::class
|
fun <T> test7(): kotlin.reflect.KClass<*> = <!TYPE_MISMATCH!>T<!>::class
|
||||||
fun test8() = <!NULLABLE_TYPE_IN_CLASS_LITERAL_LHS!>String?::class<!>
|
fun test8() = <!NULLABLE_TYPE_IN_CLASS_LITERAL_LHS!>String?::class<!>
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -21,9 +21,9 @@ interface<!SYNTAX!><!> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<!UPPER_BOUND_VIOLATED!>enum class<!SYNTAX!><!> {
|
enum class<!SYNTAX!><!> {
|
||||||
|
|
||||||
}<!>
|
}
|
||||||
|
|
||||||
annotation class<!SYNTAX!><!> {
|
annotation class<!SYNTAX!><!> {
|
||||||
|
|
||||||
@@ -48,9 +48,9 @@ class Outer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<!UPPER_BOUND_VIOLATED!>enum class<!SYNTAX!><!> {
|
enum class<!SYNTAX!><!> {
|
||||||
|
|
||||||
}<!>
|
}
|
||||||
|
|
||||||
annotation class<!SYNTAX!><!> {
|
annotation class<!SYNTAX!><!> {
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// FILE: test.kt
|
// FILE: test.kt
|
||||||
enum class MyEnum(): <!CLASS_IN_SUPERTYPE_FOR_ENUM!>MyClass<!>() {}
|
enum class MyEnum(): <!CLASS_IN_SUPERTYPE_FOR_ENUM!>MyClass<!>() {}
|
||||||
enum class MyEnum2(): MyTrait {}
|
enum class MyEnum2(): MyTrait {}
|
||||||
enum class MyEnum3(): <!UPPER_BOUND_VIOLATED{LT}!><!CLASS_IN_SUPERTYPE_FOR_ENUM, FINAL_SUPERTYPE, UPPER_BOUND_VIOLATED{PSI}!>MyEnumBase<!>()<!> {}
|
enum class MyEnum3(): <!CLASS_IN_SUPERTYPE_FOR_ENUM, FINAL_SUPERTYPE!>MyEnumBase<!>() {}
|
||||||
|
|
||||||
open class MyClass() {}
|
open class MyClass() {}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
open class C<T : C<T>>
|
|
||||||
class TestOK : C<TestOK>()
|
|
||||||
class TestFail : <!UPPER_BOUND_VIOLATED!>C<C<TestFail>><!>()
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
open class C<T : C<T>>
|
open class C<T : C<T>>
|
||||||
class TestOK : C<TestOK>()
|
class TestOK : C<TestOK>()
|
||||||
class TestFail : C<<!UPPER_BOUND_VIOLATED!>C<<!UPPER_BOUND_VIOLATED!>TestFail<!>><!>>()
|
class TestFail : C<<!UPPER_BOUND_VIOLATED!>C<<!UPPER_BOUND_VIOLATED!>TestFail<!>><!>>()
|
||||||
|
|||||||
-1
@@ -1 +0,0 @@
|
|||||||
class D<A : D<A, String>, B : D<A, B>>
|
|
||||||
+1
@@ -1 +1,2 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
class D<A : D<A, <!UPPER_BOUND_VIOLATED!>String<!>>, B : D<A, B>>
|
class D<A : D<A, <!UPPER_BOUND_VIOLATED!>String<!>>, B : D<A, B>>
|
||||||
|
|||||||
-5
@@ -1,5 +0,0 @@
|
|||||||
class Outer<E : Any> {
|
|
||||||
inner class Inner<F, G>
|
|
||||||
}
|
|
||||||
|
|
||||||
val x: Outer<String?>.Inner<String, Int> = null!!
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
class Outer<E : Any> {
|
class Outer<E : Any> {
|
||||||
inner class Inner<F, G>
|
inner class Inner<F, G>
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
-13
@@ -1,13 +0,0 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
|
||||||
|
|
||||||
interface A<T : CharSequence>
|
|
||||||
|
|
||||||
fun <S : CharSequence?> foo1(a: A<S>) {}
|
|
||||||
|
|
||||||
class B1<E : String?> : A<E>
|
|
||||||
class B2<E : CharSequence?> : A<E>
|
|
||||||
class B3<E> : A<E>
|
|
||||||
|
|
||||||
class B4<E : CharSequence> : A<E>
|
|
||||||
|
|
||||||
fun <X : CharSequence, Y1 : X, Y2: Y1?> foo(a: A<X>, b: A<Y1>, c: A<Y2>) {}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
interface A<T : CharSequence>
|
interface A<T : CharSequence>
|
||||||
|
|||||||
+2
-2
@@ -7,10 +7,10 @@ fun <E : CharSequence> E.foo2() {}
|
|||||||
|
|
||||||
fun <F : String?> bar(x: F) {
|
fun <F : String?> bar(x: F) {
|
||||||
A(<!ARGUMENT_TYPE_MISMATCH!>x<!>)
|
A(<!ARGUMENT_TYPE_MISMATCH!>x<!>)
|
||||||
A<F>(<!ARGUMENT_TYPE_MISMATCH!>x<!>)
|
A<<!UPPER_BOUND_VIOLATED!>F<!>>(<!ARGUMENT_TYPE_MISMATCH!>x<!>)
|
||||||
|
|
||||||
foo1(<!ARGUMENT_TYPE_MISMATCH!>x<!>)
|
foo1(<!ARGUMENT_TYPE_MISMATCH!>x<!>)
|
||||||
foo1<F>(<!ARGUMENT_TYPE_MISMATCH!>x<!>)
|
foo1<<!UPPER_BOUND_VIOLATED!>F<!>>(<!ARGUMENT_TYPE_MISMATCH!>x<!>)
|
||||||
|
|
||||||
x<!UNSAFE_CALL!>.<!>foo2()
|
x<!UNSAFE_CALL!>.<!>foo2()
|
||||||
x.<!INAPPLICABLE_CANDIDATE!>foo2<!><F>()
|
x.<!INAPPLICABLE_CANDIDATE!>foo2<!><F>()
|
||||||
|
|||||||
+3
-3
@@ -16,7 +16,7 @@ class A<F> {
|
|||||||
val x2 = foo2(x)
|
val x2 = foo2(x)
|
||||||
x2.checkType { _<F>() }
|
x2.checkType { _<F>() }
|
||||||
|
|
||||||
foo1<F?>(<!ARGUMENT_TYPE_MISMATCH!>y<!>)
|
foo1<<!UPPER_BOUND_VIOLATED!>F?<!>>(<!ARGUMENT_TYPE_MISMATCH!>y<!>)
|
||||||
foo1(<!ARGUMENT_TYPE_MISMATCH!>y<!>)
|
foo1(<!ARGUMENT_TYPE_MISMATCH!>y<!>)
|
||||||
foo2<F?>(y)
|
foo2<F?>(y)
|
||||||
|
|
||||||
@@ -36,13 +36,13 @@ class A<F> {
|
|||||||
val x5 = foo2(z)
|
val x5 = foo2(z)
|
||||||
x4.checkType { _<Z>() }
|
x4.checkType { _<Z>() }
|
||||||
|
|
||||||
foo1<W>(<!ARGUMENT_TYPE_MISMATCH!>w<!>)
|
foo1<<!UPPER_BOUND_VIOLATED!>W<!>>(<!ARGUMENT_TYPE_MISMATCH!>w<!>)
|
||||||
foo1(<!ARGUMENT_TYPE_MISMATCH!>w<!>)
|
foo1(<!ARGUMENT_TYPE_MISMATCH!>w<!>)
|
||||||
foo2<W>(w)
|
foo2<W>(w)
|
||||||
|
|
||||||
val x6 = foo2(w)
|
val x6 = foo2(w)
|
||||||
x6.checkType { _<W>() }
|
x6.checkType { _<W>() }
|
||||||
|
|
||||||
foo1<W>(<!ARGUMENT_TYPE_MISMATCH!>w<!>)
|
foo1<<!UPPER_BOUND_VIOLATED!>W<!>>(<!ARGUMENT_TYPE_MISMATCH!>w<!>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -17,7 +17,7 @@ class A<F> {
|
|||||||
fun <Z : F, W : Z?> bar() {
|
fun <Z : F, W : Z?> bar() {
|
||||||
// F
|
// F
|
||||||
fooInv1<Inv<F>>(Inv<F>())
|
fooInv1<Inv<F>>(Inv<F>())
|
||||||
fooInv2<Inv<F>>(<!ARGUMENT_TYPE_MISMATCH!>Inv<F>()<!>)
|
fooInv2<<!UPPER_BOUND_VIOLATED!>Inv<F><!>>(<!ARGUMENT_TYPE_MISMATCH!>Inv<F>()<!>)
|
||||||
fooInv1(Inv<F>())
|
fooInv1(Inv<F>())
|
||||||
fooInv2(<!ARGUMENT_TYPE_MISMATCH!>Inv<F>()<!>)
|
fooInv2(<!ARGUMENT_TYPE_MISMATCH!>Inv<F>()<!>)
|
||||||
|
|
||||||
@@ -32,13 +32,13 @@ class A<F> {
|
|||||||
fooOut2(Out<F>())
|
fooOut2(Out<F>())
|
||||||
|
|
||||||
// Z
|
// Z
|
||||||
fooInv1<Inv<Z>>(<!ARGUMENT_TYPE_MISMATCH!>Inv<Z>()<!>)
|
fooInv1<<!UPPER_BOUND_VIOLATED!>Inv<Z><!>>(<!ARGUMENT_TYPE_MISMATCH!>Inv<Z>()<!>)
|
||||||
fooInv2<Inv<Z>>(<!ARGUMENT_TYPE_MISMATCH!>Inv<Z>()<!>)
|
fooInv2<<!UPPER_BOUND_VIOLATED!>Inv<Z><!>>(<!ARGUMENT_TYPE_MISMATCH!>Inv<Z>()<!>)
|
||||||
fooInv1(<!ARGUMENT_TYPE_MISMATCH!>Inv<Z>()<!>)
|
fooInv1(<!ARGUMENT_TYPE_MISMATCH!>Inv<Z>()<!>)
|
||||||
fooInv2(<!ARGUMENT_TYPE_MISMATCH!>Inv<Z>()<!>)
|
fooInv2(<!ARGUMENT_TYPE_MISMATCH!>Inv<Z>()<!>)
|
||||||
|
|
||||||
fooIn1<In<Z?>>(<!ARGUMENT_TYPE_MISMATCH!>In<Z?>()<!>)
|
fooIn1<<!UPPER_BOUND_VIOLATED!>In<Z?><!>>(<!ARGUMENT_TYPE_MISMATCH!>In<Z?>()<!>)
|
||||||
fooIn2<In<Z?>>(<!ARGUMENT_TYPE_MISMATCH!>In<Z?>()<!>)
|
fooIn2<<!UPPER_BOUND_VIOLATED!>In<Z?><!>>(<!ARGUMENT_TYPE_MISMATCH!>In<Z?>()<!>)
|
||||||
fooIn1(<!ARGUMENT_TYPE_MISMATCH!>In<Z?>()<!>)
|
fooIn1(<!ARGUMENT_TYPE_MISMATCH!>In<Z?>()<!>)
|
||||||
fooIn2(<!ARGUMENT_TYPE_MISMATCH!>In<Z?>()<!>)
|
fooIn2(<!ARGUMENT_TYPE_MISMATCH!>In<Z?>()<!>)
|
||||||
|
|
||||||
@@ -48,17 +48,17 @@ class A<F> {
|
|||||||
fooOut2(Out<Z>())
|
fooOut2(Out<Z>())
|
||||||
|
|
||||||
// W
|
// W
|
||||||
fooInv1<Inv<W>>(<!ARGUMENT_TYPE_MISMATCH!>Inv<W>()<!>)
|
fooInv1<<!UPPER_BOUND_VIOLATED!>Inv<W><!>>(<!ARGUMENT_TYPE_MISMATCH!>Inv<W>()<!>)
|
||||||
fooInv2<Inv<W>>(<!ARGUMENT_TYPE_MISMATCH!>Inv<W>()<!>)
|
fooInv2<<!UPPER_BOUND_VIOLATED!>Inv<W><!>>(<!ARGUMENT_TYPE_MISMATCH!>Inv<W>()<!>)
|
||||||
fooInv1(<!ARGUMENT_TYPE_MISMATCH!>Inv<W>()<!>)
|
fooInv1(<!ARGUMENT_TYPE_MISMATCH!>Inv<W>()<!>)
|
||||||
fooInv2(<!ARGUMENT_TYPE_MISMATCH!>Inv<W>()<!>)
|
fooInv2(<!ARGUMENT_TYPE_MISMATCH!>Inv<W>()<!>)
|
||||||
|
|
||||||
fooIn1<In<W?>>(<!ARGUMENT_TYPE_MISMATCH!>In<W?>()<!>)
|
fooIn1<<!UPPER_BOUND_VIOLATED!>In<W?><!>>(<!ARGUMENT_TYPE_MISMATCH!>In<W?>()<!>)
|
||||||
fooIn2<In<W?>>(<!ARGUMENT_TYPE_MISMATCH!>In<W?>()<!>)
|
fooIn2<<!UPPER_BOUND_VIOLATED!>In<W?><!>>(<!ARGUMENT_TYPE_MISMATCH!>In<W?>()<!>)
|
||||||
fooIn1(<!ARGUMENT_TYPE_MISMATCH!>In<W?>()<!>)
|
fooIn1(<!ARGUMENT_TYPE_MISMATCH!>In<W?>()<!>)
|
||||||
fooIn2(<!ARGUMENT_TYPE_MISMATCH!>In<W?>()<!>)
|
fooIn2(<!ARGUMENT_TYPE_MISMATCH!>In<W?>()<!>)
|
||||||
|
|
||||||
fooOut1<Out<W>>(<!ARGUMENT_TYPE_MISMATCH!>Out<W>()<!>)
|
fooOut1<<!UPPER_BOUND_VIOLATED!>Out<W><!>>(<!ARGUMENT_TYPE_MISMATCH!>Out<W>()<!>)
|
||||||
fooOut2<Out<W>>(Out<W>())
|
fooOut2<Out<W>>(Out<W>())
|
||||||
fooOut1(<!ARGUMENT_TYPE_MISMATCH!>Out<W>()<!>)
|
fooOut1(<!ARGUMENT_TYPE_MISMATCH!>Out<W>()<!>)
|
||||||
fooOut2(Out<W>())
|
fooOut2(Out<W>())
|
||||||
|
|||||||
+4
-4
@@ -13,14 +13,14 @@ class A<T> {
|
|||||||
|
|
||||||
fun foo2(a: A<out CharSequence>, b: A<in CharSequence>) {
|
fun foo2(a: A<out CharSequence>, b: A<in CharSequence>) {
|
||||||
a.foo1(<!ARGUMENT_TYPE_MISMATCH!>Out<CharSequence>()<!>)
|
a.foo1(<!ARGUMENT_TYPE_MISMATCH!>Out<CharSequence>()<!>)
|
||||||
a.foo1<Out<CharSequence>>(<!ARGUMENT_TYPE_MISMATCH!>Out()<!>)
|
a.foo1<<!UPPER_BOUND_VIOLATED!>Out<CharSequence><!>>(<!ARGUMENT_TYPE_MISMATCH!>Out()<!>)
|
||||||
|
|
||||||
a.foo1(Out())
|
a.foo1(Out())
|
||||||
a.foo1(Out<Nothing>())
|
a.foo1(Out<Nothing>())
|
||||||
|
|
||||||
a.foo2(Inv())
|
a.foo2(Inv())
|
||||||
a.foo2(<!ARGUMENT_TYPE_MISMATCH!>Inv<CharSequence>()<!>)
|
a.foo2(<!ARGUMENT_TYPE_MISMATCH!>Inv<CharSequence>()<!>)
|
||||||
a.foo2<Inv<CharSequence>>(<!ARGUMENT_TYPE_MISMATCH!>Inv()<!>)
|
a.foo2<<!UPPER_BOUND_VIOLATED!>Inv<CharSequence><!>>(<!ARGUMENT_TYPE_MISMATCH!>Inv()<!>)
|
||||||
|
|
||||||
a.foo3(In())
|
a.foo3(In())
|
||||||
a.foo3(In<CharSequence>())
|
a.foo3(In<CharSequence>())
|
||||||
@@ -32,11 +32,11 @@ fun foo2(a: A<out CharSequence>, b: A<in CharSequence>) {
|
|||||||
|
|
||||||
b.foo2(Inv())
|
b.foo2(Inv())
|
||||||
b.foo2(<!ARGUMENT_TYPE_MISMATCH!>Inv<CharSequence>()<!>)
|
b.foo2(<!ARGUMENT_TYPE_MISMATCH!>Inv<CharSequence>()<!>)
|
||||||
b.foo2<Inv<CharSequence>>(<!ARGUMENT_TYPE_MISMATCH!>Inv()<!>)
|
b.foo2<<!UPPER_BOUND_VIOLATED!>Inv<CharSequence><!>>(<!ARGUMENT_TYPE_MISMATCH!>Inv()<!>)
|
||||||
|
|
||||||
|
|
||||||
b.foo3(<!ARGUMENT_TYPE_MISMATCH!>In<CharSequence>()<!>)
|
b.foo3(<!ARGUMENT_TYPE_MISMATCH!>In<CharSequence>()<!>)
|
||||||
b.foo3<In<CharSequence>>(<!ARGUMENT_TYPE_MISMATCH!>In()<!>)
|
b.foo3<<!UPPER_BOUND_VIOLATED!>In<CharSequence><!>>(<!ARGUMENT_TYPE_MISMATCH!>In()<!>)
|
||||||
|
|
||||||
b.foo3(In<Any?>())
|
b.foo3(In<Any?>())
|
||||||
b.foo3(In())
|
b.foo3(In())
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
interface Trait<N : Number>
|
|
||||||
|
|
||||||
object O1 : Trait<Int>
|
|
||||||
|
|
||||||
object O2 : Trait<String>
|
|
||||||
|
|
||||||
class C {
|
|
||||||
companion object : Trait<IntRange>
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
interface Trait<N : Number>
|
interface Trait<N : Number>
|
||||||
|
|
||||||
object O1 : Trait<Int>
|
object O1 : Trait<Int>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// FIR_IDENTICAL
|
// FIR_IDENTICAL
|
||||||
// FIR_IDE_IGNORE
|
|
||||||
// !DIAGNOSTICS: -REDECLARATION -DUPLICATE_CLASS_NAMES
|
// !DIAGNOSTICS: -REDECLARATION -DUPLICATE_CLASS_NAMES
|
||||||
|
|
||||||
class C {
|
class C {
|
||||||
|
|||||||
+1
-1
@@ -21,6 +21,6 @@ object<!SYNTAX!><!> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<!UPPER_BOUND_VIOLATED!>enum class<!SYNTAX!><!> {}<!>
|
enum class<!SYNTAX!><!> {}
|
||||||
|
|
||||||
annotation class<!SYNTAX!><!> {}
|
annotation class<!SYNTAX!><!> {}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ abstract class Wrapper<T: A>(protected val t: T)
|
|||||||
class MyWrapper(a: A): Wrapper<A>(a)
|
class MyWrapper(a: A): Wrapper<A>(a)
|
||||||
|
|
||||||
// This wrapper is not legal
|
// This wrapper is not legal
|
||||||
class TheirWrapper(e: E): Wrapper<E>(<!ARGUMENT_TYPE_MISMATCH!>e<!>)
|
class TheirWrapper(e: E): Wrapper<<!UPPER_BOUND_VIOLATED!>E<!>>(<!ARGUMENT_TYPE_MISMATCH!>e<!>)
|
||||||
|
|
||||||
data class Pair<out T>(val a: T, val b: T)
|
data class Pair<out T>(val a: T, val b: T)
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class E
|
|||||||
class MyWrapper(a: A): Wrapper<A>(a)
|
class MyWrapper(a: A): Wrapper<A>(a)
|
||||||
|
|
||||||
// This wrapper is not legal
|
// This wrapper is not legal
|
||||||
class TheirWrapper(e: E): Wrapper<E>(<!ARGUMENT_TYPE_MISMATCH!>e<!>)
|
class TheirWrapper(e: E): Wrapper<<!UPPER_BOUND_VIOLATED!>E<!>>(<!ARGUMENT_TYPE_MISMATCH!>e<!>)
|
||||||
|
|
||||||
data class Pair<out T>(val a: T, val b: T)
|
data class Pair<out T>(val a: T, val b: T)
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ fun testA(a: A<*, *>) {
|
|||||||
a.t().checkType { _<A<*, *>>() }
|
a.t().checkType { _<A<*, *>>() }
|
||||||
}
|
}
|
||||||
|
|
||||||
interface B<R, T: B<List<R>, T>> {
|
interface B<R, T: B<List<R>, <!UPPER_BOUND_VIOLATED!>T<!>>> {
|
||||||
fun r(): R
|
fun r(): R
|
||||||
fun t(): T
|
fun t(): T
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@ class Num<T: Number>(val x: T)
|
|||||||
typealias N<T> = Num<T>
|
typealias N<T> = Num<T>
|
||||||
typealias N2<T> = N<T>
|
typealias N2<T> = N<T>
|
||||||
|
|
||||||
val x1 = Num<String>(<!ARGUMENT_TYPE_MISMATCH!>""<!>)
|
val x1 = Num<<!UPPER_BOUND_VIOLATED!>String<!>>(<!ARGUMENT_TYPE_MISMATCH!>""<!>)
|
||||||
val x2 = N<String>("")
|
val x2 = N<String>("")
|
||||||
val x3 = N2<String>("")
|
val x3 = N2<String>("")
|
||||||
|
|
||||||
@@ -12,6 +12,6 @@ class TColl<T, C : Collection<T>>
|
|||||||
typealias TC<T, C> = TColl<T, C>
|
typealias TC<T, C> = TColl<T, C>
|
||||||
typealias TC2<T, C> = TC<T, C>
|
typealias TC2<T, C> = TC<T, C>
|
||||||
|
|
||||||
val y1 = TColl<Any, <!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Any<!>>()
|
val y1 = TColl<Any, <!UPPER_BOUND_VIOLATED!>Any<!>>()
|
||||||
val y2 = TC<Any, Any>()
|
val y2 = TC<Any, Any>()
|
||||||
val y3 = TC2<Any, Any>()
|
val y3 = TC2<Any, Any>()
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
open class Case1<K : Number> {
|
open class Case1<K : Number> {
|
||||||
open inner class Case1_1<L>: Case1<Int>() where L : CharSequence {
|
open inner class Case1_1<L>: Case1<Int>() where L : CharSequence {
|
||||||
inner class Case1_2<M>: <!UPPER_BOUND_VIOLATED!>Case1<K>.Case1_1<M><!>() where M : Map<K, L> {
|
inner class Case1_2<M>: Case1<K>.Case1_1<<!UPPER_BOUND_VIOLATED!>M<!>>() where M : Map<K, L> {
|
||||||
inline fun <reified T>case_1(x: Any?) {
|
inline fun <reified T>case_1(x: Any?) {
|
||||||
x as M
|
x as M
|
||||||
x as L
|
x as L
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
open class Case1<K : Number> {
|
open class Case1<K : Number> {
|
||||||
open inner class Case1_1<L>: Case1<Int>() where L : CharSequence {
|
open inner class Case1_1<L>: Case1<Int>() where L : CharSequence {
|
||||||
inner class Case1_2<M>: <!UPPER_BOUND_VIOLATED!>Case1<K>.Case1_1<M><!>() where M : Map<K, L> {
|
inner class Case1_2<M>: Case1<K>.Case1_1<<!UPPER_BOUND_VIOLATED!>M<!>>() where M : Map<K, L> {
|
||||||
inline fun <reified T>case_1(x: Any?) {
|
inline fun <reified T>case_1(x: Any?) {
|
||||||
x as M
|
x as M
|
||||||
x as L
|
x as L
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
open class Case1<K : Number> {
|
open class Case1<K : Number> {
|
||||||
open inner class Case1_1<L>: Case1<Int>() where L : CharSequence {
|
open inner class Case1_1<L>: Case1<Int>() where L : CharSequence {
|
||||||
inner class Case1_2<M>: <!UPPER_BOUND_VIOLATED!>Case1<K>.Case1_1<M><!>() where M : Map<K, L> {
|
inner class Case1_2<M>: Case1<K>.Case1_1<<!UPPER_BOUND_VIOLATED!>M<!>>() where M : Map<K, L> {
|
||||||
inline fun <reified T>case_1(x: Any?) {
|
inline fun <reified T>case_1(x: Any?) {
|
||||||
x as M
|
x as M
|
||||||
x as L
|
x as L
|
||||||
|
|||||||
Vendored
+4
-2
@@ -1,10 +1,12 @@
|
|||||||
|
// EXPECTED_DUPLICATED_HIGHLIGHTING
|
||||||
open class A {}
|
open class A {}
|
||||||
open class B<T : A>()
|
open class B<T : A>()
|
||||||
|
|
||||||
class Pair<A, B>
|
class Pair<A, B>
|
||||||
|
|
||||||
abstract class C<T : B<Int>, X : (B<Char>) -> Pair<B<Any>, B<A>>>() : <error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'A'">B<Any></error>() { // 2 errors
|
abstract class C<T : B<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'A'">Int</error>>, X : (B<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'A'"><error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'A'">Char</error></error>>) -> Pair<B<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'A'">Any</error>>, B<A>>>() : B<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'A'">Any</error>>() { // 2 errors
|
||||||
val a = B<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'A'">Char</error>>() // error
|
val a = B<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'A'">Char</error>>() // error
|
||||||
|
|
||||||
abstract val x : (B<Char>) -> B<Any>
|
abstract val x : (B<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'A'"><error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'A'">Char</error></error>>) -> B<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'A'">Any</error>>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -6,10 +6,10 @@
|
|||||||
class C : A<C>()
|
class C : A<C>()
|
||||||
|
|
||||||
val a = B<C>()
|
val a = B<C>()
|
||||||
val a1 = B<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'A<TypeVariable(X)>'">Int</error>>()
|
val a1 = B<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'A<kotlin/Int>'">Int</error>>()
|
||||||
|
|
||||||
class X<A, B : A>()
|
class X<A, B : A>()
|
||||||
|
|
||||||
val b = X<Any, X<A<C>, C>>()
|
val b = X<Any, X<A<C>, C>>()
|
||||||
val b0 = X<Any, <error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'kotlin/Any'">Any?</error>>()
|
val b0 = X<Any, <error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'kotlin/Any'">Any?</error>>()
|
||||||
val b1 = X<Any, <error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'A<C>'">X<A<C>, String></error>>()
|
val b1 = X<Any, X<A<C>, <error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'A<C>'">String</error>>>()
|
||||||
|
|||||||
+5
-5
@@ -30,8 +30,8 @@ class Test1<T>()
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
Test1<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'Jet87/A'">B</error>>()
|
Test1<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'it(Jet87/A & Jet87/B)'">B</error>>()
|
||||||
Test1<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'Jet87/B'">A</error>>()
|
Test1<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'it(Jet87/A & Jet87/B)'">A</error>>()
|
||||||
Test1<C>()
|
Test1<C>()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ class Foo() {}
|
|||||||
|
|
||||||
class Bar<T : Foo>
|
class Bar<T : Foo>
|
||||||
|
|
||||||
class Buzz<T> where T : Bar<Int>, T : <error descr="[UNRESOLVED_REFERENCE] Unresolved reference: nioho">nioho</error>
|
class Buzz<T> where T : Bar<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'Jet87/Foo'">Int</error>>, T : <error descr="[UNRESOLVED_REFERENCE] Unresolved reference: nioho">nioho</error>
|
||||||
|
|
||||||
class X<T : Foo>
|
class X<T : Foo>
|
||||||
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>
|
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>
|
||||||
@@ -56,8 +56,8 @@ fun <T> test2(t : T)
|
|||||||
t.bar()
|
t.bar()
|
||||||
}
|
}
|
||||||
|
|
||||||
val t1 = test2<A>(<error descr="[ARGUMENT_TYPE_MISMATCH] Argument type mismatch: actual type is Jet87/A but T was expected">A()</error>)
|
val t1 = test2<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'it(Jet87/A & Jet87/B)'">A</error>>(<error descr="[ARGUMENT_TYPE_MISMATCH] Argument type mismatch: actual type is Jet87/A but T was expected">A()</error>)
|
||||||
val t2 = test2<B>(<error descr="[ARGUMENT_TYPE_MISMATCH] Argument type mismatch: actual type is Jet87/C but T was expected">C()</error>)
|
val t2 = test2<<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'it(Jet87/A & Jet87/B)'">B</error>>(<error descr="[ARGUMENT_TYPE_MISMATCH] Argument type mismatch: actual type is Jet87/C but T was expected">C()</error>)
|
||||||
val t3 = test2<C>(C())
|
val t3 = test2<C>(C())
|
||||||
|
|
||||||
val <T, B: T> Pair<T, B>.x : Int get() = 0
|
val <T, B: T> Pair<T, B>.x : Int get() = 0
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ class C {
|
|||||||
|
|
||||||
class<error descr="Name expected"> </error>{}
|
class<error descr="Name expected"> </error>{}
|
||||||
|
|
||||||
<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'kotlin/Enum<C.<no name provided>>'">enum class<error descr="Name expected"> </error>{}</error>
|
enum class<error descr="Name expected"> </error>{}
|
||||||
}
|
}
|
||||||
|
|
||||||
class C1<<error descr="Type parameter name expected">in</error>> {}
|
class C1<<error descr="Type parameter name expected">in</error>> {}
|
||||||
|
|||||||
@@ -19,6 +19,6 @@ object<error descr="Name expected"> </error>{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<error descr="[UPPER_BOUND_VIOLATED] Type argument is not within its bounds: should be subtype of 'kotlin/Enum<<no name provided>>'">enum class<error descr="Name expected"> </error>{}</error>
|
enum class<error descr="Name expected"> </error>{}
|
||||||
|
|
||||||
annotation class<error descr="Name expected"> </error>{}
|
annotation class<error descr="Name expected"> </error>{}
|
||||||
|
|||||||
Reference in New Issue
Block a user