From fd2b4fd49789eadb9f2bfc6adf9a6fda585291e5 Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Sun, 5 Jun 2022 21:53:54 +0300 Subject: [PATCH] [FIR] Fix false positive USELESS_CAST on stub types, ^KT-50293 Fixed --- .../expression/FirUselessTypeOperationCallChecker.kt | 6 +++++- .../src/org/jetbrains/kotlin/fir/types/TypeUtils.kt | 1 + .../fir/declarations/impl/FirErrorFunctionImpl.kt | 2 +- .../fir/declarations/impl/FirErrorPropertyImpl.kt | 2 +- .../fir/expressions/impl/FirErrorExpressionImpl.kt | 2 +- .../jetbrains/kotlin/fir/types/FirErrorTypeRef.kt | 1 + .../jetbrains/kotlin/fir/types/FirResolvedTypeRef.kt | 1 + .../fir/types/builder/FirResolvedTypeRefBuilder.kt | 3 +++ .../kotlin/fir/types/impl/FirResolvedTypeRefImpl.kt | 1 + .../fir/types/builder/FirErrorTypeRefBuilder.kt | 2 +- .../kotlin/fir/types/impl/FirErrorTypeRefImpl.kt | 9 +++++++-- .../fir/types/impl/FirImplicitBuiltinTypeRef.kt | 3 +++ .../kotlin/fir/tree/generator/BuilderConfigurator.kt | 1 + .../fir/tree/generator/ImplementationConfigurator.kt | 6 +++--- .../kotlin/fir/tree/generator/NodeConfigurator.kt | 1 + .../tests/inference/builderInference/kt49829.fir.kt | 12 ------------ .../tests/inference/builderInference/kt49829.kt | 5 +++-- 17 files changed, 34 insertions(+), 24 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/inference/builderInference/kt49829.fir.kt diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUselessTypeOperationCallChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUselessTypeOperationCallChecker.kt index d2621379b42..6f46fa2e9bf 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUselessTypeOperationCallChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUselessTypeOperationCallChecker.kt @@ -38,7 +38,11 @@ object FirUselessTypeOperationCallChecker : FirTypeOperatorCallChecker() { when (expression.operation) { FirOperation.IS -> reporter.reportOn(expression.source, FirErrors.USELESS_IS_CHECK, true, context) FirOperation.NOT_IS -> reporter.reportOn(expression.source, FirErrors.USELESS_IS_CHECK, false, context) - FirOperation.AS, FirOperation.SAFE_AS -> reporter.reportOn(expression.source, FirErrors.USELESS_CAST, context) + FirOperation.AS, FirOperation.SAFE_AS -> { + if ((arg.typeRef as? FirResolvedTypeRef)?.isFromStubType != true) { + reporter.reportOn(expression.source, FirErrors.USELESS_CAST, context) + } + } else -> throw AssertionError("Should not be here: ${expression.operation}") } } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt index 44a5698f11b..8345d791f01 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt @@ -322,6 +322,7 @@ fun FirTypeRef.withReplacedConeType( type = newType annotations += this@withReplacedConeType.annotations delegatedTypeRef = this@withReplacedConeType.delegatedTypeRef + isFromStubType = this@withReplacedConeType.type is ConeStubType } } } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirErrorFunctionImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirErrorFunctionImpl.kt index 4d40b4c64fc..39c89a33254 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirErrorFunctionImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirErrorFunctionImpl.kt @@ -52,7 +52,7 @@ internal class FirErrorFunctionImpl( override val symbol: FirErrorFunctionSymbol, ) : FirErrorFunction() { override var status: FirDeclarationStatus = FirResolvedDeclarationStatusImpl.DEFAULT_STATUS_FOR_STATUSLESS_DECLARATIONS - override var returnTypeRef: FirTypeRef = FirErrorTypeRefImpl(null, null, diagnostic) + override var returnTypeRef: FirTypeRef = FirErrorTypeRefImpl(null, null, diagnostic, false) override val receiverTypeRef: FirTypeRef? get() = null override var controlFlowGraphReference: FirControlFlowGraphReference? = null override val body: FirBlock? get() = null diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirErrorPropertyImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirErrorPropertyImpl.kt index 777cb078314..518cb8f5f5c 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirErrorPropertyImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirErrorPropertyImpl.kt @@ -55,7 +55,7 @@ internal class FirErrorPropertyImpl( ) : FirErrorProperty() { override val typeParameters: List get() = emptyList() override var status: FirDeclarationStatus = FirResolvedDeclarationStatusImpl.DEFAULT_STATUS_FOR_STATUSLESS_DECLARATIONS - override var returnTypeRef: FirTypeRef = FirErrorTypeRefImpl(null, null, diagnostic) + override var returnTypeRef: FirTypeRef = FirErrorTypeRefImpl(null, null, diagnostic, false) override val receiverTypeRef: FirTypeRef? get() = null override val initializer: FirExpression? get() = null override val delegate: FirExpression? get() = null diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirErrorExpressionImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirErrorExpressionImpl.kt index 9b7e40c649b..cfe8e74473f 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirErrorExpressionImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirErrorExpressionImpl.kt @@ -28,7 +28,7 @@ internal class FirErrorExpressionImpl( override val diagnostic: ConeDiagnostic, override var expression: FirExpression?, ) : FirErrorExpression() { - override var typeRef: FirTypeRef = FirErrorTypeRefImpl(source, null, ConeStubDiagnostic(diagnostic)) + override var typeRef: FirTypeRef = FirErrorTypeRefImpl(source, null, ConeStubDiagnostic(diagnostic), false) override fun acceptChildren(visitor: FirVisitor, data: D) { typeRef.accept(visitor, data) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/types/FirErrorTypeRef.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/types/FirErrorTypeRef.kt index f412e8b4e54..8bb7e99ed4c 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/types/FirErrorTypeRef.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/types/FirErrorTypeRef.kt @@ -22,6 +22,7 @@ abstract class FirErrorTypeRef : FirResolvedTypeRef(), FirDiagnosticHolder { abstract override val annotations: List abstract override val type: ConeKotlinType abstract override val delegatedTypeRef: FirTypeRef? + abstract override val isFromStubType: Boolean abstract override val diagnostic: ConeDiagnostic override fun accept(visitor: FirVisitor, data: D): R = visitor.visitErrorTypeRef(this, data) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/types/FirResolvedTypeRef.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/types/FirResolvedTypeRef.kt index 19bc51abadc..dcfc03a28a5 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/types/FirResolvedTypeRef.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/types/FirResolvedTypeRef.kt @@ -20,6 +20,7 @@ abstract class FirResolvedTypeRef : FirTypeRef() { abstract override val annotations: List abstract val type: ConeKotlinType abstract val delegatedTypeRef: FirTypeRef? + abstract val isFromStubType: Boolean override fun accept(visitor: FirVisitor, data: D): R = visitor.visitResolvedTypeRef(this, data) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/types/builder/FirResolvedTypeRefBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/types/builder/FirResolvedTypeRefBuilder.kt index 8b1defedb47..e8d3fb8d124 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/types/builder/FirResolvedTypeRefBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/types/builder/FirResolvedTypeRefBuilder.kt @@ -30,6 +30,7 @@ class FirResolvedTypeRefBuilder : FirAnnotationContainerBuilder { override val annotations: MutableList = mutableListOf() lateinit var type: ConeKotlinType var delegatedTypeRef: FirTypeRef? = null + var isFromStubType: Boolean = false @OptIn(FirImplementationDetail::class) override fun build(): FirResolvedTypeRef { @@ -38,6 +39,7 @@ class FirResolvedTypeRefBuilder : FirAnnotationContainerBuilder { annotations, type, delegatedTypeRef, + isFromStubType, ) } @@ -61,5 +63,6 @@ inline fun buildResolvedTypeRefCopy(original: FirResolvedTypeRef, init: FirResol copyBuilder.annotations.addAll(original.annotations) copyBuilder.type = original.type copyBuilder.delegatedTypeRef = original.delegatedTypeRef + copyBuilder.isFromStubType = original.isFromStubType return copyBuilder.apply(init).build() } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/types/impl/FirResolvedTypeRefImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/types/impl/FirResolvedTypeRefImpl.kt index bb22aa34d87..d8d801c00e3 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/types/impl/FirResolvedTypeRefImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/types/impl/FirResolvedTypeRefImpl.kt @@ -25,6 +25,7 @@ class FirResolvedTypeRefImpl @FirImplementationDetail constructor( override val annotations: MutableList, override val type: ConeKotlinType, override var delegatedTypeRef: FirTypeRef?, + override val isFromStubType: Boolean, ) : FirResolvedTypeRef() { override fun acceptChildren(visitor: FirVisitor, data: D) { annotations.forEach { it.accept(visitor, data) } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/builder/FirErrorTypeRefBuilder.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/builder/FirErrorTypeRefBuilder.kt index e4953910ddd..7176075a26f 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/builder/FirErrorTypeRefBuilder.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/builder/FirErrorTypeRefBuilder.kt @@ -37,7 +37,7 @@ class FirErrorTypeRefBuilder : FirAnnotationContainerBuilder { source, type, delegatedTypeRef, - diagnostic, + diagnostic ) } else { FirErrorTypeRefImpl( diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/impl/FirErrorTypeRefImpl.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/impl/FirErrorTypeRefImpl.kt index 324226d48c8..88adc89f1fc 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/impl/FirErrorTypeRefImpl.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/impl/FirErrorTypeRefImpl.kt @@ -19,11 +19,16 @@ internal class FirErrorTypeRefImpl( override val type: ConeKotlinType, override var delegatedTypeRef: FirTypeRef?, override val diagnostic: ConeDiagnostic, + override val isFromStubType: Boolean = false ) : FirErrorTypeRef() { - constructor(source: KtSourceElement?, delegatedTypeRef: FirTypeRef?, diagnostic: ConeDiagnostic) : this( + constructor(source: KtSourceElement?, delegatedTypeRef: FirTypeRef?, diagnostic: ConeDiagnostic, + isFromStubType: Boolean = false + ) : this( source, ConeErrorType(diagnostic), - delegatedTypeRef, diagnostic + delegatedTypeRef, + diagnostic, + isFromStubType ) override val annotations: MutableList = mutableListOf() diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/impl/FirImplicitBuiltinTypeRef.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/impl/FirImplicitBuiltinTypeRef.kt index c32591001c5..a010a16bca2 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/impl/FirImplicitBuiltinTypeRef.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/impl/FirImplicitBuiltinTypeRef.kt @@ -34,6 +34,9 @@ sealed class FirImplicitBuiltinTypeRef( override val delegatedTypeRef: FirTypeRef? get() = null + override val isFromStubType: Boolean + get() = false + override fun acceptChildren(visitor: FirVisitor, data: D) {} override fun transformChildren(transformer: FirTransformer, data: D): FirElement { diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt index f65b89e27dc..11aa4938a36 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt @@ -265,6 +265,7 @@ object BuilderConfigurator : AbstractBuilderConfigurator(FirTree builder(resolvedTypeRef) { defaultNull("delegatedTypeRef") + default("isFromStubType", "false") withCopy() } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt index 2ce4c2bd3ec..4f97a727716 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt @@ -224,7 +224,7 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() "getter", "setter", withGetter = true ) - default("returnTypeRef", "FirErrorTypeRefImpl(null, null, diagnostic)") + default("returnTypeRef", "FirErrorTypeRefImpl(null, null, diagnostic, false)") useTypes(errorTypeRefImplType) } @@ -421,13 +421,13 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() } impl(errorExpression) { - default("typeRef", "FirErrorTypeRefImpl(source, null, ConeStubDiagnostic(diagnostic))") + default("typeRef", "FirErrorTypeRefImpl(source, null, ConeStubDiagnostic(diagnostic), false)") useTypes(errorTypeRefImplType, coneStubDiagnosticType) } impl(errorFunction) { defaultNull("receiverTypeRef", "body", withGetter = true) - default("returnTypeRef", "FirErrorTypeRefImpl(null, null, diagnostic)") + default("returnTypeRef", "FirErrorTypeRefImpl(null, null, diagnostic, false)") useTypes(errorTypeRefImplType) } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt index 5e224b44d57..971b49dc358 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt @@ -637,6 +637,7 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild resolvedTypeRef.configure { +field("type", coneKotlinTypeType) +field("delegatedTypeRef", typeRef, nullable = true) + +booleanField("isFromStubType") } typeRefWithNullability.configure { diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/kt49829.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/kt49829.fir.kt deleted file mode 100644 index 0dcf5e0e002..00000000000 --- a/compiler/testData/diagnostics/tests/inference/builderInference/kt49829.fir.kt +++ /dev/null @@ -1,12 +0,0 @@ -// WITH_STDLIB -// For FIR: see KT-50293 - -fun main() { - val list = buildList { - add("one") - add("two") - - val secondParameter = get(1) - println(secondParameter as String) // WARNING: [CAST_NEVER_SUCCEEDS] This cast can never succeed - } -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/kt49829.kt b/compiler/testData/diagnostics/tests/inference/builderInference/kt49829.kt index ec5031c3df4..d428168c8e1 100644 --- a/compiler/testData/diagnostics/tests/inference/builderInference/kt49829.kt +++ b/compiler/testData/diagnostics/tests/inference/builderInference/kt49829.kt @@ -1,5 +1,6 @@ +// FIR_IDENTICAL // WITH_STDLIB -// For FIR: see KT-50293 +// ISSUE: KT-50293 fun main() { val list = buildList { @@ -7,6 +8,6 @@ fun main() { add("two") val secondParameter = get(1) - println(secondParameter as String) // WARNING: [CAST_NEVER_SUCCEEDS] This cast can never succeed + println(secondParameter as String) } } \ No newline at end of file