diff --git a/src/libstore/build/goal.cc b/src/libstore/build/goal.cc
index 9de40bdf2..7c985128b 100644
--- a/src/libstore/build/goal.cc
+++ b/src/libstore/build/goal.cc
@@ -13,11 +13,9 @@ bool CompareGoalPtrs::operator() (const GoalPtr & a, const GoalPtr & b) const {
 
 void addToWeakGoals(WeakGoals & goals, GoalPtr p)
 {
-    // FIXME: necessary?
-    // FIXME: O(n)
-    for (auto & i : goals)
-        if (i.lock() == p) return;
-    goals.push_back(p);
+    if (goals.find(p) != goals.end())
+        return;
+    goals.insert(p);
 }
 
 
@@ -46,10 +44,7 @@ void Goal::waiteeDone(GoalPtr waitee, ExitCode result)
         /* If we failed and keepGoing is not set, we remove all
            remaining waitees. */
         for (auto & goal : waitees) {
-            WeakGoals waiters2;
-            for (auto & j : goal->waiters)
-                if (j.lock() != shared_from_this()) waiters2.push_back(j);
-            goal->waiters = waiters2;
+            goal->waiters.extract(shared_from_this());
         }
         waitees.clear();
 
diff --git a/src/libstore/build/goal.hh b/src/libstore/build/goal.hh
index e6bf628cb..192e416d2 100644
--- a/src/libstore/build/goal.hh
+++ b/src/libstore/build/goal.hh
@@ -19,7 +19,7 @@ struct CompareGoalPtrs {
 
 /* Set of goals. */
 typedef set<GoalPtr, CompareGoalPtrs> Goals;
-typedef list<WeakGoalPtr> WeakGoals;
+typedef set<WeakGoalPtr, std::owner_less<WeakGoalPtr>> WeakGoals;
 
 /* A map of paths to goals (and the other way around). */
 typedef std::map<StorePath, WeakGoalPtr> WeakGoalMap;