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());
attrs.alloc(state.sType).mkString("derivation");
attrs.alloc(state.sName).mkString(i.queryName());
attrs.alloc(state.s.type).mkString("derivation");
attrs.alloc(state.s.name).mkString(i.queryName());
auto system = i.querySystem();
if (!system.empty())
attrs.alloc(state.sSystem).mkString(system);
attrs.alloc(state.sOutPath).mkString(state.store->printStorePath(i.queryOutPath()));
attrs.alloc(state.s.system).mkString(system);
attrs.alloc(state.s.outPath).mkString(state.store->printStorePath(i.queryOutPath()));
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.
auto & vOutputs = attrs.alloc(state.sOutputs);
auto & vOutputs = attrs.alloc(state.s.outputs);
state.mkList(vOutputs, outputs.size());
for (const auto & [m, j] : enumerate(outputs)) {
(vOutputs.listElems()[m] = state.allocValue())->mkString(j.first);
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);
/* 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);
}
attrs.alloc(state.sMeta).mkAttrs(meta);
attrs.alloc(state.s.meta).mkAttrs(meta);
(manifest.listElems()[n++] = state.allocValue())->mkAttrs(attrs);
@ -117,9 +117,9 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
debug("evaluating user environment builder");
state.forceValue(topLevel, topLevel.determinePos(noPos));
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, "");
Attr & aOutPath(*topLevel.attrs->find(state.sOutPath));
Attr & aOutPath(*topLevel.attrs->find(state.s.outPath));
auto topLevelOut = state.coerceToStorePath(aOutPath.pos, *aOutPath.value, context, "");
/* Realise the resulting store expression. */

View file

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

View file

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

View file

