diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt index 1dd104f2cfe..943f3fa5ad3 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt @@ -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) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index d3743f5eac7..f71af5f2052 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -816,6 +816,7 @@ public interface Errors { DiagnosticFactory1 TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER = DiagnosticFactory1.create(ERROR); DiagnosticFactory1 NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER = DiagnosticFactory1.create(ERROR); + DiagnosticFactory1 COULD_BE_INFERRED_ONLY_WITH_UNRESTRICTED_BUILDER_INFERENCE = DiagnosticFactory1.create(ERROR); DiagnosticFactory1 TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS = DiagnosticFactory1.create(ERROR); DiagnosticFactory1 TYPE_INFERENCE_CANNOT_CAPTURE_TYPES = DiagnosticFactory1.create(ERROR); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 147fab671eb..46bbbd6af45 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -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."); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt index 968ce9fd337..40670e8f0d7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt @@ -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)) } } diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt index 9f8aa59ac78..81b8b43d921 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt @@ -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() diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintSystemCompletionContext.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintSystemCompletionContext.kt index d9f7dbde3fd..0445128706e 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintSystemCompletionContext.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintSystemCompletionContext.kt @@ -32,4 +32,6 @@ interface ConstraintSystemCompletionContext : VariableFixationFinder.Context, Re fun fixVariable(variable: TypeVariableMarker, resultType: KotlinTypeMarker, position: FixVariableConstraintPosition<*>) fun asConstraintSystemCompletionContext(): ConstraintSystemCompletionContext + + fun couldBeResolvedWithUnrestrictedBuilderInference(): Boolean } diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt index 850a1990b4f..5352ac98140 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt @@ -118,7 +118,8 @@ class CapturedTypeFromSubtyping( open class NotEnoughInformationForTypeParameter( val typeVariable: TypeVariableMarker, - val resolvedAtom: T + val resolvedAtom: T, + val couldBeResolvedWithUnrestrictedBuilderInference: Boolean ) : ConstraintSystemError(INAPPLICABLE) class ConstrainingTypeIsError( diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt index 637b275589b..28bc250f0ff 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt @@ -38,6 +38,8 @@ class NewConstraintSystemImpl( private val properTypesCache: MutableSet = SmartSet.create() private val notProperTypesCache: MutableSet = 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 } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt index 590b90d2c0b..3fbec460fbe 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt @@ -148,6 +148,7 @@ class PostponedArgumentsAnalyzer( if (hasInapplicableCallForBuilderInference) { inferenceSession?.initializeLambda(lambda) + c.getBuilder().markCouldBeResolvedWithUnrestrictedBuilderInference() c.getBuilder().removePostponedVariables() return } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt index cfe45b8097f..38f7370adc3 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt @@ -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 { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrorsImpl.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrorsImpl.kt index 721314f16d6..f35a016c6c4 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrorsImpl.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrorsImpl.kt @@ -54,5 +54,6 @@ class DelegatedPropertyConstraintPositionImpl(topLevelCall: KotlinCall) : Delega class NotEnoughInformationForTypeParameterImpl( typeVariable: TypeVariableMarker, - resolvedAtom: ResolvedAtom -) : NotEnoughInformationForTypeParameter(typeVariable, resolvedAtom) + resolvedAtom: ResolvedAtom, + couldBeResolvedWithUnrestrictedBuilderInference: Boolean +) : NotEnoughInformationForTypeParameter(typeVariable, resolvedAtom, couldBeResolvedWithUnrestrictedBuilderInference) diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/kt47744.kt b/compiler/testData/diagnostics/tests/inference/builderInference/kt47744.kt index 210223998e3..8027f7966d8 100644 --- a/compiler/testData/diagnostics/tests/inference/builderInference/kt47744.kt +++ b/compiler/testData/diagnostics/tests/inference/builderInference/kt47744.kt @@ -26,7 +26,7 @@ inline fun select(crossinline builder: SelectBuilder.() -> Unit) = Unit a fun test() { val x: Flow = flow { - produce { + produce { select { onSend("") { diff --git a/compiler/testData/diagnostics/testsWithStdLib/builderInference/incorrectCallsWithRestrictions.kt b/compiler/testData/diagnostics/testsWithStdLib/builderInference/incorrectCallsWithRestrictions.kt index 634ec01b919..ad418bef64b 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/builderInference/incorrectCallsWithRestrictions.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/builderInference/incorrectCallsWithRestrictions.kt @@ -24,12 +24,12 @@ val test2 = generate { notYield(3) } -val test3 = generate { +val test3 = generate { yield(3) yieldBarReturnType(3) } -val test4 = generate { +val test4 = generate { yield(3) barReturnType() } diff --git a/compiler/testData/diagnostics/testsWithStdLib/builderInference/resolveUsualCallWithBuilderInferenceWithRestrictions.kt b/compiler/testData/diagnostics/testsWithStdLib/builderInference/resolveUsualCallWithBuilderInferenceWithRestrictions.kt index 8405228535c..a193991da3a 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/builderInference/resolveUsualCallWithBuilderInferenceWithRestrictions.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/builderInference/resolveUsualCallWithBuilderInferenceWithRestrictions.kt @@ -28,7 +28,7 @@ val memberWithoutAnn = build { +val extension = build { extensionAdd("foo") } diff --git a/compiler/testData/diagnostics/testsWithStdLib/builderInference/useInferenceInformationFromExtensionWithRestrictions.kt b/compiler/testData/diagnostics/testsWithStdLib/builderInference/useInferenceInformationFromExtensionWithRestrictions.kt index 86d13bf0ff0..e0eb81b8a56 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/builderInference/useInferenceInformationFromExtensionWithRestrictions.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/builderInference/useInferenceInformationFromExtensionWithRestrictions.kt @@ -23,7 +23,7 @@ val normal = generate { yield(42) } -val extension = generate { +val extension = generate { extensionYield("foo") }