Skip to content

Commit 717db34

Browse files
committed
[CSStep] Fix up closure type if conjunction fails in diagnostic mode
To avoid unnecessary fixes when solver discovers that closure type is only partially resolved after conjunction failure, let's fix it up by replacing type variables with placeholders after solution application.
1 parent 94a4d84 commit 717db34

File tree

1 file changed

+37
-3
lines changed

1 file changed

+37
-3
lines changed

lib/Sema/CSStep.h

+37-3
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,9 @@ class ConjunctionStep : public BindingStep<ConjunctionElementProducer> {
781781
class SolverSnapshot {
782782
ConstraintSystem &CS;
783783

784+
/// The conjunction this snapshot belongs to.
785+
Constraint *Conjunction;
786+
784787
Optional<llvm::SaveAndRestore<DeclContext *>> DC = None;
785788

786789
llvm::SetVector<TypeVariableType *> TypeVars;
@@ -794,8 +797,9 @@ class ConjunctionStep : public BindingStep<ConjunctionElementProducer> {
794797

795798
public:
796799
SolverSnapshot(ConstraintSystem &cs, Constraint *conjunction)
797-
: CS(cs), TypeVars(std::move(cs.TypeVariables)) {
798-
auto *locator = conjunction->getLocator();
800+
: CS(cs), Conjunction(conjunction),
801+
TypeVars(std::move(cs.TypeVariables)) {
802+
auto *locator = Conjunction->getLocator();
799803
// If this conjunction represents a closure, we need to
800804
// switch declaration context over to it.
801805
if (locator->directlyAt<ClosureExpr>()) {
@@ -820,7 +824,7 @@ class ConjunctionStep : public BindingStep<ConjunctionElementProducer> {
820824
IsolationScope = std::make_unique<Scope>(CS);
821825

822826
// Apply solution inferred for the conjunction.
823-
CS.applySolution(solution);
827+
applySolution(solution);
824828

825829
// Add constraints to the graph after solution
826830
// has been applied to make sure that all type
@@ -855,6 +859,36 @@ class ConjunctionStep : public BindingStep<ConjunctionElementProducer> {
855859
for (auto &constraint : CS.InactiveConstraints)
856860
CG.addConstraint(&constraint);
857861
}
862+
863+
void applySolution(const Solution &solution) {
864+
CS.applySolution(solution);
865+
866+
if (!CS.shouldAttemptFixes())
867+
return;
868+
869+
// If inference succeeded, we are done.
870+
auto score = solution.getFixedScore();
871+
if (score.Data[SK_Fix] == 0)
872+
return;
873+
874+
// If this conjunction represents a closure and inference
875+
// has failed, let's bind all of unresolved type variables
876+
// in its interface type to holes to avoid extraneous
877+
// fixes produced by outer context.
878+
879+
auto locator = Conjunction->getLocator();
880+
if (locator->directlyAt<ClosureExpr>()) {
881+
auto closureTy =
882+
CS.getClosureType(castToExpr<ClosureExpr>(locator->getAnchor()));
883+
884+
CS.simplifyType(closureTy).visit([&](Type componentTy) {
885+
if (auto *typeVar = componentTy->getAs<TypeVariableType>()) {
886+
CS.assignFixedType(
887+
typeVar, PlaceholderType::get(CS.getASTContext(), typeVar));
888+
}
889+
});
890+
}
891+
}
858892
};
859893

860894
/// Best solution solver reached so far.

0 commit comments

Comments
 (0)