[NI] Initial support of "not enough information" diagnostic
#KT-30590 In Progress
This commit is contained in:
+5
@@ -10532,6 +10532,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/inference/reportingImprovements/FunctionPlaceholder.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inferTypeFromUnresolvedArgument.kt")
|
||||
public void testInferTypeFromUnresolvedArgument() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/reportingImprovements/inferTypeFromUnresolvedArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NoAmbiguityForDifferentFunctionTypes.kt")
|
||||
public void testNoAmbiguityForDifferentFunctionTypes() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/reportingImprovements/NoAmbiguityForDifferentFunctionTypes.kt");
|
||||
|
||||
@@ -735,6 +735,8 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtParameter> CANNOT_INFER_PARAMETER_TYPE = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<PsiElement, InferenceErrorData> TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, String> NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<PsiElement, InferenceErrorData> TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, InferenceErrorData> TYPE_INFERENCE_CANNOT_CAPTURE_TYPES = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, InferenceErrorData> TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
+2
@@ -831,6 +831,8 @@ public class DefaultErrorMessages {
|
||||
MAP.put(TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS, "Type inference failed: {0}", TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS_RENDERER);
|
||||
MAP.put(TYPE_INFERENCE_CANNOT_CAPTURE_TYPES, "Type inference failed: {0}", TYPE_INFERENCE_CANNOT_CAPTURE_TYPES_RENDERER);
|
||||
MAP.put(TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER, "Type inference failed: {0}", TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER_RENDERER);
|
||||
MAP.put(NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, "Not enough information to infer type variable {0}", STRING);
|
||||
|
||||
MAP.put(TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR, "Type inference failed: {0}", TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR_RENDERER);
|
||||
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 " +
|
||||
|
||||
+14
-1
@@ -32,7 +32,8 @@ class DiagnosticReporterByTrackingStrategy(
|
||||
val constantExpressionEvaluator: ConstantExpressionEvaluator,
|
||||
val context: BasicCallResolutionContext,
|
||||
val psiKotlinCall: PSIKotlinCall,
|
||||
val dataFlowValueFactory: DataFlowValueFactory
|
||||
val dataFlowValueFactory: DataFlowValueFactory,
|
||||
val allDiagnostics: List<KotlinCallDiagnostic>
|
||||
) : DiagnosticReporter {
|
||||
private val trace = context.trace as TrackingBindingTrace
|
||||
private val tracingStrategy: TracingStrategy get() = psiKotlinCall.tracingStrategy
|
||||
@@ -245,6 +246,18 @@ class DiagnosticReporterByTrackingStrategy(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
NotEnoughInformationForTypeParameter::class.java -> {
|
||||
val error = diagnostic as NotEnoughInformationForTypeParameter
|
||||
val call = error.resolvedAtom.atom?.safeAs<PSIKotlinCall>()?.psiCall ?: call
|
||||
val expression = call.calleeExpression ?: return
|
||||
val typeVariableName = when (val typeVariable = error.typeVariable) {
|
||||
is TypeVariableFromCallableDescriptor -> typeVariable.originalTypeParameter.name.asString()
|
||||
is TypeVariableForLambdaReturnType -> "return type of lambda"
|
||||
else -> error("Unsupported type variable: $typeVariable")
|
||||
}
|
||||
trace.report(NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER.on(expression, typeVariableName))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-3
@@ -423,13 +423,21 @@ class KotlinToResolvedCallTransformer(
|
||||
) {
|
||||
val trackingTrace = TrackingBindingTrace(trace)
|
||||
val newContext = context.replaceBindingTrace(trackingTrace)
|
||||
val diagnosticReporter =
|
||||
DiagnosticReporterByTrackingStrategy(constantExpressionEvaluator, newContext, completedCallAtom.atom.psiKotlinCall, context.dataFlowValueFactory)
|
||||
|
||||
val diagnosticHolder = KotlinDiagnosticsHolder.SimpleHolder()
|
||||
additionalDiagnosticReporter.reportAdditionalDiagnostics(completedCallAtom, resultingDescriptor, diagnosticHolder, diagnostics)
|
||||
|
||||
for (diagnostic in diagnostics + diagnosticHolder.getDiagnostics()) {
|
||||
val allDiagnostics = diagnostics + diagnosticHolder.getDiagnostics()
|
||||
|
||||
val diagnosticReporter = DiagnosticReporterByTrackingStrategy(
|
||||
constantExpressionEvaluator,
|
||||
newContext,
|
||||
completedCallAtom.atom.psiKotlinCall,
|
||||
context.dataFlowValueFactory,
|
||||
allDiagnostics
|
||||
)
|
||||
|
||||
for (diagnostic in allDiagnostics) {
|
||||
trackingTrace.reported = false
|
||||
diagnostic.report(diagnosticReporter)
|
||||
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ class KotlinConstraintSystemCompleter(
|
||||
fixVariable(c, topLevelType, variableWithConstraints, postponedKtPrimitives)
|
||||
|
||||
if (!variableForFixation.hasProperConstraint) {
|
||||
c.addError(NotEnoughInformationForTypeParameter(variableWithConstraints.typeVariable))
|
||||
c.addError(NotEnoughInformationForTypeParameter(variableWithConstraints.typeVariable, topLevelAtoms.first()))
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
+4
-1
@@ -101,7 +101,10 @@ class CapturedTypeFromSubtyping(
|
||||
val position: ConstraintPosition
|
||||
) : ConstraintSystemCallDiagnostic(INAPPLICABLE)
|
||||
|
||||
class NotEnoughInformationForTypeParameter(val typeVariable: TypeVariableMarker) : ConstraintSystemCallDiagnostic(INAPPLICABLE)
|
||||
class NotEnoughInformationForTypeParameter(
|
||||
val typeVariable: TypeVariableMarker,
|
||||
val resolvedAtom: ResolvedAtom
|
||||
) : ConstraintSystemCallDiagnostic(INAPPLICABLE)
|
||||
|
||||
class ConstrainingTypeIsError(
|
||||
val typeVariable: TypeVariableMarker,
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
fun <K> id2(x: K, s: String): K = x
|
||||
|
||||
fun test() {
|
||||
<!NI;IMPLICIT_NOTHING_AS_TYPE_PARAMETER, NI;NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>id2<!>(<!UNRESOLVED_REFERENCE!>unresolved<!>, "foo")
|
||||
<!NI;UNREACHABLE_CODE!><!NI;IMPLICIT_NOTHING_AS_TYPE_PARAMETER, NI;NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>id2<!>(<!UNRESOLVED_REFERENCE!>unresolved<!>, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>42<!>)<!>
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package
|
||||
|
||||
public fun </*0*/ K> id2(/*0*/ x: K, /*1*/ s: kotlin.String): K
|
||||
public fun test(): kotlin.Unit
|
||||
@@ -10539,6 +10539,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/reportingImprovements/FunctionPlaceholder.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inferTypeFromUnresolvedArgument.kt")
|
||||
public void testInferTypeFromUnresolvedArgument() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/reportingImprovements/inferTypeFromUnresolvedArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NoAmbiguityForDifferentFunctionTypes.kt")
|
||||
public void testNoAmbiguityForDifferentFunctionTypes() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/reportingImprovements/NoAmbiguityForDifferentFunctionTypes.kt");
|
||||
|
||||
Generated
+5
@@ -10534,6 +10534,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
||||
runTest("compiler/testData/diagnostics/tests/inference/reportingImprovements/FunctionPlaceholder.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inferTypeFromUnresolvedArgument.kt")
|
||||
public void testInferTypeFromUnresolvedArgument() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/reportingImprovements/inferTypeFromUnresolvedArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NoAmbiguityForDifferentFunctionTypes.kt")
|
||||
public void testNoAmbiguityForDifferentFunctionTypes() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/reportingImprovements/NoAmbiguityForDifferentFunctionTypes.kt");
|
||||
|
||||
Reference in New Issue
Block a user