[FIR] Add CAST_NEVER_SUCCEEDS
This commit is contained in:
committed by
TeamCityServer
parent
4ca757446a
commit
2b5524b18f
+6
@@ -3104,6 +3104,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.CAST_NEVER_SUCCEEDS) { firDiagnostic ->
|
||||||
|
CastNeverSucceedsImpl(
|
||||||
|
firDiagnostic as FirPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.USELESS_CAST) { firDiagnostic ->
|
add(FirErrors.USELESS_CAST) { firDiagnostic ->
|
||||||
UselessCastImpl(
|
UselessCastImpl(
|
||||||
firDiagnostic as KtPsiDiagnostic,
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
|||||||
+4
@@ -2173,6 +2173,10 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
abstract val type: KtType
|
abstract val type: KtType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class CastNeverSucceeds : KtFirDiagnostic<KtBinaryExpressionWithTypeRHS>() {
|
||||||
|
override val diagnosticClass get() = CastNeverSucceeds::class
|
||||||
|
}
|
||||||
|
|
||||||
abstract class UselessCast : KtFirDiagnostic<KtBinaryExpressionWithTypeRHS>() {
|
abstract class UselessCast : KtFirDiagnostic<KtBinaryExpressionWithTypeRHS>() {
|
||||||
override val diagnosticClass get() = UselessCast::class
|
override val diagnosticClass get() = UselessCast::class
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -2618,6 +2618,13 @@ internal class CannotCheckForErasedImpl(
|
|||||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class CastNeverSucceedsImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.CastNeverSucceeds(), KtAbstractFirDiagnostic<KtBinaryExpressionWithTypeRHS> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
internal class UselessCastImpl(
|
internal class UselessCastImpl(
|
||||||
override val firDiagnostic: KtPsiDiagnostic,
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ fun test_1(b: B<String, Number>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test_2(s: String) {
|
fun test_2(s: String) {
|
||||||
val func = { s.length } as B<Int, Int>
|
val func = { s.length } <!CAST_NEVER_SUCCEEDS!>as<!> B<Int, Int>
|
||||||
}
|
}
|
||||||
|
|
||||||
class B<out K, V>(val k: K, val v: V)
|
class B<out K, V>(val k: K, val v: V)
|
||||||
|
|||||||
+1
@@ -1105,6 +1105,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
val CANNOT_CHECK_FOR_ERASED by error<PsiElement> {
|
val CANNOT_CHECK_FOR_ERASED by error<PsiElement> {
|
||||||
parameter<ConeKotlinType>("type")
|
parameter<ConeKotlinType>("type")
|
||||||
}
|
}
|
||||||
|
val CAST_NEVER_SUCCEEDS by warning<KtBinaryExpressionWithTypeRHS>(PositioningStrategy.OPERATOR)
|
||||||
val USELESS_CAST by warning<KtBinaryExpressionWithTypeRHS>(PositioningStrategy.AS_TYPE)
|
val USELESS_CAST by warning<KtBinaryExpressionWithTypeRHS>(PositioningStrategy.AS_TYPE)
|
||||||
val USELESS_IS_CHECK by warning<KtElement> {
|
val USELESS_IS_CHECK by warning<KtElement> {
|
||||||
parameter<Boolean>("compileTimeCheckResult")
|
parameter<Boolean>("compileTimeCheckResult")
|
||||||
|
|||||||
@@ -591,6 +591,7 @@ object FirErrors {
|
|||||||
|
|
||||||
// Casts and is-checks
|
// Casts and is-checks
|
||||||
val CANNOT_CHECK_FOR_ERASED by error1<PsiElement, ConeKotlinType>()
|
val CANNOT_CHECK_FOR_ERASED by error1<PsiElement, ConeKotlinType>()
|
||||||
|
val CAST_NEVER_SUCCEEDS by warning0<KtBinaryExpressionWithTypeRHS>(SourceElementPositioningStrategies.OPERATOR)
|
||||||
val USELESS_CAST by warning0<KtBinaryExpressionWithTypeRHS>(SourceElementPositioningStrategies.AS_TYPE)
|
val USELESS_CAST by warning0<KtBinaryExpressionWithTypeRHS>(SourceElementPositioningStrategies.AS_TYPE)
|
||||||
val USELESS_IS_CHECK by warning1<KtElement, Boolean>()
|
val USELESS_IS_CHECK by warning1<KtElement, Boolean>()
|
||||||
val IS_ENUM_ENTRY by error0<KtTypeReference>()
|
val IS_ENUM_ENTRY by error0<KtTypeReference>()
|
||||||
|
|||||||
+1
-1
@@ -132,7 +132,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
|
|||||||
override val typeOperatorCallCheckers: Set<FirTypeOperatorCallChecker>
|
override val typeOperatorCallCheckers: Set<FirTypeOperatorCallChecker>
|
||||||
get() = setOf(
|
get() = setOf(
|
||||||
FirUselessTypeOperationCallChecker,
|
FirUselessTypeOperationCallChecker,
|
||||||
FirCannotCheckForErasedChecker
|
FirCastOperatorsChecker
|
||||||
)
|
)
|
||||||
|
|
||||||
override val resolvedQualifierCheckers: Set<FirResolvedQualifierChecker>
|
override val resolvedQualifierCheckers: Set<FirResolvedQualifierChecker>
|
||||||
|
|||||||
+87
-2
@@ -5,19 +5,104 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.analysis.checkers
|
package org.jetbrains.kotlin.fir.analysis.checkers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.isInterface
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.defaultType
|
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||||
import org.jetbrains.kotlin.fir.resolve.platformClassMapper
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.platformClassMapper
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.typeContext
|
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeChecker.findCorrespondingSupertypes
|
import org.jetbrains.kotlin.types.AbstractTypeChecker.findCorrespondingSupertypes
|
||||||
import org.jetbrains.kotlin.types.model.typeConstructor
|
import org.jetbrains.kotlin.types.model.typeConstructor
|
||||||
|
|
||||||
|
fun isCastPossible(
|
||||||
|
lhsType: ConeKotlinType,
|
||||||
|
rhsType: ConeKotlinType,
|
||||||
|
isSafeCase: Boolean,
|
||||||
|
context: CheckerContext
|
||||||
|
): Boolean {
|
||||||
|
val lhsLowerType = lhsType.lowerBoundIfFlexible()
|
||||||
|
val rhsLowerType = rhsType.lowerBoundIfFlexible()
|
||||||
|
val session = context.session
|
||||||
|
|
||||||
|
if (lhsLowerType is ConeIntersectionType) {
|
||||||
|
var result = false
|
||||||
|
for (intersectedType in lhsLowerType.intersectedTypes) {
|
||||||
|
val isIntersectedCastPossible = isCastPossible(intersectedType, rhsLowerType, isSafeCase, context)
|
||||||
|
val intersectedTypeSymbol = intersectedType.toRegularClassSymbol(context.session)
|
||||||
|
if (intersectedTypeSymbol?.isInterface == false && !isIntersectedCastPossible) {
|
||||||
|
return false // Any class type in intersection type should be subtype of RHS
|
||||||
|
}
|
||||||
|
result = result or isIntersectedCastPossible
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
val lhsNullable = lhsLowerType.canBeNull
|
||||||
|
val rhsNullable = rhsLowerType.canBeNull
|
||||||
|
if (lhsLowerType.isNothing) return true
|
||||||
|
if (lhsLowerType.isNullableNothing && !rhsNullable) {
|
||||||
|
return isSafeCase
|
||||||
|
}
|
||||||
|
if (rhsLowerType.isNothing) return false
|
||||||
|
if (rhsLowerType.isNullableNothing) return lhsNullable
|
||||||
|
if (lhsNullable && rhsNullable) return true
|
||||||
|
val lhsClassSymbol = lhsLowerType.toRegularClassSymbol(context.session)
|
||||||
|
val rhsClassSymbol = rhsLowerType.toRegularClassSymbol(context.session)
|
||||||
|
if (isRelated(lhsLowerType, rhsLowerType, lhsClassSymbol, rhsClassSymbol, context)) return true
|
||||||
|
// This is an oversimplification (which does not render the method incomplete):
|
||||||
|
// we consider any type parameter capable of taking any value, which may be made more precise if we considered bounds
|
||||||
|
if (lhsLowerType is ConeTypeParameterType || rhsLowerType is ConeTypeParameterType) return true
|
||||||
|
|
||||||
|
if (isFinal(lhsLowerType, session) || isFinal(rhsLowerType, session)) return false
|
||||||
|
if (lhsClassSymbol?.isInterface == true || rhsClassSymbol?.isInterface == true) return true
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Two types are related, roughly, when one of them is a subtype of the other constructing class
|
||||||
|
*
|
||||||
|
* Note that some types have platform-specific counterparts, i.e. kotlin.String is mapped to java.lang.String,
|
||||||
|
* such types (and all their sub- and supertypes) are related too.
|
||||||
|
*
|
||||||
|
* Due to limitations in PlatformToKotlinClassMap, we only consider mapping of platform classes to Kotlin classed
|
||||||
|
* (i.e. java.lang.String -> kotlin.String) and ignore mappings that go the other way.
|
||||||
|
*/
|
||||||
|
private fun isRelated(
|
||||||
|
aType: ConeKotlinType,
|
||||||
|
bType: ConeKotlinType,
|
||||||
|
aClassSymbol: FirRegularClassSymbol?,
|
||||||
|
bClassSymbol: FirRegularClassSymbol?,
|
||||||
|
context: CheckerContext
|
||||||
|
): Boolean {
|
||||||
|
val typeContext = context.session.typeContext
|
||||||
|
|
||||||
|
if (AbstractTypeChecker.isSubtypeOf(typeContext, aType, bType) ||
|
||||||
|
AbstractTypeChecker.isSubtypeOf(typeContext, bType, aType)
|
||||||
|
) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getCorrespondingKotlinClass(type: ConeKotlinType): ConeKotlinType {
|
||||||
|
return context.session.platformClassMapper.getCorrespondingKotlinClass(type.classId)?.defaultType(listOf()) ?: type
|
||||||
|
}
|
||||||
|
|
||||||
|
val aNormalizedType = getCorrespondingKotlinClass(aClassSymbol?.defaultType() ?: aType)
|
||||||
|
val bNormalizedType = getCorrespondingKotlinClass(bClassSymbol?.defaultType() ?: bType)
|
||||||
|
|
||||||
|
return AbstractTypeChecker.isSubtypeOf(typeContext, aNormalizedType, bNormalizedType) ||
|
||||||
|
AbstractTypeChecker.isSubtypeOf(typeContext, bNormalizedType, aNormalizedType)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isFinal(type: ConeKotlinType, session: FirSession): Boolean {
|
||||||
|
return !type.canHaveSubtypes(session)
|
||||||
|
}
|
||||||
|
|
||||||
fun isCastErased(supertype: ConeKotlinType, subtype: ConeKotlinType, context: CheckerContext): Boolean {
|
fun isCastErased(supertype: ConeKotlinType, subtype: ConeKotlinType, context: CheckerContext): Boolean {
|
||||||
val typeContext = context.session.typeContext
|
val typeContext = context.session.typeContext
|
||||||
|
|
||||||
|
|||||||
-31
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.expression
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.isCastErased
|
|
||||||
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.expressions.FirOperation
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirTypeOperatorCall
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
|
||||||
|
|
||||||
object FirCannotCheckForErasedChecker : FirTypeOperatorCallChecker() {
|
|
||||||
override fun check(expression: FirTypeOperatorCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
|
||||||
if (expression.operation != FirOperation.IS) return
|
|
||||||
|
|
||||||
val session = context.session
|
|
||||||
val subjectType = expression.argumentList.arguments[0].typeRef.coneType.fullyExpandedType(session)
|
|
||||||
val conversionTypeRef = expression.conversionTypeRef
|
|
||||||
val targetType = conversionTypeRef.coneType.fullyExpandedType(session)
|
|
||||||
|
|
||||||
if (isCastErased(subjectType, targetType, context)) {
|
|
||||||
reporter.reportOn(conversionTypeRef.source, FirErrors.CANNOT_CHECK_FOR_ERASED, targetType, context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+2
-2
@@ -5,13 +5,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.CastingType
|
import org.jetbrains.kotlin.fir.analysis.checkers.CastingType
|
||||||
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.isCastErased
|
import org.jetbrains.kotlin.fir.analysis.checkers.isCastErased
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.checkCasting
|
import org.jetbrains.kotlin.fir.analysis.checkers.checkCasting
|
||||||
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.expressions.FirExpressionWithSmartcast
|
import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirOperation
|
import org.jetbrains.kotlin.fir.expressions.FirOperation
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirTypeOperatorCall
|
import org.jetbrains.kotlin.fir.expressions.FirTypeOperatorCall
|
||||||
|
|||||||
+1
@@ -725,6 +725,7 @@ object PositioningStrategies {
|
|||||||
override fun mark(element: KtExpression): List<TextRange> {
|
override fun mark(element: KtExpression): List<TextRange> {
|
||||||
return when (element) {
|
return when (element) {
|
||||||
is KtBinaryExpression -> mark(element.operationReference)
|
is KtBinaryExpression -> mark(element.operationReference)
|
||||||
|
is KtBinaryExpressionWithTypeRHS -> mark(element.operationReference)
|
||||||
is KtUnaryExpression -> mark(element.operationReference)
|
is KtUnaryExpression -> mark(element.operationReference)
|
||||||
else -> super.mark(element)
|
else -> super.mark(element)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -32,11 +32,11 @@ fun test() {
|
|||||||
checkSubtype<Double>(<!ARGUMENT_TYPE_MISMATCH!>1<!>)
|
checkSubtype<Double>(<!ARGUMENT_TYPE_MISMATCH!>1<!>)
|
||||||
checkSubtype<Float>(<!ARGUMENT_TYPE_MISMATCH!>1<!>)
|
checkSubtype<Float>(<!ARGUMENT_TYPE_MISMATCH!>1<!>)
|
||||||
|
|
||||||
1 as Byte
|
1 <!CAST_NEVER_SUCCEEDS!>as<!> Byte
|
||||||
1 <!USELESS_CAST!>as Int<!>
|
1 <!USELESS_CAST!>as Int<!>
|
||||||
0xff as Long
|
0xff <!CAST_NEVER_SUCCEEDS!>as<!> Long
|
||||||
|
|
||||||
1.1 as Int
|
1.1 <!CAST_NEVER_SUCCEEDS!>as<!> Int
|
||||||
checkSubtype<Int>(<!ARGUMENT_TYPE_MISMATCH!>1.1<!>)
|
checkSubtype<Int>(<!ARGUMENT_TYPE_MISMATCH!>1.1<!>)
|
||||||
|
|
||||||
varargByte(0x77, 1, 3, <!ARGUMENT_TYPE_MISMATCH!>200<!>, 0b111)
|
varargByte(0x77, 1, 3, <!ARGUMENT_TYPE_MISMATCH!>200<!>, 0b111)
|
||||||
|
|||||||
@@ -33,4 +33,4 @@ fun bar(a: Ann = <!ANNOTATION_CLASS_CONSTRUCTOR_CALL!>Ann()<!>) {
|
|||||||
operator fun String.invoke() {}
|
operator fun String.invoke() {}
|
||||||
|
|
||||||
// from stdlib
|
// from stdlib
|
||||||
fun <T> javaClass() : Class<T> = null as Class<T>
|
fun <T> javaClass() : Class<T> = null <!CAST_NEVER_SUCCEEDS!>as<!> Class<T>
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
// Nothing can be cast to Nothing
|
|
||||||
fun foo(x: String) {
|
|
||||||
x as Nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
fun gav(y: String?) {
|
|
||||||
y as Nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only nullable can be cast to Nothing?
|
|
||||||
fun bar(x: String, y: String?) {
|
|
||||||
x as Nothing?
|
|
||||||
y as Nothing?
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// Nothing can be cast to Nothing
|
// Nothing can be cast to Nothing
|
||||||
fun foo(x: String) {
|
fun foo(x: String) {
|
||||||
x <!CAST_NEVER_SUCCEEDS!>as<!> Nothing
|
x <!CAST_NEVER_SUCCEEDS!>as<!> Nothing
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
typealias MyString = String
|
|
||||||
|
|
||||||
val x: MyString = ""
|
|
||||||
val y = x as Any
|
|
||||||
|
|
||||||
interface Base
|
|
||||||
class Derived : Base
|
|
||||||
interface Other : Base
|
|
||||||
typealias IBase = Base
|
|
||||||
typealias IOther = Other
|
|
||||||
|
|
||||||
val ib: IBase = Derived()
|
|
||||||
val d = ib as Derived
|
|
||||||
val o = ib as Other
|
|
||||||
val io = ib as IOther
|
|
||||||
val s = d as String
|
|
||||||
val ms = d as MyString
|
|
||||||
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
typealias MyString = String
|
typealias MyString = String
|
||||||
|
|
||||||
val x: MyString = ""
|
val x: MyString = ""
|
||||||
|
|||||||
+36
-36
@@ -1,51 +1,51 @@
|
|||||||
fun asCall() {
|
fun asCall() {
|
||||||
1 <!USELESS_CAST!>as Int<!>
|
1 <!USELESS_CAST!>as Int<!>
|
||||||
1 as Byte
|
1 <!CAST_NEVER_SUCCEEDS!>as<!> Byte
|
||||||
1 as Short
|
1 <!CAST_NEVER_SUCCEEDS!>as<!> Short
|
||||||
1 as Long
|
1 <!CAST_NEVER_SUCCEEDS!>as<!> Long
|
||||||
1 as Char
|
1 <!CAST_NEVER_SUCCEEDS!>as<!> Char
|
||||||
1 as Double
|
1 <!CAST_NEVER_SUCCEEDS!>as<!> Double
|
||||||
1 as Float
|
1 <!CAST_NEVER_SUCCEEDS!>as<!> Float
|
||||||
|
|
||||||
1.0 as Int
|
1.0 <!CAST_NEVER_SUCCEEDS!>as<!> Int
|
||||||
1.0 as Byte
|
1.0 <!CAST_NEVER_SUCCEEDS!>as<!> Byte
|
||||||
1.0 as Short
|
1.0 <!CAST_NEVER_SUCCEEDS!>as<!> Short
|
||||||
1.0 as Long
|
1.0 <!CAST_NEVER_SUCCEEDS!>as<!> Long
|
||||||
1.0 as Char
|
1.0 <!CAST_NEVER_SUCCEEDS!>as<!> Char
|
||||||
1.0 <!USELESS_CAST!>as Double<!>
|
1.0 <!USELESS_CAST!>as Double<!>
|
||||||
1.0 as Float
|
1.0 <!CAST_NEVER_SUCCEEDS!>as<!> Float
|
||||||
|
|
||||||
1f as Int
|
1f <!CAST_NEVER_SUCCEEDS!>as<!> Int
|
||||||
1f as Byte
|
1f <!CAST_NEVER_SUCCEEDS!>as<!> Byte
|
||||||
1f as Short
|
1f <!CAST_NEVER_SUCCEEDS!>as<!> Short
|
||||||
1f as Long
|
1f <!CAST_NEVER_SUCCEEDS!>as<!> Long
|
||||||
1f as Char
|
1f <!CAST_NEVER_SUCCEEDS!>as<!> Char
|
||||||
1f as Double
|
1f <!CAST_NEVER_SUCCEEDS!>as<!> Double
|
||||||
1f <!USELESS_CAST!>as Float<!>
|
1f <!USELESS_CAST!>as Float<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun asSafe() {
|
fun asSafe() {
|
||||||
1 as? Int
|
1 as? Int
|
||||||
1 as? Byte
|
1 <!CAST_NEVER_SUCCEEDS!>as?<!> Byte
|
||||||
1 as? Short
|
1 <!CAST_NEVER_SUCCEEDS!>as?<!> Short
|
||||||
1 as? Long
|
1 <!CAST_NEVER_SUCCEEDS!>as?<!> Long
|
||||||
1 as? Char
|
1 <!CAST_NEVER_SUCCEEDS!>as?<!> Char
|
||||||
1 as? Double
|
1 <!CAST_NEVER_SUCCEEDS!>as?<!> Double
|
||||||
1 as? Float
|
1 <!CAST_NEVER_SUCCEEDS!>as?<!> Float
|
||||||
|
|
||||||
1.0 as? Int
|
1.0 <!CAST_NEVER_SUCCEEDS!>as?<!> Int
|
||||||
1.0 as? Byte
|
1.0 <!CAST_NEVER_SUCCEEDS!>as?<!> Byte
|
||||||
1.0 as? Short
|
1.0 <!CAST_NEVER_SUCCEEDS!>as?<!> Short
|
||||||
1.0 as? Long
|
1.0 <!CAST_NEVER_SUCCEEDS!>as?<!> Long
|
||||||
1.0 as? Char
|
1.0 <!CAST_NEVER_SUCCEEDS!>as?<!> Char
|
||||||
1.0 as? Double
|
1.0 as? Double
|
||||||
1.0 as? Float
|
1.0 <!CAST_NEVER_SUCCEEDS!>as?<!> Float
|
||||||
|
|
||||||
1f as? Int
|
1f <!CAST_NEVER_SUCCEEDS!>as?<!> Int
|
||||||
1f as? Byte
|
1f <!CAST_NEVER_SUCCEEDS!>as?<!> Byte
|
||||||
1f as? Short
|
1f <!CAST_NEVER_SUCCEEDS!>as?<!> Short
|
||||||
1f as? Long
|
1f <!CAST_NEVER_SUCCEEDS!>as?<!> Long
|
||||||
1f as? Char
|
1f <!CAST_NEVER_SUCCEEDS!>as?<!> Char
|
||||||
1f as? Double
|
1f <!CAST_NEVER_SUCCEEDS!>as?<!> Double
|
||||||
1f as? Float
|
1f as? Float
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
// !DIAGNOSTICS: -PLATFORM_CLASS_MAPPED_TO_KOTLIN -USELESS_CAST
|
|
||||||
import java.lang.String as JString
|
|
||||||
import java.lang.CharSequence as JCS
|
|
||||||
|
|
||||||
fun test(
|
|
||||||
s: String,
|
|
||||||
js: JString,
|
|
||||||
cs: CharSequence,
|
|
||||||
jcs: JCS
|
|
||||||
) {
|
|
||||||
s as JString
|
|
||||||
s as JCS
|
|
||||||
s as CharSequence
|
|
||||||
s as String
|
|
||||||
|
|
||||||
js as JString
|
|
||||||
js as JCS
|
|
||||||
js as CharSequence
|
|
||||||
js as String
|
|
||||||
|
|
||||||
cs as JString
|
|
||||||
cs as JCS
|
|
||||||
cs as CharSequence
|
|
||||||
cs as String
|
|
||||||
|
|
||||||
jcs as JString
|
|
||||||
jcs as JCS
|
|
||||||
jcs as CharSequence
|
|
||||||
jcs as String
|
|
||||||
|
|
||||||
jcs as Int
|
|
||||||
s as java.lang.Integer
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !DIAGNOSTICS: -PLATFORM_CLASS_MAPPED_TO_KOTLIN -USELESS_CAST
|
// !DIAGNOSTICS: -PLATFORM_CLASS_MAPPED_TO_KOTLIN -USELESS_CAST
|
||||||
import java.lang.String as JString
|
import java.lang.String as JString
|
||||||
import java.lang.CharSequence as JCS
|
import java.lang.CharSequence as JCS
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
// !DIAGNOSTICS: -PLATFORM_CLASS_MAPPED_TO_KOTLIN -UNUSED_PARAMETER -ABSTRACT_MEMBER_NOT_IMPLEMENTED -USELESS_CAST
|
|
||||||
import java.lang.CharSequence as JCS
|
|
||||||
|
|
||||||
class JSub: JCS
|
|
||||||
class Sub: CharSequence
|
|
||||||
|
|
||||||
fun test(
|
|
||||||
s: Sub,
|
|
||||||
js: JSub,
|
|
||||||
cs: CharSequence,
|
|
||||||
jcs: JCS
|
|
||||||
) {
|
|
||||||
// js as CharSequence // - this case is not supported due to limitation in PlatformToKotlinClassMap
|
|
||||||
js as JCS
|
|
||||||
|
|
||||||
s as CharSequence
|
|
||||||
s as JCS
|
|
||||||
|
|
||||||
js as Sub
|
|
||||||
s as JSub
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !DIAGNOSTICS: -PLATFORM_CLASS_MAPPED_TO_KOTLIN -UNUSED_PARAMETER -ABSTRACT_MEMBER_NOT_IMPLEMENTED -USELESS_CAST
|
// !DIAGNOSTICS: -PLATFORM_CLASS_MAPPED_TO_KOTLIN -UNUSED_PARAMETER -ABSTRACT_MEMBER_NOT_IMPLEMENTED -USELESS_CAST
|
||||||
import java.lang.CharSequence as JCS
|
import java.lang.CharSequence as JCS
|
||||||
|
|
||||||
|
|||||||
-34
@@ -1,34 +0,0 @@
|
|||||||
// !DIAGNOSTICS: -UNCHECKED_CAST
|
|
||||||
interface Trait1
|
|
||||||
interface Trait2
|
|
||||||
open class OClass1
|
|
||||||
open class OClass2
|
|
||||||
class FClass1
|
|
||||||
class FClass2
|
|
||||||
|
|
||||||
fun <TP1: OClass1, TP2: OClass2> test(
|
|
||||||
t1: Trait1,
|
|
||||||
oc1: OClass1,
|
|
||||||
fc1: FClass1,
|
|
||||||
tp1: TP1
|
|
||||||
) {
|
|
||||||
t1 as Trait2
|
|
||||||
t1 as OClass2
|
|
||||||
t1 as FClass2
|
|
||||||
t1 as TP2
|
|
||||||
|
|
||||||
oc1 as Trait2
|
|
||||||
oc1 as OClass2
|
|
||||||
oc1 as FClass2
|
|
||||||
oc1 as TP2
|
|
||||||
|
|
||||||
fc1 as Trait2
|
|
||||||
fc1 as OClass2
|
|
||||||
fc1 as FClass2
|
|
||||||
fc1 as TP2
|
|
||||||
|
|
||||||
tp1 as Trait2
|
|
||||||
tp1 as OClass2
|
|
||||||
tp1 as FClass2
|
|
||||||
tp1 as TP2
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !DIAGNOSTICS: -UNCHECKED_CAST
|
// !DIAGNOSTICS: -UNCHECKED_CAST
|
||||||
interface Trait1
|
interface Trait1
|
||||||
interface Trait2
|
interface Trait2
|
||||||
|
|||||||
+17
-17
@@ -19,35 +19,35 @@ class Inv<T>() {
|
|||||||
|
|
||||||
fun testInOut() {
|
fun testInOut() {
|
||||||
In<String>().f("1");
|
In<String>().f("1");
|
||||||
(null as In<in String>).f("1")
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> In<in String>).f("1")
|
||||||
(null as In<*>).<!NONE_APPLICABLE!>f<!>("1") // Wrong Arg
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> In<*>).<!NONE_APPLICABLE!>f<!>("1") // Wrong Arg
|
||||||
|
|
||||||
In<String>().f(1);
|
In<String>().f(1);
|
||||||
(null as In<in String>).f(1)
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> In<in String>).f(1)
|
||||||
(null as In<*>).f(1);
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> In<*>).f(1);
|
||||||
|
|
||||||
Out<Int>().f(1)
|
Out<Int>().f(1)
|
||||||
(null as Out<out Int>).f(1)
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> Out<out Int>).f(1)
|
||||||
(null as Out<*>).f(1)
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> Out<*>).f(1)
|
||||||
|
|
||||||
Out<Int>().f()
|
Out<Int>().f()
|
||||||
(null as Out<out Int>).f()
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> Out<out Int>).f()
|
||||||
(null as Out<*>).f()
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> Out<*>).f()
|
||||||
|
|
||||||
Inv<Int>().f(1)
|
Inv<Int>().f(1)
|
||||||
(null as Inv<in Int>).f(1)
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<in Int>).f(1)
|
||||||
(null as Inv<out Int>).f(<!ARGUMENT_TYPE_MISMATCH!>1<!>) // !!
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<out Int>).f(<!ARGUMENT_TYPE_MISMATCH!>1<!>) // !!
|
||||||
(null as Inv<*>).f(<!ARGUMENT_TYPE_MISMATCH!>1<!>) // !!
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<*>).f(<!ARGUMENT_TYPE_MISMATCH!>1<!>) // !!
|
||||||
|
|
||||||
Inv<Int>().inf(1)
|
Inv<Int>().inf(1)
|
||||||
(null as Inv<in Int>).inf(1)
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<in Int>).inf(1)
|
||||||
(null as Inv<out Int>).inf(<!ARGUMENT_TYPE_MISMATCH!>1<!>) // !!
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<out Int>).inf(<!ARGUMENT_TYPE_MISMATCH!>1<!>) // !!
|
||||||
(null as Inv<*>).inf(<!ARGUMENT_TYPE_MISMATCH!>1<!>) // !!
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<*>).inf(<!ARGUMENT_TYPE_MISMATCH!>1<!>) // !!
|
||||||
|
|
||||||
Inv<Int>().outf()
|
Inv<Int>().outf()
|
||||||
checkSubtype<Int>(<!ARGUMENT_TYPE_MISMATCH!>(null as Inv<in Int>).outf()<!>) // Type mismatch
|
checkSubtype<Int>(<!ARGUMENT_TYPE_MISMATCH!>(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<in Int>).outf()<!>) // Type mismatch
|
||||||
(null as Inv<out Int>).outf()
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<out Int>).outf()
|
||||||
(null as Inv<*>).outf()
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> Inv<*>).outf()
|
||||||
|
|
||||||
Inv<Int>().outf(<!TOO_MANY_ARGUMENTS!>1<!>) // Wrong Arg
|
Inv<Int>().outf(<!TOO_MANY_ARGUMENTS!>1<!>) // Wrong Arg
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -9,4 +9,4 @@ fun <T> foo2(): T = TODO()
|
|||||||
val test = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo2<!>().plus("") <!USELESS_CAST!>as String<!>
|
val test = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo2<!>().plus("") <!USELESS_CAST!>as String<!>
|
||||||
|
|
||||||
fun <T> T.bar() = this
|
fun <T> T.bar() = this
|
||||||
val barTest = "".bar() as Number
|
val barTest = "".bar() <!CAST_NEVER_SUCCEEDS!>as<!> Number
|
||||||
|
|||||||
-11
@@ -1,11 +0,0 @@
|
|||||||
fun <R> runCatching(block: () -> R) = null as Result<R>
|
|
||||||
|
|
||||||
class Result<out T> {
|
|
||||||
fun getOrNull(): T? = null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun main() {
|
|
||||||
runCatching {
|
|
||||||
null
|
|
||||||
}.getOrNull() // don't report IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION
|
|
||||||
}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
fun <R> runCatching(block: () -> R) = null <!CAST_NEVER_SUCCEEDS!>as<!> Result<R>
|
fun <R> runCatching(block: () -> R) = null <!CAST_NEVER_SUCCEEDS!>as<!> Result<R>
|
||||||
|
|
||||||
class Result<out T> {
|
class Result<out T> {
|
||||||
|
|||||||
+1
-1
@@ -52,7 +52,7 @@ fun test() {
|
|||||||
if (<!USELESS_IS_CHECK!>x11 is Foo<<!UNRESOLVED_REFERENCE!>_<!>><!>) { }
|
if (<!USELESS_IS_CHECK!>x11 is Foo<<!UNRESOLVED_REFERENCE!>_<!>><!>) { }
|
||||||
|
|
||||||
x10 as <!UNRESOLVED_REFERENCE!>_<!>
|
x10 as <!UNRESOLVED_REFERENCE!>_<!>
|
||||||
x10 as Foo<<!UNRESOLVED_REFERENCE!>_<!>>
|
x10 <!CAST_NEVER_SUCCEEDS!>as<!> Foo<<!UNRESOLVED_REFERENCE!>_<!>>
|
||||||
|
|
||||||
val x12: Foo<@<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>_<!> Int>? = null
|
val x12: Foo<@<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>_<!> Int>? = null
|
||||||
val x13: Foo<@<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>_<!>() Int>? = null
|
val x13: Foo<@<!UNDERSCORE_USAGE_WITHOUT_BACKTICKS, UNRESOLVED_REFERENCE!>_<!>() Int>? = null
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
// KT-702 Type inference failed
|
|
||||||
fun <T> getJavaClass() : java.lang.Class<T> { return "" as Class<T> }
|
|
||||||
|
|
||||||
public class Throwables() {
|
|
||||||
companion object {
|
|
||||||
public fun <X : Throwable?> propagateIfInstanceOf(throwable : Throwable?, declaredType : Class<X?>?) {
|
|
||||||
if (((throwable != null) && declaredType?.isInstance(throwable)!!))
|
|
||||||
{
|
|
||||||
throw <!SAFE_CALL_WILL_CHANGE_NULLABILITY!>declaredType<!UNNECESSARY_SAFE_CALL!>?.<!>cast(throwable)<!>!!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public fun propagateIfPossible(throwable : Throwable?) {
|
|
||||||
propagateIfInstanceOf(throwable, getJavaClass<Error?>()) //; Type inference failed: Mismatch while expanding constraints
|
|
||||||
propagateIfInstanceOf(throwable, getJavaClass<RuntimeException?>()) // Type inference failed: Mismatch while expanding constraints
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// KT-702 Type inference failed
|
// KT-702 Type inference failed
|
||||||
fun <T> getJavaClass() : java.lang.Class<T> { return "" <!CAST_NEVER_SUCCEEDS!>as<!> Class<T> }
|
fun <T> getJavaClass() : java.lang.Class<T> { return "" <!CAST_NEVER_SUCCEEDS!>as<!> Class<T> }
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
class TypeInfo<T>
|
class TypeInfo<T>
|
||||||
|
|
||||||
fun <T> typeinfo() : TypeInfo<T> = null as TypeInfo<T>
|
fun <T> typeinfo() : TypeInfo<T> = null <!CAST_NEVER_SUCCEEDS!>as<!> TypeInfo<T>
|
||||||
|
|
||||||
fun <T> TypeInfo<T>.getJavaClass() : java.lang.Class<T> {
|
fun <T> TypeInfo<T>.getJavaClass() : java.lang.Class<T> {
|
||||||
val t : java.lang.Object = this as java.lang.Object
|
val t : java.lang.Object = this as java.lang.Object
|
||||||
@@ -13,4 +13,4 @@ fun <T> getJavaClass() = typeinfo<T>().getJavaClass()
|
|||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
System.out.println(getJavaClass<String>())
|
System.out.println(getJavaClass<String>())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ fun f(a: SomeClass?) {
|
|||||||
aa<!UNSAFE_CALL!>.<!>hashCode()
|
aa<!UNSAFE_CALL!>.<!>hashCode()
|
||||||
aa.<!UNRESOLVED_REFERENCE!>foo<!>
|
aa.<!UNRESOLVED_REFERENCE!>foo<!>
|
||||||
(aa as? SomeSubClass)<!UNSAFE_CALL!>.<!>foo
|
(aa as? SomeSubClass)<!UNSAFE_CALL!>.<!>foo
|
||||||
(aa as SomeSubClass).foo
|
(aa <!CAST_NEVER_SUCCEEDS!>as<!> SomeSubClass).foo
|
||||||
}
|
}
|
||||||
val b = (aa as? SomeSubClass)?.foo
|
val b = (aa as? SomeSubClass)?.foo
|
||||||
aa = null
|
aa = null
|
||||||
@@ -52,7 +52,7 @@ fun f(a: SomeClass?) {
|
|||||||
aa<!UNSAFE_CALL!>.<!>hashCode()
|
aa<!UNSAFE_CALL!>.<!>hashCode()
|
||||||
aa.<!UNRESOLVED_REFERENCE!>foo<!>
|
aa.<!UNRESOLVED_REFERENCE!>foo<!>
|
||||||
(aa as? SomeSubClass)<!UNSAFE_CALL!>.<!>foo
|
(aa as? SomeSubClass)<!UNSAFE_CALL!>.<!>foo
|
||||||
(aa as SomeSubClass).foo
|
(aa <!CAST_NEVER_SUCCEEDS!>as<!> SomeSubClass).foo
|
||||||
}
|
}
|
||||||
aa = a
|
aa = a
|
||||||
val c = aa as? SomeSubClass
|
val c = aa as? SomeSubClass
|
||||||
|
|||||||
+11
-11
@@ -4,7 +4,7 @@ fun <T : CharSequence> foo(x: Array<Any>, y: IntArray, block: (T, Int) -> Int) {
|
|||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
// comment
|
// comment
|
||||||
/* comment */
|
/* comment */
|
||||||
r = block(x[0] as T, "" as Int)
|
r = block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int)
|
||||||
|
|
||||||
// to prevent unused assignment diagnostic for the above statement
|
// to prevent unused assignment diagnostic for the above statement
|
||||||
r.hashCode()
|
r.hashCode()
|
||||||
@@ -13,42 +13,42 @@ fun <T : CharSequence> foo(x: Array<Any>, y: IntArray, block: (T, Int) -> Int) {
|
|||||||
|
|
||||||
if (i != 1) {
|
if (i != 1) {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
i += block(x[0] as T, "" as Int).toInt()
|
i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != 1)
|
if (i != 1)
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
i += block(x[0] as T, "" as Int).toInt()
|
i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||||
|
|
||||||
if (i != 2)
|
if (i != 2)
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
i += block(x[0] as T, "" as Int).toInt()
|
i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||||
else
|
else
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
i += block(x[1] as T, "" as Int).toInt()
|
i += block(x[1] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||||
|
|
||||||
while (i != 1)
|
while (i != 1)
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
i += block(x[0] as T, "" as Int).toInt()
|
i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||||
|
|
||||||
do
|
do
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
i += block(x[0] as T, "" as Int).toInt()
|
i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||||
while (i != 1)
|
while (i != 1)
|
||||||
|
|
||||||
for (j in 1..100)
|
for (j in 1..100)
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
i += block(x[0] as T, "" as Int).toInt()
|
i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||||
|
|
||||||
when (i) {
|
when (i) {
|
||||||
1 ->
|
1 ->
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
i += block(x[0] as T, "" as Int).toInt()
|
i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
val l: () -> Unit = {
|
val l: () -> Unit = {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
i += block(x[0] as T, "" as Int).toInt()
|
i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||||
}
|
}
|
||||||
l()
|
l()
|
||||||
|
|
||||||
@@ -56,5 +56,5 @@ fun <T : CharSequence> foo(x: Array<Any>, y: IntArray, block: (T, Int) -> Int) {
|
|||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
|
||||||
|
|
||||||
y[i] += block(x[0] as T, "" as Int).toInt()
|
y[i] += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -1,7 +1,7 @@
|
|||||||
fun <T : CharSequence> foo(x: Array<Any>, block: (T, Int) -> Int) {
|
fun <T : CharSequence> foo(x: Array<Any>, block: (T, Int) -> Int) {
|
||||||
var r: Any?
|
var r: Any?
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST") r = block(x[0] as T, "" as Int)
|
@Suppress("UNCHECKED_CAST") r = block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int)
|
||||||
|
|
||||||
// to prevent unused assignment diagnostic for the above statement
|
// to prevent unused assignment diagnostic for the above statement
|
||||||
r.hashCode()
|
r.hashCode()
|
||||||
@@ -9,11 +9,11 @@ fun <T : CharSequence> foo(x: Array<Any>, block: (T, Int) -> Int) {
|
|||||||
var i = 1
|
var i = 1
|
||||||
|
|
||||||
if (i != 1) {
|
if (i != 1) {
|
||||||
@Suppress("UNCHECKED_CAST") i += block(x[0] as T, "" as Int).toInt()
|
@Suppress("UNCHECKED_CAST") i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != 1) @Suppress("UNCHECKED_CAST")
|
if (i != 1) @Suppress("UNCHECKED_CAST")
|
||||||
i += block(x[0] as T, "" as Int).toInt()
|
i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||||
|
|
||||||
if (i != 1) @Suppress("UNCHECKED_CAST") i += block(x[0] as T, "" as Int).toInt()
|
if (i != 1) @Suppress("UNCHECKED_CAST") i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,5 +8,5 @@ fun interface ReadOnlyProperty<in T, out V> {
|
|||||||
|
|
||||||
class Problem {
|
class Problem {
|
||||||
val variable: Int by <!DELEGATE_SPECIAL_FUNCTION_RETURN_TYPE_MISMATCH, NEW_INFERENCE_ERROR, NEW_INFERENCE_ERROR!>delegate()<!> // delegate returns `ReadOnlyProperty<Problem, {CharSequence & Int}>`
|
val variable: Int by <!DELEGATE_SPECIAL_FUNCTION_RETURN_TYPE_MISMATCH, NEW_INFERENCE_ERROR, NEW_INFERENCE_ERROR!>delegate()<!> // delegate returns `ReadOnlyProperty<Problem, {CharSequence & Int}>`
|
||||||
fun <T : CharSequence> delegate() = null as ReadOnlyProperty<Problem, T>
|
fun <T : CharSequence> delegate() = null <!CAST_NEVER_SUCCEEDS!>as<!> ReadOnlyProperty<Problem, T>
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ fun test1(s: SubInt, sWrong: SubIntWrong) {
|
|||||||
val a = "foo"
|
val a = "foo"
|
||||||
foo(<!ARGUMENT_TYPE_MISMATCH!>a<!>)
|
foo(<!ARGUMENT_TYPE_MISMATCH!>a<!>)
|
||||||
|
|
||||||
a as (Int, String) -> String
|
a <!CAST_NEVER_SUCCEEDS!>as<!> (Int, String) -> String
|
||||||
foo(<!ARGUMENT_TYPE_MISMATCH!>a<!>)
|
foo(<!ARGUMENT_TYPE_MISMATCH!>a<!>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -37,6 +37,6 @@ fun test() {
|
|||||||
|
|
||||||
// TODO: should we allow somehow to call with passing continuation explicitly?
|
// TODO: should we allow somehow to call with passing continuation explicitly?
|
||||||
severalParams("", 89, <!TOO_MANY_ARGUMENTS!>6.9<!>) checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><Unit>() }
|
severalParams("", 89, <!TOO_MANY_ARGUMENTS!>6.9<!>) checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><Unit>() }
|
||||||
severalParams("", 89, <!TOO_MANY_ARGUMENTS!>this as Continuation<Double><!>) checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><Unit>() }
|
severalParams("", 89, <!TOO_MANY_ARGUMENTS!>this <!CAST_NEVER_SUCCEEDS!>as<!> Continuation<Double><!>) checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><Unit>() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -9,8 +9,8 @@ fun box() {
|
|||||||
val b = Array<<!REIFIED_TYPE_FORBIDDEN_SUBSTITUTION!>Nothing?<!>>(5) { null!! }
|
val b = Array<<!REIFIED_TYPE_FORBIDDEN_SUBSTITUTION!>Nothing?<!>>(5) { null!! }
|
||||||
val c = <!REIFIED_TYPE_FORBIDDEN_SUBSTITUTION!>foo<!>() { null!! }
|
val c = <!REIFIED_TYPE_FORBIDDEN_SUBSTITUTION!>foo<!>() { null!! }
|
||||||
val d = foo<Any> { null!! }
|
val d = foo<Any> { null!! }
|
||||||
val e = <!REIFIED_TYPE_FORBIDDEN_SUBSTITUTION!>foo<!> { "1" as Nothing }
|
val e = <!REIFIED_TYPE_FORBIDDEN_SUBSTITUTION!>foo<!> { "1" <!CAST_NEVER_SUCCEEDS!>as<!> Nothing }
|
||||||
val e1 = <!REIFIED_TYPE_FORBIDDEN_SUBSTITUTION!>foo<!> { "1" as Nothing? }
|
val e1 = <!REIFIED_TYPE_FORBIDDEN_SUBSTITUTION!>foo<!> { "1" <!CAST_NEVER_SUCCEEDS!>as<!> Nothing? }
|
||||||
|
|
||||||
val f = javaClass<<!REIFIED_TYPE_FORBIDDEN_SUBSTITUTION!>Nothing<!>>()
|
val f = javaClass<<!REIFIED_TYPE_FORBIDDEN_SUBSTITUTION!>Nothing<!>>()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -47,7 +47,7 @@ fun case_5(value_1: Int?) {
|
|||||||
println("!")
|
println("!")
|
||||||
contract {
|
contract {
|
||||||
returns(true) implies (value_1 != null)
|
returns(true) implies (value_1 != null)
|
||||||
} as ContractBuilder
|
} <!CAST_NEVER_SUCCEEDS!>as<!> ContractBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -93,6 +93,6 @@ fun case_9(number: Int?): Boolean {
|
|||||||
val value_1 = number != null
|
val value_1 = number != null
|
||||||
contract {
|
contract {
|
||||||
returns(false) implies (value_1)
|
returns(false) implies (value_1)
|
||||||
} as ContractBuilder
|
} <!CAST_NEVER_SUCCEEDS!>as<!> ContractBuilder
|
||||||
return number == null
|
return number == null
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -8,7 +8,7 @@ fun case_1(value_1: Int?) {
|
|||||||
println("!")
|
println("!")
|
||||||
contract {
|
contract {
|
||||||
returns(true) implies (value_1 != null)
|
returns(true) implies (value_1 != null)
|
||||||
} as ContractBuilder
|
} <!CAST_NEVER_SUCCEEDS!>as<!> ContractBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
// TESTCASE NUMBER: 2
|
// TESTCASE NUMBER: 2
|
||||||
@@ -42,6 +42,6 @@ fun case_5(number: Int?): Boolean {
|
|||||||
val value_1 = number != null
|
val value_1 = number != null
|
||||||
contract {
|
contract {
|
||||||
returns(false) implies (value_1)
|
returns(false) implies (value_1)
|
||||||
} as ContractBuilder
|
} <!CAST_NEVER_SUCCEEDS!>as<!> ContractBuilder
|
||||||
return number == null
|
return number == null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
fun case_1(x: Interface1) = x
|
fun case_1(x: Interface1) = x
|
||||||
fun case_1(x: Interface2) = x
|
fun case_1(x: Interface2) = x
|
||||||
fun case_1() {
|
fun case_1() {
|
||||||
val x: Interface1 = null as Interface1
|
val x: Interface1 = null <!CAST_NEVER_SUCCEEDS!>as<!> Interface1
|
||||||
x as Interface2
|
x as Interface2
|
||||||
<!OVERLOAD_RESOLUTION_AMBIGUITY!>case_1<!>(<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & Interface2 & Interface1")!>x<!>)
|
<!OVERLOAD_RESOLUTION_AMBIGUITY!>case_1<!>(<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & Interface2 & Interface1")!>x<!>)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user