[FE] Skip CST computation if list of types has exactly one entry

Otherwise, we can get in a situation where the single item is flexible,
and we replace its attributes with the attribute of the lower bound,
which messes up `EnhancedTypeForWarningAttribute`.

#KT-65193 Fixed
This commit is contained in:
Kirill Rakhman
2024-03-18 12:01:36 +01:00
committed by Space Team
parent 19cc739118
commit 672512d19d
3 changed files with 10 additions and 49 deletions
@@ -14,6 +14,15 @@ import org.jetbrains.kotlin.types.model.*
object NewCommonSuperTypeCalculator {
fun TypeSystemCommonSuperTypesContext.commonSuperType(types: List<KotlinTypeMarker>): KotlinTypeMarker {
// Skip computation if the list has only one element.
// It's not only an optimization, but it's required to not mess up attributes.
// See compiler/testData/diagnostics/foreignAnnotationsTests/tests/jsr305/nullabilityWarnings/kt65193.kt
// When the type is flexible, calling replaceCustomAttributes(unionTypeAttributes(types)) will take the attributes of the
// lower bound which will mess up `EnhancedTypeForWarningAttribute`s.
// It's not a problem if the list has multiple entries, because `EnhancedTypeForWarningAttribute.union` returns null,
// meaning that whenever we union multiple types, we remove any `EnhancedTypeForWarningAttribute`.
types.singleOrNull()?.let { return it }
val maxDepth = types.maxOfOrNull { it.typeDepth() } ?: 0
return commonSuperType(types, -maxDepth, true).replaceCustomAttributes(unionTypeAttributes(types))
}
@@ -1,49 +0,0 @@
// FILE: test/NonNullApi.java
package test;
import java.lang.annotation.*;
import javax.annotation.Nonnull;
import javax.annotation.meta.TypeQualifierDefault;
@Target(ElementType.PACKAGE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Nonnull
@TypeQualifierDefault({ElementType.METHOD, ElementType.PARAMETER, ElementType.PACKAGE})
public @interface NonNullApi {
}
// FILE: test/package-info.java
@NonNullApi
package test;
// FILE: test/JpaSpecificationExecutor.java
package test;
import java.util.List;
public interface JpaSpecificationExecutor<T> {
List<T> findAll();
}
// FILE: mockito/OngoingStubbing.java
package mockito;
public interface OngoingStubbing<T> {
OngoingStubbing<T> thenReturn(T var1);
public static <T> OngoingStubbing<T> when(T... methodCall) {
return null;
}
}
// FILE: test.kt
package test
import mockito.OngoingStubbing
fun test(wrapper: JpaSpecificationExecutor<String>, l: List<String>, l2: List<Int>) {
OngoingStubbing.`when`(wrapper.findAll()).thenReturn(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>l<!>)
OngoingStubbing.`when`(wrapper.findAll(), l2).thenReturn(l)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// FILE: test/NonNullApi.java
package test;