FIR: Avoid propagation of @Exact annotation through elvis

This commit is contained in:
Denis.Zharkov
2021-11-24 15:13:01 +03:00
committed by teamcityserver
parent 0d9ad62d4a
commit 7eb758fab1
6 changed files with 56 additions and 1 deletions
@@ -33179,6 +33179,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/defaultValueMustBeConstant.kt");
}
@Test
@TestMetadata("dontPropagateExact.kt")
public void testDontPropagateExact() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/dontPropagateExact.kt");
}
@Test
@TestMetadata("explicitMetadata.kt")
public void testExplicitMetadata() throws Exception {
@@ -33179,6 +33179,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/defaultValueMustBeConstant.kt");
}
@Test
@TestMetadata("dontPropagateExact.kt")
public void testDontPropagateExact() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/dontPropagateExact.kt");
}
@Test
@TestMetadata("explicitMetadata.kt")
public void testExplicitMetadata() throws Exception {
@@ -332,7 +332,22 @@ class FirCallCompletionResultsWriterTransformer(
type = substitutedType ?: initialType, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference,
) ?: substitutedType
return withReplacedConeType(finalType)
// This is probably a temporary hack, but it seems necessary because elvis has that attribute and it may leak further like
// fun <E> foo() = materializeNullable<E>() ?: materialize<E>() // `foo` return type unexpectedly gets inferred to @Exact E
//
// In FE1.0, it's not necessary since the annotation for elvis have some strange form (see org.jetbrains.kotlin.resolve.descriptorUtil.AnnotationsWithOnly)
// that is not propagated further.
val withRemovedExactAttribute = finalType?.removeExactAttribute()
return withReplacedConeType(withRemovedExactAttribute)
}
private fun ConeKotlinType.removeExactAttribute(): ConeKotlinType {
if (attributes.contains(CompilerConeAttributes.Exact)) {
return withAttributes(attributes.remove(CompilerConeAttributes.Exact), session.typeContext)
}
return this
}
override fun transformSafeCallExpression(