about summary refs log tree commit diff
path: root/src/libstore
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/build.cc204
-rw-r--r--src/libstore/derivations.cc38
-rw-r--r--src/libstore/gc.cc43
-rw-r--r--src/libstore/globals.cc16
-rw-r--r--src/libstore/local-store.cc146
-rw-r--r--src/libstore/misc.cc86
-rw-r--r--src/libstore/optimise-store.cc14
-rw-r--r--src/libstore/pathlocks.cc27
-rw-r--r--src/libstore/references.cc20
-rw-r--r--src/libstore/remote-store.cc28
-rw-r--r--src/libstore/store-api.cc44
11 files changed, 331 insertions, 335 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 5e2e7d89a3ee..8f1d5b2c891d 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -331,8 +331,8 @@ void addToWeakGoals(WeakGoals & goals, GoalPtr p)
 {
     // FIXME: necessary?
     // FIXME: O(n)
-    foreach (WeakGoals::iterator, i, goals)
-        if (i->lock() == p) return;
+    for (auto & i : goals)
+        if (i.lock() == p) return;
     goals.push_back(p);
 }
 
@@ -362,11 +362,10 @@ void Goal::waiteeDone(GoalPtr waitee, ExitCode result)
 
         /* If we failed and keepGoing is not set, we remove all
            remaining waitees. */
