Report implicit inferred Nothing only for own type parameters and in delegation resolve
^KT-47724 Fixed
This commit is contained in:
+6
@@ -14228,6 +14228,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/inference/nothingType/reifiedParameterWithRecursiveBound.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reportImplicitNothingOnlyForOwnTypeParameters.kt")
|
||||
public void testReportImplicitNothingOnlyForOwnTypeParameters() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/nothingType/reportImplicitNothingOnlyForOwnTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("specialCallWithMaterializeAndExpectedType.kt")
|
||||
public void testSpecialCallWithMaterializeAndExpectedType() throws Exception {
|
||||
|
||||
+6
@@ -14228,6 +14228,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/inference/nothingType/reifiedParameterWithRecursiveBound.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reportImplicitNothingOnlyForOwnTypeParameters.kt")
|
||||
public void testReportImplicitNothingOnlyForOwnTypeParameters() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/nothingType/reportImplicitNothingOnlyForOwnTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("specialCallWithMaterializeAndExpectedType.kt")
|
||||
public void testSpecialCallWithMaterializeAndExpectedType() throws Exception {
|
||||
|
||||
+18
-6
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.resolve.calls.checkers
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType
|
||||
import org.jetbrains.kotlin.builtins.isFunctionOrSuspendFunctionType
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnceWrtDiagnosticFactoryList
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
@@ -19,6 +21,7 @@ import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.psiExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.psiKotlinCall
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind
|
||||
import org.jetbrains.kotlin.types.DeferredType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
@@ -51,7 +54,7 @@ object ImplicitNothingAsTypeParameterCallChecker : CallChecker {
|
||||
): Boolean {
|
||||
val resultingDescriptor = resolvedCall.resultingDescriptor
|
||||
val expectedType = context.resolutionContext.expectedType
|
||||
val inferredReturnType = resultingDescriptor.returnType
|
||||
val inferredReturnType = resultingDescriptor.returnType ?: return false
|
||||
val isBuiltinFunctionalType =
|
||||
resolvedCall.resultingDescriptor.dispatchReceiverParameter?.value?.type?.isBuiltinFunctionalType == true
|
||||
|
||||
@@ -61,12 +64,13 @@ object ImplicitNothingAsTypeParameterCallChecker : CallChecker {
|
||||
val lambdasFromArgumentsReturnTypes =
|
||||
resolvedCall.candidateDescriptor.valueParameters.filter { it.type.isFunctionOrSuspendFunctionType }
|
||||
.map { it.returnType?.arguments?.last()?.type }.toSet()
|
||||
val unsubstitutedReturnType = resultingDescriptor.original.returnType
|
||||
val hasImplicitNothing = inferredReturnType?.isNothingOrNullableNothing() == true &&
|
||||
unsubstitutedReturnType?.isTypeParameter() == true &&
|
||||
(TypeUtils.noExpectedType(expectedType) || !expectedType.isNothing())
|
||||
val unsubstitutedReturnType = resultingDescriptor.original.returnType ?: return false
|
||||
val hasImplicitNothing = inferredReturnType.isNothingOrNullableNothing()
|
||||
&& unsubstitutedReturnType.isTypeParameter()
|
||||
&& (isOwnTypeParameter(unsubstitutedReturnType, resultingDescriptor.original) || isDelegationContext(context))
|
||||
&& (TypeUtils.noExpectedType(expectedType) || !expectedType.isNothing())
|
||||
|
||||
if (inferredReturnType?.isNullableNothing() == true && unsubstitutedReturnType?.isMarkedNullable == false) {
|
||||
if (inferredReturnType.isNullableNothing() && !unsubstitutedReturnType.isMarkedNullable) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -81,6 +85,14 @@ object ImplicitNothingAsTypeParameterCallChecker : CallChecker {
|
||||
return false
|
||||
}
|
||||
|
||||
private fun isOwnTypeParameter(type: KotlinType, declaration: CallableDescriptor): Boolean {
|
||||
val typeParameter = type.constructor.declarationDescriptor as? TypeParameterDescriptor ?: return false
|
||||
return typeParameter.containingDeclaration == declaration
|
||||
}
|
||||
|
||||
private fun isDelegationContext(context: CallCheckerContext) =
|
||||
context.resolutionContext.scope.kind == LexicalScopeKind.PROPERTY_DELEGATE_METHOD
|
||||
|
||||
private fun ResolvedAtom.getResolvedCallAtom(bindingContext: BindingContext): ResolvedCallAtom? {
|
||||
if (this is SingleCallResolutionResult) return resultCallAtom
|
||||
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fun <R> runCatching(block: () -> R) = null as Result<R>
|
||||
|
||||
class Result<out T> {
|
||||
fun getOrNull(): T? = null
|
||||
}
|
||||
|
||||
fun main() {
|
||||
runCatching {
|
||||
null
|
||||
}.getOrNull() // don't report IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fun <R> runCatching(block: () -> R) = null <!CAST_NEVER_SUCCEEDS!>as<!> Result<R>
|
||||
|
||||
class Result<out T> {
|
||||
fun getOrNull(): T? = null
|
||||
}
|
||||
|
||||
fun main() {
|
||||
runCatching {
|
||||
null
|
||||
}.getOrNull() // don't report IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package
|
||||
|
||||
public fun main(): kotlin.Unit
|
||||
public fun </*0*/ R> runCatching(/*0*/ block: () -> R): Result<R>
|
||||
|
||||
public final class Result</*0*/ out T> {
|
||||
public constructor Result</*0*/ out T>()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final fun getOrNull(): T?
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+1
-1
@@ -90,7 +90,7 @@ interface Worker<out T>
|
||||
interface RenderContext<StateT, in OutputT : Any>
|
||||
|
||||
val emptyOrNull: List<Nothing>? = null
|
||||
val x = emptyOrNull?.<!IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION!>get<!>(0)
|
||||
val x = emptyOrNull?.get(0)
|
||||
|
||||
val errorCompletion = { e: Throwable -> throw Exception() }
|
||||
|
||||
|
||||
Generated
+6
@@ -14234,6 +14234,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/nothingType/reifiedParameterWithRecursiveBound.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reportImplicitNothingOnlyForOwnTypeParameters.kt")
|
||||
public void testReportImplicitNothingOnlyForOwnTypeParameters() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/nothingType/reportImplicitNothingOnlyForOwnTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("specialCallWithMaterializeAndExpectedType.kt")
|
||||
public void testSpecialCallWithMaterializeAndExpectedType() throws Exception {
|
||||
|
||||
+6
@@ -14228,6 +14228,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
||||
runTest("compiler/testData/diagnostics/tests/inference/nothingType/reifiedParameterWithRecursiveBound.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reportImplicitNothingOnlyForOwnTypeParameters.kt")
|
||||
public void testReportImplicitNothingOnlyForOwnTypeParameters() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/nothingType/reportImplicitNothingOnlyForOwnTypeParameters.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("specialCallWithMaterializeAndExpectedType.kt")
|
||||
public void testSpecialCallWithMaterializeAndExpectedType() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user