Introduce specific error for calls which could be resolved only with unrestricted builder inference
^KT-47747 Fixed
This commit is contained in:
committed by
teamcityserver
parent
357fda2efa
commit
6a1ec92d39
+3
-1
@@ -241,7 +241,9 @@ class ConstraintSystemCompleter(private val components: BodyResolveComponents) {
|
|||||||
findResolvedAtomBy(typeVariable, topLevelAtoms) ?: topLevelAtoms.firstOrNull()
|
findResolvedAtomBy(typeVariable, topLevelAtoms) ?: topLevelAtoms.firstOrNull()
|
||||||
|
|
||||||
if (resolvedAtom != null) {
|
if (resolvedAtom != null) {
|
||||||
c.addError(NotEnoughInformationForTypeParameter(typeVariable, resolvedAtom))
|
c.addError(
|
||||||
|
NotEnoughInformationForTypeParameter(typeVariable, resolvedAtom, c.couldBeResolvedWithUnrestrictedBuilderInference())
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val resultErrorType = when (typeVariable) {
|
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, 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> 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_CONFLICTING_SUBSTITUTIONS = DiagnosticFactory1.create(ERROR);
|
||||||
DiagnosticFactory1<PsiElement, InferenceErrorData> TYPE_INFERENCE_CANNOT_CAPTURE_TYPES = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<PsiElement, InferenceErrorData> TYPE_INFERENCE_CANNOT_CAPTURE_TYPES = DiagnosticFactory1.create(ERROR);
|
||||||
|
|||||||
+1
@@ -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_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(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(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_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_INCORPORATION_ERROR, "Type inference failed. Please try to specify type arguments explicitly.");
|
||||||
|
|||||||
+7
-1
@@ -493,7 +493,13 @@ class DiagnosticReporterByTrackingStrategy(
|
|||||||
expression.statements.lastOrNull() ?: expression
|
expression.statements.lastOrNull() ?: expression
|
||||||
} else 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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
@@ -15,6 +15,7 @@ interface ConstraintSystemOperation {
|
|||||||
val hasContradiction: Boolean
|
val hasContradiction: Boolean
|
||||||
fun registerVariable(variable: TypeVariableMarker)
|
fun registerVariable(variable: TypeVariableMarker)
|
||||||
fun markPostponedVariable(variable: TypeVariableMarker)
|
fun markPostponedVariable(variable: TypeVariableMarker)
|
||||||
|
fun markCouldBeResolvedWithUnrestrictedBuilderInference()
|
||||||
fun unmarkPostponedVariable(variable: TypeVariableMarker)
|
fun unmarkPostponedVariable(variable: TypeVariableMarker)
|
||||||
fun removePostponedVariables()
|
fun removePostponedVariables()
|
||||||
|
|
||||||
|
|||||||
+2
@@ -32,4 +32,6 @@ interface ConstraintSystemCompletionContext : VariableFixationFinder.Context, Re
|
|||||||
fun fixVariable(variable: TypeVariableMarker, resultType: KotlinTypeMarker, position: FixVariableConstraintPosition<*>)
|
fun fixVariable(variable: TypeVariableMarker, resultType: KotlinTypeMarker, position: FixVariableConstraintPosition<*>)
|
||||||
|
|
||||||
fun asConstraintSystemCompletionContext(): ConstraintSystemCompletionContext
|
fun asConstraintSystemCompletionContext(): ConstraintSystemCompletionContext
|
||||||
|
|
||||||
|
fun couldBeResolvedWithUnrestrictedBuilderInference(): Boolean
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -118,7 +118,8 @@ class CapturedTypeFromSubtyping(
|
|||||||
|
|
||||||
open class NotEnoughInformationForTypeParameter<T>(
|
open class NotEnoughInformationForTypeParameter<T>(
|
||||||
val typeVariable: TypeVariableMarker,
|
val typeVariable: TypeVariableMarker,
|
||||||
val resolvedAtom: T
|
val resolvedAtom: T,
|
||||||
|
val couldBeResolvedWithUnrestrictedBuilderInference: Boolean
|
||||||
) : ConstraintSystemError(INAPPLICABLE)
|
) : ConstraintSystemError(INAPPLICABLE)
|
||||||
|
|
||||||
class ConstrainingTypeIsError(
|
class ConstrainingTypeIsError(
|
||||||
|
|||||||
+9
@@ -38,6 +38,8 @@ class NewConstraintSystemImpl(
|
|||||||
private val properTypesCache: MutableSet<KotlinTypeMarker> = SmartSet.create()
|
private val properTypesCache: MutableSet<KotlinTypeMarker> = SmartSet.create()
|
||||||
private val notProperTypesCache: MutableSet<KotlinTypeMarker> = SmartSet.create()
|
private val notProperTypesCache: MutableSet<KotlinTypeMarker> = SmartSet.create()
|
||||||
|
|
||||||
|
private var couldBeResolvedWithUnrestrictedBuilderInference: Boolean = false
|
||||||
|
|
||||||
private enum class State {
|
private enum class State {
|
||||||
BUILDING,
|
BUILDING,
|
||||||
TRANSACTION,
|
TRANSACTION,
|
||||||
@@ -118,6 +120,13 @@ class NewConstraintSystemImpl(
|
|||||||
storage.postponedTypeVariables += variable
|
storage.postponedTypeVariables += variable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun markCouldBeResolvedWithUnrestrictedBuilderInference() {
|
||||||
|
couldBeResolvedWithUnrestrictedBuilderInference = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun couldBeResolvedWithUnrestrictedBuilderInference() =
|
||||||
|
couldBeResolvedWithUnrestrictedBuilderInference
|
||||||
|
|
||||||
override fun unmarkPostponedVariable(variable: TypeVariableMarker) {
|
override fun unmarkPostponedVariable(variable: TypeVariableMarker) {
|
||||||
storage.postponedTypeVariables -= variable
|
storage.postponedTypeVariables -= variable
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -148,6 +148,7 @@ class PostponedArgumentsAnalyzer(
|
|||||||
|
|
||||||
if (hasInapplicableCallForBuilderInference) {
|
if (hasInapplicableCallForBuilderInference) {
|
||||||
inferenceSession?.initializeLambda(lambda)
|
inferenceSession?.initializeLambda(lambda)
|
||||||
|
c.getBuilder().markCouldBeResolvedWithUnrestrictedBuilderInference()
|
||||||
c.getBuilder().removePostponedVariables()
|
c.getBuilder().removePostponedVariables()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -316,7 +316,9 @@ class KotlinConstraintSystemCompleter(
|
|||||||
val resolvedAtom = findResolvedAtomBy(typeVariable, topLevelAtoms) ?: topLevelAtoms.firstOrNull()
|
val resolvedAtom = findResolvedAtomBy(typeVariable, topLevelAtoms) ?: topLevelAtoms.firstOrNull()
|
||||||
|
|
||||||
if (resolvedAtom != null) {
|
if (resolvedAtom != null) {
|
||||||
c.addError(NotEnoughInformationForTypeParameterImpl(typeVariable, resolvedAtom))
|
c.addError(
|
||||||
|
NotEnoughInformationForTypeParameterImpl(typeVariable, resolvedAtom, c.couldBeResolvedWithUnrestrictedBuilderInference())
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val resultErrorType = when {
|
val resultErrorType = when {
|
||||||
|
|||||||
+3
-2
@@ -54,5 +54,6 @@ class DelegatedPropertyConstraintPositionImpl(topLevelCall: KotlinCall) : Delega
|
|||||||
|
|
||||||
class NotEnoughInformationForTypeParameterImpl(
|
class NotEnoughInformationForTypeParameterImpl(
|
||||||
typeVariable: TypeVariableMarker,
|
typeVariable: TypeVariableMarker,
|
||||||
resolvedAtom: ResolvedAtom
|
resolvedAtom: ResolvedAtom,
|
||||||
) : NotEnoughInformationForTypeParameter<ResolvedAtom>(typeVariable, 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() {
|
fun test() {
|
||||||
val x: Flow<String> = flow {
|
val x: Flow<String> = flow {
|
||||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>produce<!> {
|
<!COULD_BE_INFERRED_ONLY_WITH_UNRESTRICTED_BUILDER_INFERENCE!>produce<!> {
|
||||||
select<Unit> {
|
select<Unit> {
|
||||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>onSend<!>("") {
|
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>onSend<!>("") {
|
||||||
|
|
||||||
|
|||||||
Vendored
+2
-2
@@ -24,12 +24,12 @@ val test2 = generate {
|
|||||||
notYield(3)
|
notYield(3)
|
||||||
}
|
}
|
||||||
|
|
||||||
val test3 = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {
|
val test3 = <!COULD_BE_INFERRED_ONLY_WITH_UNRESTRICTED_BUILDER_INFERENCE!>generate<!> {
|
||||||
yield(3)
|
yield(3)
|
||||||
yieldBarReturnType(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)
|
yield(3)
|
||||||
barReturnType()
|
barReturnType()
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -28,7 +28,7 @@ val memberWithoutAnn = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER{NI}, TYPE_IN
|
|||||||
add(42)
|
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")
|
extensionAdd("foo")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ val normal = generate {
|
|||||||
yield(42)
|
yield(42)
|
||||||
}
|
}
|
||||||
|
|
||||||
val extension = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {
|
val extension = <!COULD_BE_INFERRED_ONLY_WITH_UNRESTRICTED_BUILDER_INFERENCE!>generate<!> {
|
||||||
extensionYield("foo")
|
extensionYield("foo")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user