-        foreach (Goals::iterator, i, waitees) {
-            GoalPtr goal = *i;
+        for (auto & goal : waitees) {
             WeakGoals waiters2;
-            foreach (WeakGoals::iterator, j, goal->waiters)
-                if (j->lock() != shared_from_this()) waiters2.push_back(*j);
+            for (auto & j : goal->waiters)
+                if (j.lock() != shared_from_this()) waiters2.push_back(j);
             goal->waiters = waiters2;
         }
         waitees.clear();
@@ -382,8 +381,8 @@ void Goal::amDone(ExitCode result)
     assert(exitCode == ecBusy);
     assert(result == ecSuccess || result == ecFailed || result == ecNoSubstituters || result == ecIncompleteClosure);
     exitCode = result;
-    foreach (WeakGoals::iterator, i, waiters) {
-        GoalPtr goal = i->lock();
+    for (auto & i : waiters) {
+        GoalPtr goal = i.lock();
         if (goal) goal->waiteeDone(shared_from_this(), result);
     }
     waiters.clear();
@@ -509,13 +508,13 @@ void UserLock::acquire()
 
     /* Find a user account that isn't currently in use for another
        build. */
-    foreach (Strings::iterator, i, users) {
-        debug(format("trying user ‘%1%’") % *i);
+    for (auto & i : users) {
+        debug(format("trying user ‘%1%’") % i);
 
-        struct passwd * pw = getpwnam(i->c_str());
+        struct passwd * pw = getpwnam(i.c_str());
         if (!pw)
             throw Error(format("the user ‘%1%’ in the group ‘%2%’ does not exist")
-                % *i % settings.buildUsersGroup);
+                % i % settings.buildUsersGroup);
 
         createDirs(settings.nixStateDir + "/userpool");
 
@@ -533,7 +532,7 @@ void UserLock::acquire()
         if (lockFile(fd, ltWrite, false)) {
             fdUserLock = fd.borrow();
             lockedPaths.insert(fnUserLock);
-            user = *i;
+            user = i;
             uid = pw->pw_uid;
 
             /* Sanity check... */
@@ -669,12 +668,12 @@ typedef map<string, string> HashRewrites;
 
 string rewriteHashes(string s, const HashRewrites & rewrites)
 {
-    foreach (HashRewrites::const_iterator, i, rewrites) {
-        assert(i->first.size() == i->second.size());
+    for (auto & i : rewrites) {
+        assert(i.first.size() == i.second.size());
         size_t j = 0;
-        while ((j = s.find(i->first, j)) != string::npos) {
+        while ((j = s.find(i.first, j)) != string::npos) {
             debug(format("rewriting @ %1%") % j);
-            s.replace(j, i->second.size(), i->second);
+            s.replace(j, i.second.size(), i.second);
         }
     }
     return s;
@@ -962,9 +961,9 @@ void DerivationGoal::addWantedOutputs(const StringSet & outputs)
         wantedOutputs.clear();
         needRestart = true;
     } else
-        foreach (StringSet::const_iterator, i, outputs)
-            if (wantedOutputs.find(*i) == wantedOutputs.end()) {
-                wantedOutputs.insert(*i);
+        for (auto & i : outputs)
+            if (wantedOutputs.find(i) == wantedOutputs.end()) {
+                wantedOutputs.insert(i);
                 needRestart = true;
             }
 }
@@ -1307,7 +1306,7 @@ void DerivationGoal::tryToBuild()
 
     missingPaths = outputPaths(*drv);
     if (buildMode != bmCheck)
-        foreach (PathSet::iterator, i, validPaths) missingPaths.erase(*i);
+        for (auto & i : validPaths) missingPaths.erase(i);
 
     /* If any of the outputs already exist but are not valid, delete
        them. */
@@ -1469,9 +1468,9 @@ void DerivationGoal::buildDone()
             /* Move paths out of the chroot for easier debugging of
                build failures. */
             if (useChroot && buildMode == bmNormal)
-                foreach (PathSet::iterator, i, missingPaths)
-                    if (pathExists(chrootRootDir + *i))
-                        rename((chrootRootDir + *i).c_str(), i->c_str());
+                for (auto & i : missingPaths)
+                    if (pathExists(chrootRootDir + i))
+                        rename((chrootRootDir + i).c_str(), i.c_str());
 
             if (diskFull)
                 printMsg(lvlError, "note: build failure may have been caused by lack of free disk space");
@@ -1490,8 +1489,8 @@ void DerivationGoal::buildDone()
         }
 
         /* Delete unused redirected outputs (when doing hash rewriting). */
-        foreach (RedirectedOutputs::iterator, i, redirectedOutputs)
-            if (pathExists(i->second)) deletePath(i->second);
+        for (auto & i : redirectedOutputs)
+            if (pathExists(i.second)) deletePath(i.second);
 
         /* Delete the chroot (if we were using one). */
         autoDelChroot.reset(); /* this runs the destructor */
@@ -1566,7 +1565,7 @@ HookReply DerivationGoal::tryBuildHook()
        required from the build machine.  (The hook could parse the
        drv file itself, but this is easier.) */
     Strings features = tokenizeString<Strings>(get(drv->env, "requiredSystemFeatures"));
-    foreach (Strings::iterator, i, features) checkStoreName(*i); /* !!! abuse */
+    for (auto & i : features) checkStoreName(i); /* !!! abuse */
 
     /* Send the request to the hook. */
     writeLine(worker.hook->toHook.writeSide, (format("%1% %2% %3% %4%")
@@ -1608,13 +1607,13 @@ HookReply DerivationGoal::tryBuildHook()
     computeFSClosure(worker.store, drvPath, allInputs);
 
     string s;
-    foreach (PathSet::iterator, i, allInputs) { s += *i; s += ' '; }
+    for (auto & i : allInputs) { s += i; s += ' '; }
     writeLine(hook->toHook.writeSide, s);
 
     /* Tell the hooks the missing outputs that have to be copied back
        from the remote system. */
     s = "";
-    foreach (PathSet::iterator, i, missingPaths) { s += *i; s += ' '; }
+    for (auto & i : missingPaths) { s += i; s += ' '; }
     writeLine(hook->toHook.writeSide, s);
 
     hook->toHook.writeSide.close();
@@ -1742,7 +1741,7 @@ void DerivationGoal::startBuilder()
        already know the cryptographic hash of the output). */
     if (fixedOutput) {
         Strings varNames = tokenizeString<Strings>(get(drv->env, "impureEnvVars"));
-        foreach (Strings::iterator, i, varNames) env[*i] = getEnv(*i);
+        for (auto & i : varNames) env[i] = getEnv(i);
     }
 
     /* The `exportReferencesGraph' feature allows the references graph
@@ -1778,9 +1777,9 @@ void DerivationGoal::startBuilder()
         computeFSClosure(worker.store, storePath, paths);
         paths2 = paths;
 
-        foreach (PathSet::iterator, j, paths2) {
-            if (isDerivation(*j)) {
-                Derivation drv = derivationFromPath(worker.store, *j);
+        for (auto & j : paths2) {
+            if (isDerivation(j)) {
+                Derivation drv = derivationFromPath(worker.store, j);
                 for (auto & k : drv.outputs)
                     computeFSClosure(worker.store, k.second.path, paths);
             }
@@ -1951,28 +1950,28 @@ void DerivationGoal::startBuilder()
         if (chown(chrootStoreDir.c_str(), 0, buildUser.getGID()) == -1)
             throw SysError(format("cannot change ownership of ‘%1%’") % chrootStoreDir);
 
-        foreach (PathSet::iterator, i, inputPaths) {
+        for (auto & i : inputPaths) {
             struct stat st;
-            if (lstat(i->c_str(), &st))
-                throw SysError(format("getting attributes of path ‘%1%’") % *i);
+            if (lstat(i.c_str(), &st))
+                throw SysError(format("getting attributes of path ‘%1%’") % i);
             if (S_ISDIR(st.st_mode))
-                dirsInChroot[*i] = *i;
+                dirsInChroot[i] = i;
             else {
-                Path p = chrootRootDir + *i;
-                if (link(i->c_str(), p.c_str()) == -1) {
+                Path p = chrootRootDir + i;
+                if (link(i.c_str(), p.c_str()) == -1) {
                     /* Hard-linking fails if we exceed the maximum
                        link count on a file (e.g. 32000 of ext3),
                        which is quite possible after a `nix-store
                        --optimise'. */
                     if (errno != EMLINK)
-                        throw SysError(format("linking ‘%1%’ to ‘%2%’") % p % *i);
+                        throw SysError(format("linking ‘%1%’ to ‘%2%’") % p % i);
                     StringSink sink;
-                    dumpPath(*i, sink);
+                    dumpPath(i, sink);
                     StringSource source(sink.s);
                     restorePath(p, source);
                 }
 
-                regularInputPaths.insert(*i);
+                regularInputPaths.insert(i);
             }
         }
 
@@ -2007,16 +2006,16 @@ void DerivationGoal::startBuilder()
            contents of the new outputs to replace the dummy strings
            with the actual hashes. */
         if (validPaths.size() > 0)
-            foreach (PathSet::iterator, i, validPaths)
-                addHashRewrite(*i);
+            for (auto & i : validPaths)
+                addHashRewrite(i);
 
         /* If we're repairing, then we don't want to delete the
            corrupt outputs in advance.  So rewrite them as well. */
         if (buildMode == bmRepair)
-            foreach (PathSet::iterator, i, missingPaths)
-                if (worker.store.isValidPath(*i) && pathExists(*i)) {
-                    addHashRewrite(*i);
-                    redirectedBadOutputs.insert(*i);
+            for (auto & i : missingPaths)
+                if (worker.store.isValidPath(i) && pathExists(i)) {
+                    addHashRewrite(i);
+                    redirectedBadOutputs.insert(i);
                 }
     }
 
@@ -2190,8 +2189,8 @@ void DerivationGoal::runChild()
                local to the namespace, though, so setting MS_PRIVATE
                does not affect the outside world. */
             Strings mounts = tokenizeString<Strings>(readFile("/proc/self/mountinfo", true), "\n");
-            foreach (Strings::iterator, i, mounts) {
-                vector<string> fields = tokenizeString<vector<string> >(*i, " ");
+            for (auto & i : mounts) {
+                vector<string> fields = tokenizeString<vector<string> >(i, " ");
                 string fs = decodeOctalEscaped(fields.at(4));
                 if (mount(0, fs.c_str(), 0, MS_PRIVATE, 0) == -1)
                     throw SysError(format("unable to make filesystem ‘%1%’ private") % fs);
@@ -2239,10 +2238,10 @@ void DerivationGoal::runChild()
             /* Bind-mount all the directories from the "host"
                filesystem that we want in the chroot
                environment. */
-            foreach (DirsInChroot::iterator, i, dirsInChroot) {
+            for (auto & i : dirsInChroot) {
                 struct stat st;
-                Path source = i->second;
-                Path target = chrootRootDir + i->first;
+                Path source = i.second;
+                Path target = chrootRootDir + i.first;
                 if (source == "/proc") continue; // backwards compatibility
                 debug(format("bind mounting ‘%1%’ to ‘%2%’") % source % target);
                 if (stat(source.c_str(), &st) == -1)
@@ -2340,8 +2339,8 @@ void DerivationGoal::runChild()
 
         /* Fill in the environment. */
         Strings envStrs;
-        foreach (Environment::const_iterator, i, env)
-            envStrs.push_back(rewriteHashes(i->first + "=" + i->second, rewritesToTmp));
+        for (auto & i : env)
+            envStrs.push_back(rewriteHashes(i.first + "=" + i.second, rewritesToTmp));
 
         /* If we are running in `build-users' mode, then switch to the
            user we allocated above.  Make sure that we drop all root
@@ -2522,14 +2521,13 @@ PathSet parseReferenceSpecifiers(const BasicDerivation & drv, string attr)
 {
     PathSet result;
     Paths paths = tokenizeString<Paths>(attr);
-    foreach (Strings::iterator, i, paths) {
-        if (isStorePath(*i))
-            result.insert(*i);
-        else if (drv.outputs.find(*i) != drv.outputs.end())
-            result.insert(drv.outputs.find(*i)->second.path);
+    for (auto & i : paths) {
+        if (isStorePath(i))
+            result.insert(i);
+        else if (drv.outputs.find(i) != drv.outputs.end())
+            result.insert(drv.outputs.find(i)->second.path);
         else throw BuildError(
-            format("derivation contains an illegal reference specifier ‘%1%’")
-            % *i);
+            format("derivation contains an illegal reference specifier ‘%1%’") % i);
     }
     return result;
 }
@@ -2666,12 +2664,12 @@ void DerivationGoal::registerOutputs()
 
         /* For debugging, print out the referenced and unreferenced
            paths. */
-        foreach (PathSet::iterator, i, inputPaths) {
-            PathSet::iterator j = references.find(*i);
+        for (auto & i : inputPaths) {
+            PathSet::iterator j = references.find(i);
             if (j == references.end())
-                debug(format("unreferenced input: ‘%1%’") % *i);
+                debug(format("unreferenced input: ‘%1%’") % i);
             else
-                debug(format("referenced input: ‘%1%’") % *i);
+                debug(format("referenced input: ‘%1%’") % i);
         }
 
         /* Enforce `allowedReferences' and friends. */
@@ -3044,9 +3042,9 @@ void SubstitutionGoal::tryNext()
 
     /* To maintain the closure invariant, we first have to realise the
        paths referenced by this one. */
-    foreach (PathSet::iterator, i, info.references)
-        if (*i != storePath) /* ignore self-references */
-            addWaitee(worker.makeSubstitutionGoal(*i));
+    for (auto & i : info.references)
+        if (i != storePath) /* ignore self-references */
+            addWaitee(worker.makeSubstitutionGoal(i));
 
     if (waitees.empty()) /* to prevent hang (no wake-up event) */
         referencesValid();
@@ -3065,9 +3063,9 @@ void SubstitutionGoal::referencesValid()
         return;
     }
 
-    foreach (PathSet::iterator, i, info.references)
-        if (*i != storePath) /* ignore self-references */
-            assert(worker.store.isValidPath(*i));
+    for (auto & i : info.references)
+        if (i != storePath) /* ignore self-references */
+            assert(worker.store.isValidPath(i));
 
     state = &SubstitutionGoal::tryToRun;
     worker.wakeUp(shared_from_this());
@@ -3359,8 +3357,8 @@ void Worker::removeGoal(GoalPtr goal)
     }
 
     /* Wake up goals waiting for any goal to finish. */
-    foreach (WeakGoals::iterator, i, waitingForAnyGoal) {
-        GoalPtr goal = i->lock();
+    for (auto & i : waitingForAnyGoal) {
+        GoalPtr goal = i.lock();
         if (goal) wakeUp(goal);
     }
 
@@ -3413,8 +3411,8 @@ void Worker::childTerminated(pid_t pid, bool wakeSleepers)
     if (wakeSleepers) {
 
         /* Wake up goals waiting for a build slot. */
-        foreach (WeakGoals::iterator, i, wantingToBuild) {
-            GoalPtr goal = i->lock();
+        for (auto & i : wantingToBuild) {
+            GoalPtr goal = i.lock();
             if (goal) wakeUp(goal);
         }
 
@@ -3449,7 +3447,7 @@ void Worker::waitForAWhile(GoalPtr goal)
 
 void Worker::run(const Goals & _topGoals)
 {
-    foreach (Goals::iterator, i,  _topGoals) topGoals.insert(*i);
+    for (auto & i : _topGoals) topGoals.insert(i);
 
     startNest(nest, lvlDebug, format("entered goal loop"));
 
@@ -3515,12 +3513,12 @@ void Worker::waitForInput()
        deadline for any child. */
     assert(sizeof(time_t) >= sizeof(long));
     time_t nearest = LONG_MAX; // nearest deadline
-    foreach (Children::iterator, i, children) {
-        if (!i->second.respectTimeouts) continue;
+    for (auto & i : children) {
+        if (!i.second.respectTimeouts) continue;
         if (settings.maxSilentTime != 0)
-            nearest = std::min(nearest, i->second.lastOutput + settings.maxSilentTime);
+            nearest = std::min(nearest, i.second.lastOutput + settings.maxSilentTime);
         if (settings.buildTimeout != 0)
-            nearest = std::min(nearest, i->second.timeStarted + settings.buildTimeout);
+            nearest = std::min(nearest, i.second.timeStarted + settings.buildTimeout);
     }
     if (nearest != LONG_MAX) {
         timeout.tv_sec = std::max((time_t) 1, nearest - before);
@@ -3545,10 +3543,10 @@ void Worker::waitForInput()
     fd_set fds;
     FD_ZERO(&fds);
     int fdMax = 0;
-    foreach (Children::iterator, i, children) {
-        foreach (set<int>::iterator, j, i->second.fds) {
-            FD_SET(*j, &fds);
-            if (*j >= fdMax) fdMax = *j + 1;
+    for (auto & i : children) {
+        for (auto & j : i.second.fds) {
+            FD_SET(j, &fds);
+            if (j >= fdMax) fdMax = j + 1;
         }
     }
 
@@ -3566,34 +3564,34 @@ void Worker::waitForInput()
        careful that we don't keep iterators alive across calls to
        cancel(). */
     set<pid_t> pids;
-    foreach (Children::iterator, i, children) pids.insert(i->first);
+    for (auto & i : children) pids.insert(i.first);
 
-    foreach (set<pid_t>::iterator, i, pids) {
+    for (auto & i : pids) {
         checkInterrupt();
-        Children::iterator j = children.find(*i);
+        Children::iterator j = children.find(i);
         if (j == children.end()) continue; // child destroyed
         GoalPtr goal = j->second.goal.lock();
         assert(goal);
 
         set<int> fds2(j->second.fds);
-        foreach (set<int>::iterator, k, fds2) {
-            if (FD_ISSET(*k, &fds)) {
+        for (auto & k : fds2) {
+            if (FD_ISSET(k, &fds)) {
                 unsigned char buffer[4096];
-                ssize_t rd = read(*k, buffer, sizeof(buffer));
+                ssize_t rd = read(k, buffer, sizeof(buffer));
                 if (rd == -1) {
                     if (errno != EINTR)
                         throw SysError(format("reading from %1%")
                             % goal->getName());
                 } else if (rd == 0) {
                     debug(format("%1%: got EOF") % goal->getName());
-                    goal->handleEOF(*k);
-                    j->second.fds.erase(*k);
+                    goal->handleEOF(k);
+                    j->second.fds.erase(k);
                 } else {
                     printMsg(lvlVomit, format("%1%: read %2% bytes")
                         % goal->getName() % rd);
                     string data((char *) buffer, rd);
                     j->second.lastOutput = after;
-                    goal->handleChildOutput(*k, data);
+                    goal->handleChildOutput(k, data);
                 }
             }
         }
@@ -3625,8 +3623,8 @@ void Worker::waitForInput()
 
     if (!waitingForAWhile.empty() && lastWokenUp + settings.pollInterval <= after) {
         lastWokenUp = after;
-        foreach (WeakGoals::iterator, i, waitingForAWhile) {
-            GoalPtr goal = i->lock();
+        for (auto & i : waitingForAWhile) {
+            GoalPtr goal = i.lock();
             if (goal) wakeUp(goal);
         }
         waitingForAWhile.clear();
@@ -3650,22 +3648,22 @@ void LocalStore::buildPaths(const PathSet & drvPaths, BuildMode buildMode)
     Worker worker(*this);
 
     Goals goals;
-    foreach (PathSet::const_iterator, i, drvPaths) {
-        DrvPathWithOutputs i2 = parseDrvPathWithOutputs(*i);
+    for (auto & i : drvPaths) {
+        DrvPathWithOutputs i2 = parseDrvPathWithOutputs(i);
         if (isDerivation(i2.first))
             goals.insert(worker.makeDerivationGoal(i2.first, i2.second, buildMode));
         else
-            goals.insert(worker.makeSubstitutionGoal(*i, buildMode));
+            goals.insert(worker.makeSubstitutionGoal(i, buildMode));
     }
 
     worker.run(goals);
 
     PathSet failed;
-    foreach (Goals::iterator, i, goals)
-        if ((*i)->getExitCode() == Goal::ecFailed) {
-            DerivationGoal * i2 = dynamic_cast<DerivationGoal *>(i->get());
+    for (auto & i : goals)
+        if (i->getExitCode() == Goal::ecFailed) {
+            DerivationGoal * i2 = dynamic_cast<DerivationGoal *>(i.get());
             if (i2) failed.insert(i2->getDrvPath());
-            else failed.insert(dynamic_cast<SubstitutionGoal *>(i->get())->getStorePath());
+            else failed.insert(dynamic_cast<SubstitutionGoal *>(i.get())->getStorePath());
         }
 
     if (!failed.empty())
diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc
index db35af6cbccc..7959d5bfc3d5 100644
--- a/src/libstore/derivations.cc
+++ b/src/libstore/derivations.cc
@@ -32,8 +32,8 @@ Path writeDerivation(StoreAPI & store,
 {
     PathSet references;
     references.insert(drv.inputSrcs.begin(), drv.inputSrcs.end());
-    foreach (DerivationInputs::const_iterator, i, drv.inputDrvs)
-        references.insert(i->first);
+    for (auto & i : drv.inputDrvs)
+        references.insert(i.first);
     /* Note that the outputs of a derivation are *not* references
        (that can be missing (of course) and should not necessarily be
        held during a garbage collection). */
@@ -156,21 +156,21 @@ string unparseDerivation(const Derivation & drv)
     s += "Derive([";
 
     bool first = true;
-    foreach (DerivationOutputs::const_iterator, i, drv.outputs) {
+    for (auto & i : drv.outputs) {
         if (first) first = false; else s += ',';
-        s += '('; printString(s, i->first);
-        s += ','; printString(s, i->second.path);
-        s += ','; printString(s, i->second.hashAlgo);
-        s += ','; printString(s, i->second.hash);
+        s += '('; printString(s, i.first);
+        s += ','; printString(s, i.second.path);
+        s += ','; printString(s, i.second.hashAlgo);
+        s += ','; printString(s, i.second.hash);
         s += ')';
     }
 
     s += "],[";
     first = true;
-    foreach (DerivationInputs::const_iterator, i, drv.inputDrvs) {
+    for (auto & i : drv.inputDrvs) {
         if (first) first = false; else s += ',';
-        s += '('; printString(s, i->first);
-        s += ','; printStrings(s, i->second.begin(), i->second.end());
+        s += '('; printString(s, i.first);
+        s += ','; printStrings(s, i.second.begin(), i.second.end());
         s += ')';
     }
 
@@ -183,10 +183,10 @@ string unparseDerivation(const Derivation & drv)
 
     s += ",[";
     first = true;
-    foreach (StringPairs::const_iterator, i, drv.env) {
+    for (auto & i : drv.env) {
         if (first) first = false; else s += ',';
-        s += '('; printString(s, i->first);
-        s += ','; printString(s, i->second);
+        s += '('; printString(s, i.first);
+        s += ','; printString(s, i.second);
         s += ')';
     }
 
@@ -247,15 +247,15 @@ Hash hashDerivationModulo(StoreAPI & store, Derivation drv)
     /* For other derivations, replace the inputs paths with recursive
        calls to this function.*/
     DerivationInputs inputs2;
-    foreach (DerivationInputs::const_iterator, i, drv.inputDrvs) {
-        Hash h = drvHashes[i->first];
+    for (auto & i : drv.inputDrvs) {
+        Hash h = drvHashes[i.first];
         if (h.type == htUnknown) {
-            assert(store.isValidPath(i->first));
-            Derivation drv2 = readDerivation(i->first);
+            assert(store.isValidPath(i.first));
+            Derivation drv2 = readDerivation(i.first);
             h = hashDerivationModulo(store, drv2);
-            drvHashes[i->first] = h;
+            drvHashes[i.first] = h;
         }
-        inputs2[printHash(h)] = i->second;
+        inputs2[printHash(h)] = i.second;
     }
     drv.inputDrvs = inputs2;
 
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index 8d7da67f5204..998a7516a13d 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -350,15 +350,14 @@ static void addAdditionalRoots(StoreAPI & store, PathSet & roots)
 
     StringSet paths = tokenizeString<StringSet>(result, "\n");
 
-    foreach (StringSet::iterator, i, paths) {
-        if (isInStore(*i)) {
-            Path path = toStorePath(*i);
+    for (auto & i : paths)
+        if (isInStore(i)) {
+            Path path = toStorePath(i);
             if (roots.find(path) == roots.end() && store.isValidPath(path)) {
                 debug(format("got additional root ‘%1%’") % path);
                 roots.insert(path);
             }
         }
-    }
 }
 
 
@@ -408,8 +407,8 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
     if (isValidPath(path)) {
         PathSet referrers;
         queryReferrers(path, referrers);
-        foreach (PathSet::iterator, i, referrers)
-            if (*i != path) deletePathRecursive(state, *i);
+        for (auto & i : referrers)
+            if (i != path) deletePathRecursive(state, i);
         size = queryPathInfo(path).narSize;
         invalidatePathChecked(path);
     }
@@ -487,22 +486,22 @@ bool LocalStore::canReachRoot(GCState & state, PathSet & visited, const Path & p
        don't delete the derivation if any of the outputs are alive. */
     if (state.gcKeepDerivations && isDerivation(path)) {
         PathSet outputs = queryDerivationOutputs(path);
-        foreach (PathSet::iterator, i, outputs)
-            if (isValidPath(*i) && queryDeriver(*i) == path)
-                incoming.insert(*i);
+        for (auto & i : outputs)
+            if (isValidPath(i) && queryDeriver(i) == path)
+                incoming.insert(i);
     }
 
     /* If gc-keep-outputs is set, then don't delete this path if there
        are derivers of this path that are not garbage. */
     if (state.gcKeepOutputs) {
         PathSet derivers = queryValidDerivers(path);
-        foreach (PathSet::iterator, i, derivers)
-            incoming.insert(*i);
+        for (auto & i : derivers)
+            incoming.insert(i);
     }
 
-    foreach (PathSet::iterator, i, incoming)
-        if (*i != path)
-            if (canReachRoot(state, visited, *i)) {
+    for (auto & i : incoming)
+        if (i != path)
+            if (canReachRoot(state, visited, i)) {
                 state.alive.insert(path);
                 return true;
             }
@@ -622,7 +621,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
     printMsg(lvlError, format("finding garbage collector roots..."));
     Roots rootMap = options.ignoreLiveness ? Roots() : findRoots();
 
-    foreach (Roots::iterator, i, rootMap) state.roots.insert(i->second);
+    for (auto & i : rootMap) state.roots.insert(i.second);
 
     /* Add additional roots returned by the program specified by the
        NIX_ROOT_FINDER environment variable.  This is typically used
@@ -659,11 +658,11 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
 
     if (options.action == GCOptions::gcDeleteSpecific) {
 
-        foreach (PathSet::iterator, i, options.pathsToDelete) {
-            assertStorePath(*i);
-            tryToDelete(state, *i);
-            if (state.dead.find(*i) == state.dead.end())
-                throw Error(format("cannot delete path ‘%1%’ since it is still alive") % *i);
+        for (auto & i : options.pathsToDelete) {
+            assertStorePath(i);
+            tryToDelete(state, i);
+            if (state.dead.find(i) == state.dead.end())
+                throw Error(format("cannot delete path ‘%1%’ since it is still alive") % i);
         }
 
     } else if (options.maxFreed > 0) {
@@ -707,8 +706,8 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
             vector<Path> entries_(entries.begin(), entries.end());
             random_shuffle(entries_.begin(), entries_.end());
 
-            foreach (vector<Path>::iterator, i, entries_)
-                tryToDelete(state, *i);
+            for (auto & i : entries_)
+                tryToDelete(state, i);
 
         } catch (GCLimitReached & e) {
         }
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index 50374f782dee..73f8489438fc 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -248,12 +248,12 @@ template<class N> void Settings::_get(N & res, const string & name)
 string Settings::pack()
 {
     string s;
-    foreach (SettingsMap::iterator, i, settings) {
-        if (i->first.find('\n') != string::npos ||
-            i->first.find('=') != string::npos ||
-            i->second.find('\n') != string::npos)
+    for (auto & i : settings) {
+        if (i.first.find('\n') != string::npos ||
+            i.first.find('=') != string::npos ||
+            i.second.find('\n') != string::npos)
             throw Error("illegal option name/value");
-        s += i->first; s += '='; s += i->second; s += '\n';
+        s += i.first; s += '='; s += i.second; s += '\n';
     }
     return s;
 }
@@ -261,11 +261,11 @@ string Settings::pack()
 
 void Settings::unpack(const string & pack) {
     Strings lines = tokenizeString<Strings>(pack, "\n");
-    foreach (Strings::iterator, i, lines) {
-        string::size_type eq = i->find('=');
+    for (auto & i : lines) {
+        string::size_type eq = i.find('=');
         if (eq == string::npos)
             throw Error("illegal option name/value");
-        set(i->substr(0, eq), i->substr(eq + 1));
+        set(i.substr(0, eq), i.substr(eq + 1));
     }
 }
 
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 074c3394ffb1..319f1c719fd6 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -367,13 +367,13 @@ LocalStore::LocalStore(bool reserveSpace)
 LocalStore::~LocalStore()
 {
     try {
-        foreach (RunningSubstituters::iterator, i, runningSubstituters) {
-            if (i->second.disabled) continue;
-            i->second.to.close();
-            i->second.from.close();
-            i->second.error.close();
-            if (i->second.pid != -1)
-                i->second.pid.wait(true);
+        for (auto & i : runningSubstituters) {
+            if (i.second.disabled) continue;
+            i.second.to.close();
+            i.second.from.close();
+            i.second.error.close();
+            if (i.second.pid != -1)
+                i.second.pid.wait(true);
         }
     } catch (...) {
         ignoreException();
@@ -671,19 +671,19 @@ void LocalStore::checkDerivationOutputs(const Path & drvPath, const Derivation &
 
     else {
         Derivation drvCopy(drv);
-        foreach (DerivationOutputs::iterator, i, drvCopy.outputs) {
-            i->second.path = "";
-            drvCopy.env[i->first] = "";
+        for (auto & i : drvCopy.outputs) {
+            i.second.path = "";
+            drvCopy.env[i.first] = "";
         }
 
         Hash h = hashDerivationModulo(*this, drvCopy);
 
-        foreach (DerivationOutputs::const_iterator, i, drv.outputs) {
-            Path outPath = makeOutputPath(i->first, h, drvName);
-            StringPairs::const_iterator j = drv.env.find(i->first);
-            if (i->second.path != outPath || j == drv.env.end() || j->second != outPath)
+        for (auto & i : drv.outputs) {
+            Path outPath = makeOutputPath(i.first, h, drvName);
+            StringPairs::const_iterator j = drv.env.find(i.first);
+            if (i.second.path != outPath || j == drv.env.end() || j->second != outPath)
                 throw Error(format("derivation ‘%1%’ has incorrect output ‘%2%’, should be ‘%3%’")
-                    % drvPath % i->second.path % outPath);
+                    % drvPath % i.second.path % outPath);
         }
     }
 }
@@ -721,11 +721,11 @@ unsigned long long LocalStore::addValidPath(const ValidPathInfo & info, bool che
            registration above is undone. */
         if (checkOutputs) checkDerivationOutputs(info.path, drv);
 
-        foreach (DerivationOutputs::iterator, i, drv.outputs) {
+        for (auto & i : drv.outputs) {
             SQLiteStmtUse use(stmtAddDerivationOutput);
             stmtAddDerivationOutput.bind(id);
-            stmtAddDerivationOutput.bind(i->first);
-            stmtAddDerivationOutput.bind(i->second.path);
+            stmtAddDerivationOutput.bind(i.first);
+            stmtAddDerivationOutput.bind(i.second.path);
             if (sqlite3_step(stmtAddDerivationOutput) != SQLITE_DONE)
                 throwSQLiteError(db, format("adding derivation output for ‘%1%’ in database") % info.path);
         }
@@ -796,11 +796,11 @@ void LocalStore::clearFailedPaths(const PathSet & paths)
     retry_sqlite {
         SQLiteTxn txn(db);
 
-        foreach (PathSet::const_iterator, i, paths) {
+        for (auto & i : paths) {
             SQLiteStmtUse use(stmtClearFailedPath);
-            stmtClearFailedPath.bind(*i);
+            stmtClearFailedPath.bind(i);
             if (sqlite3_step(stmtClearFailedPath) != SQLITE_DONE)
-                throwSQLiteError(db, format("clearing failed path ‘%1%’ in database") % *i);
+                throwSQLiteError(db, format("clearing failed path ‘%1%’ in database") % i);
         }
 
         txn.commit();
@@ -923,8 +923,8 @@ PathSet LocalStore::queryValidPaths(const PathSet & paths)
 {
     retry_sqlite {
         PathSet res;
-        foreach (PathSet::const_iterator, i, paths)
-            if (isValidPath_(*i)) res.insert(*i);
+        for (auto & i : paths)
+            if (isValidPath_(i)) res.insert(i);
         return res;
     } end_retry_sqlite;
 }
@@ -1212,14 +1212,14 @@ template<class T> T LocalStore::getIntLineFromSubstituter(RunningSubstituter & r
 PathSet LocalStore::querySubstitutablePaths(const PathSet & paths)
 {
     PathSet res;
-    foreach (Paths::iterator, i, settings.substituters) {
+    for (auto & i : settings.substituters) {
         if (res.size() == paths.size()) break;
-        RunningSubstituter & run(runningSubstituters[*i]);
-        startSubstituter(*i, run);
+        RunningSubstituter & run(runningSubstituters[i]);
+        startSubstituter(i, run);
         if (run.disabled) continue;
         string s = "have ";
-        foreach (PathSet::const_iterator, j, paths)
-            if (res.find(*j) == res.end()) { s += *j; s += " "; }
+        for (auto & j : paths)
+            if (res.find(j) == res.end()) { s += j; s += " "; }
         writeLine(run.to, s);
         while (true) {
             /* FIXME: we only read stderr when an error occurs, so
@@ -1243,8 +1243,8 @@ void LocalStore::querySubstitutablePathInfos(const Path & substituter,
     if (run.disabled) return;
 
     string s = "info ";
-    foreach (PathSet::const_iterator, i, paths)
-        if (infos.find(*i) == infos.end()) { s += *i; s += " "; }
+    for (auto & i : paths)
+        if (infos.find(i) == infos.end()) { s += i; s += " "; }
     writeLine(run.to, s);
 
     while (true) {
@@ -1272,9 +1272,9 @@ void LocalStore::querySubstitutablePathInfos(const PathSet & paths,
     SubstitutablePathInfos & infos)
 {
     PathSet todo = paths;
-    foreach (Paths::iterator, i, settings.substituters) {
+    for (auto & i : settings.substituters) {
         if (todo.empty()) break;
-        querySubstitutablePathInfos(*i, todo, infos);
+        querySubstitutablePathInfos(i, todo, infos);
     }
 }
 
@@ -1304,30 +1304,30 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos)
         SQLiteTxn txn(db);
         PathSet paths;
 
-        foreach (ValidPathInfos::const_iterator, i, infos) {
-            assert(i->hash.type == htSHA256);
-            if (isValidPath_(i->path))
-                updatePathInfo(*i);
+        for (auto & i : infos) {
+            assert(i.hash.type == htSHA256);
+            if (isValidPath_(i.path))
+                updatePathInfo(i);
             else
-                addValidPath(*i, false);
-            paths.insert(i->path);
+                addValidPath(i, false);
+            paths.insert(i.path);
         }
 
-        foreach (ValidPathInfos::const_iterator, i, infos) {
-            unsigned long long referrer = queryValidPathId(i->path);
-            foreach (PathSet::iterator, j, i->references)
-                addReference(referrer, queryValidPathId(*j));
+        for (auto & i : infos) {
+            unsigned long long referrer = queryValidPathId(i.path);
+            for (auto & j : i.references)
+                addReference(referrer, queryValidPathId(j));
         }
 
         /* Check that the derivation outputs are correct.  We can't do
            this in addValidPath() above, because the references might
            not be valid yet. */
-        foreach (ValidPathInfos::const_iterator, i, infos)
-            if (isDerivation(i->path)) {
+        for (auto & i : infos)
+            if (isDerivation(i.path)) {
                 // FIXME: inefficient; we already loaded the
                 // derivation in addValidPath().
-                Derivation drv = readDerivation(i->path);
-                checkDerivationOutputs(i->path, drv);
+                Derivation drv = readDerivation(i.path);
+                checkDerivationOutputs(i.path, drv);
             }
 
         /* Do a topological sort of the paths.  This will throw an
@@ -1761,8 +1761,8 @@ bool LocalStore::verifyStore(bool checkContents, bool repair)
 
     PathSet validPaths2 = queryAllValidPaths(), validPaths, done;
 
-    foreach (PathSet::iterator, i, validPaths2)
-        verifyPath(*i, store, done, validPaths, repair, errors);
+    for (auto & i : validPaths2)
+        verifyPath(i, store, done, validPaths, repair, errors);
 
     /* Release the GC lock so that checking content hashes (which can
        take ages) doesn't block the GC or builds. */
@@ -1774,33 +1774,33 @@ bool LocalStore::verifyStore(bool checkContents, bool repair)
 
         Hash nullHash(htSHA256);
 
-        foreach (PathSet::iterator, i, validPaths) {
+        for (auto & i : validPaths) {
             try {
-                ValidPathInfo info = queryPathInfo(*i);
+                ValidPathInfo info = queryPathInfo(i);
 
                 /* Check the content hash (optionally - slow). */
-                printMsg(lvlTalkative, format("checking contents of ‘%1%’") % *i);
-                HashResult current = hashPath(info.hash.type, *i);
+                printMsg(lvlTalkative, format("checking contents of ‘%1%’") % i);
+                HashResult current = hashPath(info.hash.type, i);
 
                 if (info.hash != nullHash && info.hash != current.first) {
                     printMsg(lvlError, format("path ‘%1%’ was modified! "
                             "expected hash ‘%2%’, got ‘%3%’")
-                        % *i % printHash(info.hash) % printHash(current.first));
-                    if (repair) repairPath(*i); else errors = true;
+                        % i % printHash(info.hash) % printHash(current.first));
+                    if (repair) repairPath(i); else errors = true;
                 } else {
 
                     bool update = false;
 
                     /* Fill in missing hashes. */
                     if (info.hash == nullHash) {
-                        printMsg(lvlError, format("fixing missing hash on ‘%1%’") % *i);
+                        printMsg(lvlError, format("fixing missing hash on ‘%1%’") % i);
                         info.hash = current.first;
                         update = true;
                     }
 
                     /* Fill in missing narSize fields (from old stores). */
                     if (info.narSize == 0) {
-                        printMsg(lvlError, format("updating size field on ‘%1%’ to %2%") % *i % current.second);
+                        printMsg(lvlError, format("updating size field on ‘%1%’ to %2%") % i % current.second);
                         info.narSize = current.second;
                         update = true;
                     }
@@ -1812,7 +1812,7 @@ bool LocalStore::verifyStore(bool checkContents, bool repair)
             } catch (Error & e) {
                 /* It's possible that the path got GC'ed, so ignore
                    errors on invalid paths. */
-                if (isValidPath(*i))
+                if (isValidPath(i))
                     printMsg(lvlError, format("error: %1%") % e.msg());
                 else
                     printMsg(lvlError, format("warning: %1%") % e.msg());
@@ -1844,10 +1844,10 @@ void LocalStore::verifyPath(const Path & path, const PathSet & store,
            first, then we can invalidate this path as well. */
         bool canInvalidate = true;
         PathSet referrers; queryReferrers(path, referrers);
-        foreach (PathSet::iterator, i, referrers)
-            if (*i != path) {
-                verifyPath(*i, store, done, validPaths, repair, errors);
-                if (validPaths.find(*i) != validPaths.end())
+        for (auto & i : referrers)
+            if (i != path) {
+                verifyPath(i, store, done, validPaths, repair, errors);
+                if (validPaths.find(i) != validPaths.end())
                     canInvalidate = false;
             }
 
@@ -1925,12 +1925,12 @@ ValidPathInfo LocalStore::queryPathInfoOld(const Path & path)
     /* Parse it. */
     Strings lines = tokenizeString<Strings>(info, "\n");
 
-    foreach (Strings::iterator, i, lines) {
-        string::size_type p = i->find(':');
+    for (auto & i : lines) {
+        string::size_type p = i.find(':');
         if (p == string::npos)
-            throw Error(format("corrupt line in ‘%1%’: %2%") % infoFile % *i);
-        string name(*i, 0, p);
-        string value(*i, p + 2);
+            throw Error(format("corrupt line in ‘%1%’: %2%") % infoFile % i);
+        string name(i, 0, p);
+        string value(i, p + 2);
         if (name == "References") {
             Strings refs = tokenizeString<Strings>(value, " ");
             res.references = PathSet(refs.begin(), refs.end());
@@ -1960,18 +1960,18 @@ void LocalStore::upgradeStore6()
 
     SQLiteTxn txn(db);
 
-    foreach (PathSet::iterator, i, validPaths) {
-        addValidPath(queryPathInfoOld(*i), false);
+    for (auto & i : validPaths) {
+        addValidPath(queryPathInfoOld(i), false);
         std::cerr << ".";
     }
 
     std::cerr << "|";
 
-    foreach (PathSet::iterator, i, validPaths) {
-        ValidPathInfo info = queryPathInfoOld(*i);
-        unsigned long long referrer = queryValidPathId(*i);
-        foreach (PathSet::iterator, j, info.references)
-            addReference(referrer, queryValidPathId(*j));
+    for (auto & i : validPaths) {
+        ValidPathInfo info = queryPathInfoOld(i);
+        unsigned long long referrer = queryValidPathId(i);
+        for (auto & j : info.references)
+            addReference(referrer, queryValidPathId(j));
         std::cerr << ".";
     }
 
diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc
index 736434ca4895..61a976c02f5c 100644
--- a/src/libstore/misc.cc
+++ b/src/libstore/misc.cc
@@ -28,15 +28,15 @@ void computeFSClosure(StoreAPI & store, const Path & path,
 
         if (includeOutputs) {
             PathSet derivers = store.queryValidDerivers(path);
-            foreach (PathSet::iterator, i, derivers)
-                edges.insert(*i);
+            for (auto & i : derivers)
+                edges.insert(i);
         }
 
         if (includeDerivers && isDerivation(path)) {
             PathSet outputs = store.queryDerivationOutputs(path);
-            foreach (PathSet::iterator, i, outputs)
-                if (store.isValidPath(*i) && store.queryDeriver(*i) == path)
-                    edges.insert(*i);
+            for (auto & i : outputs)
+                if (store.isValidPath(i) && store.queryDeriver(i) == path)
+                    edges.insert(i);
         }
 
     } else {
@@ -44,8 +44,8 @@ void computeFSClosure(StoreAPI & store, const Path & path,
 
         if (includeOutputs && isDerivation(path)) {
             PathSet outputs = store.queryDerivationOutputs(path);
-            foreach (PathSet::iterator, i, outputs)
-                if (store.isValidPath(*i)) edges.insert(*i);
+            for (auto & i : outputs)
+                if (store.isValidPath(i)) edges.insert(i);
         }
 
         if (includeDerivers) {
@@ -54,15 +54,15 @@ void computeFSClosure(StoreAPI & store, const Path & path,
         }
     }
 
-    foreach (PathSet::iterator, i, edges)
-        computeFSClosure(store, *i, paths, flipDirection, includeOutputs, includeDerivers);
+    for (auto & i : edges)
+        computeFSClosure(store, i, paths, flipDirection, includeOutputs, includeDerivers);
 }
 
 
 Path findOutput(const Derivation & drv, string id)
 {
-    foreach (DerivationOutputs::const_iterator, i, drv.outputs)
-        if (i->first == id) return i->second.path;
+    for (auto & i : drv.outputs)
+        if (i.first == id) return i.second.path;
     throw Error(format("derivation has no output ‘%1%’") % id);
 }
 
@@ -98,36 +98,36 @@ void queryMissing(StoreAPI & store, const PathSet & targets,
 
         PathSet query, todoDrv, todoNonDrv;
 
-        foreach (PathSet::iterator, i, todo) {
-            if (done.find(*i) != done.end()) continue;
-            done.insert(*i);
+        for (auto & i : todo) {
+            if (done.find(i) != done.end()) continue;
+            done.insert(i);
 
-            DrvPathWithOutputs i2 = parseDrvPathWithOutputs(*i);
+            DrvPathWithOutputs i2 = parseDrvPathWithOutputs(i);
 
             if (isDerivation(i2.first)) {
                 if (!store.isValidPath(i2.first)) {
                     // FIXME: we could try to substitute p.
-                    unknown.insert(*i);
+                    unknown.insert(i);
                     continue;
                 }
                 Derivation drv = derivationFromPath(store, i2.first);
 
                 PathSet invalid;
-                foreach (DerivationOutputs::iterator, j, drv.outputs)
-                    if (wantOutput(j->first, i2.second)
-                        && !store.isValidPath(j->second.path))
-                        invalid.insert(j->second.path);
+                for (auto & j : drv.outputs)
+                    if (wantOutput(j.first, i2.second)
+                        && !store.isValidPath(j.second.path))
+                        invalid.insert(j.second.path);
                 if (invalid.empty()) continue;
 
-                todoDrv.insert(*i);
+                todoDrv.insert(i);
                 if (settings.useSubstitutes && substitutesAllowed(drv))
                     query.insert(invalid.begin(), invalid.end());
             }
 
             else {
-                if (store.isValidPath(*i)) continue;
-                query.insert(*i);
-                todoNonDrv.insert(*i);
+                if (store.isValidPath(i)) continue;
+                query.insert(i);
+                todoNonDrv.insert(i);
             }
         }
 
@@ -136,8 +136,8 @@ void queryMissing(StoreAPI & store, const PathSet & targets,
         SubstitutablePathInfos infos;
         store.querySubstitutablePathInfos(query, infos);
 
-        foreach (PathSet::iterator, i, todoDrv) {
-            DrvPathWithOutputs i2 = parseDrvPathWithOutputs(*i);
+        for (auto & i : todoDrv) {
+            DrvPathWithOutputs i2 = parseDrvPathWithOutputs(i);
 
             // FIXME: cache this
             Derivation drv = derivationFromPath(store, i2.first);
@@ -145,13 +145,13 @@ void queryMissing(StoreAPI & store, const PathSet & targets,
             PathSet outputs;
             bool mustBuild = false;
             if (settings.useSubstitutes && substitutesAllowed(drv)) {
-                foreach (DerivationOutputs::iterator, j, drv.outputs) {
-                    if (!wantOutput(j->first, i2.second)) continue;
-                    if (!store.isValidPath(j->second.path)) {
-                        if (infos.find(j->second.path) == infos.end())
+                for (auto & j : drv.outputs) {
+                    if (!wantOutput(j.first, i2.second)) continue;
+                    if (!store.isValidPath(j.second.path)) {
+                        if (infos.find(j.second.path) == infos.end())
                             mustBuild = true;
                         else
-                            outputs.insert(j->second.path);
+                            outputs.insert(j.second.path);
                     }
                 }
             } else
@@ -160,22 +160,22 @@ void queryMissing(StoreAPI & store, const PathSet & targets,
             if (mustBuild) {
                 willBuild.insert(i2.first);
                 todo.insert(drv.inputSrcs.begin(), drv.inputSrcs.end());
-                foreach (DerivationInputs::iterator, j, drv.inputDrvs)
-                    todo.insert(makeDrvPathWithOutputs(j->first, j->second));
+                for (auto & j : drv.inputDrvs)
+                    todo.insert(makeDrvPathWithOutputs(j.first, j.second));
             } else
                 todoNonDrv.insert(outputs.begin(), outputs.end());
         }
 
-        foreach (PathSet::iterator, i, todoNonDrv) {
-            done.insert(*i);
-            SubstitutablePathInfos::iterator info = infos.find(*i);
+        for (auto & i : todoNonDrv) {
+            done.insert(i);
+            SubstitutablePathInfos::iterator info = infos.find(i);
             if (info != infos.end()) {
-                willSubstitute.insert(*i);
+                willSubstitute.insert(i);
                 downloadSize += info->second.downloadSize;
                 narSize += info->second.narSize;
                 todo.insert(info->second.references.begin(), info->second.references.end());
             } else
-                unknown.insert(*i);
+                unknown.insert(i);
         }
     }
 }
@@ -196,11 +196,11 @@ static void dfsVisit(StoreAPI & store, const PathSet & paths,
     if (store.isValidPath(path))
         store.queryReferences(path, references);
 
-    foreach (PathSet::iterator, i, references)
+    for (auto & i : references)
         /* Don't traverse into paths that don't exist.  That can
            happen due to substitutes for non-existent paths. */
-        if (*i != path && paths.find(*i) != paths.end())
-            dfsVisit(store, paths, *i, visited, sorted, parents);
+        if (i != path && paths.find(i) != paths.end())
+            dfsVisit(store, paths, i, visited, sorted, parents);
 
     sorted.push_front(path);
     parents.erase(path);
@@ -211,8 +211,8 @@ Paths topoSortPaths(StoreAPI & store, const PathSet & paths)
 {
     Paths sorted;
     PathSet visited, parents;
-    foreach (PathSet::const_iterator, i, paths)
-        dfsVisit(store, paths, *i, visited, sorted, parents);
+    for (auto & i : paths)
+        dfsVisit(store, paths, i, visited, sorted, parents);
     return sorted;
 }
 
diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc
index 55c252b9b2e3..6f66961792fb 100644
--- a/src/libstore/optimise-store.cc
+++ b/src/libstore/optimise-store.cc
@@ -99,8 +99,8 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
 
     if (S_ISDIR(st.st_mode)) {
         Strings names = readDirectoryIgnoringInodes(path, inodeHash);
-        foreach (Strings::iterator, i, names)
-            optimisePath_(stats, path + "/" + *i, inodeHash);
+        for (auto & i : names)
+            optimisePath_(stats, path + "/" + i, inodeHash);
         return;
     }
 
@@ -218,11 +218,11 @@ void LocalStore::optimiseStore(OptimiseStats & stats)
     PathSet paths = queryAllValidPaths();
     InodeHash inodeHash = loadInodeHash();
 
-    foreach (PathSet::iterator, i, paths) {
-        addTempRoot(*i);
-        if (!isValidPath(*i)) continue; /* path was GC'ed, probably */
-        startNest(nest, lvlChatty, format("hashing files in ‘%1%’") % *i);
-        optimisePath_(stats, *i, inodeHash);
+    for (auto & i : paths) {
+        addTempRoot(i);
+        if (!isValidPath(i)) continue; /* path was GC'ed, probably */
+        startNest(nest, lvlChatty, format("hashing files in ‘%1%’") % i);
+        optimisePath_(stats, i, inodeHash);
     }
 }
 
diff --git a/src/libstore/pathlocks.cc b/src/libstore/pathlocks.cc
index 9db37e8f9aaa..1c87034f8e1a 100644
--- a/src/libstore/pathlocks.cc
+++ b/src/libstore/pathlocks.cc
@@ -60,7 +60,7 @@ bool lockFile(int fd, LockType lockType, bool wait)
         while (fcntl(fd, F_SETLK, &lock) != 0) {
             checkInterrupt();
             if (errno == EACCES || errno == EAGAIN) return false;
-            if (errno != EINTR) 
+            if (errno != EINTR)
                 throw SysError(format("acquiring/releasing lock"));
         }
     }
@@ -94,7 +94,7 @@ bool PathLocks::lockPaths(const PathSet & _paths,
     const string & waitMsg, bool wait)
 {
     assert(fds.empty());
-    
+
     /* Note that `fds' is built incrementally so that the destructor
        will only release those locks that we have already acquired. */
 
@@ -102,11 +102,10 @@ bool PathLocks::lockPaths(const PathSet & _paths,
        the same order, thus preventing deadlocks. */
     Paths paths(_paths.begin(), _paths.end());
     paths.sort();
-    
+
     /* Acquire the lock for each path. */
-    foreach (Paths::iterator, i, paths) {
+    for (auto & path : paths) {
         checkInterrupt();
-        Path path = *i;
         Path lockPath = path + ".lock";
 
         debug(format("locking path ‘%1%’") % path);
@@ -115,11 +114,11 @@ bool PathLocks::lockPaths(const PathSet & _paths,
             throw Error("deadlock: trying to re-acquire self-held lock");
 
         AutoCloseFD fd;
-        
+
         while (1) {
 
             /* Open/create the lock file. */
-	    fd = openLockFile(lockPath, true);
+            fd = openLockFile(lockPath, true);
 
             /* Acquire an exclusive lock. */
             if (!lockFile(fd, ltWrite, false)) {
@@ -168,15 +167,15 @@ PathLocks::~PathLocks()
 
 void PathLocks::unlock()
 {
-    foreach (list<FDPair>::iterator, i, fds) {
-        if (deletePaths) deleteLockFile(i->second, i->first);
+    for (auto & i : fds) {
+        if (deletePaths) deleteLockFile(i.second, i.first);
 
-        lockedPaths.erase(i->second);
-        if (close(i->first) == -1)
+        lockedPaths.erase(i.second);
+        if (close(i.first) == -1)
             printMsg(lvlError,
-                format("error (ignored): cannot close lock file on ‘%1%’") % i->second);
+                format("error (ignored): cannot close lock file on ‘%1%’") % i.second);
 
-        debug(format("lock released on ‘%1%’") % i->second);
+        debug(format("lock released on ‘%1%’") % i.second);
     }
 
     fds.clear();
@@ -195,5 +194,5 @@ bool pathIsLockedByMe(const Path & path)
     return lockedPaths.find(lockPath) != lockedPaths.end();
 }
 
- 
+
 }
diff --git a/src/libstore/references.cc b/src/libstore/references.cc
index 521244a31377..33eab5a240b5 100644
--- a/src/libstore/references.cc
+++ b/src/libstore/references.cc
@@ -13,7 +13,7 @@ namespace nix {
 static unsigned int refLength = 32; /* characters */
 
 
-static void search(const unsigned char * s, unsigned int len, 
+static void search(const unsigned char * s, unsigned int len,
     StringSet & hashes, StringSet & seen)
 {
     static bool initialised = false;
@@ -24,7 +24,7 @@ static void search(const unsigned char * s, unsigned int len,
             isBase32[(unsigned char) base32Chars[i]] = true;
         initialised = true;
     }
-    
+
     for (unsigned int i = 0; i + refLength <= len; ) {
         int j;
         bool match = true;
@@ -56,7 +56,7 @@ struct RefScanSink : Sink
     string tail;
 
     RefScanSink() : hashSink(htSHA256) { }
-    
+
     void operator () (const unsigned char * data, size_t len);
 };
 
@@ -89,17 +89,17 @@ PathSet scanForReferences(const string & path,
     /* For efficiency (and a higher hit rate), just search for the
        hash part of the file name.  (This assumes that all references
        have the form `HASH-bla'). */
-    foreach (PathSet::const_iterator, i, refs) {
-        string baseName = baseNameOf(*i);
+    for (auto & i : refs) {
+        string baseName = baseNameOf(i);
         string::size_type pos = baseName.find('-');
         if (pos == string::npos)
-            throw Error(format("bad reference ‘%1%’") % *i);
+            throw Error(format("bad reference ‘%1%’") % i);
         string s = string(baseName, 0, pos);
         assert(s.size() == refLength);
         assert(backMap.find(s) == backMap.end());
         // parseHash(htSHA256, s);
         sink.hashes.insert(s);
-        backMap[s] = *i;
+        backMap[s] = i;
     }
 
     /* Look for the hashes in the NAR dump of the path. */
@@ -107,14 +107,14 @@ PathSet scanForReferences(const string & path,
 
     /* Map the hashes found back to their store paths. */
     PathSet found;
-    foreach (StringSet::iterator, i, sink.seen) {
+    for (auto & i : sink.seen) {
         std::map<string, Path>::iterator j;
-        if ((j = backMap.find(*i)) == backMap.end()) abort();
+        if ((j = backMap.find(i)) == backMap.end()) abort();
         found.insert(j->second);
     }
 
     hash = sink.hashSink.finish();
-        
+
     return found;
 }
 
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index acabd6cf0048..6b9d5cb25327 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -31,7 +31,7 @@ Path readStorePath(Source & from)
 template<class T> T readStorePaths(Source & from)
 {
     T paths = readStrings<T>(from);
-    foreach (typename T::iterator, i, paths) assertStorePath(*i);
+    for (auto & i : paths) assertStorePath(i);
     return paths;
 }
 
@@ -166,9 +166,9 @@ void RemoteStore::setOptions()
         if (overrides["ssh-auth-sock"] == "")
             overrides["ssh-auth-sock"] = getEnv("SSH_AUTH_SOCK");
         writeInt(overrides.size(), to);
-        foreach (Settings::SettingsMap::iterator, i, overrides) {
-            writeString(i->first, to);
-            writeString(i->second, to);
+        for (auto & i : overrides) {
+            writeString(i.first, to);
+            writeString(i.second, to);
         }
     }
 
@@ -192,8 +192,8 @@ PathSet RemoteStore::queryValidPaths(const PathSet & paths)
     openConnection();
     if (GET_PROTOCOL_MINOR(daemonVersion) < 12) {
         PathSet res;
-        foreach (PathSet::const_iterator, i, paths)
-            if (isValidPath(*i)) res.insert(*i);
+        for (auto & i : paths)
+            if (isValidPath(i)) res.insert(i);
         return res;
     } else {
         writeInt(wopQueryValidPaths, to);
@@ -218,11 +218,11 @@ PathSet RemoteStore::querySubstitutablePaths(const PathSet & paths)
     openConnection();
     if (GET_PROTOCOL_MINOR(daemonVersion) < 12) {
         PathSet res;
-        foreach (PathSet::const_iterator, i, paths) {
+        for (auto & i : paths) {
             writeInt(wopHasSubstitutes, to);
-            writeString(*i, to);
+            writeString(i, to);
             processStderr();
-            if (readInt(from)) res.insert(*i);
+            if (readInt(from)) res.insert(i);
         }
         return res;
     } else {
@@ -245,10 +245,10 @@ void RemoteStore::querySubstitutablePathInfos(const PathSet & paths,
 
     if (GET_PROTOCOL_MINOR(daemonVersion) < 12) {
 
-        foreach (PathSet::const_iterator, i, paths) {
+        for (auto & i : paths) {
             SubstitutablePathInfo info;
             writeInt(wopQuerySubstitutablePathInfo, to);
-            writeString(*i, to);
+            writeString(i, to);
             processStderr();
             unsigned int reply = readInt(from);
             if (reply == 0) continue;
@@ -257,7 +257,7 @@ void RemoteStore::querySubstitutablePathInfos(const PathSet & paths,
             info.references = readStorePaths<PathSet>(from);
             info.downloadSize = readLongLong(from);
             info.narSize = GET_PROTOCOL_MINOR(daemonVersion) >= 7 ? readLongLong(from) : 0;
-            infos[*i] = info;
+            infos[i] = info;
         }
 
     } else {
@@ -473,8 +473,8 @@ void RemoteStore::buildPaths(const PathSet & drvPaths, BuildMode buildMode)
         /* For backwards compatibility with old daemons, strip output
            identifiers. */
         PathSet drvPaths2;
-        foreach (PathSet::const_iterator, i, drvPaths)
-            drvPaths2.insert(string(*i, 0, i->find('!')));
+        for (auto & i : drvPaths)
+            drvPaths2.insert(string(i, 0, i.find('!')));
         writeStrings(drvPaths2, to);
     }
     processStderr();
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index d3cbd1e7dee2..80f17d109ad6 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -82,14 +82,14 @@ void checkStoreName(const string & name)
        reasons (e.g., "." and ".."). */
     if (string(name, 0, 1) == ".")
         throw Error(format("illegal name: ‘%1%’") % name);
-    foreach (string::const_iterator, i, name)
-        if (!((*i >= 'A' && *i <= 'Z') ||
-              (*i >= 'a' && *i <= 'z') ||
-              (*i >= '0' && *i <= '9') ||
-              validChars.find(*i) != string::npos))
+    for (auto & i : name)
+        if (!((i >= 'A' && i <= 'Z') ||
+              (i >= 'a' && i <= 'z') ||
+              (i >= '0' && i <= '9') ||
+              validChars.find(i) != string::npos))
         {
             throw Error(format("invalid character ‘%1%’ in name ‘%2%’")
-                % *i % name);
+                % i % name);
         }
 }
 
@@ -101,22 +101,22 @@ void checkStoreName(const string & name)
    where
 
    <store> = the location of the Nix store, usually /nix/store
-   
+
    <name> = a human readable name for the path, typically obtained
      from the name attribute of the derivation, or the name of the
      source file from which the store path is created.  For derivation
      outputs other than the default "out" output, the string "-<id>"
      is suffixed to <name>.
-     
+
    <h> = base-32 representation of the first 160 bits of a SHA-256
      hash of <s>; the hash part of the store name
-     
+
    <s> = the string "<type>:sha256:<h2>:<store>:<name>";
      note that it includes the location of the store as well as the
      name to make sure that changes to either of those are reflected
      in the hash (e.g. you won't get /nix/store/<h>-name1 and
      /nix/store/<h>-name2 with equal hash parts).
-     
+
    <type> = one of:
      "text:<r1>:<r2>:...<rN>"
        for plain text files written to the store using
@@ -219,9 +219,9 @@ Path computeStorePathForText(const string & name, const string & s,
        hacky, but we can't put them in `s' since that would be
        ambiguous. */
     string type = "text";
-    foreach (PathSet::const_iterator, i, references) {
+    for (auto & i : references) {
         type += ":";
-        type += *i;
+        type += i;
     }
     return makeStorePath(type, hash, name);
 }
@@ -234,11 +234,11 @@ string StoreAPI::makeValidityRegistration(const PathSet & paths,
     bool showDerivers, bool showHash)
 {
     string s = "";
-    
-    foreach (PathSet::iterator, i, paths) {
-        s += *i + "\n";
 
-        ValidPathInfo info = queryPathInfo(*i);
+    for (auto & i : paths) {
+        s += i + "\n";
+
+        ValidPathInfo info = queryPathInfo(i);
 
         if (showHash) {
             s += printHash(info.hash) + "\n";
@@ -250,8 +250,8 @@ string StoreAPI::makeValidityRegistration(const PathSet & paths,
 
         s += (format("%1%\n") % info.references.size()).str();
 
-        foreach (PathSet::iterator, j, info.references)
-            s += *j + "\n";
+        for (auto & j : info.references)
+            s += j + "\n";
     }
 
     return s;
@@ -286,9 +286,9 @@ ValidPathInfo decodeValidPathInfo(std::istream & str, bool hashGiven)
 string showPaths(const PathSet & paths)
 {
     string s;
-    foreach (PathSet::const_iterator, i, paths) {
+    for (auto & i : paths) {
         if (s.size() != 0) s += ", ";
-        s += "‘" + *i + "’";
+        s += "‘" + i + "’";
     }
     return s;
 }
@@ -297,9 +297,9 @@ string showPaths(const PathSet & paths)
 void exportPaths(StoreAPI & store, const Paths & paths,
     bool sign, Sink & sink)
 {
-    foreach (Paths::const_iterator, i, paths) {
+    for (auto & i : paths) {
         writeInt(1, sink);
-        store.exportPath(*i, sign, sink);
+        store.exportPath(i, sign, sink);
     }
     writeInt(0, sink);
 }