diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 62e5163c9..907f15246 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -55,7 +55,7 @@ void EvalState::realiseContext(const PathSet & context)
         if (!store->isValidPath(ctx))
             throw InvalidPathError(store->printStorePath(ctx));
         if (!decoded.second.empty() && ctx.isDerivation()) {
-            drvs.push_back(StorePathWithOutputs{ctx.clone(), {decoded.second}});
+            drvs.push_back(StorePathWithOutputs{ctx, {decoded.second}});
 
             /* Add the output of this derivation to the allowed
                paths. */
@@ -723,9 +723,9 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
             StorePathSet refs;
             state.store->computeFSClosure(state.store->parseStorePath(std::string_view(path).substr(1)), refs);
             for (auto & j : refs) {
-                drv.inputSrcs.insert(j.clone());
+                drv.inputSrcs.insert(j);
                 if (j.isDerivation())
-                    drv.inputDrvs[j.clone()] = state.store->readDerivation(j).outputNames();
+                    drv.inputDrvs[j] = state.store->readDerivation(j).outputNames();
             }
         }
 
@@ -792,7 +792,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
         for (auto & i : outputs) {
             if (!jsonObject) drv.env[i] = "";
             drv.outputs.insert_or_assign(i,
-                DerivationOutput(StorePath::dummy.clone(), "", ""));
+                DerivationOutput { StorePath::dummy, "", "" });
         }
 
         Hash h = hashDerivationModulo(*state.store, Derivation(drv), true);
@@ -801,7 +801,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
             auto outPath = state.store->makeOutputPath(i, h, drvName);
             if (!jsonObject) drv.env[i] = state.store->printStorePath(outPath);
             drv.outputs.insert_or_assign(i,
-                DerivationOutput(std::move(outPath), "", ""));
+                DerivationOutput { std::move(outPath), "", "" });
         }
     }
 
@@ -814,7 +814,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
     /* Optimisation, but required in read-only mode! because in that
        case we don't actually write store derivations, so we can't
        read them later. */
