[FE 1.0] Don't lose diagnostics during lambda analysis at the overload resolution by return type stage

^KT-49658 Fixed
This commit is contained in:
Victor Petukhov
2022-01-11 15:22:03 +03:00
committed by teamcity
parent 7820b268fb
commit 37d163d417
17 changed files with 212 additions and 21 deletions
@@ -1103,6 +1103,7 @@ public interface Errors {
DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<KtElement, KtElement> ILLEGAL_ESCAPE = DiagnosticFactory1.create(ERROR, CUT_CHAR_QUOTES);
DiagnosticFactory1<KtConstantExpression, KotlinType> NULL_FOR_NONNULL_TYPE = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<KtConstantExpression, KotlinType> NULL_FOR_NONNULL_TYPE_WARNING = DiagnosticFactory1.create(WARNING);
DiagnosticFactory0<KtEscapeStringTemplateEntry> ILLEGAL_ESCAPE_SEQUENCE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtConstantExpression> UNSIGNED_LITERAL_WITHOUT_DECLARATIONS_ON_CLASSPATH = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtExpression> SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED = DiagnosticFactory0.create(ERROR);
@@ -632,6 +632,7 @@ public class DefaultErrorMessages {
MAP.put(TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL, "Too many characters in a character literal ''{0}''", ELEMENT_TEXT);
MAP.put(ILLEGAL_ESCAPE, "Illegal escape: ''{0}''", ELEMENT_TEXT);
MAP.put(NULL_FOR_NONNULL_TYPE, "Null can not be a value of a non-null type {0}", RENDER_TYPE);
MAP.put(NULL_FOR_NONNULL_TYPE_WARNING, "Null can not be a value of a non-null type {0}", RENDER_TYPE);
MAP.put(ELSE_MISPLACED_IN_WHEN, "'else' entry must be the last one in a when-expression");
MAP.put(REDUNDANT_ELSE_IN_WHEN, "'when' is exhaustive so 'else' is redundant here");
@@ -215,18 +215,14 @@ class DiagnosticReporterByTrackingStrategy(
}
}
ArgumentNullabilityMismatchDiagnostic::class.java -> {
require(diagnostic is ArgumentNullabilityMismatchDiagnostic)
val expression = callArgument.safeAs<PSIKotlinCallArgument>()?.valueArgument?.getArgumentExpression()?.let {
KtPsiUtil.deparenthesize(it) ?: it
}
if (expression != null) {
if (expression.isNull() && expression is KtConstantExpression) {
trace.reportDiagnosticOnce(NULL_FOR_NONNULL_TYPE.on(expression, diagnostic.expectedType))
} else {
trace.report(TYPE_MISMATCH.on(expression, diagnostic.expectedType, diagnostic.actualType))
}
}
ArgumentNullabilityErrorDiagnostic::class.java -> {
require(diagnostic is ArgumentNullabilityErrorDiagnostic)
reportNullabilityMismatchDiagnostic(callArgument, diagnostic)
}
ArgumentNullabilityWarningDiagnostic::class.java -> {
require(diagnostic is ArgumentNullabilityWarningDiagnostic)
reportNullabilityMismatchDiagnostic(callArgument, diagnostic)
}
CallableReferencesDefaultArgumentUsed::class.java -> {
@@ -582,6 +578,27 @@ class DiagnosticReporterByTrackingStrategy(
}
}
private fun reportNullabilityMismatchDiagnostic(callArgument: KotlinCallArgument, diagnostic: ArgumentNullabilityMismatchDiagnostic) {
val expression = callArgument.safeAs<PSIKotlinCallArgument>()?.valueArgument?.getArgumentExpression()?.let {
KtPsiUtil.deparenthesize(it) ?: it
}
if (expression != null) {
if (expression.isNull() && expression is KtConstantExpression) {
val factory = when (diagnostic) {
is ArgumentNullabilityErrorDiagnostic -> NULL_FOR_NONNULL_TYPE
is ArgumentNullabilityWarningDiagnostic -> NULL_FOR_NONNULL_TYPE_WARNING
}
trace.reportDiagnosticOnce(factory.on(expression, diagnostic.expectedType))
} else {
val factory = when (diagnostic) {
is ArgumentNullabilityErrorDiagnostic -> TYPE_MISMATCH
is ArgumentNullabilityWarningDiagnostic -> TYPE_MISMATCH_WARNING
}
trace.report(factory.on(expression, diagnostic.expectedType, diagnostic.actualType))
}
}
}
private fun reportNotEnoughInformationForTypeParameterForSpecialCall(
resolvedAtom: ResolvedCallAtom,
error: NotEnoughInformationForTypeParameterImpl
@@ -622,7 +639,6 @@ class DiagnosticReporterByTrackingStrategy(
|| it.constructor == uninferredTypeVariable.freshTypeConstructor(typeSystemContext)
}
@OptIn(ExperimentalStdlibApi::class)
private fun getSubResolvedAtomsOfSpecialCallToReportUninferredTypeParameter(
resolvedAtom: ResolvedAtom,
uninferredTypeVariable: TypeVariableMarker