Java nullability checker: take type arguments' types from resolution atom if possible, instead of from resolved call directly

^KT-47833 Fixed
This commit is contained in:
Victor Petukhov
2021-07-27 16:07:00 +03:00
committed by teamcityserver
parent 93f9d9dacd
commit 7567597be6
6 changed files with 67 additions and 2 deletions
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue
import org.jetbrains.kotlin.resolve.calls.smartcasts.Nullability
import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
@@ -135,10 +136,18 @@ class JavaNullabilityChecker(val upperBoundChecker: UpperBoundChecker) : Additio
?: return
val resolvedCall = c.trace.bindingContext[BindingContext.RESOLVED_CALL, call] ?: return
for ((typeParameter, typeArgument) in resolvedCall.typeArguments) {
val typeArguments = if (resolvedCall is NewResolvedCallImpl<*>) {
resolvedCall.resolvedCallAtom.typeArgumentMappingByOriginal
} else {
resolvedCall.typeArguments.entries
}
for ((typeParameter, typeArgument) in typeArguments) {
// continue if we don't have explicit type arguments
val typeReference = call.typeArguments.getOrNull(typeParameter.index)?.typeReference ?: continue
if (typeArgument == null) continue
upperBoundChecker.checkBounds(
typeReference, typeArgument, typeParameter, TypeSubstitutor.create(typeArgument), c.trace, withOnlyCheckForWarning = true
)
@@ -19,16 +19,22 @@ package org.jetbrains.kotlin.resolve.calls.components
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.types.KotlinType
class TypeArgumentsToParametersMapper {
sealed class TypeArgumentsMapping(val diagnostics: List<KotlinCallDiagnostic>) {
sealed class TypeArgumentsMapping(val diagnostics: List<KotlinCallDiagnostic>) :
Iterable<Map.Entry<TypeParameterDescriptor, KotlinType?>> {
abstract fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): TypeArgument
object NoExplicitArguments : TypeArgumentsMapping(emptyList()) {
private val emptyIterator = mapOf<Nothing, Nothing>().iterator()
override fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): TypeArgument =
TypeArgumentPlaceholder
override fun iterator() = emptyIterator
}
class TypeArgumentsMappingImpl(
@@ -37,6 +43,8 @@ class TypeArgumentsToParametersMapper {
) : TypeArgumentsMapping(diagnostics) {
override fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): TypeArgument =
typeParameterToArgumentMap[typeParameterDescriptor] ?: TypeArgumentPlaceholder
override fun iterator() = typeParameterToArgumentMap.mapValues { (it.value as? SimpleTypeArgument)?.type }.iterator()
}
}
@@ -0,0 +1,30 @@
// FILE: main.kt
sealed class ClientBootResult
object ClientBootSuccess : ClientBootResult()
fun example(): Single<out ClientBootResult> {
return Single.just(true).map<ClientBootResult> { ClientBootSuccess }
}
// FILE: Single.java
import io.reactivex.rxjava3.annotations.NonNull;
public class Single<@NonNull T> {
@NonNull
public static <@NonNull T> Single<T> just(T item) {
return null;
}
@NonNull
public final <@NonNull R> Single<R> map(@NonNull Function<? super T, ? extends R> mapper) {
return null;
}
}
// FILE: Function.java
import io.reactivex.rxjava3.annotations.NonNull;
@FunctionalInterface
public interface Function<@NonNull T, @NonNull R> {
R apply(T t) throws Throwable;
}
@@ -86,6 +86,12 @@ public class ForeignAnnotationsCompiledJavaTestGenerated extends AbstractForeign
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47920.kt");
}
@Test
@TestMetadata("kt47833.kt")
public void testKt47833() throws Exception {
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47833.kt");
}
@Test
@TestMetadata("lombokSimple.kt")
public void testLombokSimple() throws Exception {
@@ -86,6 +86,12 @@ public class ForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated exte
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47920.kt");
}
@Test
@TestMetadata("kt47833.kt")
public void testKt47833() throws Exception {
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47833.kt");
}
@Test
@TestMetadata("lombokSimple.kt")
public void testLombokSimple() throws Exception {
@@ -86,6 +86,12 @@ public class ForeignAnnotationsSourceJavaTestGenerated extends AbstractForeignAn
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47920.kt");
}
@Test
@TestMetadata("kt47833.kt")
public void testKt47833() throws Exception {
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47833.kt");
}
@Test
@TestMetadata("lombokSimple.kt")
public void testLombokSimple() throws Exception {