-    drvHashes.insert_or_assign(drvPath.clone(),
+    drvHashes.insert_or_assign(drvPath,
         hashDerivationModulo(*state.store, Derivation(drv), false));
 
     state.mkAttrs(v, 1 + drv.outputs.size());
diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc
index 1037b2e28..f8eff508c 100644
--- a/src/libstore/binary-cache-store.cc
+++ b/src/libstore/binary-cache-store.cc
@@ -360,7 +360,7 @@ StorePath BinaryCacheStore::addTextToStore(const string & name, const string & s
     const StorePathSet & references, RepairFlag repair)
 {
     ValidPathInfo info(computeStorePathForText(name, s, references));
-    info.references = cloneStorePathSet(references);
+    info.references = references;
 
     if (repair || !isValidPath(info.path)) {
         StringSink sink;
@@ -395,14 +395,14 @@ void BinaryCacheStore::addSignatures(const StorePath & storePath, const StringSe
 
 std::shared_ptr<std::string> BinaryCacheStore::getBuildLog(const StorePath & path)
 {
-    auto drvPath = path.clone();
+    auto drvPath = path;
 
     if (!path.isDerivation()) {
         try {
             auto info = queryPathInfo(path);
             // FIXME: add a "Log" field to .narinfo
             if (!info->deriver) return nullptr;
-            drvPath = info->deriver->clone();
+            drvPath = *info->deriver;
         } catch (InvalidPath &) {
             return nullptr;
         }
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 8ad2ca4f3..53a0958aa 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -295,7 +295,7 @@ public:
 
     /* Make a goal (with caching). */
     GoalPtr makeDerivationGoal(const StorePath & drvPath, const StringSet & wantedOutputs, BuildMode buildMode = bmNormal);
-    std::shared_ptr<DerivationGoal> makeBasicDerivationGoal(StorePath && drvPath,
+    std::shared_ptr<DerivationGoal> makeBasicDerivationGoal(const StorePath & drvPath,
         const BasicDerivation & drv, BuildMode buildMode = bmNormal);
     GoalPtr makeSubstitutionGoal(const StorePath & storePath, RepairFlag repair = NoRepair);
 
@@ -347,7 +347,7 @@ public:
        contents. */
     bool pathContentsGood(const StorePath & path);
 
-    void markContentsGood(StorePath && path);
+    void markContentsGood(const StorePath & path);
 
     void updateProgress()
     {
@@ -900,9 +900,9 @@ private:
     friend struct RestrictedStore;
 
 public:
-    DerivationGoal(StorePath && drvPath, const StringSet & wantedOutputs,
+    DerivationGoal(const StorePath & drvPath, const StringSet & wantedOutputs,
         Worker & worker, BuildMode buildMode = bmNormal);
-    DerivationGoal(StorePath && drvPath, const BasicDerivation & drv,
+    DerivationGoal(const StorePath & drvPath, const BasicDerivation & drv,
         Worker & worker, BuildMode buildMode = bmNormal);
     ~DerivationGoal();
 
@@ -924,7 +924,7 @@ public:
 
     StorePath getDrvPath()
     {
-        return drvPath.clone();
+        return drvPath;
     }
 
     /* Add wanted outputs to an already existing derivation goal. */
@@ -1021,11 +1021,11 @@ private:
 const Path DerivationGoal::homeDir = "/homeless-shelter";
 
 
-DerivationGoal::DerivationGoal(StorePath && drvPath, const StringSet & wantedOutputs,
+DerivationGoal::DerivationGoal(const StorePath & drvPath, const StringSet & wantedOutputs,
     Worker & worker, BuildMode buildMode)
     : Goal(worker)
     , useDerivation(true)
-    , drvPath(std::move(drvPath))
+    , drvPath(drvPath)
     , wantedOutputs(wantedOutputs)
     , buildMode(buildMode)
 {
@@ -1038,11 +1038,11 @@ DerivationGoal::DerivationGoal(StorePath && drvPath, const StringSet & wantedOut
 }
 
 
-DerivationGoal::DerivationGoal(StorePath && drvPath, const BasicDerivation & drv,
+DerivationGoal::DerivationGoal(const StorePath & drvPath, const BasicDerivation & drv,
     Worker & worker, BuildMode buildMode)
     : Goal(worker)
     , useDerivation(false)
-    , drvPath(std::move(drvPath))
+    , drvPath(drvPath)
     , buildMode(buildMode)
 {
     this->drv = std::make_unique<BasicDerivation>(BasicDerivation(drv));
@@ -1193,7 +1193,7 @@ void DerivationGoal::haveDerivation()
         return;
     }
 
-    parsedDrv = std::make_unique<ParsedDerivation>(drvPath.clone(), *drv);
+    parsedDrv = std::make_unique<ParsedDerivation>(drvPath, *drv);
 
     /* We are first going to try to create the invalid output paths
        through substitutes.  If that doesn't work, we'll build
@@ -1301,7 +1301,7 @@ void DerivationGoal::repairClosure()
         if (i.isDerivation()) {
             Derivation drv = worker.store.derivationFromPath(i);
             for (auto & j : drv.outputs)
-                outputsToDrv.insert_or_assign(j.second.path.clone(), i.clone());
+                outputsToDrv.insert_or_assign(j.second.path, i);
         }
 
     /* Check each path (slow!). */
@@ -1454,7 +1454,7 @@ void DerivationGoal::tryToBuild()
         return;
     }
 
-    missingPaths = cloneStorePathSet(drv->outputPaths());
+    missingPaths = drv->outputPaths();
     if (buildMode != bmCheck)
         for (auto & i : validPaths) missingPaths.erase(i);
 
@@ -1901,14 +1901,14 @@ StorePathSet DerivationGoal::exportReferences(const StorePathSet & storePaths)
         if (!inputPaths.count(storePath))
             throw BuildError("cannot export references of path '%s' because it is not in the input closure of the derivation", worker.store.printStorePath(storePath));
 
-        worker.store.computeFSClosure(singleton(storePath), paths);
+        worker.store.computeFSClosure({storePath}, paths);
     }
 
     /* If there are derivations in the graph, then include their
        outputs as well.  This is useful if you want to do things
        like passing all build-time dependencies of some path to a
        derivation that builds a NixOS DVD image. */
-    auto paths2 = cloneStorePathSet(paths);
+    auto paths2 = paths;
 
     for (auto & j : paths2) {
         if (j.isDerivation()) {
@@ -2037,7 +2037,7 @@ void DerivationGoal::startBuilder()
             /* Write closure info to <fileName>. */
             writeFile(tmpDir + "/" + fileName,
                 worker.store.makeValidityRegistration(
-                    exportReferences(singleton(storePath)), false, false));
+                    exportReferences({storePath}), false, false));
         }
     }
 
@@ -2222,7 +2222,7 @@ void DerivationGoal::startBuilder()
             for (auto & i : missingPaths)
                 if (worker.store.isValidPath(i) && pathExists(worker.store.printStorePath(i))) {
                     addHashRewrite(i);
-                    redirectedBadOutputs.insert(i.clone());
+                    redirectedBadOutputs.insert(i);
                 }
     }
 
@@ -2717,8 +2717,8 @@ struct RestrictedStore : public LocalFSStore
     StorePathSet queryAllValidPaths() override
     {
         StorePathSet paths;
-        for (auto & p : goal.inputPaths) paths.insert(p.clone());
-        for (auto & p : goal.addedPaths) paths.insert(p.clone());
+        for (auto & p : goal.inputPaths) paths.insert(p);
+        for (auto & p : goal.addedPaths) paths.insert(p);
         return paths;
     }
 
@@ -2806,7 +2806,7 @@ struct RestrictedStore : public LocalFSStore
                 auto drv = derivationFromPath(path.path);
                 for (auto & output : drv.outputs)
                     if (wantOutput(output.first, path.outputs))
-                        newPaths.insert(output.second.path.clone());
+                        newPaths.insert(output.second.path);
             } else if (!goal.isAllowed(path.path))
                 throw InvalidPath("cannot build unknown path '%s' in recursive Nix", printStorePath(path.path));
         }
@@ -2851,7 +2851,7 @@ struct RestrictedStore : public LocalFSStore
             if (goal.isAllowed(path.path))
                 allowed.emplace_back(path);
             else
-                unknown.insert(path.path.clone());
+                unknown.insert(path.path);
         }
 
         next->queryMissing(allowed, willBuild, willSubstitute,
@@ -2946,7 +2946,7 @@ void DerivationGoal::addDependency(const StorePath & path)
 {
     if (isAllowed(path)) return;
 
-    addedPaths.insert(path.clone());
+    addedPaths.insert(path);
 
     /* If we're doing a sandbox build, then we have to make the path
        appear in the sandbox. */
@@ -3568,7 +3568,7 @@ StorePathSet parseReferenceSpecifiers(Store & store, const BasicDerivation & drv
         if (store.isStorePath(i))
             result.insert(store.parseStorePath(i));
         else if (drv.outputs.count(i))
-            result.insert(drv.outputs.find(i)->second.path.clone());
+            result.insert(drv.outputs.find(i)->second.path);
         else throw BuildError("derivation contains an illegal reference specifier '%s'", i);
     }
     return result;
@@ -3626,9 +3626,9 @@ void DerivationGoal::registerOutputs()
        output paths, and any paths that have been built via recursive
        Nix calls. */
     StorePathSet referenceablePaths;
-    for (auto & p : inputPaths) referenceablePaths.insert(p.clone());
-    for (auto & i : drv->outputs) referenceablePaths.insert(i.second.path.clone());
-    for (auto & p : addedPaths) referenceablePaths.insert(p.clone());
+    for (auto & p : inputPaths) referenceablePaths.insert(p);
+    for (auto & i : drv->outputs) referenceablePaths.insert(i.second.path);
+    for (auto & p : addedPaths) referenceablePaths.insert(p);
 
     /* Check whether the output paths were created, and grep each
        output path to determine what other paths it references.  Also make all
@@ -3827,7 +3827,7 @@ void DerivationGoal::registerOutputs()
         info.narHash = hash.first;
         info.narSize = hash.second;
         info.references = std::move(references);
-        info.deriver = drvPath.clone();
+        info.deriver = drvPath;
         info.ultimate = true;
         info.ca = ca;
         worker.store.signPathInfo(info);
@@ -3942,23 +3942,23 @@ void DerivationGoal::checkOutputs(const std::map<Path, ValidPathInfo> & outputs)
             uint64_t closureSize = 0;
             StorePathSet pathsDone;
             std::queue<StorePath> pathsLeft;
-            pathsLeft.push(path.clone());
+            pathsLeft.push(path);
 
             while (!pathsLeft.empty()) {
-                auto path = pathsLeft.front().clone();
+                auto path = pathsLeft.front();
                 pathsLeft.pop();
-                if (!pathsDone.insert(path.clone()).second) continue;
+                if (!pathsDone.insert(path).second) continue;
 
                 auto i = outputsByPath.find(worker.store.printStorePath(path));
                 if (i != outputsByPath.end()) {
                     closureSize += i->second.narSize;
                     for (auto & ref : i->second.references)
-                        pathsLeft.push(ref.clone());
+                        pathsLeft.push(ref);
                 } else {
                     auto info = worker.store.queryPathInfo(path);
                     closureSize += info->narSize;
                     for (auto & ref : info->references)
-                        pathsLeft.push(ref.clone());
+                        pathsLeft.push(ref);
                 }
             }
 
@@ -3985,8 +3985,8 @@ void DerivationGoal::checkOutputs(const std::map<Path, ValidPathInfo> & outputs)
                 auto spec = parseReferenceSpecifiers(worker.store, *drv, *value);
 
                 auto used = recursive
-                    ? cloneStorePathSet(getClosure(info.path).first)
-                    : cloneStorePathSet(info.references);
+                    ? getClosure(info.path).first
+                    : info.references;
 
                 if (recursive && checks.ignoreSelfRefs)
                     used.erase(info.path);
@@ -3996,10 +3996,10 @@ void DerivationGoal::checkOutputs(const std::map<Path, ValidPathInfo> & outputs)
                 for (auto & i : used)
                     if (allowed) {
                         if (!spec.count(i))
-                            badPaths.insert(i.clone());
+                            badPaths.insert(i);
                     } else {
                         if (spec.count(i))
-                            badPaths.insert(i.clone());
+                            badPaths.insert(i);
                     }
 
                 if (!badPaths.empty()) {
@@ -4199,7 +4199,7 @@ StorePathSet DerivationGoal::checkPathValidity(bool returnValid, bool checkHash)
         bool good =
             worker.store.isValidPath(i.second.path) &&
             (!checkHash || worker.pathContentsGood(i.second.path));
-        if (good == returnValid) result.insert(i.second.path.clone());
+        if (good == returnValid) result.insert(i.second.path);
     }
     return result;
 }
@@ -4215,7 +4215,7 @@ void DerivationGoal::addHashRewrite(const StorePath & path)
     deletePath(worker.store.printStorePath(p));
     inputRewrites[h1] = h2;
     outputRewrites[h2] = h1;
-    redirectedOutputs.insert_or_assign(path.clone(), std::move(p));
+    redirectedOutputs.insert_or_assign(path, std::move(p));
 }
 
 
@@ -4290,7 +4290,7 @@ private:
     GoalState state;
 
 public:
-    SubstitutionGoal(StorePath && storePath, Worker & worker, RepairFlag repair = NoRepair);
+    SubstitutionGoal(const StorePath & storePath, Worker & worker, RepairFlag repair = NoRepair);
     ~SubstitutionGoal();
 
     void timedOut(Error && ex) override { abort(); };
@@ -4316,13 +4316,13 @@ public:
     void handleChildOutput(int fd, const string & data) override;
     void handleEOF(int fd) override;
 
-    StorePath getStorePath() { return storePath.clone(); }
+    StorePath getStorePath() { return storePath; }
 };
 
 
-SubstitutionGoal::SubstitutionGoal(StorePath && storePath, Worker & worker, RepairFlag repair)
+SubstitutionGoal::SubstitutionGoal(const StorePath & storePath, Worker & worker, RepairFlag repair)
     : Goal(worker)
-    , storePath(std::move(storePath))
+    , storePath(storePath)
     , repair(repair)
 {
     state = &SubstitutionGoal::init;
@@ -4556,7 +4556,7 @@ void SubstitutionGoal::finished()
         return;
     }
 
-    worker.markContentsGood(storePath.clone());
+    worker.markContentsGood(storePath);
 
     printMsg(lvlChatty, "substitution of path '%s' succeeded", worker.store.printStorePath(storePath));
 
@@ -4626,10 +4626,10 @@ Worker::~Worker()
 GoalPtr Worker::makeDerivationGoal(const StorePath & path,
     const StringSet & wantedOutputs, BuildMode buildMode)
 {
-    GoalPtr goal = derivationGoals[path.clone()].lock(); // FIXME
+    GoalPtr goal = derivationGoals[path].lock(); // FIXME
     if (!goal) {
-        goal = std::make_shared<DerivationGoal>(path.clone(), wantedOutputs, *this, buildMode);
-        derivationGoals.insert_or_assign(path.clone(), goal);
+        goal = std::make_shared<DerivationGoal>(path, wantedOutputs, *this, buildMode);
+        derivationGoals.insert_or_assign(path, goal);
         wakeUp(goal);
     } else
         (dynamic_cast<DerivationGoal *>(goal.get()))->addWantedOutputs(wantedOutputs);
@@ -4637,10 +4637,10 @@ GoalPtr Worker::makeDerivationGoal(const StorePath & path,
 }
 
 
-std::shared_ptr<DerivationGoal> Worker::makeBasicDerivationGoal(StorePath && drvPath,
+std::shared_ptr<DerivationGoal> Worker::makeBasicDerivationGoal(const StorePath & drvPath,
     const BasicDerivation & drv, BuildMode buildMode)
 {
-    auto goal = std::make_shared<DerivationGoal>(std::move(drvPath), drv, *this, buildMode);
+    auto goal = std::make_shared<DerivationGoal>(drvPath, drv, *this, buildMode);
     wakeUp(goal);
     return goal;
 }
@@ -4648,10 +4648,10 @@ std::shared_ptr<DerivationGoal> Worker::makeBasicDerivationGoal(StorePath && drv
 
 GoalPtr Worker::makeSubstitutionGoal(const StorePath & path, RepairFlag repair)
 {
-    GoalPtr goal = substitutionGoals[path.clone()].lock(); // FIXME
+    GoalPtr goal = substitutionGoals[path].lock(); // FIXME
     if (!goal) {
-        goal = std::make_shared<SubstitutionGoal>(path.clone(), *this, repair);
-        substitutionGoals.insert_or_assign(path.clone(), goal);
+        goal = std::make_shared<SubstitutionGoal>(path, *this, repair);
+        substitutionGoals.insert_or_assign(path, goal);
         wakeUp(goal);
     }
     return goal;
@@ -4996,7 +4996,7 @@ bool Worker::pathContentsGood(const StorePath & path)
         Hash nullHash(htSHA256);
         res = info->narHash == nullHash || info->narHash == current.first;
     }
-    pathContentsGoodCache.insert_or_assign(path.clone(), res);
+    pathContentsGoodCache.insert_or_assign(path, res);
     if (!res)
         logError({
             .name = "Corrupted path",
@@ -5006,9 +5006,9 @@ bool Worker::pathContentsGood(const StorePath & path)
 }
 
 
-void Worker::markContentsGood(StorePath && path)
+void Worker::markContentsGood(const StorePath & path)
 {
-    pathContentsGoodCache.insert_or_assign(std::move(path), true);
+    pathContentsGoodCache.insert_or_assign(path, true);
 }
 
 
@@ -5073,7 +5073,7 @@ BuildResult LocalStore::buildDerivation(const StorePath & drvPath, const BasicDe
     BuildMode buildMode)
 {
     Worker worker(*this);
-    auto goal = worker.makeBasicDerivationGoal(drvPath.clone(), drv, buildMode);
+    auto goal = worker.makeBasicDerivationGoal(drvPath, drv, buildMode);
 
     BuildResult result;
 
@@ -5094,7 +5094,7 @@ void LocalStore::ensurePath(const StorePath & path)
     /* If the path is already valid, we're done. */
     if (isValidPath(path)) return;
 
-    primeCache(*this, {StorePathWithOutputs(path)});
+    primeCache(*this, {{path}});
 
     Worker worker(*this);
     GoalPtr goal = worker.makeSubstitutionGoal(path);
diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc
index 620722516..e370e278c 100644
--- a/src/libstore/daemon.cc
+++ b/src/libstore/daemon.cc
@@ -293,7 +293,7 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
         auto path = store->parseStorePath(readString(from));
         logger->startWork();
         StorePathSet paths; // FIXME
-        paths.insert(path.clone());
+        paths.insert(path);
         auto res = store->querySubstitutablePaths(paths);
         logger->stopWork();
         to << (res.count(path) != 0);
@@ -327,7 +327,7 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
         StorePathSet paths;
         if (op == wopQueryReferences)
             for (auto & i : store->queryPathInfo(path)->references)
-                paths.insert(i.clone());
+                paths.insert(i);
         else if (op == wopQueryReferrers)
             store->queryReferrers(path, paths);
         else if (op == wopQueryValidDerivers)
@@ -593,9 +593,7 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
         auto path = store->parseStorePath(readString(from));
         logger->startWork();
         SubstitutablePathInfos infos;
-        StorePathSet paths;
-        paths.insert(path.clone()); // FIXME
-        store->querySubstitutablePathInfos(paths, infos);
+        store->querySubstitutablePathInfos({path}, infos);
         logger->stopWork();
         auto i = infos.find(path);
         if (i == infos.end())
diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc
index 915e02eed..b95f7bfdc 100644
--- a/src/libstore/derivations.cc
+++ b/src/libstore/derivations.cc
@@ -27,28 +27,6 @@ void DerivationOutput::parseHashInfo(FileIngestionMethod & recursive, Hash & has
 }
 
 
-BasicDerivation::BasicDerivation(const BasicDerivation & other)
-    : platform(other.platform)
-    , builder(other.builder)
-    , args(other.args)
-    , env(other.env)
-{
-    for (auto & i : other.outputs)
-        outputs.insert_or_assign(i.first,
-            DerivationOutput(i.second.path.clone(), std::string(i.second.hashAlgo), std::string(i.second.hash)));
-    for (auto & i : other.inputSrcs)
-        inputSrcs.insert(i.clone());
-}
-
-
-Derivation::Derivation(const Derivation & other)
-    : BasicDerivation(other)
-{
-    for (auto & i : other.inputDrvs)
-        inputDrvs.insert_or_assign(i.first.clone(), i.second);
-}
-
-
 const StorePath & BasicDerivation::findOutput(const string & id) const
 {
     auto i = outputs.find(id);
@@ -67,9 +45,9 @@ bool BasicDerivation::isBuiltin() const
 StorePath writeDerivation(ref<Store> store,
     const Derivation & drv, std::string_view name, RepairFlag repair)
 {
-    auto references = cloneStorePathSet(drv.inputSrcs);
+    auto references = drv.inputSrcs;
     for (auto & i : drv.inputDrvs)
-        references.insert(i.first.clone());
+        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). */
@@ -155,7 +133,11 @@ static Derivation parseDerivation(const Store & store, const string & s)
         expect(str, ","); auto hashAlgo = parseString(str);
         expect(str, ","); auto hash = parseString(str);
         expect(str, ")");
-        drv.outputs.emplace(id, DerivationOutput(std::move(path), std::move(hashAlgo), std::move(hash)));
+        drv.outputs.emplace(id, DerivationOutput {
+            .path = std::move(path),
+            .hashAlgo = std::move(hashAlgo),
+            .hash = std::move(hash)
+        });
     }
 
     /* Parse the list of input derivations. */
@@ -383,7 +365,7 @@ Hash hashDerivationModulo(Store & store, const Derivation & drv, bool maskOutput
         auto h = drvHashes.find(i.first);
         if (h == drvHashes.end()) {
             assert(store.isValidPath(i.first));
-            h = drvHashes.insert_or_assign(i.first.clone(), hashDerivationModulo(store,
+            h = drvHashes.insert_or_assign(i.first, hashDerivationModulo(store,
                 store.readDerivation(i.first), false)).first;
         }
         inputs2.insert_or_assign(h->second.to_string(Base16, false), i.second);
@@ -411,7 +393,7 @@ StorePathSet BasicDerivation::outputPaths() const
 {
     StorePathSet paths;
     for (auto & i : outputs)
-        paths.insert(i.second.path.clone());
+        paths.insert(i.second.path);
     return paths;
 }
 
@@ -434,7 +416,11 @@ Source & readDerivation(Source & in, const Store & store, BasicDerivation & drv)
         auto path = store.parseStorePath(readString(in));
         auto hashAlgo = readString(in);
         auto hash = readString(in);
-        drv.outputs.emplace(name, DerivationOutput(std::move(path), std::move(hashAlgo), std::move(hash)));
+        drv.outputs.emplace(name, DerivationOutput {
+            .path = std::move(path),
+            .hashAlgo = std::move(hashAlgo),
+            .hash = std::move(hash)
+        });
     }
 
     drv.inputSrcs = readStorePaths<StorePathSet>(store, in);
diff --git a/src/libstore/derivations.hh b/src/libstore/derivations.hh
index 88aed66bf..d349c6d4d 100644
--- a/src/libstore/derivations.hh
+++ b/src/libstore/derivations.hh
@@ -17,11 +17,6 @@ struct DerivationOutput
     StorePath path;
     std::string hashAlgo; /* hash used for expected hash computation */
     std::string hash; /* expected hash, may be null */
-    DerivationOutput(StorePath && path, std::string && hashAlgo, std::string && hash)
-        : path(std::move(path))
-        , hashAlgo(std::move(hashAlgo))
-        , hash(std::move(hash))
-    { }
     void parseHashInfo(FileIngestionMethod & recursive, Hash & hash) const;
 };
 
@@ -43,7 +38,6 @@ struct BasicDerivation
     StringPairs env;
 
     BasicDerivation() { }
-    explicit BasicDerivation(const BasicDerivation & other);
     virtual ~BasicDerivation() { };
 
     /* Return the path corresponding to the output identifier `id' in
@@ -71,8 +65,6 @@ struct Derivation : BasicDerivation
         std::map<std::string, StringSet> * actualInputs = nullptr) const;
 
     Derivation() { }
-    Derivation(Derivation && other) = default;
-    explicit Derivation(const Derivation & other);
 };
 
 
diff --git a/src/libstore/export-import.cc b/src/libstore/export-import.cc
index 54471d4a3..cb9da027d 100644
--- a/src/libstore/export-import.cc
+++ b/src/libstore/export-import.cc
@@ -105,7 +105,7 @@ StorePaths Store::importPaths(Source & source, std::shared_ptr<FSAccessor> acces
         auto source = StringSource { *tee.source.data };
         addToStore(info, source, NoRepair, checkSigs, accessor);
 
-        res.push_back(info.path.clone());
+        res.push_back(info.path);
     }
 
     return res;
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index 04e3849f7..57fb20845 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -128,7 +128,7 @@ Path LocalFSStore::addPermRoot(const StorePath & storePath,
        gcroots directory. */
     if (settings.checkRootReachability) {
         auto roots = findRoots(false);
-        if (roots[storePath.clone()].count(gcRoot) == 0)
+        if (roots[storePath].count(gcRoot) == 0)
             logWarning({
                 .name = "GC root",
                 .hint = hintfmt("warning: '%1%' is not in a directory where the garbage collector looks for roots; "
@@ -478,9 +478,9 @@ void LocalStore::findRuntimeRoots(Roots & roots, bool censor)
         if (!isValidPath(path)) continue;
         debug("got additional root '%1%'", pathS);
         if (censor)
-            roots[path.clone()].insert(censored);
+            roots[path].insert(censored);
         else
-            roots[path.clone()].insert(links.begin(), links.end());
+            roots[path].insert(links.begin(), links.end());
     }
 }
 
@@ -592,11 +592,11 @@ bool LocalStore::canReachRoot(GCState & state, StorePathSet & visited, const Sto
 
     if (state.roots.count(path)) {
         debug("cannot delete '%1%' because it's a root", printStorePath(path));
-        state.alive.insert(path.clone());
+        state.alive.insert(path);
         return true;
     }
 
-    visited.insert(path.clone());
+    visited.insert(path);
 
     if (!isValidPath(path)) return false;
 
@@ -610,7 +610,7 @@ bool LocalStore::canReachRoot(GCState & state, StorePathSet & visited, const Sto
     if (state.gcKeepDerivations && path.isDerivation()) {
         for (auto & i : queryDerivationOutputs(path))
             if (isValidPath(i) && queryPathInfo(i)->deriver == path)
-                incoming.insert(i.clone());
+                incoming.insert(i);
     }
 
     /* If keep-outputs is set, then don't delete this path if there
@@ -618,13 +618,13 @@ bool LocalStore::canReachRoot(GCState & state, StorePathSet & visited, const Sto
     if (state.gcKeepOutputs) {
         auto derivers = queryValidDerivers(path);
         for (auto & i : derivers)
-            incoming.insert(i.clone());
+            incoming.insert(i);
     }
 
     for (auto & i : incoming)
         if (i != path)
             if (canReachRoot(state, visited, i)) {
-                state.alive.insert(path.clone());
+                state.alive.insert(path);
                 return true;
             }
 
@@ -668,7 +668,7 @@ void LocalStore::tryToDelete(GCState & state, const Path & path)
            ‘nix-store --delete’ doesn't have the unexpected effect of
            recursing into derivations and outputs. */
         for (auto & i : visited)
-            state.dead.insert(i.clone());
+            state.dead.insert(i);
         if (state.shouldDelete)
             deletePathRecursive(state, path);
     }
@@ -754,7 +754,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
     if (!options.ignoreLiveness)
         findRootsNoTemp(rootMap, true);
 
-    for (auto & i : rootMap) state.roots.insert(i.first.clone());
+    for (auto & i : rootMap) state.roots.insert(i.first);
 
     /* Read the temporary roots.  This acquires read locks on all
        per-process temporary root files.  So after this point no paths
@@ -763,8 +763,8 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
     Roots tempRoots;
     findTempRoots(fds, tempRoots, true);
     for (auto & root : tempRoots) {
-        state.tempRoots.insert(root.first.clone());
-        state.roots.insert(root.first.clone());
+        state.tempRoots.insert(root.first);
+        state.roots.insert(root.first);
     }
 
     /* After this point the set of roots or temporary roots cannot
diff --git a/src/libstore/legacy-ssh-store.cc b/src/libstore/legacy-ssh-store.cc
index af20d389b..45c70fad6 100644
--- a/src/libstore/legacy-ssh-store.cc
+++ b/src/libstore/legacy-ssh-store.cc
@@ -256,7 +256,7 @@ struct LegacySSHStore : public Store
         conn->to.flush();
 
         for (auto & i : readStorePaths<StorePathSet>(*this, conn->from))
-            out.insert(i.clone());
+            out.insert(i);
     }
 
     StorePathSet queryValidPaths(const StorePathSet & paths,
diff --git a/src/libstore/local-fs-store.cc b/src/libstore/local-fs-store.cc
index 2d564a0d7..dd96d2578 100644
--- a/src/libstore/local-fs-store.cc
+++ b/src/libstore/local-fs-store.cc
@@ -90,13 +90,13 @@ const string LocalFSStore::drvsLogDir = "drvs";
 
 std::shared_ptr<std::string> LocalFSStore::getBuildLog(const StorePath & path_)
 {
-    auto path = path_.clone();
+    auto path = path_;
 
     if (!path.isDerivation()) {
         try {
             auto info = queryPathInfo(path);
             if (!info->deriver) return nullptr;
-            path = info->deriver->clone();
+            path = *info->deriver;
         } catch (InvalidPath &) {
             return nullptr;
         }
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index e3b718e88..0df4374b9 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -631,7 +631,7 @@ void LocalStore::queryPathInfoUncached(const StorePath & path,
     Callback<std::shared_ptr<const ValidPathInfo>> callback) noexcept
 {
     try {
-        auto info = std::make_shared<ValidPathInfo>(path.clone());
+        auto info = std::make_shared<ValidPathInfo>(path);
 
         callback(retrySQLite<std::shared_ptr<ValidPathInfo>>([&]() {
             auto state(_state.lock());
@@ -721,7 +721,7 @@ StorePathSet LocalStore::queryValidPaths(const StorePathSet & paths, SubstituteF
 {
     StorePathSet res;
     for (auto & i : paths)
-        if (isValidPath(i)) res.insert(i.clone());
+        if (isValidPath(i)) res.insert(i);
     return res;
 }
 
@@ -816,7 +816,7 @@ StorePathSet LocalStore::querySubstitutablePaths(const StorePathSet & paths)
 
     StorePathSet remaining;
     for (auto & i : paths)
-        remaining.insert(i.clone());
+        remaining.insert(i);
 
     StorePathSet res;
 
@@ -830,9 +830,9 @@ StorePathSet LocalStore::querySubstitutablePaths(const StorePathSet & paths)
         StorePathSet remaining2;
         for (auto & path : remaining)
             if (valid.count(path))
-                res.insert(path.clone());
+                res.insert(path);
             else
-                remaining2.insert(path.clone());
+                remaining2.insert(path);
 
         std::swap(remaining, remaining2);
     }
@@ -854,9 +854,9 @@ void LocalStore::querySubstitutablePathInfos(const StorePathSet & paths,
                 auto info = sub->queryPathInfo(path);
                 auto narInfo = std::dynamic_pointer_cast<const NarInfo>(
                     std::shared_ptr<const ValidPathInfo>(info));
-                infos.insert_or_assign(path.clone(), SubstitutablePathInfo{
-                    info->deriver ? info->deriver->clone() : std::optional<StorePath>(),
-                    cloneStorePathSet(info->references),
+                infos.insert_or_assign(path, SubstitutablePathInfo{
+                    info->deriver,
+                    info->references,
                     narInfo ? narInfo->fileSize : 0,
                     info->narSize});
             } catch (InvalidPath &) {
@@ -900,7 +900,7 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos)
                 updatePathInfo(*state, i);
             else
                 addValidPath(*state, i, false);
-            paths.insert(i.path.clone());
+            paths.insert(i.path);
         }
 
         for (auto & i : infos) {
@@ -1074,7 +1074,7 @@ StorePath LocalStore::addToStoreFromDump(const string & dump, const string & nam
 
             optimisePath(realPath); // FIXME: combine with hashPath()
 
-            ValidPathInfo info(dstPath.clone());
+            ValidPathInfo info(dstPath);
             info.narHash = hash.first;
             info.narSize = hash.second;
             info.ca = makeFixedOutputCA(method, h);
@@ -1137,10 +1137,10 @@ StorePath LocalStore::addTextToStore(const string & name, const string & s,
 
             optimisePath(realPath);
 
-            ValidPathInfo info(dstPath.clone());
+            ValidPathInfo info(dstPath);
             info.narHash = narHash;
             info.narSize = sink.s->size();
-            info.references = cloneStorePathSet(references);
+            info.references = references;
             info.ca = "text:" + hash.to_string(Base32, true);
             registerValidPath(info);
         }
diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc
index 9c47fe524..e68edb38c 100644
--- a/src/libstore/misc.cc
+++ b/src/libstore/misc.cc
@@ -103,7 +103,7 @@ void Store::computeFSClosure(const StorePath & startPath,
     StorePathSet & paths_, bool flipDirection, bool includeOutputs, bool includeDerivers)
 {
     StorePathSet paths;
-    paths.insert(startPath.clone());
+    paths.insert(startPath);
     computeFSClosure(paths, paths_, flipDirection, includeOutputs, includeDerivers);
 }
 
@@ -141,11 +141,11 @@ void Store::queryMissing(const std::vector<StorePathWithOutputs> & targets,
     auto mustBuildDrv = [&](const StorePath & drvPath, const Derivation & drv) {
         {
             auto state(state_.lock());
-            state->willBuild.insert(drvPath.clone());
+            state->willBuild.insert(drvPath);
         }
 
         for (auto & i : drv.inputDrvs)
-            pool.enqueue(std::bind(doPath, StorePathWithOutputs(i.first, i.second)));
+            pool.enqueue(std::bind(doPath, StorePathWithOutputs { i.first, i.second }));
     };
 
     auto checkOutput = [&](
@@ -157,9 +157,7 @@ void Store::queryMissing(const std::vector<StorePathWithOutputs> & targets,
         auto outPath = parseStorePath(outPathS);
 
         SubstitutablePathInfos infos;
-        StorePathSet paths; // FIXME
-        paths.insert(outPath.clone());
-        querySubstitutablePathInfos(paths, infos);
+        querySubstitutablePathInfos({outPath}, infos);
 
         if (infos.empty()) {
             drvState_->lock()->done = true;
@@ -170,10 +168,10 @@ void Store::queryMissing(const std::vector<StorePathWithOutputs> & targets,
                 if (drvState->done) return;
                 assert(drvState->left);
                 drvState->left--;
-                drvState->outPaths.insert(outPath.clone());
+                drvState->outPaths.insert(outPath);
                 if (!drvState->left) {
                     for (auto & path : drvState->outPaths)
-                        pool.enqueue(std::bind(doPath, StorePathWithOutputs(path.clone())));
+                        pool.enqueue(std::bind(doPath, StorePathWithOutputs { path } ));
                 }
             }
         }
@@ -190,12 +188,12 @@ void Store::queryMissing(const std::vector<StorePathWithOutputs> & targets,
             if (!isValidPath(path.path)) {
                 // FIXME: we could try to substitute the derivation.
                 auto state(state_.lock());
-                state->unknown.insert(path.path.clone());
+                state->unknown.insert(path.path);
                 return;
             }
 
             auto drv = make_ref<Derivation>(derivationFromPath(path.path));
-            ParsedDerivation parsedDrv(path.path.clone(), *drv);
+            ParsedDerivation parsedDrv(StorePath(path.path), *drv);
 
             PathSet invalid;
             for (auto & j : drv->outputs)
@@ -216,13 +214,11 @@ void Store::queryMissing(const std::vector<StorePathWithOutputs> & targets,
             if (isValidPath(path.path)) return;
 
             SubstitutablePathInfos infos;
-            StorePathSet paths; // FIXME
-            paths.insert(path.path.clone());
-            querySubstitutablePathInfos(paths, infos);
+            querySubstitutablePathInfos({path.path}, infos);
 
             if (infos.empty()) {
                 auto state(state_.lock());
-                state->unknown.insert(path.path.clone());
+                state->unknown.insert(path.path);
                 return;
             }
 
@@ -231,13 +227,13 @@ void Store::queryMissing(const std::vector<StorePathWithOutputs> & targets,
 
             {
                 auto state(state_.lock());
-                state->willSubstitute.insert(path.path.clone());
+                state->willSubstitute.insert(path.path);
                 state->downloadSize += info->second.downloadSize;
                 state->narSize += info->second.narSize;
             }
 
             for (auto & ref : info->second.references)
-                pool.enqueue(std::bind(doPath, StorePathWithOutputs(ref)));
+                pool.enqueue(std::bind(doPath, StorePathWithOutputs { ref }));
         }
     };
 
@@ -260,12 +256,12 @@ StorePaths Store::topoSortPaths(const StorePathSet & paths)
             throw BuildError("cycle detected in the references of '%s' from '%s'",
                 printStorePath(path), printStorePath(*parent));
 
-        if (!visited.insert(path.clone()).second) return;
-        parents.insert(path.clone());
+        if (!visited.insert(path).second) return;
+        parents.insert(path);
 
         StorePathSet references;
         try {
-            references = cloneStorePathSet(queryPathInfo(path)->references);
+            references = queryPathInfo(path)->references;
         } catch (InvalidPath &) {
         }
 
@@ -275,7 +271,7 @@ StorePaths Store::topoSortPaths(const StorePathSet & paths)
             if (i != path && paths.count(i))
                 dfsVisit(i, &path);
 
-        sorted.push_back(path.clone());
+        sorted.push_back(path);
         parents.erase(path);
     };
 
diff --git a/src/libstore/nar-info.cc b/src/libstore/nar-info.cc
index d7fc30e91..bb4448c90 100644
--- a/src/libstore/nar-info.cc
+++ b/src/libstore/nar-info.cc
@@ -4,7 +4,7 @@
 namespace nix {
 
 NarInfo::NarInfo(const Store & store, const std::string & s, const std::string & whence)
-    : ValidPathInfo(StorePath::dummy.clone()) // FIXME: hack
+    : ValidPathInfo(StorePath(StorePath::dummy)) // FIXME: hack
 {
     auto corrupt = [&]() {
         throw Error("NAR info file '%1%' is corrupt", whence);
diff --git a/src/libstore/parsed-derivations.cc b/src/libstore/parsed-derivations.cc
index 45c033c66..24f848e46 100644
--- a/src/libstore/parsed-derivations.cc
+++ b/src/libstore/parsed-derivations.cc
@@ -4,8 +4,8 @@
 
 namespace nix {
 
-ParsedDerivation::ParsedDerivation(StorePath && drvPath, BasicDerivation & drv)
-    : drvPath(std::move(drvPath)), drv(drv)
+ParsedDerivation::ParsedDerivation(const StorePath & drvPath, BasicDerivation & drv)
+    : drvPath(drvPath), drv(drv)
 {
     /* Parse the __json attribute, if any. */
     auto jsonAttr = drv.env.find("__json");
diff --git a/src/libstore/parsed-derivations.hh b/src/libstore/parsed-derivations.hh
index f4df5dd54..7621342d7 100644
--- a/src/libstore/parsed-derivations.hh
+++ b/src/libstore/parsed-derivations.hh
@@ -12,7 +12,7 @@ class ParsedDerivation
 
 public:
 
-    ParsedDerivation(StorePath && drvPath, BasicDerivation & drv);
+    ParsedDerivation(const StorePath & drvPath, BasicDerivation & drv);
 
     ~ParsedDerivation();
 
diff --git a/src/libstore/path.cc b/src/libstore/path.cc
index bb2089ea4..b3d8ce95c 100644
--- a/src/libstore/path.cc
+++ b/src/libstore/path.cc
@@ -84,29 +84,6 @@ PathSet Store::printStorePathSet(const StorePathSet & paths) const
     return res;
 }
 
-StorePathSet cloneStorePathSet(const StorePathSet & paths)
-{
-    StorePathSet res;
-    for (auto & p : paths)
-        res.insert(p.clone());
-    return res;
-}
-
-StorePathSet storePathsToSet(const StorePaths & paths)
-{
-    StorePathSet res;
-    for (auto & p : paths)
-        res.insert(p.clone());
-    return res;
-}
-
-StorePathSet singleton(const StorePath & path)
-{
-    StorePathSet res;
-    res.insert(path.clone());
-    return res;
-}
-
 std::pair<std::string_view, StringSet> parsePathWithOutputs(std::string_view s)
 {
     size_t n = s.find("!");
diff --git a/src/libstore/path.hh b/src/libstore/path.hh
index 85c3d8e53..aaebd3ec3 100644
--- a/src/libstore/path.hh
+++ b/src/libstore/path.hh
@@ -11,10 +11,6 @@ class StorePath
 {
     std::string baseName;
 
-    StorePath(const StorePath & path)
-        : baseName(path.baseName)
-    { }
-
 public:
 
     /* Size of the hash part of store paths, in base-32 characters. */
@@ -26,16 +22,6 @@ public:
 
     StorePath(const Hash & hash, std::string_view name);
 
-    StorePath(StorePath && path)
-        : baseName(std::move(path.baseName))
-    { }
-
-    StorePath & operator = (StorePath && path)
-    {
-        baseName = std::move(path.baseName);
-        return *this;
-    }
-
     std::string_view to_string() const
     {
         return baseName;
@@ -56,11 +42,6 @@ public:
         return baseName != other.baseName;
     }
 
-    StorePath clone() const
-    {
-        return StorePath(*this);
-    }
-
     /* Check whether a file name ends with the extension for
        derivations. */
     bool isDerivation() const;
@@ -81,11 +62,6 @@ public:
 typedef std::set<StorePath> StorePathSet;
 typedef std::vector<StorePath> StorePaths;
 
-StorePathSet cloneStorePathSet(const StorePathSet & paths);
-StorePathSet storePathsToSet(const StorePaths & paths);
-
-StorePathSet singleton(const StorePath & path);
-
 /* Extension of derivations in the Nix store. */
 const std::string drvExtension = ".drv";
 
@@ -99,18 +75,6 @@ struct StorePathWithOutputs
     StorePath path;
     std::set<std::string> outputs;
 
-    StorePathWithOutputs(const StorePath & path, const std::set<std::string> & outputs = {})
-        : path(path.clone()), outputs(outputs)
-    { }
-
-    StorePathWithOutputs(StorePath && path, std::set<std::string> && outputs)
-        : path(std::move(path)), outputs(std::move(outputs))
-    { }
-
-    StorePathWithOutputs(const StorePathWithOutputs & other)
-        : path(other.path.clone()), outputs(other.outputs)
-    { }
-
     std::string to_string(const Store & store) const;
 };
 
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index 99fee8150..fc5ab5865 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -268,7 +268,7 @@ StorePathSet RemoteStore::queryValidPaths(const StorePathSet & paths, Substitute
     if (GET_PROTOCOL_MINOR(conn->daemonVersion) < 12) {
         StorePathSet res;
         for (auto & i : paths)
-            if (isValidPath(i)) res.insert(i.clone());
+            if (isValidPath(i)) res.insert(i);
         return res;
     } else {
         conn->to << wopQueryValidPaths;
@@ -296,7 +296,7 @@ StorePathSet RemoteStore::querySubstitutablePaths(const StorePathSet & paths)
         for (auto & i : paths) {
             conn->to << wopHasSubstitutes << printStorePath(i);
             conn.processStderr();
-            if (readInt(conn->from)) res.insert(i.clone());
+            if (readInt(conn->from)) res.insert(i);
         }
         return res;
     } else {
@@ -329,7 +329,7 @@ void RemoteStore::querySubstitutablePathInfos(const StorePathSet & paths,
             info.references = readStorePaths<StorePathSet>(*this, conn->from);
             info.downloadSize = readLongLong(conn->from);
             info.narSize = readLongLong(conn->from);
-            infos.insert_or_assign(i.clone(), std::move(info));
+            infos.insert_or_assign(i, std::move(info));
         }
 
     } else {
@@ -372,7 +372,7 @@ void RemoteStore::queryPathInfoUncached(const StorePath & path,
                 bool valid; conn->from >> valid;
                 if (!valid) throw InvalidPath("path '%s' is not valid", printStorePath(path));
             }
-            info = std::make_shared<ValidPathInfo>(path.clone());
+            info = std::make_shared<ValidPathInfo>(StorePath(path));
             auto deriver = readString(conn->from);
             if (deriver != "") info->deriver = parseStorePath(deriver);
             info->narHash = Hash(readString(conn->from), htSHA256);
@@ -396,7 +396,7 @@ void RemoteStore::queryReferrers(const StorePath & path,
     conn->to << wopQueryReferrers << printStorePath(path);
     conn.processStderr();
     for (auto & i : readStorePaths<StorePathSet>(*this, conn->from))
-        referrers.insert(i.clone());
+        referrers.insert(i);
 }
 
 
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index 42e26c427..aae227bae 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -55,7 +55,7 @@ StorePath Store::followLinksToStorePath(std::string_view path) const
 StorePathWithOutputs Store::followLinksToStorePathWithOutputs(std::string_view path) const
 {
     auto [path2, outputs] = nix::parsePathWithOutputs(path);
-    return StorePathWithOutputs(followLinksToStorePath(path2), std::move(outputs));
+    return StorePathWithOutputs { followLinksToStorePath(path2), std::move(outputs) };
 }
 
 
@@ -545,7 +545,7 @@ void Store::buildPaths(const std::vector<StorePathWithOutputs> & paths, BuildMod
     for (auto & path : paths) {
         if (path.path.isDerivation())
             unsupported("buildPaths");
-        paths2.insert(path.path.clone());
+        paths2.insert(path.path);
     }
 
     if (queryValidPaths(paths2).size() != paths2.size())
@@ -685,21 +685,6 @@ void copyClosure(ref<Store> srcStore, ref<Store> dstStore,
 }
 
 
-ValidPathInfo::ValidPathInfo(const ValidPathInfo & other)
-    : path(other.path.clone())
-    , deriver(other.deriver ? other.deriver->clone(): std::optional<StorePath>{})
-    , narHash(other.narHash)
-    , references(cloneStorePathSet(other.references))
-    , registrationTime(other.registrationTime)
-    , narSize(other.narSize)
-    , id(other.id)
-    , ultimate(other.ultimate)
-    , sigs(other.sigs)
-    , ca(other.ca)
-{
-}
-
-
 std::optional<ValidPathInfo> decodeValidPathInfo(const Store & store, std::istream & str, bool hashGiven)
 {
     std::string path;
@@ -785,7 +770,7 @@ bool ValidPathInfo::isContentAddressed(const Store & store) const
     else if (hasPrefix(ca, "fixed:")) {
         FileIngestionMethod recursive { ca.compare(6, 2, "r:") == 0 };
         Hash hash(ca.substr(recursive == FileIngestionMethod::Recursive ? 8 : 6));
-        auto refs = cloneStorePathSet(references);
+        auto refs = references;
         bool hasSelfReference = false;
         if (refs.count(path)) {
             hasSelfReference = true;
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index 251fc4638..6f4dd959c 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -189,8 +189,9 @@ struct ValidPathInfo
 
     Strings shortRefs() const;
 
+    ValidPathInfo(const StorePath & path) : path(path) { }
+
     ValidPathInfo(StorePath && path) : path(std::move(path)) { }
-    explicit ValidPathInfo(const ValidPathInfo & other);
 
     virtual ~ValidPathInfo() { }
 };
diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc
index da6f005a3..a224d635d 100755
--- a/src/nix-build/nix-build.cc
+++ b/src/nix-build/nix-build.cc
@@ -363,7 +363,7 @@ static void _main(int argc, char * * argv)
                 if (!drv)
                     throw Error("the 'bashInteractive' attribute in <nixpkgs> did not evaluate to a derivation");
 
-                pathsToBuild.emplace_back(store->parseStorePath(drv->queryDrvPath()));
+                pathsToBuild.push_back({store->parseStorePath(drv->queryDrvPath())});
 
                 shell = drv->queryOutPath() + "/bin/bash";
 
@@ -381,9 +381,9 @@ static void _main(int argc, char * * argv)
         for (const auto & input : drv.inputDrvs)
             if (std::all_of(envExclude.cbegin(), envExclude.cend(),
                     [&](const string & exclude) { return !std::regex_search(store->printStorePath(input.first), std::regex(exclude)); }))
-                pathsToBuild.emplace_back(input.first, input.second);
+                pathsToBuild.push_back({input.first, input.second});
         for (const auto & src : drv.inputSrcs)
-            pathsToBuild.emplace_back(src);
+            pathsToBuild.push_back({src});
 
         buildPaths(pathsToBuild);
 
@@ -499,7 +499,7 @@ static void _main(int argc, char * * argv)
             if (outputName == "")
                 throw Error("derivation '%s' lacks an 'outputName' attribute", drvPath);
 
-            pathsToBuild.emplace_back(store->parseStorePath(drvPath), StringSet{outputName});
+            pathsToBuild.push_back({store->parseStorePath(drvPath), {outputName}});
 
             std::string drvPrefix;
             auto i = drvPrefixes.find(drvPath);
diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc
index 2c27d97f5..8b0692035 100644
--- a/src/nix-env/nix-env.cc
+++ b/src/nix-env/nix-env.cc
@@ -212,9 +212,7 @@ static bool isPrebuilt(EvalState & state, DrvInfo & elem)
 {
     auto path = state.store->parseStorePath(elem.queryOutPath());
     if (state.store->isValidPath(path)) return true;
-    StorePathSet paths;
-    paths.insert(path.clone()); // FIXME: why doesn't StorePathSet{path.clone()} work?
-    return state.store->querySubstitutablePaths(paths).count(path);
+    return state.store->querySubstitutablePaths({path}).count(path);
 }
 
 
@@ -425,9 +423,9 @@ static void printMissing(EvalState & state, DrvInfos & elems)
     for (auto & i : elems) {
         Path drvPath = i.queryDrvPath();
         if (drvPath != "")
-            targets.emplace_back(state.store->parseStorePath(drvPath));
+            targets.push_back({state.store->parseStorePath(drvPath)});
         else
-            targets.emplace_back(state.store->parseStorePath(i.queryOutPath()));
+            targets.push_back({state.store->parseStorePath(i.queryOutPath())});
     }
 
     printMissing(state.store, targets);
@@ -697,13 +695,13 @@ static void opSet(Globals & globals, Strings opFlags, Strings opArgs)
         drv.setName(globals.forceName);
 
     if (drv.queryDrvPath() != "") {
-        std::vector<StorePathWithOutputs> paths{globals.state->store->parseStorePath(drv.queryDrvPath())};
+        std::vector<StorePathWithOutputs> paths{{globals.state->store->parseStorePath(drv.queryDrvPath())}};
         printMissing(globals.state->store, paths);
         if (globals.dryRun) return;
         globals.state->store->buildPaths(paths, globals.state->repair ? bmRepair : bmNormal);
     } else {
         printMissing(globals.state->store,
-            {globals.state->store->parseStorePath(drv.queryOutPath())});
+            {{globals.state->store->parseStorePath(drv.queryOutPath())}});
         if (globals.dryRun) return;
         globals.state->store->ensurePath(globals.state->store->parseStorePath(drv.queryOutPath()));
     }
diff --git a/src/nix-env/user-env.cc b/src/nix-env/user-env.cc
index f804b77a0..8e7f09e12 100644
--- a/src/nix-env/user-env.cc
+++ b/src/nix-env/user-env.cc
@@ -134,7 +134,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
     /* Realise the resulting store expression. */
     debug("building user environment");
     std::vector<StorePathWithOutputs> topLevelDrvs;
-    topLevelDrvs.push_back(StorePathWithOutputs{topLevelDrv.clone()});
+    topLevelDrvs.push_back({topLevelDrv});
     state.store->buildPaths(topLevelDrvs, state.repair ? bmRepair : bmNormal);
 
     /* Switch the current user environment to the output path. */
diff --git a/src/nix-store/dotgraph.cc b/src/nix-store/dotgraph.cc
index 667d917f5..8b699f39b 100644
--- a/src/nix-store/dotgraph.cc
+++ b/src/nix-store/dotgraph.cc
@@ -54,13 +54,13 @@ void printDotGraph(ref<Store> store, StorePathSet && roots)
     while (!workList.empty()) {
         auto path = std::move(workList.extract(workList.begin()).value());
 
-        if (!doneSet.insert(path.clone()).second) continue;
+        if (!doneSet.insert(path).second) continue;
 
         cout << makeNode(std::string(path.to_string()), path.name(), "#ff0000");
 
         for (auto & p : store->queryPathInfo(path)->references) {
             if (p != path) {
-                workList.insert(p.clone());
+                workList.insert(p);
                 cout << makeEdge(std::string(p.to_string()), std::string(path.to_string()));
             }
         }
diff --git a/src/nix-store/graphml.cc b/src/nix-store/graphml.cc
index 347708851..8ca5c9c8d 100644
--- a/src/nix-store/graphml.cc
+++ b/src/nix-store/graphml.cc
@@ -65,7 +65,7 @@ void printGraphML(ref<Store> store, StorePathSet && roots)
     while (!workList.empty()) {
         auto path = std::move(workList.extract(workList.begin()).value());
 
-        ret = doneSet.insert(path.clone());
+        ret = doneSet.insert(path);
         if (ret.second == false) continue;
 
         auto info = store->queryPathInfo(path);
@@ -73,7 +73,7 @@ void printGraphML(ref<Store> store, StorePathSet && roots)
 
         for (auto & p : info->references) {
             if (p != path) {
-                workList.insert(p.clone());
+                workList.insert(p);
                 cout << makeEdge(path.to_string(), p.to_string());
             }
         }
diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc
index 6d2139526..5c5afd5ec 100644
--- a/src/nix-store/nix-store.cc
+++ b/src/nix-store/nix-store.cc
@@ -49,11 +49,11 @@ ref<LocalStore> ensureLocalStore()
 
 static StorePath useDeriver(const StorePath & path)
 {
-    if (path.isDerivation()) return path.clone();
+    if (path.isDerivation()) return path;
     auto info = store->queryPathInfo(path);
     if (!info->deriver)
         throw Error("deriver of path '%s' is not known", store->printStorePath(path));
-    return info->deriver->clone();
+    return *info->deriver;
 }
 
 
@@ -214,15 +214,15 @@ static void opPrintFixedPath(Strings opFlags, Strings opArgs)
 
 static StorePathSet maybeUseOutputs(const StorePath & storePath, bool useOutput, bool forceRealise)
 {
-    if (forceRealise) realisePath(storePath);
+    if (forceRealise) realisePath({storePath});
     if (useOutput && storePath.isDerivation()) {
         auto drv = store->derivationFromPath(storePath);
         StorePathSet outputs;
         for (auto & i : drv.outputs)
-            outputs.insert(i.second.path.clone());
+            outputs.insert(i.second.path);
         return outputs;
     }
-    else return singleton(storePath.clone());
+    else return {storePath};
 }
 
 
@@ -232,7 +232,7 @@ static StorePathSet maybeUseOutputs(const StorePath & storePath, bool useOutput,
 static void printTree(const StorePath & path,
     const string & firstPad, const string & tailPad, StorePathSet & done)
 {
-    if (!done.insert(path.clone()).second) {
+    if (!done.insert(path).second) {
         cout << fmt("%s%s [...]\n", firstPad, store->printStorePath(path));
         return;
     }
@@ -310,7 +310,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
         case qOutputs: {
             for (auto & i : opArgs) {
                 auto i2 = store->followLinksToStorePath(i);
-                if (forceRealise) realisePath(i2);
+                if (forceRealise) realisePath({i2});
                 Derivation drv = store->derivationFromPath(i2);
                 for (auto & j : drv.outputs)
                     cout << fmt("%1%\n", store->printStorePath(j.second.path));
@@ -329,13 +329,13 @@ static void opQuery(Strings opFlags, Strings opArgs)
                     if (query == qRequisites) store->computeFSClosure(j, paths, false, includeOutputs);
                     else if (query == qReferences) {
                         for (auto & p : store->queryPathInfo(j)->references)
-                            paths.insert(p.clone());
+                            paths.insert(p);
                     }
                     else if (query == qReferrers) {
                         StorePathSet tmp;
                         store->queryReferrers(j, tmp);
                         for (auto & i : tmp)
-                            paths.insert(i.clone());
+                            paths.insert(i);
                     }
                     else if (query == qReferrersClosure) store->computeFSClosure(j, paths, true);
                 }
@@ -391,7 +391,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
             StorePathSet roots;
             for (auto & i : opArgs)
                 for (auto & j : maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise))
-                    roots.insert(j.clone());
+                    roots.insert(j);
             printDotGraph(ref<Store>(store), std::move(roots));
             break;
         }
@@ -400,7 +400,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
             StorePathSet roots;
             for (auto & i : opArgs)
                 for (auto & j : maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise))
-                    roots.insert(j.clone());
+                    roots.insert(j);
             printGraphML(ref<Store>(store), std::move(roots));
             break;
         }
@@ -415,7 +415,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
             StorePathSet args;
             for (auto & i : opArgs)
                 for (auto & p : maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise))
-                    args.insert(p.clone());
+                    args.insert(p);
 
             StorePathSet referrers;
             store->computeFSClosure(
@@ -482,10 +482,10 @@ static void opDumpDB(Strings opFlags, Strings opArgs)
     if (!opFlags.empty()) throw UsageError("unknown flag");
     if (!opArgs.empty()) {
         for (auto & i : opArgs)
-            cout << store->makeValidityRegistration(singleton(store->followLinksToStorePath(i)), true, true);
+            cout << store->makeValidityRegistration({store->followLinksToStorePath(i)}, true, true);
     } else {
         for (auto & i : store->queryAllValidPaths())
-            cout << store->makeValidityRegistration(singleton(i), true, true);
+            cout << store->makeValidityRegistration({i}, true, true);
     }
 }
 
@@ -586,7 +586,7 @@ static void opGC(Strings opFlags, Strings opArgs)
         // Transpose and sort the roots.
         for (auto & [target, links] : roots)
             for (auto & link : links)
-                roots2.emplace(link, target.clone());
+                roots2.emplace(link, target);
         for (auto & [link, target] : roots2)
             std::cout << link << " -> " << store->printStorePath(target) << "\n";
     }
@@ -830,7 +830,7 @@ static void opServe(Strings opFlags, Strings opArgs)
                     std::vector<StorePathWithOutputs> paths2;
                     for (auto & path : paths)
                         if (!path.isDerivation())
-                            paths2.emplace_back(path.clone());
+                            paths2.push_back({path});
                     unsigned long long downloadSize, narSize;
                     StorePathSet willBuild, willSubstitute, unknown;
                     store->queryMissing(paths2,
@@ -840,7 +840,7 @@ static void opServe(Strings opFlags, Strings opArgs)
                     if (!willSubstitute.empty())
                         try {
                             std::vector<StorePathWithOutputs> subs;
-                            for (auto & p : willSubstitute) subs.emplace_back(p.clone());
+                            for (auto & p : willSubstitute) subs.push_back({p});
                             store->buildPaths(subs);
                         } catch (Error & e) {
                             logWarning(e.info());
@@ -895,7 +895,7 @@ static void opServe(Strings opFlags, Strings opArgs)
 
                 std::vector<StorePathWithOutputs> paths;
                 for (auto & s : readStrings<Strings>(in))
-                    paths.emplace_back(store->parsePathWithOutputs(s));
+                    paths.push_back(store->parsePathWithOutputs(s));
 
                 getBuildSettings();
 
diff --git a/src/nix/command.cc b/src/nix/command.cc
index 71b027719..d62626c26 100644
--- a/src/nix/command.cc
+++ b/src/nix/command.cc
@@ -59,19 +59,19 @@ void StorePathsCommand::run(ref<Store> store)
         if (installables.size())
             throw UsageError("'--all' does not expect arguments");
         for (auto & p : store->queryAllValidPaths())
-            storePaths.push_back(p.clone());
+            storePaths.push_back(p);
     }
 
     else {
         for (auto & p : toStorePaths(store, realiseMode, installables))
-            storePaths.push_back(p.clone());
+            storePaths.push_back(p);
 
         if (recursive) {
             StorePathSet closure;
-            store->computeFSClosure(storePathsToSet(storePaths), closure, false, false);
+            store->computeFSClosure(StorePathSet(storePaths.begin(), storePaths.end()), closure, false, false);
             storePaths.clear();
             for (auto & p : closure)
-                storePaths.push_back(p.clone());
+                storePaths.push_back(p);
         }
     }
 
@@ -133,7 +133,7 @@ void MixProfile::updateProfile(const Buildables & buildables)
         for (auto & output : buildable.outputs) {
             if (result)
                 throw Error("'--profile' requires that the arguments produce a single store path, but there are multiple");
-            result = output.second.clone();
+            result = output.second;
         }
     }
 
diff --git a/src/nix/copy.cc b/src/nix/copy.cc
index c7c38709d..64099f476 100644
--- a/src/nix/copy.cc
+++ b/src/nix/copy.cc
@@ -94,7 +94,7 @@ struct CmdCopy : StorePathsCommand
 
         ref<Store> dstStore = dstUri.empty() ? openStore() : openStore(dstUri);
 
-        copyPaths(srcStore, dstStore, storePathsToSet(storePaths),
+        copyPaths(srcStore, dstStore, StorePathSet(storePaths.begin(), storePaths.end()),
             NoRepair, checkSigs, substitute);
     }
 };
diff --git a/src/nix/develop.cc b/src/nix/develop.cc
index 3045d7dc3..05a9b9cd9 100644
--- a/src/nix/develop.cc
+++ b/src/nix/develop.cc
@@ -135,12 +135,12 @@ StorePath getDerivationEnvironment(ref<Store> store, const StorePath & drvPath)
     drv.inputSrcs.insert(std::move(getEnvShPath));
     Hash h = hashDerivationModulo(*store, drv, true);
     auto shellOutPath = store->makeOutputPath("out", h, drvName);
-    drv.outputs.insert_or_assign("out", DerivationOutput(shellOutPath.clone(), "", ""));
+    drv.outputs.insert_or_assign("out", DerivationOutput { shellOutPath, "", "" });
     drv.env["out"] = store->printStorePath(shellOutPath);
     auto shellDrvPath2 = writeDerivation(store, drv, drvName);
 
     /* Build the derivation. */
-    store->buildPaths({shellDrvPath2});
+    store->buildPaths({{shellDrvPath2}});
 
     assert(store->isValidPath(shellOutPath));
 
@@ -205,7 +205,7 @@ struct Common : InstallableCommand, MixProfile
     {
         auto path = installable->getStorePath();
         if (path && hasSuffix(path->to_string(), "-env"))
-            return path->clone();
+            return *path;
         else {
             auto drvs = toDerivations(store, {installable});
 
diff --git a/src/nix/installables.cc b/src/nix/installables.cc
index 937d69206..708a0dc88 100644
--- a/src/nix/installables.cc
+++ b/src/nix/installables.cc
@@ -102,9 +102,9 @@ struct InstallableStorePath : Installable
     Buildables toBuildables() override
     {
         std::map<std::string, StorePath> outputs;
-        outputs.insert_or_assign("out", storePath.clone());
+        outputs.insert_or_assign("out", storePath);
         Buildable b{
-            .drvPath = storePath.isDerivation() ? storePath.clone() : std::optional<StorePath>(),
+            .drvPath = storePath.isDerivation() ? storePath : std::optional<StorePath>(),
             .outputs = std::move(outputs)
         };
         Buildables bs;
@@ -114,7 +114,7 @@ struct InstallableStorePath : Installable
 
     std::optional<StorePath> getStorePath() override
     {
-        return storePath.clone();
+        return storePath;
     }
 };
 
@@ -141,7 +141,7 @@ struct InstallableValue : Installable
 
         for (auto & drv : drvs) {
             Buildable b{.drvPath = state->store->parseStorePath(drv.queryDrvPath())};
-            drvPaths.insert(b.drvPath->clone());
+            drvPaths.insert(*b.drvPath);
 
             auto outputName = drv.queryOutputName();
             if (outputName == "")
@@ -155,10 +155,10 @@ struct InstallableValue : Installable
         // Hack to recognize .all: if all drvs have the same drvPath,
         // merge the buildables.
         if (drvPaths.size() == 1) {
-            Buildable b{.drvPath = drvPaths.begin()->clone()};
+            Buildable b{.drvPath = *drvPaths.begin()};
             for (auto & b2 : res)
                 for (auto & output : b2.outputs)
-                    b.outputs.insert_or_assign(output.first, output.second.clone());
+                    b.outputs.insert_or_assign(output.first, output.second);
             Buildables bs;
             bs.push_back(std::move(b));
             return bs;
@@ -273,7 +273,7 @@ Buildables build(ref<Store> store, RealiseMode mode,
                 pathsToBuild.push_back({*b.drvPath, outputNames});
             } else
                 for (auto & output : b.outputs)
-                    pathsToBuild.push_back({output.second.clone()});
+                    pathsToBuild.push_back({output.second});
             buildables.push_back(std::move(b));
         }
     }
@@ -293,7 +293,7 @@ StorePathSet toStorePaths(ref<Store> store, RealiseMode mode,
 
     for (auto & b : build(store, mode, installables))
         for (auto & output : b.outputs)
-            outPaths.insert(output.second.clone());
+            outPaths.insert(output.second);
 
     return outPaths;
 }
@@ -306,7 +306,7 @@ StorePath toStorePath(ref<Store> store, RealiseMode mode,
     if (paths.size() != 1)
             throw Error("argument '%s' should evaluate to one store path", installable->what());
 
-    return paths.begin()->clone();
+    return *paths.begin();
 }
 
 StorePathSet toDerivations(ref<Store> store,
@@ -324,10 +324,10 @@ StorePathSet toDerivations(ref<Store> store,
                     if (derivers.empty())
                         throw Error("'%s' does not have a known deriver", i->what());
                     // FIXME: use all derivers?
-                    drvPaths.insert(derivers.begin()->clone());
+                    drvPaths.insert(*derivers.begin());
                 }
             } else
-                drvPaths.insert(b.drvPath->clone());
+                drvPaths.insert(*b.drvPath);
         }
 
     return drvPaths;
diff --git a/src/nix/make-content-addressable.cc b/src/nix/make-content-addressable.cc
index 1211dad7b..0ebb8f13b 100644
--- a/src/nix/make-content-addressable.cc
+++ b/src/nix/make-content-addressable.cc
@@ -36,7 +36,7 @@ struct CmdMakeContentAddressable : StorePathsCommand, MixJSON
 
     void run(ref<Store> store, StorePaths storePaths) override
     {
-        auto paths = store->topoSortPaths(storePathsToSet(storePaths));
+        auto paths = store->topoSortPaths(StorePathSet(storePaths.begin(), storePaths.end()));
 
         std::reverse(paths.begin(), paths.end());
 
@@ -62,7 +62,7 @@ struct CmdMakeContentAddressable : StorePathsCommand, MixJSON
                     hasSelfReference = true;
                 else {
                     auto i = remappings.find(ref);
-                    auto replacement = i != remappings.end() ? i->second.clone() : ref.clone();
+                    auto replacement = i != remappings.end() ? i->second : ref;
                     // FIXME: warn about unremapped paths?
                     if (replacement != ref)
                         rewrites.insert_or_assign(store->printStorePath(ref), store->printStorePath(replacement));
@@ -79,7 +79,7 @@ struct CmdMakeContentAddressable : StorePathsCommand, MixJSON
 
             ValidPathInfo info(store->makeFixedOutputPath(FileIngestionMethod::Recursive, narHash, path.name(), references, hasSelfReference));
             info.references = std::move(references);
-            if (hasSelfReference) info.references.insert(info.path.clone());
+            if (hasSelfReference) info.references.insert(info.path);
             info.narHash = narHash;
             info.narSize = sink.s->size();
             info.ca = makeFixedOutputCA(FileIngestionMethod::Recursive, info.narHash);
diff --git a/src/nix/path-info.cc b/src/nix/path-info.cc
index 88d7fffd4..fb7bacc4c 100644
--- a/src/nix/path-info.cc
+++ b/src/nix/path-info.cc
@@ -90,7 +90,7 @@ struct CmdPathInfo : StorePathsCommand, MixJSON
             JSONPlaceholder jsonRoot(std::cout);
             store->pathInfoToJSON(jsonRoot,
                 // FIXME: preserve order?
-                storePathsToSet(storePaths),
+                StorePathSet(storePaths.begin(), storePaths.end()),
                 true, showClosureSize, SRI, AllowInvalid);
         }
 
diff --git a/src/nix/run.cc b/src/nix/run.cc
index c9b69aec7..321ee1d11 100644
--- a/src/nix/run.cc
+++ b/src/nix/run.cc
@@ -111,16 +111,16 @@ struct CmdShell : InstallablesCommand, RunCommon, MixEnvironment
 
         std::unordered_set<StorePath> done;
         std::queue<StorePath> todo;
-        for (auto & path : outPaths) todo.push(path.clone());
+        for (auto & path : outPaths) todo.push(path);
 
         setEnviron();
 
         auto unixPath = tokenizeString<Strings>(getEnv("PATH").value_or(""), ":");
 
         while (!todo.empty()) {
-            auto path = todo.front().clone();
+            auto path = todo.front();
             todo.pop();
-            if (!done.insert(path.clone()).second) continue;
+            if (!done.insert(path).second) continue;
 
             if (true)
                 unixPath.push_front(store->printStorePath(path) + "/bin");
diff --git a/src/nix/why-depends.cc b/src/nix/why-depends.cc
index a4ee2d971..167c974ee 100644
--- a/src/nix/why-depends.cc
+++ b/src/nix/why-depends.cc
@@ -106,16 +106,16 @@ struct CmdWhyDepends : SourceExprCommand
         std::map<StorePath, Node> graph;
 
         for (auto & path : closure)
-            graph.emplace(path.clone(), Node { .path = path.clone(), .refs = cloneStorePathSet(store->queryPathInfo(path)->references) });
+            graph.emplace(path, Node { .path = path, .refs = store->queryPathInfo(path)->references });
 
         // Transpose the graph.
         for (auto & node : graph)
             for (auto & ref : node.second.refs)
-                graph.find(ref)->second.rrefs.insert(node.first.clone());
+                graph.find(ref)->second.rrefs.insert(node.first);
 
         /* Run Dijkstra's shortest path algorithm to get the distance
            of every path in the closure to 'dependency'. */
-        graph.emplace(dependencyPath.clone(), Node { .path = dependencyPath.clone(), .dist = 0 });
+        graph.emplace(dependencyPath, Node { .path = dependencyPath, .dist = 0 });
 
         std::priority_queue<Node *> queue;