Merge pull request #19392 from xedin/use-unique_ptr-for-worklist

[CSStep] Switch to use `std::unique_ptr` for work list
diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp
index 564da3e..5b1f047 100644
--- a/lib/Sema/CSSolver.cpp
+++ b/lib/Sema/CSSolver.cpp
@@ -19,6 +19,7 @@
 #include "TypeCheckType.h"
 #include "swift/AST/ParameterList.h"
 #include "swift/AST/TypeWalker.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Support/Compiler.h"
@@ -1226,15 +1227,9 @@
 void ConstraintSystem::solve(SmallVectorImpl<Solution> &solutions) {
   assert(solverState);
 
-  SmallVector<SolverStep *, 16> workList;
+  SmallVector<std::unique_ptr<SolverStep>, 16> workList;
   // First step is always wraps whole constraint system.
-  workList.push_back(SplitterStep::create(*this, solutions));
-
-  SWIFT_DEFER {
-    // Delete all of the leftover steps from the work list.
-    while (!workList.empty())
-      delete workList.pop_back_val();
-  };
+  workList.push_back(llvm::make_unique<SplitterStep>(*this, solutions));
 
   // Indicate whether previous step in the stack has failed
   // (returned StepResult::Kind = Error), this is useful to
@@ -1264,7 +1259,7 @@
   // a solution, or producing another set of mergeable
   // steps to take before arriving to solution.
   while (!workList.empty()) {
-    auto *step = workList.back();
+    auto &step = workList.back();
 
     // Now let's try to advance to the next step or re-take previous,
     // which should produce another steps to follow,
@@ -1274,7 +1269,7 @@
                step->getState() == StepState::Done) &&
              "Cannot re-take already running/done step.");
 
