Introduce specific error for calls which could be resolved only with unrestricted builder inference

^KT-47747 Fixed
This commit is contained in:
Victor Petukhov
2021-07-15 12:57:31 +03:00
committed by teamcityserver
parent 357fda2efa
commit 6a1ec92d39
15 changed files with 38 additions and 11 deletions
@@ -241,7 +241,9 @@ class ConstraintSystemCompleter(private val components: BodyResolveComponents) {
findResolvedAtomBy(typeVariable, topLevelAtoms) ?: topLevelAtoms.firstOrNull()
if (resolvedAtom != null) {
c.addError(NotEnoughInformationForTypeParameter(typeVariable, resolvedAtom))
c.addError(
NotEnoughInformationForTypeParameter(typeVariable, resolvedAtom, c.couldBeResolvedWithUnrestrictedBuilderInference())
)
}
val resultErrorType = when (typeVariable) {
@@ -816,6 +816,7 @@ public interface Errors {
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, String> COULD_BE_INFERRED_ONLY_WITH_UNRESTRICTED_BUILDER_INFERENCE = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, InferenceErrorData> TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, InferenceErrorData> TYPE_INFERENCE_CANNOT_CAPTURE_TYPES = DiagnosticFactory1.create(ERROR);
@@ -919,6 +919,7 @@ public class DefaultErrorMessages {
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(COULD_BE_INFERRED_ONLY_WITH_UNRESTRICTED_BUILDER_INFERENCE, "Builder inference lambda contains inapplicable calls so {1} can't be inferred. It could be resolved only with unrestricted builder inference. Please use -Xunrestricted-builder-inference compiler flag to enable it.", 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.");
@@ -493,7 +493,13 @@ class DiagnosticReporterByTrackingStrategy(
expression.statements.lastOrNull() ?: expression
} else expression
trace.reportDiagnosticOnce(NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER.on(unwrappedExpression, typeVariableName))
val diagnostic = if (error.couldBeResolvedWithUnrestrictedBuilderInference) {
COULD_BE_INFERRED_ONLY_WITH_UNRESTRICTED_BUILDER_INFERENCE
} else {
NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER
}
trace.reportDiagnosticOnce(diagnostic.on(unwrappedExpression, typeVariableName))
}
}
@@ -15,6 +15,7 @@ interface ConstraintSystemOperation {
val hasContradiction: Boolean
fun registerVariable(variable: TypeVariableMarker)
fun markPostponedVariable(variable: TypeVariableMarker)
fun markCouldBeResolvedWithUnrestrictedBuilderInference()
fun unmarkPostponedVariable(variable: TypeVariableMarker)
fun removePostponedVariables()
@@ -32,4 +32,6 @@ interface ConstraintSystemCompletionContext : VariableFixationFinder.Context, Re
fun fixVariable(variable: TypeVariableMarker, resultType: KotlinTypeMarker, position: FixVariableConstraintPosition<*>)
fun asConstraintSystemCompletionContext(): ConstraintSystemCompletionContext
fun couldBeResolvedWithUnrestrictedBuilderInference(): Boolean
}
@@ -118,7 +118,8 @@ class CapturedTypeFromSubtyping(
open class NotEnoughInformationForTypeParameter<T>(
val typeVariable: TypeVariableMarker,
val resolvedAtom: T
val resolvedAtom: T,
val couldBeResolvedWithUnrestrictedBuilderInference: Boolean
) : ConstraintSystemError(INAPPLICABLE)
class ConstrainingTypeIsError(
@@ -38,6 +38,8 @@ class NewConstraintSystemImpl(
private val properTypesCache: MutableSet<KotlinTypeMarker> = SmartSet.create()
private val notProperTypesCache: MutableSet<KotlinTypeMarker> = SmartSet.create()
private var couldBeResolvedWithUnrestrictedBuilderInference: Boolean = false
private enum class State {
BUILDING,
TRANSACTION,
@@ -118,6 +120,13 @@ class NewConstraintSystemImpl(
storage.postponedTypeVariables += variable
}
override fun markCouldBeResolvedWithUnrestrictedBuilderInference() {
couldBeResolvedWithUnrestrictedBuilderInference = true
}
override fun couldBeResolvedWithUnrestrictedBuilderInference() =
couldBeResolvedWithUnrestrictedBuilderInference
override fun unmarkPostponedVariable(variable: TypeVariableMarker) {
storage.postponedTypeVariables -= variable
}
@@ -148,6 +148,7 @@ class PostponedArgumentsAnalyzer(
if (hasInapplicableCallForBuilderInference) {
inferenceSession?.initializeLambda(lambda)
c.getBuilder().markCouldBeResolvedWithUnrestrictedBuilderInference()
c.getBuilder().removePostponedVariables()
return
}
@@ -316,7 +316,9 @@ class KotlinConstraintSystemCompleter(
val resolvedAtom = findResolvedAtomBy(typeVariable, topLevelAtoms) ?: topLevelAtoms.firstOrNull()
if (resolvedAtom != null) {
c.addError(NotEnoughInformationForTypeParameterImpl(typeVariable, resolvedAtom))
c.addError(
NotEnoughInformationForTypeParameterImpl(typeVariable, resolvedAtom, c.couldBeResolvedWithUnrestrictedBuilderInference())
)
}
val resultErrorType = when {
@@ -54,5 +54,6 @@ class DelegatedPropertyConstraintPositionImpl(topLevelCall: KotlinCall) : Delega
class NotEnoughInformationForTypeParameterImpl(
typeVariable: TypeVariableMarker,
resolvedAtom: ResolvedAtom
) : NotEnoughInformationForTypeParameter<ResolvedAtom>(typeVariable, resolvedAtom)
resolvedAtom: ResolvedAtom,
couldBeResolvedWithUnrestrictedBuilderInference: Boolean
) : NotEnoughInformationForTypeParameter<ResolvedAtom>(typeVariable, resolvedAtom, couldBeResolvedWithUnrestrictedBuilderInference)
@@ -26,7 +26,7 @@ inline fun <R> select(crossinline builder: SelectBuilder<R>.() -> Unit) = Unit a
fun test() {
val x: Flow<String> = flow {
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>produce<!> {
<!COULD_BE_INFERRED_ONLY_WITH_UNRESTRICTED_BUILDER_INFERENCE!>produce<!> {
select<Unit> {
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>onSend<!>("") {
@@ -24,12 +24,12 @@ val test2 = generate {
notYield(3)
}
val test3 = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {
val test3 = <!COULD_BE_INFERRED_ONLY_WITH_UNRESTRICTED_BUILDER_INFERENCE!>generate<!> {
yield(3)
yieldBarReturnType(3)
}
val test4 = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {
val test4 = <!COULD_BE_INFERRED_ONLY_WITH_UNRESTRICTED_BUILDER_INFERENCE!>generate<!> {
yield(3)
barReturnType()
}
@@ -28,7 +28,7 @@ val memberWithoutAnn = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER{NI}, TYPE_IN
add(42)
}
val extension = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER{OI}!>build<!> {
val extension = <!COULD_BE_INFERRED_ONLY_WITH_UNRESTRICTED_BUILDER_INFERENCE, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER{OI}, TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER{OI}!>build<!> {
extensionAdd("foo")
}
@@ -23,7 +23,7 @@ val normal = generate {
yield(42)
}
val extension = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {
val extension = <!COULD_BE_INFERRED_ONLY_WITH_UNRESTRICTED_BUILDER_INFERENCE!>generate<!> {
extensionYield("foo")
}