[FE] Show causing types in the INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION diagnostic

This commit is contained in:
Victor Petukhov
2022-05-25 18:14:19 +02:00
committed by teamcity
parent 6a34b184ac
commit 867ad24c86
51 changed files with 217 additions and 163 deletions
@@ -899,10 +899,10 @@ public interface Errors {
DiagnosticFactoryForDeprecation1<PsiElement, TypeParameterDescriptor> TYPE_INFERENCE_ONLY_INPUT_TYPES =
DiagnosticFactoryForDeprecation1.create(LanguageFeature.StrictOnlyInputTypesChecks);
DiagnosticFactoryForDeprecation3<PsiElement, String, Collection<KotlinType>, String> INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION =
DiagnosticFactoryForDeprecation3.create(LanguageFeature.ForbidInferringTypeVariablesIntoEmptyIntersection);
DiagnosticFactory2<PsiElement, String, Collection<KotlinType>> INFERRED_TYPE_VARIABLE_INTO_POSSIBLE_EMPTY_INTERSECTION =
DiagnosticFactory2.create(WARNING);
DiagnosticFactoryForDeprecation4<PsiElement, String, Collection<KotlinType>, String, String> INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION =
DiagnosticFactoryForDeprecation4.create(LanguageFeature.ForbidInferringTypeVariablesIntoEmptyIntersection);
DiagnosticFactory4<PsiElement, String, Collection<KotlinType>, String, String> INFERRED_TYPE_VARIABLE_INTO_POSSIBLE_EMPTY_INTERSECTION =
DiagnosticFactory4.create(WARNING);
DiagnosticFactory1<PsiElement, InferenceErrorData> TYPE_INFERENCE_UPPER_BOUND_VIOLATED = DiagnosticFactory1.create(ERROR);
DiagnosticFactory2<KtElement, KotlinType, KotlinType> TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH = DiagnosticFactory2.create(ERROR);
DiagnosticFactory0<PsiElement> TYPE_INFERENCE_CANDIDATE_WITH_SAM_AND_VARARG = DiagnosticFactory0.create(WARNING);
@@ -965,8 +965,8 @@ public class DefaultErrorMessages {
MAP.put(TYPE_INFERENCE_INCORPORATION_ERROR, "Type inference failed. Please try to specify type arguments explicitly.");
MAP.put(TYPE_INFERENCE_ONLY_INPUT_TYPES, "Type inference failed. The value of the type parameter {0} should be mentioned in input types " +
"(argument types, receiver type or expected type). Try to specify it explicitly.", NAME);
MAP.put(INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION, "Type argument for a type parameter {0} can''t be inferred because it has incompatible upper bounds {2}: {1}", TO_STRING, RENDER_COLLECTION_OF_TYPES, TO_STRING);
MAP.put(INFERRED_TYPE_VARIABLE_INTO_POSSIBLE_EMPTY_INTERSECTION, "Type argument for a type parameter {0} has possible incompatible upper bounds: {1}", TO_STRING, RENDER_COLLECTION_OF_TYPES);
MAP.put(INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION, "Type argument for a type parameter {0} can''t be inferred because it has incompatible upper bounds: {1} ({2}{3})", TO_STRING, RENDER_COLLECTION_OF_TYPES, TO_STRING, TO_STRING);
MAP.put(INFERRED_TYPE_VARIABLE_INTO_POSSIBLE_EMPTY_INTERSECTION, "Type argument for a type parameter {0} has possible incompatible upper bounds: {1} ({2}{3})", TO_STRING, RENDER_COLLECTION_OF_TYPES, TO_STRING, TO_STRING);
MAP.put(TYPE_INFERENCE_UPPER_BOUND_VIOLATED, "{0}", TYPE_INFERENCE_UPPER_BOUND_VIOLATED_RENDERER);
MAP.put(TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH, "Type inference failed. Expected type mismatch: inferred type is {1} but {0} was expected", RENDER_TYPE, RENDER_TYPE);
MAP.put(TYPE_INFERENCE_CANDIDATE_WITH_SAM_AND_VARARG, "Please use spread operator to pass an array as vararg. It will be an error in 1.5.");
@@ -610,14 +610,19 @@ class DiagnosticReporterByTrackingStrategy(
?: typeVariable.toString()
@Suppress("UNCHECKED_CAST")
val incompatibleTypes = error.incompatibleTypes as Collection<KotlinType>
val incompatibleTypes = error.incompatibleTypes as List<KotlinType>
@Suppress("UNCHECKED_CAST")
val causingTypes = error.causingTypes as List<KotlinType>
val causingTypesText = if (incompatibleTypes == causingTypes) "" else ": ${causingTypes.joinToString()}"
val diagnostic = if (error.kind.isPossiblyEmpty()) {
INFERRED_TYPE_VARIABLE_INTO_POSSIBLE_EMPTY_INTERSECTION.on(expression, typeVariableText, incompatibleTypes)
INFERRED_TYPE_VARIABLE_INTO_POSSIBLE_EMPTY_INTERSECTION.on(
expression, typeVariableText, incompatibleTypes, error.kind.description, causingTypesText
)
} else {
INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION.on(
context.languageVersionSettings, expression, typeVariableText,
incompatibleTypes, error.kind.description?.let { " ($it)" }.orEmpty()
incompatibleTypes, error.kind.description, causingTypesText
)
}