-      auto result = advance(step, prevFailed);
+      auto result = advance(step.get(), prevFailed);
       switch (result.getKind()) {
       // It was impossible to solve this step, let's note that
       // for followup steps, to propogate the error.
@@ -1286,7 +1281,6 @@
       // toward that solution.
       case SolutionKind::Solved: {
         workList.pop_back();
-        delete step;
         break;
       }
 
diff --git a/lib/Sema/CSStep.cpp b/lib/Sema/CSStep.cpp
index a2c0512..6af164c 100644
--- a/lib/Sema/CSStep.cpp
+++ b/lib/Sema/CSStep.cpp
@@ -49,7 +49,7 @@
   if (prevFailed || CS.failedConstraint || CS.simplify())
     return done(/*isSuccess=*/false);
 
-  SmallVector<ComponentStep *, 4> components;
+  SmallVector<std::unique_ptr<ComponentStep>, 4> components;
   // Try to run "connected components" algorithm and split
   // type variables and their constraints into independent
   // sub-systems to solve.
@@ -59,10 +59,14 @@
   // try to merge solutions, "split" step should be considered
   // done and replaced by a single component step.
   if (components.size() < 2)
-    return replaceWith(components.front());
+    return replaceWith(std::move(components.front()));
+
+  SmallVector<std::unique_ptr<SolverStep>, 4> followup;
+  for (auto &step : components)
+    followup.push_back(std::move(step));
 
   /// Wait until all of the component steps are done.
-  return suspend<ComponentStep>(components);
+  return suspend(followup);
 }
 
 StepResult SplitterStep::resume(bool prevFailed) {
@@ -83,7 +87,7 @@
 }
 
 void SplitterStep::computeFollowupSteps(
-    SmallVectorImpl<ComponentStep *> &componentSteps) {
+    SmallVectorImpl<std::unique_ptr<ComponentStep>> &componentSteps) {
   // Compute next steps based on that connected components
   // algorithm tells us is splittable.
 
@@ -99,7 +103,7 @@
   SmallVector<unsigned, 16> components;
   unsigned numComponents = CG.computeConnectedComponents(typeVars, components);
   if (numComponents < 2) {
-    componentSteps.push_back(ComponentStep::create(
+    componentSteps.push_back(llvm::make_unique<ComponentStep>(
         CS, 0, /*single=*/true, &CS.InactiveConstraints, Solutions));
     return;
   }
@@ -109,7 +113,7 @@
       new SmallVector<Solution, 4>[numComponents]);
 
   for (unsigned i = 0, n = numComponents; i != n; ++i) {
-    componentSteps.push_back(ComponentStep::create(
+    componentSteps.push_back(llvm::make_unique<ComponentStep>(
         CS, i, /*single=*/false, &Components[i], PartialSolutions[i]));
   }
 
@@ -186,7 +190,8 @@
   // since components are going to be executed in LIFO order, we'd
   // want to have smaller/faster components at the back of the list.
   std::sort(componentSteps.begin(), componentSteps.end(),
-            [](const ComponentStep *lhs, const ComponentStep *rhs) {
+            [](const std::unique_ptr<ComponentStep> &lhs,
+               const std::unique_ptr<ComponentStep> &rhs) {
               return lhs->disjunctionCount() > rhs->disjunctionCount();
             });
 }
@@ -256,10 +261,12 @@
   if (bestBindings && (!disjunction || (!bestBindings->InvolvesTypeVariables &&
                                         !bestBindings->FullyBound))) {
     // Produce a type variable step.
-    return suspend(TypeVariableStep::create(CS, *bestBindings, Solutions));
+    return suspend(
+        llvm::make_unique<TypeVariableStep>(CS, *bestBindings, Solutions));
   } else if (disjunction) {
     // Produce a disjunction step.
-    return suspend(DisjunctionStep::create(CS, disjunction, Solutions));
+    return suspend(
+        llvm::make_unique<DisjunctionStep>(CS, disjunction, Solutions));
   }
 
   // If there are no disjunctions or type variables to bind
diff --git a/lib/Sema/CSStep.h b/lib/Sema/CSStep.h
index 3fd6495..f7bb00c 100644
--- a/lib/Sema/CSStep.h
+++ b/lib/Sema/CSStep.h
@@ -49,15 +49,15 @@
 
 private:
   Kind ResultKind;
-  SmallVector<SolverStep *, 4> NextSteps;
+  SmallVector<std::unique_ptr<SolverStep>, 4> NextSteps;
 
   StepResult(Kind kind) : ResultKind(kind) {}
 
-  StepResult(Kind kind, SolverStep *step) : ResultKind(kind) {
-    NextSteps.push_back(step);
+  StepResult(Kind kind, std::unique_ptr<SolverStep> step) : ResultKind(kind) {
+    NextSteps.push_back(std::move(step));
   }
 
-  StepResult(Kind kind, SmallVectorImpl<SolverStep *> &followup)
+  StepResult(Kind kind, SmallVectorImpl<std::unique_ptr<SolverStep>> &followup)
       : ResultKind(kind), NextSteps(std::move(followup)) {}
 
 public:
@@ -65,29 +65,24 @@
 
   Kind getKind() const { return ResultKind; }
 
-  void transfer(SmallVectorImpl<SolverStep *> &workList) {
+  void transfer(SmallVectorImpl<std::unique_ptr<SolverStep>> &workList) {
     workList.reserve(NextSteps.size());
-    workList.append(NextSteps.begin(), NextSteps.end());
+    for (auto &step : NextSteps)
+      workList.push_back(std::move(step));
   }
 
 private:
   static StepResult success() { return StepResult(Kind::Solved); }
   static StepResult failure() { return StepResult(Kind::Error); }
 
-  static StepResult unsolved(SolverStep *singleStep) {
-    return StepResult(Kind::Unsolved, singleStep);
+  static StepResult unsolved(std::unique_ptr<SolverStep> singleStep) {
+    return StepResult(Kind::Unsolved, std::move(singleStep));
   }
 
-  static StepResult unsolved(SmallVectorImpl<SolverStep *> &followup) {
+  static StepResult
+  unsolved(SmallVectorImpl<std::unique_ptr<SolverStep>> &followup) {
     return StepResult(Kind::Unsolved, followup);
   }
-
-  template <typename T> static StepResult unsolved(ArrayRef<T *> followup) {
-    auto result = StepResult(Kind::Unsolved);
-    for (auto *step : followup)
-      result.NextSteps.push_back(static_cast<SolverStep *>(step));
-    return result;
-  }
 };
 
 /// Represents a single independently solvable part of
@@ -167,22 +162,17 @@
     return isSuccess ? StepResult::success() : StepResult::failure();
   }
 
-  StepResult replaceWith(SolverStep *replacement) {
+  StepResult replaceWith(std::unique_ptr<SolverStep> replacement) {
     transitionTo(StepState::Done);
-    return StepResult(StepResult::Kind::Solved, replacement);
+    return StepResult(StepResult::Kind::Solved, std::move(replacement));
   }
 
-  StepResult suspend(SolverStep *followup) {
+  StepResult suspend(std::unique_ptr<SolverStep> followup) {
     transitionTo(StepState::Suspended);
-    return StepResult::unsolved(followup);
+    return StepResult::unsolved(std::move(followup));
   }
 
-  StepResult suspend(SmallVectorImpl<SolverStep *> &followup) {
-    transitionTo(StepState::Suspended);
-    return StepResult::unsolved(followup);
-  }
-
-  template <typename T> StepResult suspend(ArrayRef<T *> followup) {
+  StepResult suspend(SmallVectorImpl<std::unique_ptr<SolverStep>> &followup) {
     transitionTo(StepState::Suspended);
     return StepResult::unsolved(followup);
   }
@@ -244,10 +234,10 @@
 
   SmallVector<Constraint *, 4> OrphanedConstraints;
 
+public:
   SplitterStep(ConstraintSystem &cs, SmallVectorImpl<Solution> &solutions)
       : SolverStep(cs, solutions) {}
 
-public:
   StepResult take(bool prevFailed) override;
   StepResult resume(bool prevFailed) override;
 
@@ -255,15 +245,11 @@
     Out << "SplitterStep with #" << Components.size() << " components\n";
   }
 
-  static SplitterStep *create(ConstraintSystem &cs,
-                              SmallVectorImpl<Solution> &solutions) {
-    return new SplitterStep(cs, solutions);
-  }
-
 private:
   /// If current step needs follow-up steps to get completely solved,
   /// let's compute them using connected components algorithm.
-  void computeFollowupSteps(SmallVectorImpl<ComponentStep *> &componentSteps);
+  void computeFollowupSteps(
+      SmallVectorImpl<std::unique_ptr<ComponentStep>> &componentSteps);
 
   /// Once all of the follow-up steps are complete, let's try
   /// to merge resulting solutions together, to form final solution(s)
@@ -339,6 +325,7 @@
   /// with it, which makes it disconnected in the graph.
   Constraint *OrphanedConstraint = nullptr;
 
+public:
   ComponentStep(ConstraintSystem &cs, unsigned index, bool single,
                 ConstraintList *constraints,
                 SmallVectorImpl<Solution> &solutions)
@@ -346,7 +333,6 @@
         OriginalScore(getCurrentScore()), OriginalBestScore(getBestScore()),
         Constraints(constraints) {}
 
-public:
   /// Record a type variable as associated with this step.
   void record(TypeVariableType *typeVar) { TypeVars.push_back(typeVar); }
 
@@ -388,12 +374,6 @@
   void print(llvm::raw_ostream &Out) override {
     Out << "ComponentStep with at #" << Index << '\n';
   }
-
-  static ComponentStep *create(ConstraintSystem &cs, unsigned index,
-                               bool single, ConstraintList *constraints,
-                               SmallVectorImpl<Solution> &solutions) {
-    return new ComponentStep(cs, index, single, constraints, solutions);
-  }
 };
 
 template <typename P> class BindingStep : public SolverStep {
@@ -429,7 +409,7 @@
         auto scope = llvm::make_unique<Scope>(CS);
         if (attempt(*choice)) {
           ActiveChoice.emplace(std::move(scope), *choice);
-          return suspend(SplitterStep::create(CS, Solutions));
+          return suspend(llvm::make_unique<SplitterStep>(CS, Solutions));
         }
       }
 
@@ -490,12 +470,12 @@
   /// attempting other bindings in certain conditions.
   bool SawFirstLiteralConstraint = false;
 
+public:
   TypeVariableStep(ConstraintSystem &cs, BindingContainer &bindings,
                    SmallVectorImpl<Solution> &solutions)
       : BindingStep(cs, {cs, bindings}, solutions), TypeVar(bindings.TypeVar),
         InitialBindings(bindings.Bindings.begin(), bindings.Bindings.end()) {}
 
-public:
   void setup() override;
 
   StepResult resume(bool prevFailed) override;
@@ -505,12 +485,6 @@
         << InitialBindings.size() << " initial bindings\n";
   }
 
-  static TypeVariableStep *create(ConstraintSystem &cs,
-                                  BindingContainer &bindings,
-                                  SmallVectorImpl<Solution> &solutions) {
-    return new TypeVariableStep(cs, bindings, solutions);
-  }
-
 protected:
   bool attempt(const TypeVariableBinding &choice) override;
 
@@ -574,11 +548,6 @@
     Out << '\n';
   }
 
-  static DisjunctionStep *create(ConstraintSystem &cs, Constraint *disjunction,
-                                 SmallVectorImpl<Solution> &solutions) {
-    return new DisjunctionStep(cs, disjunction, solutions);
-  }
-
 private:
   bool shouldSkip(const DisjunctionChoice &choice) const override;