@@ -775,6 +775,12 @@ class ConjunctionStep : public BindingStep<ConjunctionElementProducer> {
775
775
llvm::SetVector<TypeVariableType *> TypeVars;
776
776
ConstraintList Constraints;
777
777
778
+ // / If this conjunction has to be solved in isolation,
779
+ // / this scope would be initialized once all of the
780
+ // / elements are successfully solved to continue solving
781
+ // / along the current path as-if there was no conjunction.
782
+ std::unique_ptr<Scope> IsolationScope = nullptr ;
783
+
778
784
public:
779
785
SolverSnapshot (ConstraintSystem &cs)
780
786
: CS(cs), TypeVars(std::move(cs.TypeVariables)) {
@@ -786,12 +792,47 @@ class ConjunctionStep : public BindingStep<ConjunctionElementProducer> {
786
792
CG.removeConstraint (&constraint);
787
793
}
788
794
795
+ void setupOuterContext (Solution solution) {
796
+ // Re-add type variables and constraints back
797
+ // to the constraint system.
798
+ restore ();
799
+
800
+ // Establish isolation scope so that conjunction solution
801
+ // and follow-up steps could be rolled back.
802
+ IsolationScope = std::make_unique<Scope>(CS);
803
+
804
+ // Apply solution inferred for the conjunction.
805
+ CS.applySolution (solution);
806
+
807
+ // Add constraints to the graph after solution
808
+ // has been applied to make sure that all type
809
+ // information is available to incremental inference.
810
+ for (auto &constraint : CS.InactiveConstraints )
811
+ CS.CG .addConstraint (&constraint);
812
+ }
813
+
814
+ bool isScoped () const { return bool (IsolationScope); }
815
+
789
816
~SolverSnapshot () {
790
- auto &CG = CS.getConstraintGraph ();
817
+ if (!IsolationScope)
818
+ restore ();
819
+
820
+ IsolationScope.reset ();
821
+ // Re-add all of the constraint to the constraint
822
+ // graph after scope has been rolled back, to make
823
+ // make sure the original (before conjunction)
824
+ // state is completely restored.
825
+ updateConstraintGraph ();
826
+ }
791
827
828
+ private:
829
+ void restore () {
792
830
CS.TypeVariables = std::move (TypeVars);
793
831
CS.InactiveConstraints .splice (CS.InactiveConstraints .end (), Constraints);
832
+ }
794
833
834
+ void updateConstraintGraph () {
835
+ auto &CG = CS.getConstraintGraph ();
795
836
for (auto &constraint : CS.InactiveConstraints )
796
837
CG.addConstraint (&constraint);
797
838
}
@@ -812,12 +853,6 @@ class ConjunctionStep : public BindingStep<ConjunctionElementProducer> {
812
853
// / Indicates that one of the elements failed inference.
813
854
bool HadFailure = false ;
814
855
815
- // / If this conjunction has to be solved in isolation,
816
- // / this scope would be initialized once all of the
817
- // / elements are successfully solved to continue solving
818
- // / along the current path as-if there was no conjunction.
819
- std::unique_ptr<Scope> IsolationScope = nullptr ;
820
-
821
856
// / If conjunction has to be solved in isolation, this
822
857
// / variable would capture the snapshot of the constraint
823
858
// / system step before conjunction step.
@@ -838,7 +873,6 @@ class ConjunctionStep : public BindingStep<ConjunctionElementProducer> {
838
873
839
874
~ConjunctionStep () override {
840
875
assert (!bool (ActiveChoice));
841
- assert (!bool (IsolationScope));
842
876
843
877
// Return all of the type variables and constraints back.
844
878
Snapshot.reset ();
0 commit comments