@ -196,53 +196,49 @@ void initLibExpr()
libexprInitialised = true;
}
EvalState::EvalState(
const SearchPath & _searchPath,
ref<Store> store,
std::shared_ptr<Store> buildStore)
: sWith(symbols.create("<with>"))
, sOutPath(symbols.create("outPath"))
, sDrvPath(symbols.create("drvPath"))
, sType(symbols.create("type"))
, sMeta(symbols.create("meta"))
, sName(symbols.create("name"))
, sValue(symbols.create("value"))
, sSystem(symbols.create("system"))
, sOverrides(symbols.create("__overrides"))
, sOutputs(symbols.create("outputs"))
, sOutputName(symbols.create("outputName"))
, sIgnoreNulls(symbols.create("__ignoreNulls"))
, sFile(symbols.create("file"))
, sLine(symbols.create("line"))
, sColumn(symbols.create("column"))
, sFunctor(symbols.create("__functor"))
, sToString(symbols.create("__toString"))
, sRight(symbols.create("right"))
, sWrong(symbols.create("wrong"))
, sStructuredAttrs(symbols.create("__structuredAttrs"))
, sAllowedReferences(symbols.create("allowedReferences"))
, sAllowedRequisites(symbols.create("allowedRequisites"))
, sDisallowedReferences(symbols.create("disallowedReferences"))
, sDisallowedRequisites(symbols.create("disallowedRequisites"))
, sMaxSize(symbols.create("maxSize"))
, sMaxClosureSize(symbols.create("maxClosureSize"))
, sBuilder(symbols.create("builder"))
, sArgs(symbols.create("args"))
, sContentAddressed(symbols.create("__contentAddressed"))
, sImpure(symbols.create("__impure"))
, sOutputHash(symbols.create("outputHash"))
, sOutputHashAlgo(symbols.create("outputHashAlgo"))
, sOutputHashMode(symbols.create("outputHashMode"))
, sRecurseForDerivations(symbols.create("recurseForDerivations"))
, sDescription(symbols.create("description"))
, sSelf(symbols.create("self"))
, sEpsilon(symbols.create(""))
, sStartSet(symbols.create("startSet"))
, sOperator(symbols.create("operator"))
, sKey(symbols.create("key"))
, sPath(symbols.create("path"))
, sPrefix(symbols.create("prefix"))
, sOutputSpecified(symbols.create("outputSpecified"))
StaticSymbols::StaticSymbols(SymbolTable & symbols)
: outPath(symbols.create("outPath"))
, drvPath(symbols.create("drvPath"))
, type(symbols.create("type"))
, meta(symbols.create("meta"))
, name(symbols.create("name"))
, value(symbols.create("value"))
, system(symbols.create("system"))
, overrides(symbols.create("__overrides"))
, outputs(symbols.create("outputs"))
, outputName(symbols.create("outputName"))
, ignoreNulls(symbols.create("__ignoreNulls"))
, file(symbols.create("file"))
, line(symbols.create("line"))
, column(symbols.create("column"))
, functor(symbols.create("__functor"))
, toString(symbols.create("__toString"))
, right(symbols.create("right"))
, wrong(symbols.create("wrong"))
, structuredAttrs(symbols.create("__structuredAttrs"))
, allowedReferences(symbols.create("allowedReferences"))
, allowedRequisites(symbols.create("allowedRequisites"))
, disallowedReferences(symbols.create("disallowedReferences"))
, disallowedRequisites(symbols.create("disallowedRequisites"))
, maxSize(symbols.create("maxSize"))
, maxClosureSize(symbols.create("maxClosureSize"))
, builder(symbols.create("builder"))
, args(symbols.create("args"))
, contentAddressed(symbols.create("__contentAddressed"))
, impure(symbols.create("__impure"))
, outputHash(symbols.create("outputHash"))
, outputHashAlgo(symbols.create("outputHashAlgo"))
, outputHashMode(symbols.create("outputHashMode"))
, recurseForDerivations(symbols.create("recurseForDerivations"))
, description(symbols.create("description"))
, self(symbols.create("self"))
, epsilon(symbols.create(""))
, startSet(symbols.create("startSet"))
, operator_(symbols.create("operator"))
, key(symbols.create("key"))
, path(symbols.create("path"))
, prefix(symbols.create("prefix"))
, outputSpecified(symbols.create("outputSpecified"))
, exprSymbols{
.sub = symbols.create("__sub"),
.lessThan = symbols.create("__lessThan"),
@ -254,6 +250,14 @@ EvalState::EvalState(
.body = symbols.create("body"),
.overrides = symbols.create("__overrides"),
}
{
}
EvalState::EvalState(
const SearchPath & _searchPath,
ref<Store> store,
std::shared_ptr<Store> buildStore)
: s(symbols)
, repair(NoRepair)
, derivationInternal(rootPath(CanonPath("/builtin/derivation.nix")))
, store(store)
@ -774,8 +778,8 @@ void EvalState::mkPos(Value & v, PosIdx p)
auto origin = positions.originOf(p);
if (auto path = std::get_if<SourcePath>(&origin)) {
auto attrs = buildBindings(3);
attrs.alloc(sFile).mkString(path->path.abs());
makePositionThunks(*this, p, attrs.alloc(sLine), attrs.alloc(sColumn));
attrs.alloc(s.file).mkString(path->path.abs());
makePositionThunks(*this, p, attrs.alloc(s.line), attrs.alloc(s.column));
v.mkAttrs(attrs);
} else
v.mkNull();
@ -1072,7 +1076,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
dynamicEnv = &env2;
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();
/* 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
function, but for functors we may keep a reference, so
heap-allocate a copy and use that instead. */
@ -1755,7 +1759,7 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res)
forceValue(fun, pos);
if (fun.type() == nAttrs) {
auto found = fun.attrs->find(sFunctor);
auto found = fun.attrs->find(s.functor);
if (found != fun.attrs->end()) {
Value * v = allocValue();
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)
{
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)
{
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;
forceValue(*i->value, i->pos);
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,
NixStringContext & context, bool coerceMore, bool copyToStore)
{
auto i = v.attrs->find(sToString);
auto i = v.attrs->find(s.toString);
if (i != v.attrs->end()) {
Value v1;
callFunction(*i->value, v, v1, pos);
@ -2290,7 +2294,7 @@ BackedStringView EvalState::coerceToString(
auto maybeString = tryAttrsToString(pos, v, context, coerceMore, copyToStore);
if (maybeString)
return std::move(*maybeString);
auto i = v.attrs->find(sOutPath);
auto i = v.attrs->find(s.outPath);
if (i == v.attrs->end()) {
error<TypeError>(
"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"),
then compare their outPaths. */
if (isDerivation(v1) && isDerivation(v2)) {
Bindings::iterator i = v1.attrs->find(sOutPath);
Bindings::iterator j = v2.attrs->find(sOutPath);
Bindings::iterator i = v1.attrs->find(s.outPath);
Bindings::iterator j = v2.attrs->find(s.outPath);
if (i != v1.attrs->end() && j != v2.attrs->end())
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
{
public:
SymbolTable symbols;
PosTable positions;
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;
const StaticSymbols s;
/**
* If set, force copying files to the Nix store even if they

View file

@ -245,7 +245,7 @@ static Flake getFlake(
Value vInfo;
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);
flake.description = description->value->string.s;
}
@ -255,14 +255,12 @@ static Flake getFlake(
if (auto inputs = vInfo.attrs->get(sInputs))
flake.inputs = parseFlakeInputs(state, inputs->value, inputs->pos, flakeDir, lockRootPath, 0);
auto sOutputs = state.symbols.create("outputs");
if (auto outputs = vInfo.attrs->get(sOutputs)) {
if (auto outputs = vInfo.attrs->get(state.s.outputs)) {
expectType(state, nFunction, *outputs->value, outputs->pos);
if (outputs->value->isLambda() && outputs->value->lambda.fun->hasFormals()) {
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 {
.ref = parseFlakeRef(state.symbols[formal.name])
});
@ -314,9 +312,9 @@ static Flake getFlake(
}
for (auto & attr : *vInfo.attrs) {
if (attr.name != state.sDescription &&
if (attr.name != state.s.description &&
attr.name != sInputs &&
attr.name != sOutputs &&
attr.name != state.s.outputs &&
attr.name != sNixConfig)
throw Error("flake '%s' has an unsupported attribute '%s', at %s",
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()
{
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();
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()
{
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");
}
return system;
@ -70,7 +70,7 @@ std::string DrvInfo::querySystem()
std::optional<StorePath> DrvInfo::queryDrvPath()
{
if (!drvPath && attrs) {
Bindings::iterator i = attrs->find(state->sDrvPath);
Bindings::iterator i = attrs->find(state->s.drvPath);
NixStringContext context;
if (i == attrs->end())
drvPath = {std::nullopt};
@ -92,7 +92,7 @@ StorePath DrvInfo::requireDrvPath()
StorePath DrvInfo::queryOutPath()
{
if (!outPath && attrs) {
Bindings::iterator i = attrs->find(state->sOutPath);
Bindings::iterator i = attrs->find(state->s.outPath);
NixStringContext context;
if (i != attrs->end())
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;
}
Attr * outputs = this->attrs->get(this->state->sOutputs);
Attr * outputs = this->attrs->get(this->state->s.outputs);
if (outputs == nullptr) {
fillDefault();
return;
@ -157,7 +157,7 @@ void DrvInfo::fillOutputs(bool withPaths)
state->forceAttrs(*out->value, outputs->pos, errMsg);
// ...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) {
continue;
// 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
// attribute `outputSpecified = true`, and changes the `outputName` attr to the
// explicitly selected-into output.
if (Attr * outSpecAttr = attrs->get(state->sOutputSpecified)) {
if (Attr * outSpecAttr = attrs->get(state->s.outputSpecified)) {
bool outputSpecified = this->state->forceBool(
*outSpecAttr->value,
outSpecAttr->pos,
@ -236,7 +236,7 @@ DrvInfo::Outputs DrvInfo::queryOutputs(bool withPaths, bool onlyOutputsToInstall
std::string DrvInfo::queryOutputName()
{
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") : "";
}
return outputName;
@ -247,7 +247,7 @@ Bindings * DrvInfo::getMeta()
{
if (meta) return meta;
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;
state->forceAttrs(*a->value, a->pos, "while evaluating the 'meta' attribute of a derivation");
meta = a->value->attrs;
@ -274,7 +274,7 @@ bool DrvInfo::checkMeta(Value & v)
return true;
}
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;
for (auto & i : *v.attrs)
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
`recurseForDerivations = true' attribute. */
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) {
continue;
}

View file

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

View file

@ -191,11 +191,11 @@ static void import(EvalState & state, const PosIdx pos, Value & vPath, Value * v
if (auto storePath = isValidDerivationInStore()) {
Derivation drv = state.store->readDerivation(*storePath);
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 },
});
attrs.alloc(state.sName).mkString(drv.env["name"]);
auto & outputsVal = attrs.alloc(state.sOutputs);
attrs.alloc(state.s.name).mkString(drv.env["name"]);
auto & outputsVal = attrs.alloc(state.s.outputs);
state.mkList(outputsVal, drv.outputs.size());
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");
/* 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");
@ -521,7 +521,7 @@ static void prim_genericClosure(EvalState & state, const PosIdx pos, Value * * a
}
/* 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");
/* 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");
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);
if (!doneKeys.insert(key->value).second) continue;
@ -650,10 +650,10 @@ static void prim_tryEval(EvalState & state, const PosIdx pos, Value * * args, Va
try {
state.forceValue(*args[0], pos);
attrs.insert(state.sValue, args[0]);
attrs.insert(state.s.value, args[0]);
attrs.alloc("success").mkBool(true);
} catch (AssertionError & e) {
attrs.alloc(state.sValue).mkBool(false);
attrs.alloc(state.s.value).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;
/* 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;
try {
@ -781,7 +781,7 @@ drvName, Bindings * attrs, Value & v)
using nlohmann::json;
std::optional<json> jsonObject;
auto pos = v.determinePos(noPos);
auto attr = attrs->find(state.sStructuredAttrs);
auto attr = attrs->find(state.s.structuredAttrs);
if (attr != attrs->end() &&
state.forceBool(*attr->value, pos,
"while evaluating the `__structuredAttrs` "
@ -790,7 +790,7 @@ drvName, Bindings * attrs, Value & v)
/* Check whether null attributes should be ignored. */
bool ignoreNulls = false;
attr = attrs->find(state.sIgnoreNulls);
attr = attrs->find(state.s.ignoreNulls);
if (attr != attrs->end())
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");
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];
vomit("processing attribute '%1%'", key);
@ -860,19 +860,19 @@ drvName, Bindings * attrs, Value & v)
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;
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;
experimentalFeatureSettings.require(Xp::ImpureDerivations);
}
/* The `args' attribute is special: it supplies the
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);
for (auto elem : i->value->listItems()) {
auto s = state.coerceToString(pos, *elem, context,
@ -888,21 +888,21 @@ drvName, Bindings * attrs, Value & v)
if (jsonObject) {
if (i->name == state.sStructuredAttrs) continue;
if (i->name == state.s.structuredAttrs) continue;
(*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);
else if (i->name == state.sSystem)
else if (i->name == state.s.system)
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);
else if (i->name == state.sOutputHashAlgo)
else if (i->name == state.s.outputHashAlgo)
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));
else if (i->name == state.sOutputs) {
else if (i->name == state.s.outputs) {
/* Require outputs to be a list of strings. */
state.forceList(*i->value, pos, context_below);
Strings ss;
@ -911,29 +911,29 @@ drvName, Bindings * attrs, Value & v)
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);
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);
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);
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);
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);
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);
} else {
auto s = state.coerceToString(pos, *i->value, context, context_below, true).toOwned();
drv.env.emplace(key, s);
if (i->name == state.sBuilder) drv.builder = std::move(s);
else if (i->name == state.sSystem) drv.platform = std::move(s);
else if (i->name == state.sOutputHash) outputHash = std::move(s);
else if (i->name == state.sOutputHashAlgo) outputHashAlgo = std::move(s);
else if (i->name == state.sOutputHashMode) handleHashMode(s);
else if (i->name == state.sOutputs)
if (i->name == state.s.builder) drv.builder = std::move(s);
else if (i->name == state.s.system) drv.platform = std::move(s);
else if (i->name == state.s.outputHash) outputHash = std::move(s);
else if (i->name == state.s.outputHashAlgo) outputHashAlgo = std::move(s);
else if (i->name == state.s.outputHashMode) handleHashMode(s);
else if (i->name == state.s.outputs)
handleOutputs(tokenizeString<Strings>(s));
}
@ -1109,7 +1109,7 @@ drvName, Bindings * attrs, Value & v)
}
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 },
});
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");
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())
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;
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];
if (n == "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");
else if (n == "filter")
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()) {
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 sym = state.symbols.create(name);
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);
}
}
@ -2256,13 +2256,13 @@ static void prim_partition(EvalState & state, const PosIdx pos, Value * * args,
auto attrs = state.buildBindings(2);
auto & vRight = attrs.alloc(state.sRight);
auto & vRight = attrs.alloc(state.s.right);
auto rsize = right.size();
state.mkList(vRight, rsize);
if (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();
state.mkList(vWrong, 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");
DrvName parsed(name);
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);
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 sPath = state.symbols.create("path");
auto sAllOutputs = state.symbols.create("allOutputs");
for (const auto & info : contextInfos) {
auto infoAttrs = state.buildBindings(3);
if (info.second.path)
infoAttrs.alloc(sPath).mkBool(true);
infoAttrs.alloc(state.s.path).mkBool(true);
if (info.second.allOutputs)
infoAttrs.alloc(sAllOutputs).mkBool(true);
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());
for (const auto & [i, output] : enumerate(info.second.outputs))
(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");
auto sPath = state.symbols.create("path");
auto sAllOutputs = state.symbols.create("allOutputs");
for (auto & i : *args[1]->attrs) {
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)
state.store->ensurePath(namePath);
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 (state.forceBool(*iter->value, iter->pos, "while evaluating the `path` attribute of a string context"))
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()) {
state.forceList(*iter->value, iter->pos, "while evaluating the `outputs` attribute of a string context");
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 attrs2 = state.buildBindings(8);
state.mkStorePathString(tree.storePath, attrs2.alloc(state.sOutPath));
state.mkStorePathString(tree.storePath, attrs2.alloc(state.s.outPath));
if (input2.getRef())
attrs2.alloc("branch").mkString(*input2.getRef());
// Backward compatibility: set 'rev' to

View file

@ -27,7 +27,7 @@ void emitTreeAttrs(
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.
@ -122,7 +122,7 @@ static void fetchTree(
fetchers::Attrs attrs;
if (auto aType = args[0]->attrs->get(state.sType)) {
if (auto aType = args[0]->attrs->get(state.s.type)) {
if (type)
state.error<EvalError>(
"unexpected attribute 'type'"
@ -136,7 +136,7 @@ static void fetchTree(
attrs.emplace("type", type.value());
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);
if (attr.value->type() == nPath || attr.value->type() == nString) {
auto s = state.coerceToString(attr.pos, *attr.value, context, "", false, false).toOwned();

View file

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

View file

@ -52,7 +52,7 @@ json printValueAsJSON(EvalState & state, bool strict,
out = *maybeString;
break;
}
auto i = v.attrs->find(state.sOutPath);
auto i = v.attrs->find(state.s.outPath);
if (i == v.attrs->end()) {
out = json::object();
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"));
Path drvPath;
a = v.attrs->find(state.sDrvPath);
a = v.attrs->find(state.s.drvPath);
if (a != v.attrs->end()) {
if (strict) state.forceValue(*a->value, a->pos);
if (a->value->type() == nString)
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 (strict) state.forceValue(*a->value, a->pos);
if (a->value->type() == nString)

View file

@ -99,11 +99,11 @@ UnresolvedApp InstallableValue::toApp(EvalState & state)
else if (type == "derivation") {
auto drvPath = cursor->forceDerivation();
auto outPath = cursor->getAttr(state.sOutPath)->getString();
auto outputName = cursor->getAttr(state.sOutputName)->getString();
auto name = cursor->getAttr(state.sName)->getString();
auto outPath = cursor->getAttr(state.s.outPath)->getString();
auto outputName = cursor->getAttr(state.s.outputName)->getString();
auto name = cursor->getAttr(state.s.name)->getString();
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 mainProgram =
aMainProgram

View file

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

View file

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

View file

@ -111,10 +111,10 @@ struct CmdSearch : InstallableCommand, MixJSON
};
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 aDescription = aMeta ? aMeta->maybeGetAttr(state->sDescription) : nullptr;
auto aMeta = cursor.maybeGetAttr(state->s.meta);
auto aDescription = aMeta ? aMeta->maybeGetAttr(state->s.description) : nullptr;
auto description = aDescription ? aDescription->getString() : "";
std::replace(description.begin(), description.end(), '\n', ' ');
auto attrPath2 = concatStringsSep(".", attrPathS);
@ -183,7 +183,7 @@ struct CmdSearch : InstallableCommand, MixJSON
recurse();
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())
recurse();
}

View file

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