libexpr: move symbols into own struct

not all of these are even used by eval itself. notably sWith wasn't used
at all, sEpsilon was only used by the eval cache one layer up, and other
attributes are used in places even further away from eval itself. we can
keep this commingling for now, but eventually we should clean it up too.

Change-Id: I5684ac614361bf008e04472130c6c02082b4c2d7
This commit is contained in:
eldritch horrors 2024-11-27 02:09:08 +01:00
parent f017f9ddd3
commit 7af000ddff
20 changed files with 183 additions and 183 deletions

View file

@ -47,22 +47,22 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
auto attrs = state.buildBindings(7 + outputs.size()); auto attrs = state.buildBindings(7 + outputs.size());
attrs.alloc(state.sType).mkString("derivation"); attrs.alloc(state.s.type).mkString("derivation");
attrs.alloc(state.sName).mkString(i.queryName()); attrs.alloc(state.s.name).mkString(i.queryName());
auto system = i.querySystem(); auto system = i.querySystem();
if (!system.empty()) if (!system.empty())
attrs.alloc(state.sSystem).mkString(system); attrs.alloc(state.s.system).mkString(system);
attrs.alloc(state.sOutPath).mkString(state.store->printStorePath(i.queryOutPath())); attrs.alloc(state.s.outPath).mkString(state.store->printStorePath(i.queryOutPath()));
if (drvPath) if (drvPath)
attrs.alloc(state.sDrvPath).mkString(state.store->printStorePath(*drvPath)); attrs.alloc(state.s.drvPath).mkString(state.store->printStorePath(*drvPath));
// Copy each output meant for installation. // Copy each output meant for installation.
auto & vOutputs = attrs.alloc(state.sOutputs); auto & vOutputs = attrs.alloc(state.s.outputs);
state.mkList(vOutputs, outputs.size()); state.mkList(vOutputs, outputs.size());
for (const auto & [m, j] : enumerate(outputs)) { for (const auto & [m, j] : enumerate(outputs)) {
(vOutputs.listElems()[m] = state.allocValue())->mkString(j.first); (vOutputs.listElems()[m] = state.allocValue())->mkString(j.first);
auto outputAttrs = state.buildBindings(2); auto outputAttrs = state.buildBindings(2);
outputAttrs.alloc(state.sOutPath).mkString(state.store->printStorePath(*j.second)); outputAttrs.alloc(state.s.outPath).mkString(state.store->printStorePath(*j.second));
attrs.alloc(j.first).mkAttrs(outputAttrs); attrs.alloc(j.first).mkAttrs(outputAttrs);
/* This is only necessary when installing store paths, e.g., /* This is only necessary when installing store paths, e.g.,
@ -81,7 +81,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
meta.insert(state.symbols.create(j), v); meta.insert(state.symbols.create(j), v);
} }
attrs.alloc(state.sMeta).mkAttrs(meta); attrs.alloc(state.s.meta).mkAttrs(meta);
(manifest.listElems()[n++] = state.allocValue())->mkAttrs(attrs); (manifest.listElems()[n++] = state.allocValue())->mkAttrs(attrs);
@ -117,9 +117,9 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
debug("evaluating user environment builder"); debug("evaluating user environment builder");
state.forceValue(topLevel, topLevel.determinePos(noPos)); state.forceValue(topLevel, topLevel.determinePos(noPos));
NixStringContext context; NixStringContext context;
Attr & aDrvPath(*topLevel.attrs->find(state.sDrvPath)); Attr & aDrvPath(*topLevel.attrs->find(state.s.drvPath));
auto topLevelDrv = state.coerceToStorePath(aDrvPath.pos, *aDrvPath.value, context, ""); auto topLevelDrv = state.coerceToStorePath(aDrvPath.pos, *aDrvPath.value, context, "");
Attr & aOutPath(*topLevel.attrs->find(state.sOutPath)); Attr & aOutPath(*topLevel.attrs->find(state.s.outPath));
auto topLevelOut = state.coerceToStorePath(aOutPath.pos, *aOutPath.value, context, ""); auto topLevelOut = state.coerceToStorePath(aOutPath.pos, *aOutPath.value, context, "");
/* Realise the resulting store expression. */ /* Realise the resulting store expression. */

View file

@ -118,8 +118,8 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
std::optional<NixInt::Inner> priority; std::optional<NixInt::Inner> priority;
if (attr->maybeGetAttr(state->sOutputSpecified)) { if (attr->maybeGetAttr(state->s.outputSpecified)) {
} else if (auto aMeta = attr->maybeGetAttr(state->sMeta)) { } else if (auto aMeta = attr->maybeGetAttr(state->s.meta)) {
if (auto aPriority = aMeta->maybeGetAttr("priority")) if (auto aPriority = aMeta->maybeGetAttr("priority"))
priority = aPriority->getInt().value; priority = aPriority->getInt().value;
} }
@ -130,12 +130,12 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
.outputs = std::visit(overloaded { .outputs = std::visit(overloaded {
[&](const ExtendedOutputsSpec::Default & d) -> OutputsSpec { [&](const ExtendedOutputsSpec::Default & d) -> OutputsSpec {
std::set<std::string> outputsToInstall; std::set<std::string> outputsToInstall;
if (auto aOutputSpecified = attr->maybeGetAttr(state->sOutputSpecified)) { if (auto aOutputSpecified = attr->maybeGetAttr(state->s.outputSpecified)) {
if (aOutputSpecified->getBool()) { if (aOutputSpecified->getBool()) {
if (auto aOutputName = attr->maybeGetAttr("outputName")) if (auto aOutputName = attr->maybeGetAttr("outputName"))
outputsToInstall = { aOutputName->getString() }; outputsToInstall = { aOutputName->getString() };
} }
} else if (auto aMeta = attr->maybeGetAttr(state->sMeta)) { } else if (auto aMeta = attr->maybeGetAttr(state->s.meta)) {
if (auto aOutputsToInstall = aMeta->maybeGetAttr("outputsToInstall")) if (auto aOutputsToInstall = aMeta->maybeGetAttr("outputsToInstall"))
for (auto & s : aOutputsToInstall->getListOfStrings()) for (auto & s : aOutputsToInstall->getListOfStrings())
outputsToInstall.insert(s); outputsToInstall.insert(s);

View file

@ -372,7 +372,7 @@ AttrCursor::AttrCursor(
AttrKey AttrCursor::getKey() AttrKey AttrCursor::getKey()
{ {
if (!parent) if (!parent)
return {0, root->state.sEpsilon}; return {0, root->state.s.epsilon};
if (!parent->first->cachedValue) { if (!parent->first->cachedValue) {
parent->first->cachedValue = root->db->getAttr(parent->first->getKey()); parent->first->cachedValue = root->db->getAttr(parent->first->getKey());
assert(parent->first->cachedValue); assert(parent->first->cachedValue);
@ -748,7 +748,7 @@ bool AttrCursor::isDerivation()
StorePath AttrCursor::forceDerivation() StorePath AttrCursor::forceDerivation()
{ {
auto aDrvPath = getAttr(root->state.sDrvPath); auto aDrvPath = getAttr(root->state.s.drvPath);
auto drvPath = root->state.store->parseStorePath(aDrvPath->getString()); auto drvPath = root->state.store->parseStorePath(aDrvPath->getString());
if (!root->state.store->isValidPath(drvPath) && !settings.readOnlyMode) { if (!root->state.store->isValidPath(drvPath) && !settings.readOnlyMode) {
/* The eval cache contains 'drvPath', but the actual path has /* The eval cache contains 'drvPath', but the actual path has

View file

@ -196,53 +196,49 @@ void initLibExpr()
libexprInitialised = true; libexprInitialised = true;
} }
EvalState::EvalState( StaticSymbols::StaticSymbols(SymbolTable & symbols)
const SearchPath & _searchPath, : outPath(symbols.create("outPath"))
ref<Store> store, , drvPath(symbols.create("drvPath"))
std::shared_ptr<Store> buildStore) , type(symbols.create("type"))
: sWith(symbols.create("<with>")) , meta(symbols.create("meta"))
, sOutPath(symbols.create("outPath")) , name(symbols.create("name"))
, sDrvPath(symbols.create("drvPath")) , value(symbols.create("value"))
, sType(symbols.create("type")) , system(symbols.create("system"))
, sMeta(symbols.create("meta")) , overrides(symbols.create("__overrides"))
, sName(symbols.create("name")) , outputs(symbols.create("outputs"))
, sValue(symbols.create("value")) , outputName(symbols.create("outputName"))
, sSystem(symbols.create("system")) , ignoreNulls(symbols.create("__ignoreNulls"))
, sOverrides(symbols.create("__overrides")) , file(symbols.create("file"))
, sOutputs(symbols.create("outputs")) , line(symbols.create("line"))
, sOutputName(symbols.create("outputName")) , column(symbols.create("column"))
, sIgnoreNulls(symbols.create("__ignoreNulls")) , functor(symbols.create("__functor"))
, sFile(symbols.create("file")) , toString(symbols.create("__toString"))
, sLine(symbols.create("line")) , right(symbols.create("right"))
, sColumn(symbols.create("column")) , wrong(symbols.create("wrong"))
, sFunctor(symbols.create("__functor")) , structuredAttrs(symbols.create("__structuredAttrs"))
, sToString(symbols.create("__toString")) , allowedReferences(symbols.create("allowedReferences"))
, sRight(symbols.create("right")) , allowedRequisites(symbols.create("allowedRequisites"))
, sWrong(symbols.create("wrong")) , disallowedReferences(symbols.create("disallowedReferences"))
, sStructuredAttrs(symbols.create("__structuredAttrs")) , disallowedRequisites(symbols.create("disallowedRequisites"))
, sAllowedReferences(symbols.create("allowedReferences")) , maxSize(symbols.create("maxSize"))
, sAllowedRequisites(symbols.create("allowedRequisites")) , maxClosureSize(symbols.create("maxClosureSize"))
, sDisallowedReferences(symbols.create("disallowedReferences")) , builder(symbols.create("builder"))
, sDisallowedRequisites(symbols.create("disallowedRequisites")) , args(symbols.create("args"))
, sMaxSize(symbols.create("maxSize")) , contentAddressed(symbols.create("__contentAddressed"))
, sMaxClosureSize(symbols.create("maxClosureSize")) , impure(symbols.create("__impure"))
, sBuilder(symbols.create("builder")) , outputHash(symbols.create("outputHash"))
, sArgs(symbols.create("args")) , outputHashAlgo(symbols.create("outputHashAlgo"))
, sContentAddressed(symbols.create("__contentAddressed")) , outputHashMode(symbols.create("outputHashMode"))
, sImpure(symbols.create("__impure")) , recurseForDerivations(symbols.create("recurseForDerivations"))
, sOutputHash(symbols.create("outputHash")) , description(symbols.create("description"))
, sOutputHashAlgo(symbols.create("outputHashAlgo")) , self(symbols.create("self"))
, sOutputHashMode(symbols.create("outputHashMode")) , epsilon(symbols.create(""))
, sRecurseForDerivations(symbols.create("recurseForDerivations")) , startSet(symbols.create("startSet"))
, sDescription(symbols.create("description")) , operator_(symbols.create("operator"))
, sSelf(symbols.create("self")) , key(symbols.create("key"))
, sEpsilon(symbols.create("")) , path(symbols.create("path"))
, sStartSet(symbols.create("startSet")) , prefix(symbols.create("prefix"))
, sOperator(symbols.create("operator")) , outputSpecified(symbols.create("outputSpecified"))
, sKey(symbols.create("key"))
, sPath(symbols.create("path"))
, sPrefix(symbols.create("prefix"))
, sOutputSpecified(symbols.create("outputSpecified"))
, exprSymbols{ , exprSymbols{
.sub = symbols.create("__sub"), .sub = symbols.create("__sub"),
.lessThan = symbols.create("__lessThan"), .lessThan = symbols.create("__lessThan"),
@ -254,6 +250,14 @@ EvalState::EvalState(
.body = symbols.create("body"), .body = symbols.create("body"),
.overrides = symbols.create("__overrides"), .overrides = symbols.create("__overrides"),
} }
{
}
EvalState::EvalState(
const SearchPath & _searchPath,
ref<Store> store,
std::shared_ptr<Store> buildStore)
: s(symbols)
, repair(NoRepair) , repair(NoRepair)
, derivationInternal(rootPath(CanonPath("/builtin/derivation.nix"))) , derivationInternal(rootPath(CanonPath("/builtin/derivation.nix")))
, store(store) , store(store)
@ -774,8 +778,8 @@ void EvalState::mkPos(Value & v, PosIdx p)
auto origin = positions.originOf(p); auto origin = positions.originOf(p);
if (auto path = std::get_if<SourcePath>(&origin)) { if (auto path = std::get_if<SourcePath>(&origin)) {
auto attrs = buildBindings(3); auto attrs = buildBindings(3);
attrs.alloc(sFile).mkString(path->path.abs()); attrs.alloc(s.file).mkString(path->path.abs());
makePositionThunks(*this, p, attrs.alloc(sLine), attrs.alloc(sColumn)); makePositionThunks(*this, p, attrs.alloc(s.line), attrs.alloc(s.column));
v.mkAttrs(attrs); v.mkAttrs(attrs);
} else } else
v.mkNull(); v.mkNull();
@ -1072,7 +1076,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
dynamicEnv = &env2; dynamicEnv = &env2;
Env * inheritEnv = inheritFromExprs ? buildInheritFromEnv(state, env2) : nullptr; Env * inheritEnv = inheritFromExprs ? buildInheritFromEnv(state, env2) : nullptr;
AttrDefs::iterator overrides = attrs.find(state.sOverrides); AttrDefs::iterator overrides = attrs.find(state.s.overrides);
bool hasOverrides = overrides != attrs.end(); bool hasOverrides = overrides != attrs.end();
/* The recursive attributes are evaluated in the new /* The recursive attributes are evaluated in the new
@ -1680,7 +1684,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
} }
} }
else if (vCur.type() == nAttrs && (functor = vCur.attrs->get(sFunctor))) { else if (vCur.type() == nAttrs && (functor = vCur.attrs->get(s.functor))) {
/* 'vCur' may be allocated on the stack of the calling /* 'vCur' may be allocated on the stack of the calling
function, but for functors we may keep a reference, so function, but for functors we may keep a reference, so
heap-allocate a copy and use that instead. */ heap-allocate a copy and use that instead. */
@ -1755,7 +1759,7 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res)
forceValue(fun, pos); forceValue(fun, pos);
if (fun.type() == nAttrs) { if (fun.type() == nAttrs) {
auto found = fun.attrs->find(sFunctor); auto found = fun.attrs->find(s.functor);
if (found != fun.attrs->end()) { if (found != fun.attrs->end()) {
Value * v = allocValue(); Value * v = allocValue();
callFunction(*found->value, fun, *v, pos); callFunction(*found->value, fun, *v, pos);
@ -2168,7 +2172,7 @@ bool EvalState::forceBool(Value & v, const PosIdx pos, std::string_view errorCtx
bool EvalState::isFunctor(Value & fun) bool EvalState::isFunctor(Value & fun)
{ {
return fun.type() == nAttrs && fun.attrs->find(sFunctor) != fun.attrs->end(); return fun.type() == nAttrs && fun.attrs->find(s.functor) != fun.attrs->end();
} }
@ -2236,7 +2240,7 @@ std::string_view EvalState::forceStringNoCtx(Value & v, const PosIdx pos, std::s
bool EvalState::isDerivation(Value & v) bool EvalState::isDerivation(Value & v)
{ {
if (v.type() != nAttrs) return false; if (v.type() != nAttrs) return false;
Bindings::iterator i = v.attrs->find(sType); Bindings::iterator i = v.attrs->find(s.type);
if (i == v.attrs->end()) return false; if (i == v.attrs->end()) return false;
forceValue(*i->value, i->pos); forceValue(*i->value, i->pos);
if (i->value->type() != nString) return false; if (i->value->type() != nString) return false;
@ -2247,7 +2251,7 @@ bool EvalState::isDerivation(Value & v)
std::optional<std::string> EvalState::tryAttrsToString(const PosIdx pos, Value & v, std::optional<std::string> EvalState::tryAttrsToString(const PosIdx pos, Value & v,
NixStringContext & context, bool coerceMore, bool copyToStore) NixStringContext & context, bool coerceMore, bool copyToStore)
{ {
auto i = v.attrs->find(sToString); auto i = v.attrs->find(s.toString);
if (i != v.attrs->end()) { if (i != v.attrs->end()) {
Value v1; Value v1;
callFunction(*i->value, v, v1, pos); callFunction(*i->value, v, v1, pos);
@ -2290,7 +2294,7 @@ BackedStringView EvalState::coerceToString(
auto maybeString = tryAttrsToString(pos, v, context, coerceMore, copyToStore); auto maybeString = tryAttrsToString(pos, v, context, coerceMore, copyToStore);
if (maybeString) if (maybeString)
return std::move(*maybeString); return std::move(*maybeString);
auto i = v.attrs->find(sOutPath); auto i = v.attrs->find(s.outPath);
if (i == v.attrs->end()) { if (i == v.attrs->end()) {
error<TypeError>( error<TypeError>(
"cannot coerce %1% to a string: %2%", "cannot coerce %1% to a string: %2%",
@ -2495,8 +2499,8 @@ bool EvalState::eqValues(Value & v1, Value & v2, const PosIdx pos, std::string_v
/* If both sets denote a derivation (type = "derivation"), /* If both sets denote a derivation (type = "derivation"),
then compare their outPaths. */ then compare their outPaths. */
if (isDerivation(v1) && isDerivation(v2)) { if (isDerivation(v1) && isDerivation(v2)) {
Bindings::iterator i = v1.attrs->find(sOutPath); Bindings::iterator i = v1.attrs->find(s.outPath);
Bindings::iterator j = v2.attrs->find(sOutPath); Bindings::iterator j = v2.attrs->find(s.outPath);
if (i != v1.attrs->end() && j != v2.attrs->end()) if (i != v1.attrs->end() && j != v2.attrs->end())
return eqValues(*i->value, *j->value, pos, errorCtx); return eqValues(*i->value, *j->value, pos, errorCtx);
} }

View file

@ -153,27 +153,27 @@ struct DebugTrace {
}; };
struct StaticSymbols
{
const Symbol outPath, drvPath, type, meta, name, value, system, overrides, outputs, outputName,
ignoreNulls, file, line, column, functor, toString, right, wrong, structuredAttrs,
allowedReferences, allowedRequisites, disallowedReferences, disallowedRequisites, maxSize,
maxClosureSize, builder, args, contentAddressed, impure, outputHash, outputHashAlgo,
outputHashMode, recurseForDerivations, description, self, epsilon, startSet, operator_, key,
path, prefix, outputSpecified;
const Expr::AstSymbols exprSymbols;
explicit StaticSymbols(SymbolTable & symbols);
};
class EvalState class EvalState
{ {
public: public:
SymbolTable symbols; SymbolTable symbols;
PosTable positions; PosTable positions;
const StaticSymbols s;
const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName, sValue,
sSystem, sOverrides, sOutputs, sOutputName, sIgnoreNulls,
sFile, sLine, sColumn, sFunctor, sToString,
sRight, sWrong, sStructuredAttrs,
sAllowedReferences, sAllowedRequisites, sDisallowedReferences, sDisallowedRequisites,
sMaxSize, sMaxClosureSize,
sBuilder, sArgs,
sContentAddressed, sImpure,
sOutputHash, sOutputHashAlgo, sOutputHashMode,
sRecurseForDerivations,
sDescription, sSelf, sEpsilon, sStartSet, sOperator, sKey, sPath,
sPrefix,
sOutputSpecified;
const Expr::AstSymbols exprSymbols;
/** /**
* If set, force copying files to the Nix store even if they * If set, force copying files to the Nix store even if they

View file

@ -245,7 +245,7 @@ static Flake getFlake(
Value vInfo; Value vInfo;
state.evalFile(CanonPath(flakeFile), vInfo, true); // FIXME: symlink attack state.evalFile(CanonPath(flakeFile), vInfo, true); // FIXME: symlink attack
if (auto description = vInfo.attrs->get(state.sDescription)) { if (auto description = vInfo.attrs->get(state.s.description)) {
expectType(state, nString, *description->value, description->pos); expectType(state, nString, *description->value, description->pos);
flake.description = description->value->string.s; flake.description = description->value->string.s;
} }
@ -255,14 +255,12 @@ static Flake getFlake(
if (auto inputs = vInfo.attrs->get(sInputs)) if (auto inputs = vInfo.attrs->get(sInputs))
flake.inputs = parseFlakeInputs(state, inputs->value, inputs->pos, flakeDir, lockRootPath, 0); flake.inputs = parseFlakeInputs(state, inputs->value, inputs->pos, flakeDir, lockRootPath, 0);
auto sOutputs = state.symbols.create("outputs"); if (auto outputs = vInfo.attrs->get(state.s.outputs)) {
if (auto outputs = vInfo.attrs->get(sOutputs)) {
expectType(state, nFunction, *outputs->value, outputs->pos); expectType(state, nFunction, *outputs->value, outputs->pos);
if (outputs->value->isLambda() && outputs->value->lambda.fun->hasFormals()) { if (outputs->value->isLambda() && outputs->value->lambda.fun->hasFormals()) {
for (auto & formal : outputs->value->lambda.fun->formals->formals) { for (auto & formal : outputs->value->lambda.fun->formals->formals) {
if (formal.name != state.sSelf) if (formal.name != state.s.self)
flake.inputs.emplace(state.symbols[formal.name], FlakeInput { flake.inputs.emplace(state.symbols[formal.name], FlakeInput {
.ref = parseFlakeRef(state.symbols[formal.name]) .ref = parseFlakeRef(state.symbols[formal.name])
}); });
@ -314,9 +312,9 @@ static Flake getFlake(
} }
for (auto & attr : *vInfo.attrs) { for (auto & attr : *vInfo.attrs) {
if (attr.name != state.sDescription && if (attr.name != state.s.description &&
attr.name != sInputs && attr.name != sInputs &&
attr.name != sOutputs && attr.name != state.s.outputs &&
attr.name != sNixConfig) attr.name != sNixConfig)
throw Error("flake '%s' has an unsupported attribute '%s', at %s", throw Error("flake '%s' has an unsupported attribute '%s', at %s",
lockedRef, state.symbols[attr.name], state.positions[attr.pos]); lockedRef, state.symbols[attr.name], state.positions[attr.pos]);

View file

@ -49,7 +49,7 @@ DrvInfo::DrvInfo(EvalState & state, ref<Store> store, const std::string & drvPat
std::string DrvInfo::queryName() std::string DrvInfo::queryName()
{ {
if (name == "" && attrs) { if (name == "" && attrs) {
auto i = attrs->find(state->sName); auto i = attrs->find(state->s.name);
if (i == attrs->end()) state->error<TypeError>("derivation name missing").debugThrow(); if (i == attrs->end()) state->error<TypeError>("derivation name missing").debugThrow();
name = state->forceStringNoCtx(*i->value, noPos, "while evaluating the 'name' attribute of a derivation"); name = state->forceStringNoCtx(*i->value, noPos, "while evaluating the 'name' attribute of a derivation");
} }
@ -60,7 +60,7 @@ std::string DrvInfo::queryName()
std::string DrvInfo::querySystem() std::string DrvInfo::querySystem()
{ {
if (system == "" && attrs) { if (system == "" && attrs) {
auto i = attrs->find(state->sSystem); auto i = attrs->find(state->s.system);
system = i == attrs->end() ? "unknown" : state->forceStringNoCtx(*i->value, i->pos, "while evaluating the 'system' attribute of a derivation"); system = i == attrs->end() ? "unknown" : state->forceStringNoCtx(*i->value, i->pos, "while evaluating the 'system' attribute of a derivation");
} }
return system; return system;
@ -70,7 +70,7 @@ std::string DrvInfo::querySystem()
std::optional<StorePath> DrvInfo::queryDrvPath() std::optional<StorePath> DrvInfo::queryDrvPath()
{ {
if (!drvPath && attrs) { if (!drvPath && attrs) {
Bindings::iterator i = attrs->find(state->sDrvPath); Bindings::iterator i = attrs->find(state->s.drvPath);
NixStringContext context; NixStringContext context;
if (i == attrs->end()) if (i == attrs->end())
drvPath = {std::nullopt}; drvPath = {std::nullopt};
@ -92,7 +92,7 @@ StorePath DrvInfo::requireDrvPath()
StorePath DrvInfo::queryOutPath() StorePath DrvInfo::queryOutPath()
{ {
if (!outPath && attrs) { if (!outPath && attrs) {
Bindings::iterator i = attrs->find(state->sOutPath); Bindings::iterator i = attrs->find(state->s.outPath);
NixStringContext context; NixStringContext context;
if (i != attrs->end()) if (i != attrs->end())
outPath = state->coerceToStorePath(i->pos, *i->value, context, "while evaluating the output path of a derivation"); outPath = state->coerceToStorePath(i->pos, *i->value, context, "while evaluating the output path of a derivation");
@ -118,7 +118,7 @@ void DrvInfo::fillOutputs(bool withPaths)
return; return;
} }
Attr * outputs = this->attrs->get(this->state->sOutputs); Attr * outputs = this->attrs->get(this->state->s.outputs);
if (outputs == nullptr) { if (outputs == nullptr) {
fillDefault(); fillDefault();
return; return;
@ -157,7 +157,7 @@ void DrvInfo::fillOutputs(bool withPaths)
state->forceAttrs(*out->value, outputs->pos, errMsg); state->forceAttrs(*out->value, outputs->pos, errMsg);
// ...and evaluate its `outPath` attribute. // ...and evaluate its `outPath` attribute.
Attr * outPath = out->value->attrs->get(this->state->sOutPath); Attr * outPath = out->value->attrs->get(this->state->s.outPath);
if (outPath == nullptr) { if (outPath == nullptr) {
continue; continue;
// FIXME: throw error? // FIXME: throw error?
@ -201,7 +201,7 @@ DrvInfo::Outputs DrvInfo::queryOutputs(bool withPaths, bool onlyOutputsToInstall
// output by its attribute, e.g. `pkgs.lix.dev`, which (lol?) sets the magic // output by its attribute, e.g. `pkgs.lix.dev`, which (lol?) sets the magic
// attribute `outputSpecified = true`, and changes the `outputName` attr to the // attribute `outputSpecified = true`, and changes the `outputName` attr to the
// explicitly selected-into output. // explicitly selected-into output.
if (Attr * outSpecAttr = attrs->get(state->sOutputSpecified)) { if (Attr * outSpecAttr = attrs->get(state->s.outputSpecified)) {
bool outputSpecified = this->state->forceBool( bool outputSpecified = this->state->forceBool(
*outSpecAttr->value, *outSpecAttr->value,
outSpecAttr->pos, outSpecAttr->pos,
@ -236,7 +236,7 @@ DrvInfo::Outputs DrvInfo::queryOutputs(bool withPaths, bool onlyOutputsToInstall
std::string DrvInfo::queryOutputName() std::string DrvInfo::queryOutputName()
{ {
if (outputName == "" && attrs) { if (outputName == "" && attrs) {
Bindings::iterator i = attrs->find(state->sOutputName); Bindings::iterator i = attrs->find(state->s.outputName);
outputName = i != attrs->end() ? state->forceStringNoCtx(*i->value, noPos, "while evaluating the output name of a derivation") : ""; outputName = i != attrs->end() ? state->forceStringNoCtx(*i->value, noPos, "while evaluating the output name of a derivation") : "";
} }
return outputName; return outputName;
@ -247,7 +247,7 @@ Bindings * DrvInfo::getMeta()
{ {
if (meta) return meta; if (meta) return meta;
if (!attrs) return 0; if (!attrs) return 0;
Bindings::iterator a = attrs->find(state->sMeta); Bindings::iterator a = attrs->find(state->s.meta);
if (a == attrs->end()) return 0; if (a == attrs->end()) return 0;
state->forceAttrs(*a->value, a->pos, "while evaluating the 'meta' attribute of a derivation"); state->forceAttrs(*a->value, a->pos, "while evaluating the 'meta' attribute of a derivation");
meta = a->value->attrs; meta = a->value->attrs;
@ -274,7 +274,7 @@ bool DrvInfo::checkMeta(Value & v)
return true; return true;
} }
else if (v.type() == nAttrs) { else if (v.type() == nAttrs) {
Bindings::iterator i = v.attrs->find(state->sOutPath); Bindings::iterator i = v.attrs->find(state->s.outPath);
if (i != v.attrs->end()) return false; if (i != v.attrs->end()) return false;
for (auto & i : *v.attrs) for (auto & i : *v.attrs)
if (!checkMeta(*i.value)) return false; if (!checkMeta(*i.value)) return false;
@ -483,7 +483,7 @@ static void getDerivations(EvalState & state, Value & vIn,
should we recurse into it? => Only if it has a should we recurse into it? => Only if it has a
`recurseForDerivations = true' attribute. */ `recurseForDerivations = true' attribute. */
if (attr->value->type() == nAttrs) { if (attr->value->type() == nAttrs) {
Attr * recurseForDrvs = attr->value->attrs->get(state.sRecurseForDerivations); Attr * recurseForDrvs = attr->value->attrs->get(state.s.recurseForDerivations);
if (recurseForDrvs == nullptr) { if (recurseForDrvs == nullptr) {
continue; continue;
} }

View file

@ -35,7 +35,7 @@ Expr * EvalState::parse(
positions, positions,
basePath, basePath,
positions.addOrigin(origin, length), positions.addOrigin(origin, length),
exprSymbols, this->s.exprSymbols,
featureSettings, featureSettings,
}; };

View file

@ -191,11 +191,11 @@ static void import(EvalState & state, const PosIdx pos, Value & vPath, Value * v
if (auto storePath = isValidDerivationInStore()) { if (auto storePath = isValidDerivationInStore()) {
Derivation drv = state.store->readDerivation(*storePath); Derivation drv = state.store->readDerivation(*storePath);
auto attrs = state.buildBindings(3 + drv.outputs.size()); auto attrs = state.buildBindings(3 + drv.outputs.size());
attrs.alloc(state.sDrvPath).mkString(path2, { attrs.alloc(state.s.drvPath).mkString(path2, {
NixStringContextElem::DrvDeep { .drvPath = *storePath }, NixStringContextElem::DrvDeep { .drvPath = *storePath },
}); });
attrs.alloc(state.sName).mkString(drv.env["name"]); attrs.alloc(state.s.name).mkString(drv.env["name"]);
auto & outputsVal = attrs.alloc(state.sOutputs); auto & outputsVal = attrs.alloc(state.s.outputs);
state.mkList(outputsVal, drv.outputs.size()); state.mkList(outputsVal, drv.outputs.size());
for (const auto & [i, o] : enumerate(drv.outputs)) { for (const auto & [i, o] : enumerate(drv.outputs)) {
@ -507,7 +507,7 @@ static void prim_genericClosure(EvalState & state, const PosIdx pos, Value * * a
state.forceAttrs(*args[0], noPos, "while evaluating the first argument passed to builtins.genericClosure"); state.forceAttrs(*args[0], noPos, "while evaluating the first argument passed to builtins.genericClosure");
/* Get the start set. */ /* Get the start set. */
Bindings::iterator startSet = getAttr(state, state.sStartSet, args[0]->attrs, "in the attrset passed as argument to builtins.genericClosure"); Bindings::iterator startSet = getAttr(state, state.s.startSet, args[0]->attrs, "in the attrset passed as argument to builtins.genericClosure");
state.forceList(*startSet->value, noPos, "while evaluating the 'startSet' attribute passed as argument to builtins.genericClosure"); state.forceList(*startSet->value, noPos, "while evaluating the 'startSet' attribute passed as argument to builtins.genericClosure");
@ -521,7 +521,7 @@ static void prim_genericClosure(EvalState & state, const PosIdx pos, Value * * a
} }
/* Get the operator. */ /* Get the operator. */
Bindings::iterator op = getAttr(state, state.sOperator, args[0]->attrs, "in the attrset passed as argument to builtins.genericClosure"); Bindings::iterator op = getAttr(state, state.s.operator_, args[0]->attrs, "in the attrset passed as argument to builtins.genericClosure");
state.forceFunction(*op->value, noPos, "while evaluating the 'operator' attribute passed as argument to builtins.genericClosure"); state.forceFunction(*op->value, noPos, "while evaluating the 'operator' attribute passed as argument to builtins.genericClosure");
/* Construct the closure by applying the operator to elements of /* Construct the closure by applying the operator to elements of
@ -538,7 +538,7 @@ static void prim_genericClosure(EvalState & state, const PosIdx pos, Value * * a
state.forceAttrs(*e, noPos, "while evaluating one of the elements generated by (or initially passed to) builtins.genericClosure"); state.forceAttrs(*e, noPos, "while evaluating one of the elements generated by (or initially passed to) builtins.genericClosure");
Bindings::iterator key = getAttr(state, state.sKey, e->attrs, "in one of the attrsets generated by (or initially passed to) builtins.genericClosure"); Bindings::iterator key = getAttr(state, state.s.key, e->attrs, "in one of the attrsets generated by (or initially passed to) builtins.genericClosure");
state.forceValue(*key->value, noPos); state.forceValue(*key->value, noPos);
if (!doneKeys.insert(key->value).second) continue; if (!doneKeys.insert(key->value).second) continue;
@ -650,10 +650,10 @@ static void prim_tryEval(EvalState & state, const PosIdx pos, Value * * args, Va
try { try {
state.forceValue(*args[0], pos); state.forceValue(*args[0], pos);
attrs.insert(state.sValue, args[0]); attrs.insert(state.s.value, args[0]);
attrs.alloc("success").mkBool(true); attrs.alloc("success").mkBool(true);
} catch (AssertionError & e) { } catch (AssertionError & e) {
attrs.alloc(state.sValue).mkBool(false); attrs.alloc(state.s.value).mkBool(false);
attrs.alloc("success").mkBool(false); attrs.alloc("success").mkBool(false);
} }
@ -735,7 +735,7 @@ static void prim_derivationStrict(EvalState & state, const PosIdx pos, Value * *
Bindings * attrs = args[0]->attrs; Bindings * attrs = args[0]->attrs;
/* Figure out the name first (for stack backtraces). */ /* Figure out the name first (for stack backtraces). */
Bindings::iterator nameAttr = getAttr(state, state.sName, attrs, "in the attrset passed as argument to builtins.derivationStrict"); Bindings::iterator nameAttr = getAttr(state, state.s.name, attrs, "in the attrset passed as argument to builtins.derivationStrict");
std::string drvName; std::string drvName;
try { try {
@ -781,7 +781,7 @@ drvName, Bindings * attrs, Value & v)
using nlohmann::json; using nlohmann::json;
std::optional<json> jsonObject; std::optional<json> jsonObject;
auto pos = v.determinePos(noPos); auto pos = v.determinePos(noPos);
auto attr = attrs->find(state.sStructuredAttrs); auto attr = attrs->find(state.s.structuredAttrs);
if (attr != attrs->end() && if (attr != attrs->end() &&
state.forceBool(*attr->value, pos, state.forceBool(*attr->value, pos,
"while evaluating the `__structuredAttrs` " "while evaluating the `__structuredAttrs` "
@ -790,7 +790,7 @@ drvName, Bindings * attrs, Value & v)
/* Check whether null attributes should be ignored. */ /* Check whether null attributes should be ignored. */
bool ignoreNulls = false; bool ignoreNulls = false;
attr = attrs->find(state.sIgnoreNulls); attr = attrs->find(state.s.ignoreNulls);
if (attr != attrs->end()) if (attr != attrs->end())
ignoreNulls = state.forceBool(*attr->value, pos, "while evaluating the `__ignoreNulls` attribute " "passed to builtins.derivationStrict"); ignoreNulls = state.forceBool(*attr->value, pos, "while evaluating the `__ignoreNulls` attribute " "passed to builtins.derivationStrict");
@ -810,7 +810,7 @@ drvName, Bindings * attrs, Value & v)
outputs.insert("out"); outputs.insert("out");
for (auto & i : attrs->lexicographicOrder(state.symbols)) { for (auto & i : attrs->lexicographicOrder(state.symbols)) {
if (i->name == state.sIgnoreNulls) continue; if (i->name == state.s.ignoreNulls) continue;
const std::string & key = state.symbols[i->name]; const std::string & key = state.symbols[i->name];
vomit("processing attribute '%1%'", key); vomit("processing attribute '%1%'", key);
@ -860,19 +860,19 @@ drvName, Bindings * attrs, Value & v)
if (i->value->type() == nNull) continue; if (i->value->type() == nNull) continue;
} }
if (i->name == state.sContentAddressed && state.forceBool(*i->value, pos, context_below)) { if (i->name == state.s.contentAddressed && state.forceBool(*i->value, pos, context_below)) {
contentAddressed = true; contentAddressed = true;
experimentalFeatureSettings.require(Xp::CaDerivations); experimentalFeatureSettings.require(Xp::CaDerivations);
} }
else if (i->name == state.sImpure && state.forceBool(*i->value, pos, context_below)) { else if (i->name == state.s.impure && state.forceBool(*i->value, pos, context_below)) {
isImpure = true; isImpure = true;
experimentalFeatureSettings.require(Xp::ImpureDerivations); experimentalFeatureSettings.require(Xp::ImpureDerivations);
} }
/* The `args' attribute is special: it supplies the /* The `args' attribute is special: it supplies the
command-line arguments to the builder. */ command-line arguments to the builder. */
else if (i->name == state.sArgs) { else if (i->name == state.s.args) {
state.forceList(*i->value, pos, context_below); state.forceList(*i->value, pos, context_below);
for (auto elem : i->value->listItems()) { for (auto elem : i->value->listItems()) {
auto s = state.coerceToString(pos, *elem, context, auto s = state.coerceToString(pos, *elem, context,
@ -888,21 +888,21 @@ drvName, Bindings * attrs, Value & v)
if (jsonObject) { if (jsonObject) {
if (i->name == state.sStructuredAttrs) continue; if (i->name == state.s.structuredAttrs) continue;
(*jsonObject)[key] = printValueAsJSON(state, true, *i->value, pos, context); (*jsonObject)[key] = printValueAsJSON(state, true, *i->value, pos, context);
if (i->name == state.sBuilder) if (i->name == state.s.builder)
drv.builder = state.forceString(*i->value, context, pos, context_below); drv.builder = state.forceString(*i->value, context, pos, context_below);
else if (i->name == state.sSystem) else if (i->name == state.s.system)
drv.platform = state.forceStringNoCtx(*i->value, pos, context_below); drv.platform = state.forceStringNoCtx(*i->value, pos, context_below);
else if (i->name == state.sOutputHash) else if (i->name == state.s.outputHash)
outputHash = state.forceStringNoCtx(*i->value, pos, context_below); outputHash = state.forceStringNoCtx(*i->value, pos, context_below);
else if (i->name == state.sOutputHashAlgo) else if (i->name == state.s.outputHashAlgo)
outputHashAlgo = state.forceStringNoCtx(*i->value, pos, context_below); outputHashAlgo = state.forceStringNoCtx(*i->value, pos, context_below);
else if (i->name == state.sOutputHashMode) else if (i->name == state.s.outputHashMode)
handleHashMode(state.forceStringNoCtx(*i->value, pos, context_below)); handleHashMode(state.forceStringNoCtx(*i->value, pos, context_below));
else if (i->name == state.sOutputs) { else if (i->name == state.s.outputs) {
/* Require outputs to be a list of strings. */ /* Require outputs to be a list of strings. */
state.forceList(*i->value, pos, context_below); state.forceList(*i->value, pos, context_below);
Strings ss; Strings ss;
@ -911,29 +911,29 @@ drvName, Bindings * attrs, Value & v)
handleOutputs(ss); handleOutputs(ss);
} }
if (i->name == state.sAllowedReferences) if (i->name == state.s.allowedReferences)
warn("In a derivation named '%s', 'structuredAttrs' disables the effect of the derivation attribute 'allowedReferences'; use 'outputChecks.<output>.allowedReferences' instead", drvName); warn("In a derivation named '%s', 'structuredAttrs' disables the effect of the derivation attribute 'allowedReferences'; use 'outputChecks.<output>.allowedReferences' instead", drvName);
if (i->name == state.sAllowedRequisites) if (i->name == state.s.allowedRequisites)
warn("In a derivation named '%s', 'structuredAttrs' disables the effect of the derivation attribute 'allowedRequisites'; use 'outputChecks.<output>.allowedRequisites' instead", drvName); warn("In a derivation named '%s', 'structuredAttrs' disables the effect of the derivation attribute 'allowedRequisites'; use 'outputChecks.<output>.allowedRequisites' instead", drvName);
if (i->name == state.sDisallowedReferences) if (i->name == state.s.disallowedReferences)
warn("In a derivation named '%s', 'structuredAttrs' disables the effect of the derivation attribute 'disallowedReferences'; use 'outputChecks.<output>.disallowedReferences' instead", drvName); warn("In a derivation named '%s', 'structuredAttrs' disables the effect of the derivation attribute 'disallowedReferences'; use 'outputChecks.<output>.disallowedReferences' instead", drvName);
if (i->name == state.sDisallowedRequisites) if (i->name == state.s.disallowedRequisites)
warn("In a derivation named '%s', 'structuredAttrs' disables the effect of the derivation attribute 'disallowedRequisites'; use 'outputChecks.<output>.disallowedRequisites' instead", drvName); warn("In a derivation named '%s', 'structuredAttrs' disables the effect of the derivation attribute 'disallowedRequisites'; use 'outputChecks.<output>.disallowedRequisites' instead", drvName);
if (i->name == state.sMaxSize) if (i->name == state.s.maxSize)
warn("In a derivation named '%s', 'structuredAttrs' disables the effect of the derivation attribute 'maxSize'; use 'outputChecks.<output>.maxSize' instead", drvName); warn("In a derivation named '%s', 'structuredAttrs' disables the effect of the derivation attribute 'maxSize'; use 'outputChecks.<output>.maxSize' instead", drvName);
if (i->name == state.sMaxClosureSize) if (i->name == state.s.maxClosureSize)
warn("In a derivation named '%s', 'structuredAttrs' disables the effect of the derivation attribute 'maxClosureSize'; use 'outputChecks.<output>.maxClosureSize' instead", drvName); warn("In a derivation named '%s', 'structuredAttrs' disables the effect of the derivation attribute 'maxClosureSize'; use 'outputChecks.<output>.maxClosureSize' instead", drvName);
} else { } else {
auto s = state.coerceToString(pos, *i->value, context, context_below, true).toOwned(); auto s = state.coerceToString(pos, *i->value, context, context_below, true).toOwned();
drv.env.emplace(key, s); drv.env.emplace(key, s);
if (i->name == state.sBuilder) drv.builder = std::move(s); if (i->name == state.s.builder) drv.builder = std::move(s);
else if (i->name == state.sSystem) drv.platform = std::move(s); else if (i->name == state.s.system) drv.platform = std::move(s);
else if (i->name == state.sOutputHash) outputHash = std::move(s); else if (i->name == state.s.outputHash) outputHash = std::move(s);
else if (i->name == state.sOutputHashAlgo) outputHashAlgo = std::move(s); else if (i->name == state.s.outputHashAlgo) outputHashAlgo = std::move(s);
else if (i->name == state.sOutputHashMode) handleHashMode(s); else if (i->name == state.s.outputHashMode) handleHashMode(s);
else if (i->name == state.sOutputs) else if (i->name == state.s.outputs)
handleOutputs(tokenizeString<Strings>(s)); handleOutputs(tokenizeString<Strings>(s));
} }
@ -1109,7 +1109,7 @@ drvName, Bindings * attrs, Value & v)
} }
auto result = state.buildBindings(1 + drv.outputs.size()); auto result = state.buildBindings(1 + drv.outputs.size());
result.alloc(state.sDrvPath).mkString(drvPathS, { result.alloc(state.s.drvPath).mkString(drvPathS, {
NixStringContextElem::DrvDeep { .drvPath = drvPath }, NixStringContextElem::DrvDeep { .drvPath = drvPath },
}); });
for (auto & i : drv.outputs) for (auto & i : drv.outputs)
@ -1287,11 +1287,11 @@ static void prim_findFile(EvalState & state, const PosIdx pos, Value * * args, V
state.forceAttrs(*v2, pos, "while evaluating an element of the list passed to builtins.findFile"); state.forceAttrs(*v2, pos, "while evaluating an element of the list passed to builtins.findFile");
std::string prefix; std::string prefix;
Bindings::iterator i = v2->attrs->find(state.sPrefix); Bindings::iterator i = v2->attrs->find(state.s.prefix);
if (i != v2->attrs->end()) if (i != v2->attrs->end())
prefix = state.forceStringNoCtx(*i->value, pos, "while evaluating the `prefix` attribute of an element of the list passed to builtins.findFile"); prefix = state.forceStringNoCtx(*i->value, pos, "while evaluating the `prefix` attribute of an element of the list passed to builtins.findFile");
i = getAttr(state, state.sPath, v2->attrs, "in an element of the __nixPath"); i = getAttr(state, state.s.path, v2->attrs, "in an element of the __nixPath");
NixStringContext context; NixStringContext context;
auto path = state.coerceToString(pos, *i->value, context, auto path = state.coerceToString(pos, *i->value, context,
@ -1580,7 +1580,7 @@ static void prim_path(EvalState & state, const PosIdx pos, Value * * args, Value
auto n = state.symbols[attr.name]; auto n = state.symbols[attr.name];
if (n == "path") if (n == "path")
path.emplace(state.coerceToPath(attr.pos, *attr.value, context, "while evaluating the 'path' attribute passed to 'builtins.path'")); path.emplace(state.coerceToPath(attr.pos, *attr.value, context, "while evaluating the 'path' attribute passed to 'builtins.path'"));
else if (attr.name == state.sName) else if (attr.name == state.s.name)
name = state.forceStringNoCtx(*attr.value, attr.pos, "while evaluating the `name` attribute passed to builtins.path"); name = state.forceStringNoCtx(*attr.value, attr.pos, "while evaluating the `name` attribute passed to builtins.path");
else if (n == "filter") else if (n == "filter")
state.forceFunction(*(filterFun = attr.value), attr.pos, "while evaluating the `filter` parameter passed to builtins.path"); state.forceFunction(*(filterFun = attr.value), attr.pos, "while evaluating the `filter` parameter passed to builtins.path");
@ -1794,13 +1794,13 @@ static void prim_listToAttrs(EvalState & state, const PosIdx pos, Value * * args
for (auto v2 : args[0]->listItems()) { for (auto v2 : args[0]->listItems()) {
state.forceAttrs(*v2, pos, "while evaluating an element of the list passed to builtins.listToAttrs"); state.forceAttrs(*v2, pos, "while evaluating an element of the list passed to builtins.listToAttrs");
Bindings::iterator j = getAttr(state, state.sName, v2->attrs, "in a {name=...; value=...;} pair"); Bindings::iterator j = getAttr(state, state.s.name, v2->attrs, "in a {name=...; value=...;} pair");
auto name = state.forceStringNoCtx(*j->value, j->pos, "while evaluating the `name` attribute of an element of the list passed to builtins.listToAttrs"); auto name = state.forceStringNoCtx(*j->value, j->pos, "while evaluating the `name` attribute of an element of the list passed to builtins.listToAttrs");
auto sym = state.symbols.create(name); auto sym = state.symbols.create(name);
if (seen.insert(sym).second) { if (seen.insert(sym).second) {
Bindings::iterator j2 = getAttr(state, state.sValue, v2->attrs, "in a {name=...; value=...;} pair"); Bindings::iterator j2 = getAttr(state, state.s.value, v2->attrs, "in a {name=...; value=...;} pair");
attrs.insert(sym, j2->value, j2->pos); attrs.insert(sym, j2->value, j2->pos);
} }
} }
@ -2256,13 +2256,13 @@ static void prim_partition(EvalState & state, const PosIdx pos, Value * * args,
auto attrs = state.buildBindings(2); auto attrs = state.buildBindings(2);
auto & vRight = attrs.alloc(state.sRight); auto & vRight = attrs.alloc(state.s.right);
auto rsize = right.size(); auto rsize = right.size();
state.mkList(vRight, rsize); state.mkList(vRight, rsize);
if (rsize) if (rsize)
memcpy(vRight.listElems(), right.data(), sizeof(Value *) * rsize); memcpy(vRight.listElems(), right.data(), sizeof(Value *) * rsize);
auto & vWrong = attrs.alloc(state.sWrong); auto & vWrong = attrs.alloc(state.s.wrong);
auto wsize = wrong.size(); auto wsize = wrong.size();
state.mkList(vWrong, wsize); state.mkList(vWrong, wsize);
if (wsize) if (wsize)
@ -2740,7 +2740,7 @@ static void prim_parseDrvName(EvalState & state, const PosIdx pos, Value * * arg
auto name = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.parseDrvName"); auto name = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.parseDrvName");
DrvName parsed(name); DrvName parsed(name);
auto attrs = state.buildBindings(2); auto attrs = state.buildBindings(2);
attrs.alloc(state.sName).mkString(parsed.name); attrs.alloc(state.s.name).mkString(parsed.name);
attrs.alloc("version").mkString(parsed.version); attrs.alloc("version").mkString(parsed.version);
v.mkAttrs(attrs); v.mkAttrs(attrs);
} }

View file

@ -140,16 +140,15 @@ void prim_getContext(EvalState & state, const PosIdx pos, Value * * args, Value
auto attrs = state.buildBindings(contextInfos.size()); auto attrs = state.buildBindings(contextInfos.size());
auto sPath = state.symbols.create("path");
auto sAllOutputs = state.symbols.create("allOutputs"); auto sAllOutputs = state.symbols.create("allOutputs");
for (const auto & info : contextInfos) { for (const auto & info : contextInfos) {
auto infoAttrs = state.buildBindings(3); auto infoAttrs = state.buildBindings(3);
if (info.second.path) if (info.second.path)
infoAttrs.alloc(sPath).mkBool(true); infoAttrs.alloc(state.s.path).mkBool(true);
if (info.second.allOutputs) if (info.second.allOutputs)
infoAttrs.alloc(sAllOutputs).mkBool(true); infoAttrs.alloc(sAllOutputs).mkBool(true);
if (!info.second.outputs.empty()) { if (!info.second.outputs.empty()) {
auto & outputsVal = infoAttrs.alloc(state.sOutputs); auto & outputsVal = infoAttrs.alloc(state.s.outputs);
state.mkList(outputsVal, info.second.outputs.size()); state.mkList(outputsVal, info.second.outputs.size());
for (const auto & [i, output] : enumerate(info.second.outputs)) for (const auto & [i, output] : enumerate(info.second.outputs))
(outputsVal.listElems()[i] = state.allocValue())->mkString(output); (outputsVal.listElems()[i] = state.allocValue())->mkString(output);
@ -173,7 +172,6 @@ static void prim_appendContext(EvalState & state, const PosIdx pos, Value * * ar
state.forceAttrs(*args[1], pos, "while evaluating the second argument passed to builtins.appendContext"); state.forceAttrs(*args[1], pos, "while evaluating the second argument passed to builtins.appendContext");
auto sPath = state.symbols.create("path");
auto sAllOutputs = state.symbols.create("allOutputs"); auto sAllOutputs = state.symbols.create("allOutputs");
for (auto & i : *args[1]->attrs) { for (auto & i : *args[1]->attrs) {
const auto & name = state.symbols[i.name]; const auto & name = state.symbols[i.name];
@ -186,7 +184,7 @@ static void prim_appendContext(EvalState & state, const PosIdx pos, Value * * ar
if (!settings.readOnlyMode) if (!settings.readOnlyMode)
state.store->ensurePath(namePath); state.store->ensurePath(namePath);
state.forceAttrs(*i.value, i.pos, "while evaluating the value of a string context"); state.forceAttrs(*i.value, i.pos, "while evaluating the value of a string context");
auto iter = i.value->attrs->find(sPath); auto iter = i.value->attrs->find(state.s.path);
if (iter != i.value->attrs->end()) { if (iter != i.value->attrs->end()) {
if (state.forceBool(*iter->value, iter->pos, "while evaluating the `path` attribute of a string context")) if (state.forceBool(*iter->value, iter->pos, "while evaluating the `path` attribute of a string context"))
context.emplace(NixStringContextElem::Opaque { context.emplace(NixStringContextElem::Opaque {
@ -209,7 +207,7 @@ static void prim_appendContext(EvalState & state, const PosIdx pos, Value * * ar
} }
} }
iter = i.value->attrs->find(state.sOutputs); iter = i.value->attrs->find(state.s.outputs);
if (iter != i.value->attrs->end()) { if (iter != i.value->attrs->end()) {
state.forceList(*iter->value, iter->pos, "while evaluating the `outputs` attribute of a string context"); state.forceList(*iter->value, iter->pos, "while evaluating the `outputs` attribute of a string context");
if (iter->value->listSize() && !isDerivation(name)) { if (iter->value->listSize() && !isDerivation(name)) {

View file

@ -68,7 +68,7 @@ static void prim_fetchMercurial(EvalState & state, const PosIdx pos, Value * * a
auto [tree, input2] = input.fetch(state.store); auto [tree, input2] = input.fetch(state.store);
auto attrs2 = state.buildBindings(8); auto attrs2 = state.buildBindings(8);
state.mkStorePathString(tree.storePath, attrs2.alloc(state.sOutPath)); state.mkStorePathString(tree.storePath, attrs2.alloc(state.s.outPath));
if (input2.getRef()) if (input2.getRef())
attrs2.alloc("branch").mkString(*input2.getRef()); attrs2.alloc("branch").mkString(*input2.getRef());
// Backward compatibility: set 'rev' to // Backward compatibility: set 'rev' to

View file

@ -27,7 +27,7 @@ void emitTreeAttrs(
auto attrs = state.buildBindings(10); auto attrs = state.buildBindings(10);
state.mkStorePathString(tree.storePath, attrs.alloc(state.sOutPath)); state.mkStorePathString(tree.storePath, attrs.alloc(state.s.outPath));
// FIXME: support arbitrary input attributes. // FIXME: support arbitrary input attributes.
@ -122,7 +122,7 @@ static void fetchTree(
fetchers::Attrs attrs; fetchers::Attrs attrs;
if (auto aType = args[0]->attrs->get(state.sType)) { if (auto aType = args[0]->attrs->get(state.s.type)) {
if (type) if (type)
state.error<EvalError>( state.error<EvalError>(
"unexpected attribute 'type'" "unexpected attribute 'type'"
@ -136,7 +136,7 @@ static void fetchTree(
attrs.emplace("type", type.value()); attrs.emplace("type", type.value());
for (auto & attr : *args[0]->attrs) { for (auto & attr : *args[0]->attrs) {
if (attr.name == state.sType) continue; if (attr.name == state.s.type) continue;
state.forceValue(*attr.value, attr.pos); state.forceValue(*attr.value, attr.pos);
if (attr.value->type() == nPath || attr.value->type() == nString) { if (attr.value->type() == nPath || attr.value->type() == nString) {
auto s = state.coerceToString(attr.pos, *attr.value, context, "", false, false).toOwned(); auto s = state.coerceToString(attr.pos, *attr.value, context, "", false, false).toOwned();

View file

@ -231,7 +231,7 @@ private:
void printDerivation(Value & v) void printDerivation(Value & v)
{ {
Bindings::iterator i = v.attrs->find(state.sDrvPath); Bindings::iterator i = v.attrs->find(state.s.drvPath);
NixStringContext context; NixStringContext context;
std::string storePath; std::string storePath;
if (i != v.attrs->end()) if (i != v.attrs->end())

View file

@ -52,7 +52,7 @@ json printValueAsJSON(EvalState & state, bool strict,
out = *maybeString; out = *maybeString;
break; break;
} }
auto i = v.attrs->find(state.sOutPath); auto i = v.attrs->find(state.s.outPath);
if (i == v.attrs->end()) { if (i == v.attrs->end()) {
out = json::object(); out = json::object();
StringSet names; StringSet names;

View file

@ -89,14 +89,14 @@ static void printValueAsXML(EvalState & state, bool strict, bool location,
Bindings::iterator a = v.attrs->find(state.symbols.create("derivation")); Bindings::iterator a = v.attrs->find(state.symbols.create("derivation"));
Path drvPath; Path drvPath;
a = v.attrs->find(state.sDrvPath); a = v.attrs->find(state.s.drvPath);
if (a != v.attrs->end()) { if (a != v.attrs->end()) {
if (strict) state.forceValue(*a->value, a->pos); if (strict) state.forceValue(*a->value, a->pos);
if (a->value->type() == nString) if (a->value->type() == nString)
xmlAttrs["drvPath"] = drvPath = a->value->string.s; xmlAttrs["drvPath"] = drvPath = a->value->string.s;
} }
a = v.attrs->find(state.sOutPath); a = v.attrs->find(state.s.outPath);
if (a != v.attrs->end()) { if (a != v.attrs->end()) {
if (strict) state.forceValue(*a->value, a->pos); if (strict) state.forceValue(*a->value, a->pos);
if (a->value->type() == nString) if (a->value->type() == nString)

View file

@ -99,11 +99,11 @@ UnresolvedApp InstallableValue::toApp(EvalState & state)
else if (type == "derivation") { else if (type == "derivation") {
auto drvPath = cursor->forceDerivation(); auto drvPath = cursor->forceDerivation();
auto outPath = cursor->getAttr(state.sOutPath)->getString(); auto outPath = cursor->getAttr(state.s.outPath)->getString();
auto outputName = cursor->getAttr(state.sOutputName)->getString(); auto outputName = cursor->getAttr(state.s.outputName)->getString();
auto name = cursor->getAttr(state.sName)->getString(); auto name = cursor->getAttr(state.s.name)->getString();
auto aPname = cursor->maybeGetAttr("pname"); auto aPname = cursor->maybeGetAttr("pname");
auto aMeta = cursor->maybeGetAttr(state.sMeta); auto aMeta = cursor->maybeGetAttr(state.s.meta);
auto aMainProgram = aMeta ? aMeta->maybeGetAttr("mainProgram") : nullptr; auto aMainProgram = aMeta ? aMeta->maybeGetAttr("mainProgram") : nullptr;
auto mainProgram = auto mainProgram =
aMainProgram aMainProgram

View file

@ -96,14 +96,14 @@ struct CmdBundle : InstallableCommand
if (!evalState->isDerivation(*vRes)) if (!evalState->isDerivation(*vRes))
throw Error("the bundler '%s' does not produce a derivation", bundler.what()); throw Error("the bundler '%s' does not produce a derivation", bundler.what());
auto attr1 = vRes->attrs->get(evalState->sDrvPath); auto attr1 = vRes->attrs->get(evalState->s.drvPath);
if (!attr1) if (!attr1)
throw Error("the bundler '%s' does not produce a derivation", bundler.what()); throw Error("the bundler '%s' does not produce a derivation", bundler.what());
NixStringContext context2; NixStringContext context2;
auto drvPath = evalState->coerceToStorePath(attr1->pos, *attr1->value, context2, ""); auto drvPath = evalState->coerceToStorePath(attr1->pos, *attr1->value, context2, "");
auto attr2 = vRes->attrs->get(evalState->sOutPath); auto attr2 = vRes->attrs->get(evalState->s.outPath);
if (!attr2) if (!attr2)
throw Error("the bundler '%s' does not produce a derivation", bundler.what()); throw Error("the bundler '%s' does not produce a derivation", bundler.what());
@ -119,7 +119,7 @@ struct CmdBundle : InstallableCommand
auto outPathS = store->printStorePath(outPath); auto outPathS = store->printStorePath(outPath);
if (!outLink) { if (!outLink) {
auto * attr = vRes->attrs->get(evalState->sName); auto * attr = vRes->attrs->get(evalState->s.name);
if (!attr) if (!attr)
throw Error("attribute 'name' missing"); throw Error("attribute 'name' missing");
outLink = evalState->forceStringNoCtx(*attr->value, attr->pos, ""); outLink = evalState->forceStringNoCtx(*attr->value, attr->pos, "");

View file

@ -1242,10 +1242,10 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
auto showDerivation = [&]() auto showDerivation = [&]()
{ {
auto name = visitor.getAttr(state->sName)->getString(); auto name = visitor.getAttr(state->s.name)->getString();
std::optional<std::string> description; std::optional<std::string> description;
if (auto aMeta = visitor.maybeGetAttr(state->sMeta)) { if (auto aMeta = visitor.maybeGetAttr(state->s.meta)) {
if (auto aDescription = aMeta->maybeGetAttr(state->sDescription)) if (auto aDescription = aMeta->maybeGetAttr(state->s.description))
description = aDescription->getString(); description = aDescription->getString();
} }

View file

@ -111,10 +111,10 @@ struct CmdSearch : InstallableCommand, MixJSON
}; };
if (cursor.isDerivation()) { if (cursor.isDerivation()) {
DrvName name(cursor.getAttr(state->sName)->getString()); DrvName name(cursor.getAttr(state->s.name)->getString());
auto aMeta = cursor.maybeGetAttr(state->sMeta); auto aMeta = cursor.maybeGetAttr(state->s.meta);
auto aDescription = aMeta ? aMeta->maybeGetAttr(state->sDescription) : nullptr; auto aDescription = aMeta ? aMeta->maybeGetAttr(state->s.description) : nullptr;
auto description = aDescription ? aDescription->getString() : ""; auto description = aDescription ? aDescription->getString() : "";
std::replace(description.begin(), description.end(), '\n', ' '); std::replace(description.begin(), description.end(), '\n', ' ');
auto attrPath2 = concatStringsSep(".", attrPathS); auto attrPath2 = concatStringsSep(".", attrPathS);
@ -183,7 +183,7 @@ struct CmdSearch : InstallableCommand, MixJSON
recurse(); recurse();
else if (attrPathS[0] == "legacyPackages" && attrPath.size() > 2) { else if (attrPathS[0] == "legacyPackages" && attrPath.size() > 2) {
auto attr = cursor.maybeGetAttr(state->sRecurseForDerivations); auto attr = cursor.maybeGetAttr(state->s.recurseForDerivations);
if (attr && attr->getBool()) if (attr && attr->getBool())
recurse(); recurse();
} }

View file

@ -437,7 +437,7 @@ TEST_F(ValuePrintingTests, ansiColorsDerivation)
vDerivation.mkString("derivation"); vDerivation.mkString("derivation");
BindingsBuilder builder(state, state.allocBindings(10)); BindingsBuilder builder(state, state.allocBindings(10));
builder.insert(state.sType, &vDerivation); builder.insert(state.s.type, &vDerivation);
Value vAttrs; Value vAttrs;
vAttrs.mkAttrs(builder.finish()); vAttrs.mkAttrs(builder.finish());
@ -488,8 +488,8 @@ TEST_F(ValuePrintingTests, ansiColorsDerivationError)
vDerivation.mkString("derivation"); vDerivation.mkString("derivation");
BindingsBuilder builder(state, state.allocBindings(10)); BindingsBuilder builder(state, state.allocBindings(10));
builder.insert(state.sType, &vDerivation); builder.insert(state.s.type, &vDerivation);
builder.insert(state.sDrvPath, &vError); builder.insert(state.s.drvPath, &vError);
Value vAttrs; Value vAttrs;
vAttrs.mkAttrs(builder.finish()); vAttrs.mkAttrs(builder.finish());