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:
committed by
teamcityserver
parent
93f9d9dacd
commit
7567597be6
+10
-1
@@ -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
|
||||
)
|
||||
|
||||
+9
-1
@@ -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;
|
||||
}
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user