[FIR] Fix false positive case of CANNOT_CHECK_FOR_ERASED
Restore CANNOT_CHECK_FOR_ERASED as error
This commit is contained in:
committed by
teamcityserver
parent
850d76f6bf
commit
f05436b939
+6
@@ -4095,6 +4095,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
|||||||
runTest("compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut2.kt");
|
runTest("compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("IsErasedAllowFromOut3.kt")
|
||||||
|
public void testIsErasedAllowFromOut3() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut3.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("IsErasedAllowFromOutAtClass.kt")
|
@TestMetadata("IsErasedAllowFromOutAtClass.kt")
|
||||||
public void testIsErasedAllowFromOutAtClass() throws Exception {
|
public void testIsErasedAllowFromOutAtClass() throws Exception {
|
||||||
|
|||||||
+6
@@ -4095,6 +4095,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut2.kt");
|
runTest("compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("IsErasedAllowFromOut3.kt")
|
||||||
|
public void testIsErasedAllowFromOut3() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut3.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("IsErasedAllowFromOutAtClass.kt")
|
@TestMetadata("IsErasedAllowFromOutAtClass.kt")
|
||||||
public void testIsErasedAllowFromOutAtClass() throws Exception {
|
public void testIsErasedAllowFromOutAtClass() throws Exception {
|
||||||
|
|||||||
+6
@@ -4095,6 +4095,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
|||||||
runTest("compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut2.kt");
|
runTest("compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("IsErasedAllowFromOut3.kt")
|
||||||
|
public void testIsErasedAllowFromOut3() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut3.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("IsErasedAllowFromOutAtClass.kt")
|
@TestMetadata("IsErasedAllowFromOutAtClass.kt")
|
||||||
public void testIsErasedAllowFromOutAtClass() throws Exception {
|
public void testIsErasedAllowFromOutAtClass() throws Exception {
|
||||||
|
|||||||
+1
-1
@@ -1102,7 +1102,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val CASTS_AND_IS_CHECKS by object : DiagnosticGroup("Casts and is-checks") {
|
val CASTS_AND_IS_CHECKS by object : DiagnosticGroup("Casts and is-checks") {
|
||||||
val CANNOT_CHECK_FOR_ERASED by warning<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 CAST_NEVER_SUCCEEDS by warning<KtBinaryExpressionWithTypeRHS>(PositioningStrategy.OPERATOR)
|
||||||
|
|||||||
+1
-1
@@ -590,7 +590,7 @@ object FirErrors {
|
|||||||
val USELESS_ELVIS_RIGHT_IS_NULL by warning0<KtBinaryExpression>(SourceElementPositioningStrategies.USELESS_ELVIS)
|
val USELESS_ELVIS_RIGHT_IS_NULL by warning0<KtBinaryExpression>(SourceElementPositioningStrategies.USELESS_ELVIS)
|
||||||
|
|
||||||
// Casts and is-checks
|
// Casts and is-checks
|
||||||
val CANNOT_CHECK_FOR_ERASED by warning1<PsiElement, ConeKotlinType>()
|
val CANNOT_CHECK_FOR_ERASED by error1<PsiElement, ConeKotlinType>()
|
||||||
val CAST_NEVER_SUCCEEDS by warning0<KtBinaryExpressionWithTypeRHS>(SourceElementPositioningStrategies.OPERATOR)
|
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 UNCHECKED_CAST by warning2<KtBinaryExpressionWithTypeRHS, ConeKotlinType, ConeKotlinType>(SourceElementPositioningStrategies.AS_TYPE)
|
val UNCHECKED_CAST by warning2<KtBinaryExpressionWithTypeRHS, ConeKotlinType, ConeKotlinType>(SourceElementPositioningStrategies.AS_TYPE)
|
||||||
|
|||||||
+5
-10
@@ -237,17 +237,12 @@ fun findStaticallyKnownSubtype(
|
|||||||
// If some parameters are not determined by unification, it means that these parameters are lost,
|
// If some parameters are not determined by unification, it means that these parameters are lost,
|
||||||
// let's put ConeStubType instead, so that we can only cast to something like List<*>, e.g. (a: Any) as List<*>
|
// let's put ConeStubType instead, so that we can only cast to something like List<*>, e.g. (a: Any) as List<*>
|
||||||
for (variable in variables) {
|
for (variable in variables) {
|
||||||
val value = substitution[variable]
|
val resultValue = when (val value = substitution[variable]) {
|
||||||
val resultValue = if (value == null) {
|
null -> null
|
||||||
if (!resultSubstitution.containsKey(variable)) {
|
is ConeStarProjection -> {
|
||||||
context.session.builtinTypes.nullableAnyType.type
|
ConeStubTypeForTypeVariableInSubtyping(ConeTypeVariable("", null), ConeNullability.NULLABLE)
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
}
|
||||||
} else if (value is ConeStarProjection) {
|
else -> value.type
|
||||||
ConeStubTypeForTypeVariableInSubtyping(ConeTypeVariable("", variable.toLookupTag()), ConeNullability.NULLABLE)
|
|
||||||
} else {
|
|
||||||
value.type
|
|
||||||
}
|
}
|
||||||
if (resultValue != null) {
|
if (resultValue != null) {
|
||||||
resultSubstitution[variable] = resultValue
|
resultSubstitution[variable] = resultValue
|
||||||
|
|||||||
+2
-1
@@ -606,7 +606,8 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
|
|
||||||
private fun FirTypeRef.withTypeArgumentsForBareType(argument: FirExpression, operation: FirOperation): FirTypeRef {
|
private fun FirTypeRef.withTypeArgumentsForBareType(argument: FirExpression, operation: FirOperation): FirTypeRef {
|
||||||
val type = coneTypeSafe<ConeClassLikeType>() ?: return this
|
val type = coneTypeSafe<ConeClassLikeType>() ?: return this
|
||||||
if (type.typeArguments.isNotEmpty()) return this
|
if (type.typeArguments.isNotEmpty()) return this // TODO: Incorrect for local classes.
|
||||||
|
// TODO: Check equality of size of arguments and parameters?
|
||||||
|
|
||||||
val firClass = type.lookupTag.toSymbol(session)?.fir ?: return this
|
val firClass = type.lookupTag.toSymbol(session)?.fir ?: return this
|
||||||
if (firClass.typeParameters.isEmpty()) return this
|
if (firClass.typeParameters.isEmpty()) return this
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
open class Base
|
||||||
|
class Derived<E : CharSequence> : Base()
|
||||||
|
fun f(entry: Base) = entry is Derived<out CharSequence>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun f(/*0*/ entry: Base): kotlin.Boolean
|
||||||
|
|
||||||
|
public open class Base {
|
||||||
|
public constructor Base()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Derived</*0*/ E : kotlin.CharSequence> : Base {
|
||||||
|
public constructor Derived</*0*/ E : kotlin.CharSequence>()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+8
-3
@@ -6,11 +6,11 @@ fun <E> foo(x: Any, y: Any) : Any {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (1 == 2) {
|
if (1 == 2) {
|
||||||
x <!UNCHECKED_CAST!>as C<!>
|
x as C
|
||||||
}
|
}
|
||||||
|
|
||||||
if (2 == 3) {
|
if (2 == 3) {
|
||||||
x <!UNCHECKED_CAST!>as? C<!>
|
x as? C
|
||||||
}
|
}
|
||||||
|
|
||||||
class Outer<F> {
|
class Outer<F> {
|
||||||
@@ -22,7 +22,12 @@ fun <E> foo(x: Any, y: Any) : Any {
|
|||||||
return y
|
return y
|
||||||
}
|
}
|
||||||
|
|
||||||
y <!UNCHECKED_CAST!>as Outer<*>.Inner<!>
|
if (y is Outer<*>.Inner) {
|
||||||
|
return y
|
||||||
|
}
|
||||||
|
|
||||||
|
y as Outer<*>.Inner
|
||||||
|
y as Outer.Inner
|
||||||
|
|
||||||
return C()
|
return C()
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -22,7 +22,12 @@ fun <E> foo(x: Any, y: Any) : Any {
|
|||||||
return y
|
return y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (y is <!CANNOT_CHECK_FOR_ERASED!>Outer<*>.Inner<!>) {
|
||||||
|
return y
|
||||||
|
}
|
||||||
|
|
||||||
y <!UNCHECKED_CAST!>as Outer<*>.Inner<!>
|
y <!UNCHECKED_CAST!>as Outer<*>.Inner<!>
|
||||||
|
y <!USELESS_CAST!>as <!NO_TYPE_ARGUMENTS_ON_RHS!>Outer.Inner<!><!>
|
||||||
|
|
||||||
return C()
|
return C()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
class Base<in T>
|
class Base<in T>
|
||||||
class Qwe<T : Any>(val a: T?) {
|
class Qwe<T : Any>(val a: T?) {
|
||||||
fun test1(obj: Any) {
|
fun test1(obj: Any) {
|
||||||
obj <!UNCHECKED_CAST!>as Qwe<T><!>
|
obj as Qwe<T>
|
||||||
check(obj.a)
|
check(obj.a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Generated
+6
@@ -4101,6 +4101,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut2.kt");
|
runTest("compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("IsErasedAllowFromOut3.kt")
|
||||||
|
public void testIsErasedAllowFromOut3() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/cast/IsErasedAllowFromOut3.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("IsErasedAllowFromOutAtClass.kt")
|
@TestMetadata("IsErasedAllowFromOutAtClass.kt")
|
||||||
public void testIsErasedAllowFromOutAtClass() throws Exception {
|
public void testIsErasedAllowFromOutAtClass() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user