Report warning about implicitly inferred nothing only for return position
^KT-31535 Fixed
This commit is contained in:
+14
-6
@@ -9,8 +9,11 @@ import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.builtins.isFunctionType
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.types.DeferredType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils
|
||||
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
||||
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
|
||||
|
||||
object ImplicitNothingAsTypeParameterCallChecker : CallChecker {
|
||||
private val SPECIAL_FUNCTION_NAMES = ControlStructureTypingUtils.ResolveConstruct.values().map { it.specialFunctionName }.toSet()
|
||||
@@ -32,16 +35,21 @@ object ImplicitNothingAsTypeParameterCallChecker : CallChecker {
|
||||
* }
|
||||
*/
|
||||
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
|
||||
if (resolvedCall.candidateDescriptor.name !in SPECIAL_FUNCTION_NAMES && resolvedCall.call.typeArguments.isEmpty()) {
|
||||
val resultingDescriptor = resolvedCall.resultingDescriptor
|
||||
val inferredReturnType = resultingDescriptor.returnType
|
||||
if (inferredReturnType is DeferredType)
|
||||
return
|
||||
if (resultingDescriptor.name !in SPECIAL_FUNCTION_NAMES && resolvedCall.call.typeArguments.isEmpty()) {
|
||||
val lambdasFromArgumentsReturnTypes =
|
||||
resolvedCall.candidateDescriptor.valueParameters.filter { it.type.isFunctionType }
|
||||
.map { it.returnType?.arguments?.last()?.type }.toSet()
|
||||
val unsubstitutedReturnType = resultingDescriptor.original.returnType
|
||||
val expectedType = context.resolutionContext.expectedType
|
||||
val hasImplicitNothing = inferredReturnType?.isNothing() == true &&
|
||||
unsubstitutedReturnType?.isTypeParameter() == true &&
|
||||
(TypeUtils.noExpectedType(expectedType) || !expectedType.isNothing())
|
||||
|
||||
val hasImplicitNothingExceptLambdaReturnTypes = resolvedCall.typeArguments.any { (unsubstitutedType, resultingType) ->
|
||||
resultingType.isNothing() && unsubstitutedType.defaultType !in lambdasFromArgumentsReturnTypes
|
||||
}
|
||||
|
||||
if (hasImplicitNothingExceptLambdaReturnTypes) {
|
||||
if (hasImplicitNothing && unsubstitutedReturnType !in lambdasFromArgumentsReturnTypes) {
|
||||
context.trace.report(Errors.IMPLICIT_NOTHING_AS_TYPE_PARAMETER.on(reportOn))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user