diff --git a/src/libexpr/attr-path.cc b/src/libexpr/attr-path.cc index b02b08db4..58705bfa1 100644 --- a/src/libexpr/attr-path.cc +++ b/src/libexpr/attr-path.cc @@ -110,8 +110,8 @@ std::pair findPackageFilename(EvalState & state, Value & v { Value * v2; try { - auto dummyArgs = state.allocBindings(0); - v2 = findAlongAttrPath(state, "meta.position", *dummyArgs, v).first; + auto & dummyArgs = Bindings::emptyBindings; + v2 = findAlongAttrPath(state, "meta.position", dummyArgs, v).first; } catch (Error &) { throw NoPositionInfo("package '%s' has no source location information", what); } diff --git a/src/libexpr/attr-set.cc b/src/libexpr/attr-set.cc index eb44b0dd9..48d4c4d4a 100644 --- a/src/libexpr/attr-set.cc +++ b/src/libexpr/attr-set.cc @@ -5,13 +5,15 @@ namespace nix { +Bindings Bindings::emptyBindings; + /* Allocate a new array of attributes for an attribute set with a specific capacity. The space is implicitly reserved after the Bindings structure. */ Bindings * EvalState::allocBindings(size_t capacity) { if (capacity == 0) - return &emptyBindings; + return &Bindings::emptyBindings; if (capacity > std::numeric_limits::max()) throw Error("attribute set of size %d is too big", capacity); nrAttrsets++; diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index df4e52e5d..b586c3409 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -202,7 +202,6 @@ EvalState::EvalState( , settings{settings} , symbols(StaticEvalSymbols::staticSymbolTable()) , repair(NoRepair) - , emptyBindings(Bindings()) , storeFS(makeMountedSourceAccessor({ {CanonPath::root, makeEmptySourceAccessor()}, /* In the pure eval case, we can simply require diff --git a/src/libexpr/include/nix/expr/attr-set.hh b/src/libexpr/include/nix/expr/attr-set.hh index b5e927a7e..4ab54c8eb 100644 --- a/src/libexpr/include/nix/expr/attr-set.hh +++ b/src/libexpr/include/nix/expr/attr-set.hh @@ -54,6 +54,12 @@ public: typedef uint32_t size_t; PosIdx pos; + /** + * An instance of bindings objects with 0 attributes. + * This object must never be modified. + */ + static Bindings emptyBindings; + private: size_t size_ = 0; Attr attrs[0]; diff --git a/src/libexpr/include/nix/expr/eval.hh b/src/libexpr/include/nix/expr/eval.hh index 5015a009b..0b91645ea 100644 --- a/src/libexpr/include/nix/expr/eval.hh +++ b/src/libexpr/include/nix/expr/eval.hh @@ -313,8 +313,6 @@ public: */ RepairFlag repair; - Bindings emptyBindings; - /** * Empty list constant. */ diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 9ba417c32..2a3eec672 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -3326,14 +3326,14 @@ static void prim_functionArgs(EvalState & state, const PosIdx pos, Value ** args { state.forceValue(*args[0], pos); if (args[0]->isPrimOpApp() || args[0]->isPrimOp()) { - v.mkAttrs(&state.emptyBindings); + v.mkAttrs(&Bindings::emptyBindings); return; } if (!args[0]->isLambda()) state.error("'functionArgs' requires a function").atPos(pos).debugThrow(); if (!args[0]->lambda().fun->hasFormals()) { - v.mkAttrs(&state.emptyBindings); + v.mkAttrs(&Bindings::emptyBindings); return; } diff --git a/src/nix/flake.cc b/src/nix/flake.cc index 8d6387c9d..3b1e2f5e4 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -522,7 +522,7 @@ struct CmdFlakeCheck : FlakeCommand auto checkNixOSConfiguration = [&](const std::string & attrPath, Value & v, const PosIdx pos) { try { Activity act(*logger, lvlInfo, actUnknown, fmt("checking NixOS configuration '%s'", attrPath)); - Bindings & bindings(*state->allocBindings(0)); + Bindings & bindings = Bindings::emptyBindings; auto vToplevel = findAlongAttrPath(*state, "config.system.build.toplevel", bindings, v).first; state->forceValue(*vToplevel, pos); if (!state->isDerivation(*vToplevel)) diff --git a/src/nix/nix-env/user-env.cc b/src/nix/nix-env/user-env.cc index 4ed93135d..552172825 100644 --- a/src/nix/nix-env/user-env.cc +++ b/src/nix/nix-env/user-env.cc @@ -24,7 +24,7 @@ PackageInfos queryInstalled(EvalState & state, const Path & userEnv) if (pathExists(manifestFile)) { Value v; state.evalFile(state.rootPath(CanonPath(manifestFile)).resolveSymlinks(), v); - Bindings & bindings(*state.allocBindings(0)); + Bindings & bindings = Bindings::emptyBindings; getDerivations(state, v, "", bindings, elems, false); } return elems; diff --git a/src/nix/upgrade-nix.cc b/src/nix/upgrade-nix.cc index 48235a27f..f26613bf8 100644 --- a/src/nix/upgrade-nix.cc +++ b/src/nix/upgrade-nix.cc @@ -162,7 +162,7 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand auto state = std::make_unique(LookupPath{}, store, fetchSettings, evalSettings); auto v = state->allocValue(); state->eval(state->parseExprFromString(res.data, state->rootPath(CanonPath("/no-such-path"))), *v); - Bindings & bindings(*state->allocBindings(0)); + Bindings & bindings = Bindings::emptyBindings; auto v2 = findAlongAttrPath(*state, settings.thisSystem, bindings, *v).first; return store->parseStorePath(