Improve diagnostic on overload resolution ambiguity

Report type mismatch on argument when a nullable argument is passed to non-null parameter.

 Note that this affects only functions with simple types without generics

 #KT-2007 Fixed
 #KT-9282 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2017-06-20 17:18:53 +03:00
parent 16de991b07
commit 7a9e1b2b1d
11 changed files with 82 additions and 11 deletions
@@ -53,6 +53,7 @@ import org.jetbrains.kotlin.types.checker.ErrorTypesAreEqualToAnything
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver
import org.jetbrains.kotlin.types.typeUtil.containsTypeProjectionsInTopLevelArguments
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
import java.util.*
class CandidateResolver(
@@ -376,7 +377,7 @@ class CandidateResolver(
if (!ArgumentTypeResolver.isSubtypeOfForArgumentType(type, expectedType)) {
val smartCast = smartCastValueArgumentTypeIfPossible(expression, newContext.expectedType, type, newContext)
if (smartCast == null) {
resultStatus = OTHER_ERROR
resultStatus = tryNotNullableArgument(type, expectedType) ?: OTHER_ERROR
matchStatus = ArgumentMatchStatus.TYPE_MISMATCH
}
else {
@@ -417,6 +418,14 @@ class CandidateResolver(
}
}
private fun tryNotNullableArgument(argumentType: KotlinType, parameterType: KotlinType): ResolutionStatus? {
if (!argumentType.isMarkedNullable || parameterType.isMarkedNullable) return null
val notNullableArgumentType = argumentType.makeNotNullable()
val isApplicable = ArgumentTypeResolver.isSubtypeOfForArgumentType(notNullableArgumentType, parameterType)
return if (isApplicable) NULLABLE_ARGUMENT_TYPE_MISMATCH else null
}
private fun CallCandidateResolutionContext<*>.checkReceiverTypeError(): Unit = check {
val extensionReceiver = candidateDescriptor.extensionReceiverParameter
val dispatchReceiver = candidateDescriptor.dispatchReceiverParameter
@@ -26,6 +26,7 @@ public enum ResolutionStatus {
WRONG_NUMBER_OF_TYPE_ARGUMENTS_ERROR,
UNSTABLE_SMARTCAST_ERROR,
INVISIBLE_MEMBER_ERROR,
NULLABLE_ARGUMENT_TYPE_MISMATCH,
OTHER_ERROR,
ARGUMENTS_MAPPING_ERROR,
// '1.foo()' shouldn't be resolved to 'fun String.foo()'
@@ -44,6 +45,7 @@ public enum ResolutionStatus {
EnumSet.of(WRONG_NUMBER_OF_TYPE_ARGUMENTS_ERROR),
EnumSet.of(UNSTABLE_SMARTCAST_ERROR),
EnumSet.of(INVISIBLE_MEMBER_ERROR),
EnumSet.of(NULLABLE_ARGUMENT_TYPE_MISMATCH),
EnumSet.of(OTHER_ERROR),
EnumSet.of(ARGUMENTS_MAPPING_ERROR),
EnumSet.of(RECEIVER_TYPE_ERROR),