diff --git a/lix/legacy/user-env.cc b/lix/legacy/user-env.cc index 95a8621ea..b2af09e48 100644 --- a/lix/legacy/user-env.cc +++ b/lix/legacy/user-env.cc @@ -46,23 +46,25 @@ bool createUserEnv(EvalState & state, DrvInfos & elems, auto attrs = state.ctx.buildBindings(7 + outputs.size()); - attrs.alloc(state.ctx.s.type).mkString("derivation"); - attrs.alloc(state.ctx.s.name).mkString(i.queryName(state)); + attrs.alloc(state.ctx.symbols.sym_type).mkString("derivation"); + attrs.alloc(state.ctx.symbols.sym_name).mkString(i.queryName(state)); auto system = i.querySystem(state); if (!system.empty()) - attrs.alloc(state.ctx.s.system).mkString(system); - attrs.alloc(state.ctx.s.outPath).mkString(state.ctx.store->printStorePath(i.queryOutPath(state))); + attrs.alloc(state.ctx.symbols.sym_system).mkString(system); + attrs.alloc(state.ctx.symbols.sym_outPath) + .mkString(state.ctx.store->printStorePath(i.queryOutPath(state))); if (drvPath) - attrs.alloc(state.ctx.s.drvPath).mkString(state.ctx.store->printStorePath(*drvPath)); + attrs.alloc(state.ctx.symbols.sym_drvPath).mkString(state.ctx.store->printStorePath(*drvPath)); // Copy each output meant for installation. - auto & vOutputs = attrs.alloc(state.ctx.s.outputs); + auto & vOutputs = attrs.alloc(state.ctx.symbols.sym_outputs); auto outputsList = state.ctx.mem.newList(outputs.size()); vOutputs = {NewValueAs::list, outputsList}; for (const auto & [m, j] : enumerate(outputs)) { outputsList->elems[m].mkString(j.first); auto outputAttrs = state.ctx.buildBindings(2); - outputAttrs.alloc(state.ctx.s.outPath).mkString(state.ctx.store->printStorePath(*j.second)); + outputAttrs.alloc(state.ctx.symbols.sym_outPath) + .mkString(state.ctx.store->printStorePath(*j.second)); attrs.alloc(j.first).mkAttrs(outputAttrs); /* This is only necessary when installing store paths, e.g., @@ -81,7 +83,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems, meta.insert(state.ctx.symbols.create(j), *v); } - attrs.alloc(state.ctx.s.meta).mkAttrs(meta); + attrs.alloc(state.ctx.symbols.sym_meta).mkAttrs(meta); manifest->elems[n++].mkAttrs(attrs); @@ -116,9 +118,9 @@ bool createUserEnv(EvalState & state, DrvInfos & elems, debug("evaluating user environment builder"); state.forceValue(topLevel, noPos); NixStringContext context; - const Attr & aDrvPath(*topLevel.attrs()->get(state.ctx.s.drvPath)); + const Attr & aDrvPath(*topLevel.attrs()->get(state.ctx.symbols.sym_drvPath)); auto topLevelDrv = state.coerceToStorePath(aDrvPath.pos, aDrvPath.value, context, ""); - const Attr & aOutPath(*topLevel.attrs()->get(state.ctx.s.outPath)); + const Attr & aOutPath(*topLevel.attrs()->get(state.ctx.symbols.sym_outPath)); auto topLevelOut = state.coerceToStorePath(aOutPath.pos, aOutPath.value, context, ""); /* Realise the resulting store expression. */ diff --git a/lix/libexpr/eval.cc b/lix/libexpr/eval.cc index f438d501b..330497e92 100644 --- a/lix/libexpr/eval.cc +++ b/lix/libexpr/eval.cc @@ -231,62 +231,6 @@ void initLibExpr() libexprInitialised = true; } -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")) - , 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"), - .mul = symbols.create("__mul"), - .div = symbols.create("__div"), - .or_ = symbols.create("or"), - .findFile = symbols.create("__findFile"), - .nixPath = symbols.create("__nixPath"), - .body = symbols.create("body"), - .overrides = symbols.create("__overrides"), - } -{ -} - EvalMemory::EvalMemory() { assert(libexprInitialised); @@ -413,8 +357,7 @@ Evaluator::Evaluator( std::shared_ptr buildStore, std::function debugRepl ) - : s(symbols) - , paths(aio, store, [&] { + : paths(aio, store, [&] { SearchPath searchPath; if (!evalSettings.pureEval) { for (auto & i : _searchPath.elements) @@ -962,8 +905,8 @@ void EvalState::mkPos(Value & v, PosIdx p) auto origin = ctx.positions.originOf(p); if (auto path = std::get_if(&origin)) { auto attrs = ctx.buildBindings(3); - attrs.alloc(ctx.s.file).mkString(path->to_string()); - makePositionThunks(*this, p, attrs.alloc(ctx.s.line), attrs.alloc(ctx.s.column)); + attrs.alloc(ctx.symbols.sym_file).mkString(path->to_string()); + makePositionThunks(*this, p, attrs.alloc(ctx.symbols.sym_line), attrs.alloc(ctx.symbols.sym_column)); v.mkAttrs(attrs); } else v.mkNull(); @@ -1182,7 +1125,7 @@ void ExprSet::eval(EvalState & state, Env & env, Value & v) dynamicEnv = &env2; Env * inheritEnv = inheritFromExprs ? buildInheritFromEnv(state, env2) : nullptr; - ExprAttrs::AttrDefs::iterator overrides = attrs.find(state.ctx.s.overrides); + ExprAttrs::AttrDefs::iterator overrides = attrs.find(state.ctx.symbols.sym___overrides); bool hasOverrides = overrides != attrs.end(); /* The recursive attributes are evaluated in the new @@ -1797,7 +1740,8 @@ void EvalState::callFunction(Value & fun, std::span args, Value & vRes, c } } - else if (vCur.type() == nAttrs && (functor = vCur.attrs()->get(ctx.s.functor))) { + else if (vCur.type() == nAttrs && (functor = vCur.attrs()->get(ctx.symbols.sym___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. */ @@ -1811,13 +1755,16 @@ void EvalState::callFunction(Value & fun, std::span args, Value & vRes, c args = args.subspan(1); } - else - ctx.errors.make( + else { + ctx.errors + .make( "attempt to call something which is not a function but %1%: %2%", showType(vCur), - ValuePrinter(*this, vCur, errorPrintOptions)) + ValuePrinter(*this, vCur, errorPrintOptions) + ) .atPos(pos) .debugThrow(); + } } vRes = vCur; @@ -1856,7 +1803,7 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res, PosI forceValue(fun, pos); if (fun.type() == nAttrs) { - auto found = fun.attrs()->get(ctx.s.functor); + auto found = fun.attrs()->get(ctx.symbols.sym___functor); if (found) { Value v; callFunction(found->value, fun, v, pos); @@ -2322,7 +2269,7 @@ bool EvalState::forceBool(Value & v, const PosIdx pos, std::string_view errorCtx bool EvalState::isFunctor(Value & fun) { - return fun.type() == nAttrs && fun.attrs()->get(ctx.s.functor); + return fun.type() == nAttrs && fun.attrs()->get(ctx.symbols.sym___functor); } @@ -2397,7 +2344,7 @@ std::string_view EvalState::forceStringNoCtx(Value & v, const PosIdx pos, std::s bool EvalState::isDerivation(Value & v) { if (v.type() != nAttrs) return false; - auto i = v.attrs()->get(ctx.s.type); + auto i = v.attrs()->get(ctx.symbols.sym_type); if (!i) { return false; } @@ -2412,7 +2359,7 @@ bool EvalState::isDerivation(Value & v) std::optional EvalState::tryAttrsToString(const PosIdx pos, Value & v, NixStringContext & context, StringCoercionMode mode, bool copyToStore) { - auto i = v.attrs()->get(ctx.s.toString); + auto i = v.attrs()->get(ctx.symbols.sym___toString); if (i) { Value v1; try { @@ -2461,7 +2408,7 @@ BackedStringView EvalState::coerceToString( auto maybeString = tryAttrsToString(pos, v, context, mode, copyToStore); if (maybeString) return std::move(*maybeString); - auto i = v.attrs()->get(ctx.s.outPath); + auto i = v.attrs()->get(ctx.symbols.sym_outPath); if (!i) { ctx.errors.make( "cannot coerce %1% to a string: %2%", @@ -2701,8 +2648,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)) { - auto i = v1.attrs()->get(ctx.s.outPath); - auto j = v2.attrs()->get(ctx.s.outPath); + auto i = v1.attrs()->get(ctx.symbols.sym_outPath); + auto j = v2.attrs()->get(ctx.symbols.sym_outPath); if (i && j) { return eqValues(i->value, j->value, pos, errorCtx); } diff --git a/lix/libexpr/eval.hh b/lix/libexpr/eval.hh index c1dd9c525..b18b936bd 100644 --- a/lix/libexpr/eval.hh +++ b/lix/libexpr/eval.hh @@ -163,20 +163,6 @@ public: } }; -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, startSet, operator_, key, - path, prefix, outputSpecified; - - const Expr::AstSymbols exprSymbols; - - explicit StaticSymbols(SymbolTable & symbols); -}; - class EvalMemory { static constexpr size_t CACHES = 8; @@ -491,9 +477,8 @@ class Evaluator EvalState * activeEval = nullptr; public: - SymbolTable symbols; + NixSymbolTable symbols; PosTable positions; - const StaticSymbols s; EvalMemory mem; EvalRuntimeCaches caches; EvalPaths paths; diff --git a/lix/libexpr/flake/flake.cc b/lix/libexpr/flake/flake.cc index 044940abc..3a486f77c 100644 --- a/lix/libexpr/flake/flake.cc +++ b/lix/libexpr/flake/flake.cc @@ -334,7 +334,7 @@ static Flake getFlake( Value vInfo; state.eval(flakeExpr, vInfo); - if (auto description = vInfo.attrs()->get(state.ctx.s.description)) { + if (auto description = vInfo.attrs()->get(state.ctx.symbols.sym_description)) { expectType(state, nString, description->value, description->pos); flake.description = description->value.str(); } @@ -367,7 +367,7 @@ static Flake getFlake( flake.resolvedRef = resolvedRef; } - if (auto outputs = vInfo.attrs()->get(state.ctx.s.outputs)) { + if (auto outputs = vInfo.attrs()->get(state.ctx.symbols.sym_outputs)) { expectType(state, nFunction, outputs->value, outputs->pos); if (outputs->value.isLambda()) { @@ -376,19 +376,19 @@ static Flake getFlake( pattern) { for (auto & formal : pattern->formals) { - if (formal.name != state.ctx.s.self) + if (formal.name != state.ctx.symbols.sym_self) { flake.inputs.emplace( state.ctx.symbols[formal.name], - FlakeInput{ - .ref = parseFlakeRef(std::string(state.ctx.symbols[formal.name])) - } + FlakeInput{.ref = parseFlakeRef(std::string(state.ctx.symbols[formal.name]))} ); + } } } } - } else + } else { throw Error("flake '%s' lacks attribute 'outputs'", lockedRef); + } auto sNixConfig = state.ctx.symbols.create("nixConfig"); @@ -457,12 +457,16 @@ static Flake getFlake( } for (auto & attr : *vInfo.attrs()) { - if (attr.name != state.ctx.s.description && - attr.name != sInputs && - attr.name != state.ctx.s.outputs && - attr.name != sNixConfig) - throw Error("flake '%s' has an unsupported attribute '%s', at %s", - lockedRef, state.ctx.symbols[attr.name], state.ctx.positions[attr.pos]); + if (attr.name != state.ctx.symbols.sym_description && attr.name != sInputs + && attr.name != state.ctx.symbols.sym_outputs && attr.name != sNixConfig) + { + throw Error( + "flake '%s' has an unsupported attribute '%s', at %s", + lockedRef, + state.ctx.symbols[attr.name], + state.ctx.positions[attr.pos] + ); + } } return flake; diff --git a/lix/libexpr/get-drvs.cc b/lix/libexpr/get-drvs.cc index 51587cc62..c08f296ed 100644 --- a/lix/libexpr/get-drvs.cc +++ b/lix/libexpr/get-drvs.cc @@ -64,7 +64,7 @@ try { std::string DrvInfo::queryName(EvalState & state) { if (name == "" && attrs) { - auto i = attrs->get(state.ctx.s.name); + auto i = attrs->get(state.ctx.symbols.sym_name); if (!i) { state.ctx.errors.make("derivation name missing").debugThrow(); } @@ -79,7 +79,7 @@ std::string DrvInfo::queryName(EvalState & state) std::string DrvInfo::querySystem(EvalState & state) { if (system == "" && attrs) { - auto i = attrs->get(state.ctx.s.system); + auto i = attrs->get(state.ctx.symbols.sym_system); system = !i ? "unknown" : state.forceStringNoCtx( @@ -93,7 +93,7 @@ std::string DrvInfo::querySystem(EvalState & state) std::optional DrvInfo::queryDrvPath(EvalState & state) { if (!drvPath && attrs) { - auto i = attrs->get(state.ctx.s.drvPath); + auto i = attrs->get(state.ctx.symbols.sym_drvPath); NixStringContext context; if (!i) { drvPath = {std::nullopt}; @@ -121,7 +121,7 @@ StorePath DrvInfo::requireDrvPath(EvalState & state) StorePath DrvInfo::queryOutPath(EvalState & state) { if (!outPath && attrs) { - auto i = attrs->get(state.ctx.s.outPath); + auto i = attrs->get(state.ctx.symbols.sym_outPath); NixStringContext context; if (i) { outPath = state.coerceToStorePath( @@ -150,7 +150,7 @@ void DrvInfo::fillOutputs(EvalState & state, bool withPaths) return; } - const Attr * outputs = this->attrs->get(state.ctx.s.outputs); + const Attr * outputs = this->attrs->get(state.ctx.symbols.sym_outputs); if (outputs == nullptr) { fillDefault(); return; @@ -183,7 +183,7 @@ void DrvInfo::fillOutputs(EvalState & state, bool withPaths) state.forceAttrs(out->value, outputs->pos, errMsg); // ...and evaluate its `outPath` attribute. - const Attr * outPath = out->value.attrs()->get(state.ctx.s.outPath); + const Attr * outPath = out->value.attrs()->get(state.ctx.symbols.sym_outPath); if (outPath == nullptr) { continue; // FIXME: throw error? @@ -222,7 +222,7 @@ DrvInfo::Outputs DrvInfo::queryOutputs(EvalState & state, bool withPaths, bool o // 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 (const Attr * outSpecAttr = attrs->get(state.ctx.s.outputSpecified)) { + if (const Attr * outSpecAttr = attrs->get(state.ctx.symbols.sym_outputSpecified)) { bool outputSpecified = state.forceBool( outSpecAttr->value, outSpecAttr->pos, @@ -264,7 +264,7 @@ DrvInfo::Outputs DrvInfo::queryOutputs(EvalState & state, bool withPaths, bool o std::string DrvInfo::queryOutputName(EvalState & state) { if (outputName == "" && attrs) { - auto i = attrs->get(state.ctx.s.outputName); + auto i = attrs->get(state.ctx.symbols.sym_outputName); outputName = i ? state.forceStringNoCtx( i->value, noPos, "while evaluating the output name of a derivation" ) @@ -278,7 +278,7 @@ Bindings * DrvInfo::getMeta(EvalState & state) { if (meta) return meta; if (!attrs) return 0; - auto a = attrs->get(state.ctx.s.meta); + auto a = attrs->get(state.ctx.symbols.sym_meta); if (!a) { return 0; } @@ -310,7 +310,7 @@ bool DrvInfo::checkMeta(EvalState & state, Value & v) return true; } else if (v.type() == nAttrs) { - auto i = v.attrs()->get(state.ctx.s.outPath); + auto i = v.attrs()->get(state.ctx.symbols.sym_outPath); if (i) { return false; } @@ -524,7 +524,7 @@ static void getDerivations(EvalState & state, Value & vIn, PosIdx pos, `recurseForDerivations = true' attribute. */ if (attr->value.type() == nAttrs) { const Attr * recurseForDrvs = - attr->value.attrs()->get(state.ctx.s.recurseForDerivations); + attr->value.attrs()->get(state.ctx.symbols.sym_recurseForDerivations); if (recurseForDrvs == nullptr) { continue; } diff --git a/lix/libexpr/nixexpr.hh b/lix/libexpr/nixexpr.hh index a5e867254..806dae45a 100644 --- a/lix/libexpr/nixexpr.hh +++ b/lix/libexpr/nixexpr.hh @@ -114,9 +114,6 @@ protected: Expr(const PosIdx pos) : pos(pos) {}; public: - struct AstSymbols { - Symbol sub, lessThan, mul, div, or_, findFile, nixPath, body, overrides; - }; PosIdx pos; diff --git a/lix/libexpr/parser/parser-impl1.inc.cc b/lix/libexpr/parser/parser-impl1.inc.cc index 41e070e4d..6162b4bea 100644 --- a/lix/libexpr/parser/parser-impl1.inc.cc +++ b/lix/libexpr/parser/parser-impl1.inc.cc @@ -137,7 +137,7 @@ struct ExprState std::unique_ptr order(PosIdx pos, bool less, State & state) { - return call(pos, state, state.s.lessThan, !less); + return call(pos, state, state.symbols.sym___lessThan, !less); } std::unique_ptr concatStrings(PosIdx pos) @@ -153,7 +153,9 @@ struct ExprState std::vector> args(2); args[0] = std::make_unique(pos, 0); args[1] = popExprOnly(); - return std::make_unique(pos, state.mkInternalVar(pos, state.s.sub), std::move(args)); + return std::make_unique( + pos, state.mkInternalVar(pos, state.symbols.sym___sub), std::move(args) + ); } void applyOp(PosIdx pos, auto & op, State & state) { @@ -163,27 +165,27 @@ struct ExprState return std::make_unique(pos, std::move(e)); }; - auto expr = (overloaded { - [&] (Op::implies) { return applyBinary(pos); }, - [&] (Op::or_) { return applyBinary(pos); }, - [&] (Op::and_) { return applyBinary(pos); }, - [&] (Op::equals) { return applyBinary(pos); }, - [&] (Op::not_equals) { return applyBinary(pos); }, - [&] (Op::less) { return order(pos, true, state); }, - [&] (Op::greater_eq) { return not_(order(pos, true, state)); }, - [&] (Op::greater) { return order(pos, false, state); }, - [&] (Op::less_eq) { return not_(order(pos, false, state)); }, - [&] (Op::update) { return applyBinary(pos); }, - [&] (Op::not_) { return applyUnary(pos); }, - [&] (Op::plus) { return concatStrings(pos); }, - [&] (Op::minus) { return call(pos, state, state.s.sub); }, - [&] (Op::mul) { return call(pos, state, state.s.mul); }, - [&] (Op::div) { return call(pos, state, state.s.div); }, - [&] (Op::concat) { return applyBinary(pos); }, - [&] (has_attr & a) { return applyUnary(pos, std::move(a.path)); }, - [&] (Op::unary_minus) { return negate(pos, state); }, - [&] (Op::pipe_right) { return pipe(pos, state, true); }, - [&] (Op::pipe_left) { return pipe(pos, state); }, + auto expr = (overloaded{ + [&](Op::implies) { return applyBinary(pos); }, + [&](Op::or_) { return applyBinary(pos); }, + [&](Op::and_) { return applyBinary(pos); }, + [&](Op::equals) { return applyBinary(pos); }, + [&](Op::not_equals) { return applyBinary(pos); }, + [&](Op::less) { return order(pos, true, state); }, + [&](Op::greater_eq) { return not_(order(pos, true, state)); }, + [&](Op::greater) { return order(pos, false, state); }, + [&](Op::less_eq) { return not_(order(pos, false, state)); }, + [&](Op::update) { return applyBinary(pos); }, + [&](Op::not_) { return applyUnary(pos); }, + [&](Op::plus) { return concatStrings(pos); }, + [&](Op::minus) { return call(pos, state, state.symbols.sym___sub); }, + [&](Op::mul) { return call(pos, state, state.symbols.sym___mul); }, + [&](Op::div) { return call(pos, state, state.symbols.sym___div); }, + [&](Op::concat) { return applyBinary(pos); }, + [&](has_attr & a) { return applyUnary(pos, std::move(a.path)); }, + [&](Op::unary_minus) { return negate(pos, state); }, + [&](Op::pipe_right) { return pipe(pos, state, true); }, + [&](Op::pipe_left) { return pipe(pos, state); }, })(op); pushExpr(pos, std::move(expr)); } @@ -755,7 +757,7 @@ template<> struct BuildAST { * https://github.com/NixOS/nix/commit/62a6eeb1f3da0a5954ad2da54c454eb7fc1c6e5d * (TODO: Provide a better and officially supported and documented mechanism for doing this) */ - args[0] = std::make_unique(pos, ps.s.nixPath); + args[0] = std::make_unique(pos, ps.symbols.sym___nixPath); args[1] = std::make_unique(pos, in.string()); s.parts.emplace_back( pos, @@ -765,8 +767,10 @@ template<> struct BuildAST { * until we can figure out how to design a better replacement. * https://git.lix.systems/lix-project/lix/issues/599 */ - std::make_unique(pos, ps.s.findFile), - std::move(args))); + std::make_unique(pos, ps.symbols.sym___findFile), + std::move(args) + ) + ); } }; @@ -831,7 +835,7 @@ template<> struct BuildAST : change_head(pos, std::make_unique(std::move(b.set)), pos, ps.s.body); + s.emplaceExpr(pos, std::make_unique(std::move(b.set)), pos, ps.symbols.sym_body); } }; @@ -893,7 +897,7 @@ template<> struct BuildAST { template<> struct BuildAST { static void apply(const auto & in, SelectState & s, State & ps) { std::vector> args(1); - args[0] = std::make_unique(ps.at(in), ps.s.or_); + args[0] = std::make_unique(ps.at(in), ps.symbols.sym_or); s->emplaceExpr(s.pos, s->popExprOnly(), std::move(args)); } }; diff --git a/lix/libexpr/parser/parser.cc b/lix/libexpr/parser/parser.cc index 2766abfe2..9ac022e78 100644 --- a/lix/libexpr/parser/parser.cc +++ b/lix/libexpr/parser/parser.cc @@ -28,7 +28,6 @@ Expr * Evaluator::parse( positions, basePath, positions.addOrigin(origin, length), - this->s.exprSymbols, featureSettings, }; @@ -63,7 +62,6 @@ Evaluator::parse_repl( positions, basePath, positions.addOrigin(origin, length), - this->s.exprSymbols, featureSettings, }; diff --git a/lix/libexpr/parser/state.hh b/lix/libexpr/parser/state.hh index d9624214e..326127e45 100644 --- a/lix/libexpr/parser/state.hh +++ b/lix/libexpr/parser/state.hh @@ -25,11 +25,10 @@ struct IndStringLine { struct State { - SymbolTable & symbols; + NixSymbolTable & symbols; PosTable & positions; SourcePath basePath; PosTable::Origin origin; - const Expr::AstSymbols & s; const FeatureSettings & featureSettings; bool hasWarnedAboutBadLineEndings = false; // State to only warn on first occurrence @@ -194,7 +193,7 @@ inline void State::addAttr(ExprAttrs * attrs, AttrPath && attrPath, std::unique_ // Before inserting new attrs, check for __override and throw an error // (the error will initially be a warning to ease migration) - if (!featureSettings.isEnabled(Dep::RecSetOverrides) && attr.symbol == s.overrides) { + if (!featureSettings.isEnabled(Dep::RecSetOverrides) && attr.symbol == symbols.sym___overrides) { if (auto set = dynamic_cast(attrs); set && set->recursive) { overridesFound(pos); } diff --git a/lix/libexpr/primops.cc b/lix/libexpr/primops.cc index 5b81bd17d..1c196ace3 100644 --- a/lix/libexpr/primops.cc +++ b/lix/libexpr/primops.cc @@ -180,11 +180,15 @@ static void import(EvalState & state, Value & vPath, Value * vScope, Value & v) if (auto storePath = isValidDerivationInStore()) { Derivation drv = state.aio.blockOn(state.ctx.store->readDerivation(*storePath)); auto attrs = state.ctx.buildBindings(3 + drv.outputs.size()); - attrs.alloc(state.ctx.s.drvPath).mkString(path2, { - NixStringContextElem::DrvDeep { .drvPath = *storePath }, - }); - attrs.alloc(state.ctx.s.name).mkString(drv.env["name"]); - auto & outputsVal = attrs.alloc(state.ctx.s.outputs); + attrs.alloc(state.ctx.symbols.sym_drvPath) + .mkString( + path2, + { + NixStringContextElem::DrvDeep{.drvPath = *storePath}, + } + ); + attrs.alloc(state.ctx.symbols.sym_name).mkString(drv.env["name"]); + auto & outputsVal = attrs.alloc(state.ctx.symbols.sym_outputs); auto outputsList = state.ctx.mem.newList(drv.outputs.size()); outputsVal = {NewValueAs::list, outputsList}; @@ -544,7 +548,7 @@ static void prim_genericClosure(EvalState & state, Value * * args, Value & v) /* Get the start set. */ auto startSet = getAttr( state, - state.ctx.s.startSet, + state.ctx.symbols.sym_startSet, args[0]->attrs(), "in the attrset passed as argument to builtins.genericClosure" ); @@ -568,7 +572,7 @@ static void prim_genericClosure(EvalState & state, Value * * args, Value & v) /* Get the operator. */ auto op = getAttr( state, - state.ctx.s.operator_, + state.ctx.symbols.sym_operator, args[0]->attrs(), "in the attrset passed as argument to builtins.genericClosure" ); @@ -599,7 +603,7 @@ static void prim_genericClosure(EvalState & state, Value * * args, Value & v) auto key = getAttr( state, - state.ctx.s.key, + state.ctx.symbols.sym_key, e.attrs(), "in one of the attrsets generated by (or initially passed to) builtins.genericClosure" ); @@ -722,9 +726,9 @@ static void prim_tryEval(EvalState & state, Value * * args, Value & v) return true; }(); if (success) - attrs.insert(state.ctx.s.value, *args[0]); + attrs.insert(state.ctx.symbols.sym_value, *args[0]); else - attrs.alloc(state.ctx.s.value).mkBool(false); + attrs.alloc(state.ctx.symbols.sym_value).mkBool(false); attrs.alloc("success").mkBool(success); v.mkAttrs(attrs); @@ -835,7 +839,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v) /* Figure out the name first (for stack backtraces). */ auto nameAttr = getAttr( state, - state.ctx.s.name, + state.ctx.symbols.sym_name, attrs, "in the attrset passed as argument to builtins.derivationStrict" ); @@ -890,7 +894,7 @@ drvName, Bindings * attrs, Value & v) { /* Check whether attributes should be passed as a JSON file. */ std::optional jsonObject; - auto attr = attrs->get(state.ctx.s.structuredAttrs); + auto attr = attrs->get(state.ctx.symbols.sym___structuredAttrs); if (attr && state.forceBool( attr->value, @@ -904,7 +908,7 @@ drvName, Bindings * attrs, Value & v) /* Check whether null attributes should be ignored. */ bool ignoreNulls = false; - attr = attrs->get(state.ctx.s.ignoreNulls); + attr = attrs->get(state.ctx.symbols.sym___ignoreNulls); if (attr) { ignoreNulls = state.forceBool( attr->value, @@ -928,7 +932,9 @@ drvName, Bindings * attrs, Value & v) outputs.insert("out"); for (auto & i : attrs->lexicographicOrder(state.ctx.symbols)) { - if (i->name == state.ctx.s.ignoreNulls) continue; + if (i->name == state.ctx.symbols.sym___ignoreNulls) { + continue; + } auto & key = state.ctx.symbols[i->name]; vomit("processing attribute '%1%'", key); @@ -974,14 +980,14 @@ drvName, Bindings * attrs, Value & v) } } - if (i->name == state.ctx.s.contentAddressed + if (i->name == state.ctx.symbols.sym___contentAddressed && state.forceBool(i->value, noPos, context_below)) { state.ctx.errors.make("ca derivations are not supported in Lix") .debugThrow(); } - else if (i->name == state.ctx.s.impure + else if (i->name == state.ctx.symbols.sym___impure && state.forceBool(i->value, noPos, context_below)) { state.ctx.errors.make("impure derivations are not supported in Lix") @@ -990,7 +996,7 @@ drvName, Bindings * attrs, Value & v) /* The `args' attribute is special: it supplies the command-line arguments to the builder. */ - else if (i->name == state.ctx.s.args) + else if (i->name == state.ctx.symbols.sym_args) { state.forceList(i->value, noPos, context_below); for (auto & elem : i->value.listItems()) { @@ -1009,27 +1015,28 @@ drvName, Bindings * attrs, Value & v) /* All other attributes are passed to the builder through the environment. */ - else - { + else { if (jsonObject) { - if (i->name == state.ctx.s.structuredAttrs) continue; + if (i->name == state.ctx.symbols.sym___structuredAttrs) { + continue; + } (*jsonObject)[std::string(key)] = printValueAsJSON(state, true, i->value, noPos, context); - if (i->name == state.ctx.s.builder) + if (i->name == state.ctx.symbols.sym_builder) { drv.builder = state.forceString(i->value, context, noPos, context_below); - else if (i->name == state.ctx.s.system) + } else if (i->name == state.ctx.symbols.sym_system) { drv.platform = state.forceStringNoCtx(i->value, noPos, context_below); - else if (i->name == state.ctx.s.outputHash) + } else if (i->name == state.ctx.symbols.sym_outputHash) { outputHash = state.forceStringNoCtx(i->value, noPos, context_below); - else if (i->name == state.ctx.s.outputHashAlgo) + } else if (i->name == state.ctx.symbols.sym_outputHashAlgo) { outputHashAlgo = state.forceStringNoCtx(i->value, noPos, context_below); - else if (i->name == state.ctx.s.outputHashMode) + } else if (i->name == state.ctx.symbols.sym_outputHashMode) { handleHashMode(state.forceStringNoCtx(i->value, noPos, context_below)); - else if (i->name == state.ctx.s.outputs) { + } else if (i->name == state.ctx.symbols.sym_outputs) { /* Require ‘outputs’ to be a list of strings. */ state.forceList(i->value, noPos, context_below); Strings ss; @@ -1039,48 +1046,54 @@ drvName, Bindings * attrs, Value & v) handleOutputs(ss); } - if (i->name == state.ctx.s.allowedReferences) + if (i->name == state.ctx.symbols.sym_allowedReferences) { printTaggedWarning( "In a derivation named '%s', 'structuredAttrs' disables the effect of " "the derivation attribute 'allowedReferences'; use " "'outputChecks..allowedReferences' instead", drvName ); - if (i->name == state.ctx.s.allowedRequisites) + } + if (i->name == state.ctx.symbols.sym_allowedRequisites) { printTaggedWarning( "In a derivation named '%s', 'structuredAttrs' disables the effect of " "the derivation attribute 'allowedRequisites'; use " "'outputChecks..allowedRequisites' instead", drvName ); - if (i->name == state.ctx.s.disallowedReferences) + } + if (i->name == state.ctx.symbols.sym_disallowedReferences) { printTaggedWarning( "In a derivation named '%s', 'structuredAttrs' disables the effect of " "the derivation attribute 'disallowedReferences'; use " "'outputChecks..disallowedReferences' instead", drvName ); - if (i->name == state.ctx.s.disallowedRequisites) + } + if (i->name == state.ctx.symbols.sym_disallowedRequisites) { printTaggedWarning( "In a derivation named '%s', 'structuredAttrs' disables the effect of " "the derivation attribute 'disallowedRequisites'; use " "'outputChecks..disallowedRequisites' instead", drvName ); - if (i->name == state.ctx.s.maxSize) + } + if (i->name == state.ctx.symbols.sym_maxSize) { printTaggedWarning( "In a derivation named '%s', 'structuredAttrs' disables the effect of " "the derivation attribute 'maxSize'; use " "'outputChecks..maxSize' instead", drvName ); - if (i->name == state.ctx.s.maxClosureSize) + } + if (i->name == state.ctx.symbols.sym_maxClosureSize) { printTaggedWarning( "In a derivation named '%s', 'structuredAttrs' disables the effect of " "the derivation attribute 'maxClosureSize'; use " "'outputChecks..maxClosureSize' instead", drvName ); + } } else { auto s = state @@ -1093,15 +1106,19 @@ drvName, Bindings * attrs, Value & v) ) .toOwned(); drv.env.emplace(key, s); - if (i->name == state.ctx.s.builder) { + if (i->name == state.ctx.symbols.sym_builder) { drv.builder = std::move(s); - } else if (i->name == state.ctx.s.system) + } else if (i->name == state.ctx.symbols.sym_system) { drv.platform = std::move(s); - else if (i->name == state.ctx.s.outputHash) outputHash = std::move(s); - else if (i->name == state.ctx.s.outputHashAlgo) outputHashAlgo = std::move(s); - else if (i->name == state.ctx.s.outputHashMode) handleHashMode(s); - else if (i->name == state.ctx.s.outputs) + } else if (i->name == state.ctx.symbols.sym_outputHash) { + outputHash = std::move(s); + } else if (i->name == state.ctx.symbols.sym_outputHashAlgo) { + outputHashAlgo = std::move(s); + } else if (i->name == state.ctx.symbols.sym_outputHashMode) { + handleHashMode(s); + } else if (i->name == state.ctx.symbols.sym_outputs) { handleOutputs(tokenizeString(s)); + } } } @@ -1239,9 +1256,13 @@ drvName, Bindings * attrs, Value & v) } auto result = state.ctx.buildBindings(1 + drv.outputs.size()); - result.alloc(state.ctx.s.drvPath).mkString(drvPathS, { - NixStringContextElem::DrvDeep { .drvPath = drvPath }, - }); + result.alloc(state.ctx.symbols.sym_drvPath) + .mkString( + drvPathS, + { + NixStringContextElem::DrvDeep{.drvPath = drvPath}, + } + ); for (auto & i : drv.outputs) mkOutputString(state, result, drvPath, i); @@ -1414,7 +1435,7 @@ static void prim_findFile(EvalState & state, Value * * args, Value & v) ); std::string prefix; - auto i = v2.attrs()->get(state.ctx.s.prefix); + auto i = v2.attrs()->get(state.ctx.symbols.sym_prefix); if (i) { prefix = state.forceStringNoCtx( i->value, @@ -1424,7 +1445,7 @@ static void prim_findFile(EvalState & state, Value * * args, Value & v) ); } - i = getAttr(state, state.ctx.s.path, v2.attrs(), "in an element of the __nixPath"); + i = getAttr(state, state.ctx.symbols.sym_path, v2.attrs(), "in an element of the __nixPath"); NixStringContext context; auto path = state @@ -1728,7 +1749,7 @@ static void prim_path(EvalState & state, Value * * args, Value & v) context, "while evaluating the 'path' attribute passed to 'builtins.path'" )); - } else if (attr.name == state.ctx.s.name) { + } else if (attr.name == state.ctx.symbols.sym_name) { name = state.forceStringNoCtx( attr.value, attr.pos, @@ -1962,7 +1983,7 @@ static void prim_listToAttrs(EvalState & state, Value * * args, Value & v) v2, noPos, "while evaluating an element of the list passed to builtins.listToAttrs" ); - auto j = getAttr(state, state.ctx.s.name, v2.attrs(), "in a {name=...; value=...;} pair"); + auto j = getAttr(state, state.ctx.symbols.sym_name, v2.attrs(), "in a {name=...; value=...;} pair"); auto name = state.forceStringNoCtx( j->value, @@ -1974,7 +1995,7 @@ static void prim_listToAttrs(EvalState & state, Value * * args, Value & v) auto sym = state.ctx.symbols.create(name); if (seen.insert(sym).second) { auto j2 = - getAttr(state, state.ctx.s.value, v2.attrs(), "in a {name=...; value=...;} pair"); + getAttr(state, state.ctx.symbols.sym_value, v2.attrs(), "in a {name=...; value=...;} pair"); attrs.insert(sym, j2->value, j2->pos); } } @@ -2466,7 +2487,7 @@ static void prim_partition(EvalState & state, Value * * args, Value & v) auto attrs = state.ctx.buildBindings(2); - auto & vRight = attrs.alloc(state.ctx.s.right); + auto & vRight = attrs.alloc(state.ctx.symbols.sym_right); auto rsize = right.size(); auto rlist = state.ctx.mem.newList(rsize); vRight = {NewValueAs::list, rlist}; @@ -2474,7 +2495,7 @@ static void prim_partition(EvalState & state, Value * * args, Value & v) rlist->elems[i] = elems[idx]; } - auto & vWrong = attrs.alloc(state.ctx.s.wrong); + auto & vWrong = attrs.alloc(state.ctx.symbols.sym_wrong); auto wsize = wrong.size(); auto wlist = state.ctx.mem.newList(wsize); vWrong = {NewValueAs::list, wlist}; @@ -2982,7 +3003,7 @@ static void prim_parseDrvName(EvalState & state, Value * * args, Value & v) auto name = state.forceStringNoCtx(*args[0], noPos, "while evaluating the first argument passed to builtins.parseDrvName"); DrvName parsed(name); auto attrs = state.ctx.buildBindings(2); - attrs.alloc(state.ctx.s.name).mkString(parsed.name); + attrs.alloc(state.ctx.symbols.sym_name).mkString(parsed.name); attrs.alloc("version").mkString(parsed.version); v.mkAttrs(attrs); } diff --git a/lix/libexpr/primops/context.cc b/lix/libexpr/primops/context.cc index d7e23f3df..4c29759d4 100644 --- a/lix/libexpr/primops/context.cc +++ b/lix/libexpr/primops/context.cc @@ -136,11 +136,11 @@ void prim_getContext(EvalState & state, Value * * args, Value & v) for (const auto & info : contextInfos) { auto infoAttrs = state.ctx.buildBindings(3); if (info.second.path) - infoAttrs.alloc(state.ctx.s.path).mkBool(true); + infoAttrs.alloc(state.ctx.symbols.sym_path).mkBool(true); if (info.second.allOutputs) infoAttrs.alloc(sAllOutputs).mkBool(true); if (!info.second.outputs.empty()) { - auto & outputsVal = infoAttrs.alloc(state.ctx.s.outputs); + auto & outputsVal = infoAttrs.alloc(state.ctx.symbols.sym_outputs); auto content = state.ctx.mem.newList(info.second.outputs.size()); outputsVal = {NewValueAs::list, content}; for (const auto & [i, output] : enumerate(info.second.outputs)) @@ -177,7 +177,7 @@ void prim_appendContext(EvalState & state, Value ** args, Value & v) if (!settings.readOnlyMode) state.aio.blockOn(state.ctx.store->ensurePath(namePath)); state.forceAttrs(i.value, i.pos, "while evaluating the value of a string context"); - auto a = i.value.attrs()->get(state.ctx.s.path); + auto a = i.value.attrs()->get(state.ctx.symbols.sym_path); if (a) { if (state.forceBool( a->value, a->pos, "while evaluating the `path` attribute of a string context" @@ -209,7 +209,7 @@ void prim_appendContext(EvalState & state, Value ** args, Value & v) } } - a = i.value.attrs()->get(state.ctx.s.outputs); + a = i.value.attrs()->get(state.ctx.symbols.sym_outputs); if (a) { state.forceList( a->value, a->pos, "while evaluating the `outputs` attribute of a string context" diff --git a/lix/libexpr/primops/fetchMercurial.cc b/lix/libexpr/primops/fetchMercurial.cc index 145adb74f..2bbce96bc 100644 --- a/lix/libexpr/primops/fetchMercurial.cc +++ b/lix/libexpr/primops/fetchMercurial.cc @@ -88,7 +88,7 @@ void prim_fetchMercurial(EvalState & state, Value ** args, Value & v) auto [tree, input2] = state.aio.blockOn(input.fetch(state.ctx.store)); auto attrs2 = state.ctx.buildBindings(8); - state.ctx.paths.mkStorePathString(tree.storePath, attrs2.alloc(state.ctx.s.outPath)); + state.ctx.paths.mkStorePathString(tree.storePath, attrs2.alloc(state.ctx.symbols.sym_outPath)); if (input2.getRef()) attrs2.alloc("branch").mkString(*input2.getRef()); // Backward compatibility: set 'rev' to diff --git a/lix/libexpr/primops/fetchTree.cc b/lix/libexpr/primops/fetchTree.cc index af1dd4d1e..49b8ebd90 100644 --- a/lix/libexpr/primops/fetchTree.cc +++ b/lix/libexpr/primops/fetchTree.cc @@ -26,8 +26,7 @@ void emitTreeAttrs( auto attrs = state.buildBindings(10); - - state.paths.mkStorePathString(tree.storePath, attrs.alloc(state.s.outPath)); + state.paths.mkStorePathString(tree.storePath, attrs.alloc(state.symbols.sym_outPath)); // FIXME: support arbitrary input attributes. @@ -122,7 +121,7 @@ static void fetchTree( fetchers::Attrs attrs; - if (auto aType = args[0]->attrs()->get(state.ctx.s.type)) { + if (auto aType = args[0]->attrs()->get(state.ctx.symbols.sym_type)) { if (type) state.ctx.errors.make( "unexpected attribute 'type'" @@ -141,7 +140,9 @@ static void fetchTree( attrs.emplace("type", type.value()); for (auto & attr : *args[0]->attrs()) { - if (attr.name == state.ctx.s.type) continue; + if (attr.name == state.ctx.symbols.sym_type) { + continue; + } state.forceValue(attr.value, attr.pos); if (attr.value.type() == nPath || attr.value.type() == nString) { auto s = diff --git a/lix/libexpr/print.cc b/lix/libexpr/print.cc index d6e844711..a92337886 100644 --- a/lix/libexpr/print.cc +++ b/lix/libexpr/print.cc @@ -232,7 +232,7 @@ private: void printDerivation(Value & v) { - auto i = v.attrs()->get(state.ctx.s.drvPath); + auto i = v.attrs()->get(state.ctx.symbols.sym_drvPath); NixStringContext context; std::string storePath; if (i) { diff --git a/lix/libexpr/value-to-json.cc b/lix/libexpr/value-to-json.cc index f32d35091..a1440a443 100644 --- a/lix/libexpr/value-to-json.cc +++ b/lix/libexpr/value-to-json.cc @@ -51,7 +51,7 @@ JSON printValueAsJSON(EvalState & state, bool strict, out = *maybeString; break; } - auto i = v.attrs()->get(state.ctx.s.outPath); + auto i = v.attrs()->get(state.ctx.symbols.sym_outPath); if (!i) { out = JSON::object(); StringSet names; diff --git a/lix/libexpr/value-to-xml.cc b/lix/libexpr/value-to-xml.cc index 6b09439b1..e1360c473 100644 --- a/lix/libexpr/value-to-xml.cc +++ b/lix/libexpr/value-to-xml.cc @@ -87,7 +87,7 @@ static void printValueAsXML(EvalState & state, bool strict, bool location, auto a = v.attrs()->get(state.ctx.symbols.create("derivation")); Path drvPath; - a = v.attrs()->get(state.ctx.s.drvPath); + a = v.attrs()->get(state.ctx.symbols.sym_drvPath); if (a) { if (strict) { state.forceValue(a->value, a->pos); @@ -97,7 +97,7 @@ static void printValueAsXML(EvalState & state, bool strict, bool location, } } - a = v.attrs()->get(state.ctx.s.outPath); + a = v.attrs()->get(state.ctx.symbols.sym_outPath); if (a) { if (strict) { state.forceValue(a->value, a->pos); diff --git a/lix/nix/bundle.cc b/lix/nix/bundle.cc index fa9160c26..4f689021d 100644 --- a/lix/nix/bundle.cc +++ b/lix/nix/bundle.cc @@ -104,14 +104,14 @@ struct CmdBundle : InstallableCommand throw Error("the bundler '%s' does not produce a derivation", bundler.what()); } - auto attr1 = vRes.attrs()->get(evaluator->s.drvPath); + auto attr1 = vRes.attrs()->get(evaluator->symbols.sym_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(evaluator->s.outPath); + auto attr2 = vRes.attrs()->get(evaluator->symbols.sym_outPath); if (!attr2) throw Error("the bundler '%s' does not produce a derivation", bundler.what()); @@ -125,7 +125,7 @@ struct CmdBundle : InstallableCommand })); if (!outLink) { - auto * attr = vRes.attrs()->get(evaluator->s.name); + auto * attr = vRes.attrs()->get(evaluator->symbols.sym_name); if (!attr) throw Error("attribute 'name' missing"); outLink = evalState->forceStringNoCtx(attr->value, attr->pos, ""); diff --git a/subprojects/nix-eval-jobs/src/worker.cc b/subprojects/nix-eval-jobs/src/worker.cc index 4bd68efd4..29db4fa89 100644 --- a/subprojects/nix-eval-jobs/src/worker.cc +++ b/subprojects/nix-eval-jobs/src/worker.cc @@ -230,7 +230,7 @@ try { if (name == "recurseForDerivations" && !args.forceRecurse) { auto attrv = v.attrs()->get( - evaluator->s.recurseForDerivations); + evaluator->symbols.sym_recurseForDerivations); recurse = state->forceBool( attrv->value, attrv->pos, "while evaluating recurseForDerivations"); diff --git a/tests/unit/libexpr/value/print.cc b/tests/unit/libexpr/value/print.cc index de6948bcb..09b4ecb15 100644 --- a/tests/unit/libexpr/value/print.cc +++ b/tests/unit/libexpr/value/print.cc @@ -440,7 +440,7 @@ TEST_F(ValuePrintingTests, ansiColorsDerivation) vDerivation.mkString("derivation"); BindingsBuilder builder = evaluator.buildBindings(10); - builder.insert(evaluator.s.type, vDerivation); + builder.insert(evaluator.symbols.sym_type, vDerivation); Value vAttrs; vAttrs.mkAttrs(builder.finish());