Do not enhance star projections for bounds of raw types
We have an invariant that their lower bound is always SomeType<Any?> and their upper bound is SomeType<*>. Ehancing the latter to SomeType<out Any> making lower bound not being a subtype of upper bound that breaks contract for flexible types (fails with exception)
This commit is contained in:
committed by
Victor Petukhov
parent
16b4a2c465
commit
6661814e40
+1
-1
@@ -13,7 +13,7 @@ public open class B {
|
||||
public constructor B()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
@jspecify.annotations.DefaultNotNull public open fun noBoundsNotNull(/*0*/ a: A<out @jspecify.annotations.NotNull kotlin.Any, out @jspecify.annotations.Nullable kotlin.Any, out @codeanalysis.annotations.NullnessUnknown kotlin.Any>): kotlin.Unit
|
||||
@jspecify.annotations.DefaultNotNull public open fun noBoundsNotNull(/*0*/ a: A<out @jspecify.annotations.NotNull kotlin.Any, out @jspecify.annotations.Nullable kotlin.Any, out @jspecify.annotations.NullnessUnknown kotlin.Any>): kotlin.Unit
|
||||
@jspecify.annotations.DefaultNullable public open fun noBoundsNullable(/*0*/ a: A<out @jspecify.annotations.NotNull kotlin.Any, *, *>?): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@ package test
|
||||
|
||||
public open class A {
|
||||
public constructor A()
|
||||
public open fun bar(/*0*/ l: test.L<*, kotlin.Int>): kotlin.Unit
|
||||
public open fun bar(/*0*/ l: test.L<out kotlin.collections.(Mutable)Map<kotlin.String!, *>, kotlin.Int>): kotlin.Unit
|
||||
public open fun baz1(): test.L<kotlin.collections.(Mutable)Map<kotlin.String, kotlin.Int>, @spr.Nullable kotlin.Int?>
|
||||
public open fun baz2(): test.L<*, kotlin.Int>
|
||||
public open fun baz2(): test.L<out kotlin.collections.(Mutable)Map<kotlin.String!, *>, kotlin.Int>
|
||||
public open fun baz3(): test.L<out kotlin.collections.(Mutable)Map<kotlin.String, kotlin.Int>, kotlin.Int>
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open fun foo(/*0*/ l: test.L<kotlin.collections.(Mutable)Map<kotlin.String, kotlin.Int>, @spr.Nullable kotlin.Int?>): kotlin.Unit
|
||||
@@ -48,9 +48,9 @@ package test {
|
||||
|
||||
public open class A {
|
||||
public constructor A()
|
||||
public open fun bar(/*0*/ l: test.L<*, kotlin.Int>): kotlin.Unit
|
||||
public open fun bar(/*0*/ l: test.L<out kotlin.collections.(Mutable)Map<kotlin.String!, *>, kotlin.Int>): kotlin.Unit
|
||||
public open fun baz1(): test.L<kotlin.collections.(Mutable)Map<kotlin.String, kotlin.Int>, @spr.Nullable kotlin.Int?>
|
||||
public open fun baz2(): test.L<*, kotlin.Int>
|
||||
public open fun baz2(): test.L<out kotlin.collections.(Mutable)Map<kotlin.String!, *>, kotlin.Int>
|
||||
public open fun baz3(): test.L<out kotlin.collections.(Mutable)Map<kotlin.String, kotlin.Int>, kotlin.Int>
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open fun foo(/*0*/ l: test.L<kotlin.collections.(Mutable)Map<kotlin.String, kotlin.Int>, @spr.Nullable kotlin.Int?>): kotlin.Unit
|
||||
|
||||
+15
-5
@@ -49,7 +49,8 @@ class JavaTypeEnhancement(private val javaResolverSettings: JavaResolverSettings
|
||||
val typeIfChanged: KotlinType? get() = type.takeIf { wereChanges }
|
||||
}
|
||||
|
||||
private class SimpleResult(override val type: SimpleType, subtreeSize: Int, wereChanges: Boolean) : Result(type, subtreeSize, wereChanges)
|
||||
private class SimpleResult(override val type: SimpleType, subtreeSize: Int, wereChanges: Boolean) :
|
||||
Result(type, subtreeSize, wereChanges)
|
||||
|
||||
// The index in the lambda is the position of the type component:
|
||||
// Example: for `A<B, C<D, E>>`, indices go as follows: `0 - A<...>, 1 - B, 2 - C<D, E>, 3 - D, 4 - E`,
|
||||
@@ -61,8 +62,9 @@ class JavaTypeEnhancement(private val javaResolverSettings: JavaResolverSettings
|
||||
if (isError) return Result(this, 1, false)
|
||||
return when (this) {
|
||||
is FlexibleType -> {
|
||||
val lowerResult = lowerBound.enhanceInflexible(qualifiers, index, TypeComponentPosition.FLEXIBLE_LOWER)
|
||||
val upperResult = upperBound.enhanceInflexible(qualifiers, index, TypeComponentPosition.FLEXIBLE_UPPER)
|
||||
val isRawType = this is RawType
|
||||
val lowerResult = lowerBound.enhanceInflexible(qualifiers, index, TypeComponentPosition.FLEXIBLE_LOWER, isRawType)
|
||||
val upperResult = upperBound.enhanceInflexible(qualifiers, index, TypeComponentPosition.FLEXIBLE_UPPER, isRawType)
|
||||
assert(lowerResult.subtreeSize == upperResult.subtreeSize) {
|
||||
"Different tree sizes of bounds: " +
|
||||
"lower = ($lowerBound, ${lowerResult.subtreeSize}), " +
|
||||
@@ -90,7 +92,8 @@ class JavaTypeEnhancement(private val javaResolverSettings: JavaResolverSettings
|
||||
private fun SimpleType.enhanceInflexible(
|
||||
qualifiers: (Int) -> JavaTypeQualifiers,
|
||||
index: Int,
|
||||
position: TypeComponentPosition
|
||||
position: TypeComponentPosition,
|
||||
isBoundOfRawType: Boolean = false
|
||||
): SimpleResult {
|
||||
val shouldEnhance = position.shouldEnhance()
|
||||
if (!shouldEnhance && arguments.isEmpty()) return SimpleResult(this, 1, false)
|
||||
@@ -107,8 +110,15 @@ class JavaTypeEnhancement(private val javaResolverSettings: JavaResolverSettings
|
||||
var wereChanges = enhancedMutabilityAnnotations != null
|
||||
val enhancedArguments = arguments.mapIndexed { localArgIndex, arg ->
|
||||
if (arg.isStarProjection) {
|
||||
val qualifiersForStarProjection = qualifiers(globalArgIndex)
|
||||
globalArgIndex++
|
||||
TypeUtils.makeStarProjection(enhancedClassifier.typeConstructor.parameters[localArgIndex])
|
||||
|
||||
if (qualifiersForStarProjection.nullability == NOT_NULL && !isBoundOfRawType) {
|
||||
val enhanced = arg.type.unwrap().makeNotNullable()
|
||||
createProjection(enhanced, arg.projectionKind, typeParameterDescriptor = typeConstructor.parameters[localArgIndex])
|
||||
} else {
|
||||
TypeUtils.makeStarProjection(enhancedClassifier.typeConstructor.parameters[localArgIndex])
|
||||
}
|
||||
} else {
|
||||
val enhanced = arg.type.unwrap().enhancePossiblyFlexible(qualifiers, globalArgIndex)
|
||||
wereChanges = wereChanges || enhanced.wereChanges
|
||||
|
||||
Reference in New Issue
Block a user