aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreldritch horrors <pennae@lix.systems>2024-06-16 23:10:09 +0200
committereldritch horrors <pennae@lix.systems>2024-06-17 19:46:44 +0000
commitad5366c2ad43216ac9a61ccb1477ff9859d1a75c (patch)
treee986b1f0e9510641279bba164b36bae9a96be6be
parentb8f49a8eaf619df6d228f2e0f9814c4a5fa4aec5 (diff)
libexpr: pass Exprs as references, not pointers
almost all places where Exprs are passed as pointers expect the pointers to be non-null. pass them as references to encode this constraint in the type system as well (and also communicate that Exprs must not be freed). Change-Id: Ia98f166fec3c23151f906e13acb4a0954a5980a2
-rw-r--r--src/libcmd/installables.cc6
-rw-r--r--src/libcmd/repl.cc20
-rw-r--r--src/libexpr/eval-inline.hh4
-rw-r--r--src/libexpr/eval.cc60
-rw-r--r--src/libexpr/eval.hh20
-rw-r--r--src/libexpr/nixexpr.hh9
-rw-r--r--src/libexpr/primops.cc10
-rw-r--r--src/libexpr/value.hh4
-rw-r--r--src/nix-build/nix-build.cc4
-rw-r--r--src/nix-env/nix-env.cc2
-rw-r--r--src/nix-instantiate/nix-instantiate.cc8
-rw-r--r--src/nix/main.cc2
-rw-r--r--tests/unit/libexpr-support/tests/libexpr.hh3
-rw-r--r--tests/unit/libexpr/value/print.cc8
14 files changed, 85 insertions, 75 deletions
diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc
index ab0e4fd1c..a10214561 100644
--- a/src/libcmd/installables.cc
+++ b/src/libcmd/installables.cc
@@ -214,7 +214,7 @@ void SourceExprCommand::completeInstallable(AddCompletions & completions, std::s
evalSettings.pureEval = false;
auto state = getEvalState();
- Expr *e = state->parseExprFromFile(
+ Expr & e = state->parseExprFromFile(
resolveExprPath(state->checkSourcePath(lookupFileArg(*state, *file)))
);
@@ -434,13 +434,13 @@ Installables SourceExprCommand::parseInstallables(
auto vFile = state->allocValue();
if (file == "-") {
- auto e = state->parseStdin();
+ auto & e = state->parseStdin();
state->eval(e, *vFile);
}
else if (file)
state->evalFile(lookupFileArg(*state, *file), *vFile);
else {
- auto e = state->parseExprFromString(*expr, state->rootPath(CanonPath::fromCwd()));
+ auto & e = state->parseExprFromString(*expr, state->rootPath(CanonPath::fromCwd()));
state->eval(e, *vFile);
}
diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc
index 24ab8acb9..99abbe44b 100644
--- a/src/libcmd/repl.cc
+++ b/src/libcmd/repl.cc
@@ -155,7 +155,7 @@ struct NixRepl
void reloadFiles();
void addAttrsToScope(Value & attrs);
void addVarToScope(const Symbol name, Value & v);
- Expr * parseString(std::string s);
+ Expr & parseString(std::string s);
void evalString(std::string s, Value & v);
void loadDebugTraceEnv(DebugTrace & dt);
@@ -428,9 +428,9 @@ StringSet NixRepl::completePrefix(const std::string & prefix)
auto expr = cur.substr(0, dot);
auto cur2 = cur.substr(dot + 1);
- Expr * e = parseString(expr);
+ Expr & e = parseString(expr);
Value v;
- e->eval(*state, *env, v);
+ e.eval(*state, *env, v);
state->forceAttrs(v, noPos, "while evaluating an attrset for the purpose of completion (this error should not be displayed; file an issue?)");
for (auto & i : *v.attrs) {
@@ -821,7 +821,7 @@ ProcessLineResult NixRepl::processLine(std::string line)
line[p + 1] != '=' &&
isVarName(name = removeWhitespace(line.substr(0, p))))
{
- Expr * e = parseString(line.substr(p + 1));
+ Expr & e = parseString(line.substr(p + 1));
Value & v(*state->allocValue());
v.mkThunk(env, e);
addVarToScope(state->symbols.create(name), v);
@@ -946,7 +946,7 @@ Value * NixRepl::getReplOverlaysEvalFunction()
auto code =
#include "repl-overlays.nix.gen.hh"
;
- auto expr = state->parseExprFromString(
+ auto & expr = state->parseExprFromString(
code,
SourcePath(evalReplInitFilesPath),
state->staticBaseEnv
@@ -1054,7 +1054,7 @@ Value * NixRepl::bindingsToAttrs()
}
-Expr * NixRepl::parseString(std::string s)
+Expr & NixRepl::parseString(std::string s)
{
return state->parseExprFromString(std::move(s), state->rootPath(CanonPath::fromCwd()), staticEnv);
}
@@ -1062,16 +1062,16 @@ Expr * NixRepl::parseString(std::string s)
void NixRepl::evalString(std::string s, Value & v)
{
- Expr * e = parseString(s);
- e->eval(*state, *env, v);
+ Expr & e = parseString(s);
+ e.eval(*state, *env, v);
state->forceValue(v, v.determinePos(noPos));
}
Value * NixRepl::evalFile(SourcePath & path)
{
- auto expr = state->parseExprFromFile(path, staticEnv);
+ auto & expr = state->parseExprFromFile(path, staticEnv);
Value * result(state->allocValue());
- expr->eval(*state, *env, *result);
+ expr.eval(*state, *env, *result);
state->forceValue(*result, result->determinePos(noPos));
return result;
}
diff --git a/src/libexpr/eval-inline.hh b/src/libexpr/eval-inline.hh
index 03320c7c9..94d4c55ef 100644
--- a/src/libexpr/eval-inline.hh
+++ b/src/libexpr/eval-inline.hh
@@ -86,11 +86,11 @@ void EvalState::forceValue(Value & v, const PosIdx pos)
{
if (v.isThunk()) {
Env * env = v.thunk.env;
- Expr * expr = v.thunk.expr;
+ Expr & expr = *v.thunk.expr;
try {
v.mkBlackhole();
//checkInterrupt();
- expr->eval(*this, *env, v);
+ expr.eval(*this, *env, v);
} catch (...) {
v.mkThunk(env, expr);
tryFixupBlackHolePos(v, pos);
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 4c68fd0b9..c8329a602 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -950,14 +950,14 @@ void EvalState::mkList(Value & v, size_t size)
unsigned long nrThunks = 0;
-static inline void mkThunk(Value & v, Env & env, Expr * expr)
+static inline void mkThunk(Value & v, Env & env, Expr & expr)
{
v.mkThunk(&env, expr);
nrThunks++;
}
-void EvalState::mkThunk_(Value & v, Expr * expr)
+void EvalState::mkThunk_(Value & v, Expr & expr)
{
mkThunk(v, baseEnv, expr);
}
@@ -1058,7 +1058,7 @@ void EvalState::mkSingleDerivedPathString(
Value * Expr::maybeThunk(EvalState & state, Env & env)
{
Value * v = state.allocValue();
- mkThunk(*v, env, this);
+ mkThunk(*v, env, *this);
return v;
}
@@ -1122,7 +1122,7 @@ void EvalState::evalFile(const SourcePath & path_, Value & v, bool mustBeTrivial
e = j->second;
if (!e)
- e = parseExprFromFile(checkSourcePath(resolvedPath));
+ e = &parseExprFromFile(checkSourcePath(resolvedPath));
cacheFile(path, resolvedPath, e, v, mustBeTrivial);
}
@@ -1159,7 +1159,7 @@ void EvalState::cacheFile(
if (mustBeTrivial &&
!(dynamic_cast<ExprAttrs *>(e)))
error<EvalError>("file '%s' must be an attribute set", path).debugThrow();
- eval(e, v);
+ eval(*e, v);
} catch (Error & e) {
addErrorTrace(e, "while evaluating the file '%1%':", resolvedPath.to_string());
throw;
@@ -1170,23 +1170,23 @@ void EvalState::cacheFile(
}
-void EvalState::eval(Expr * e, Value & v)
+void EvalState::eval(Expr & e, Value & v)
{
- e->eval(*this, baseEnv, v);
+ e.eval(*this, baseEnv, v);
}
-inline bool EvalState::evalBool(Env & env, Expr * e, const PosIdx pos, std::string_view errorCtx)
+inline bool EvalState::evalBool(Env & env, Expr & e, const PosIdx pos, std::string_view errorCtx)
{
try {
Value v;
- e->eval(*this, env, v);
+ e.eval(*this, env, v);
if (v.type() != nBool)
error<TypeError>(
"expected a Boolean but found %1%: %2%",
showType(v),
ValuePrinter(*this, v, errorPrintOptions)
- ).atPos(pos).withFrame(env, *e).debugThrow();
+ ).atPos(pos).withFrame(env, e).debugThrow();
return v.boolean;
} catch (Error & e) {
e.addTrace(positions[pos], errorCtx);
@@ -1195,16 +1195,16 @@ inline bool EvalState::evalBool(Env & env, Expr * e, const PosIdx pos, std::stri
}
-inline void EvalState::evalAttrs(Env & env, Expr * e, Value & v, const PosIdx pos, std::string_view errorCtx)
+inline void EvalState::evalAttrs(Env & env, Expr & e, Value & v, const PosIdx pos, std::string_view errorCtx)
{
try {
- e->eval(*this, env, v);
+ e.eval(*this, env, v);
if (v.type() != nAttrs)
error<TypeError>(
"expected a set but found %1%: %2%",
showType(v),
ValuePrinter(*this, v, errorPrintOptions)
- ).withFrame(env, *e).debugThrow();
+ ).withFrame(env, e).debugThrow();
} catch (Error & e) {
e.addTrace(positions[pos], errorCtx);
throw;
@@ -1277,7 +1277,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
Value * vAttr;
if (hasOverrides && i.second.kind != AttrDef::Kind::Inherited) {
vAttr = state.allocValue();
- mkThunk(*vAttr, *i.second.chooseByKind(&env2, &env, inheritEnv), i.second.e);
+ mkThunk(*vAttr, *i.second.chooseByKind(&env2, &env, inheritEnv), *i.second.e);
} else
vAttr = i.second.e->maybeThunk(state, *i.second.chooseByKind(&env2, &env, inheritEnv));
env2.values[displ++] = vAttr;
@@ -1868,13 +1868,13 @@ void ExprWith::eval(EvalState & state, Env & env, Value & v)
void ExprIf::eval(EvalState & state, Env & env, Value & v)
{
// We cheat in the parser, and pass the position of the condition as the position of the if itself.
- (state.evalBool(env, cond, pos, "while evaluating a branch condition") ? then : else_)->eval(state, env, v);
+ (state.evalBool(env, *cond, pos, "while evaluating a branch condition") ? *then : *else_).eval(state, env, v);
}
void ExprAssert::eval(EvalState & state, Env & env, Value & v)
{
- if (!state.evalBool(env, cond, pos, "in the condition of the assert statement")) {
+ if (!state.evalBool(env, *cond, pos, "in the condition of the assert statement")) {
std::ostringstream out;
cond->show(state.symbols, out);
state.error<AssertionError>("assertion '%1%' failed", out.str()).atPos(pos).withFrame(env, *this).debugThrow();
@@ -1885,7 +1885,7 @@ void ExprAssert::eval(EvalState & state, Env & env, Value & v)
void ExprOpNot::eval(EvalState & state, Env & env, Value & v)
{
- v.mkBool(!state.evalBool(env, e, getPos(), "in the argument of the not operator")); // XXX: FIXME: !
+ v.mkBool(!state.evalBool(env, *e, getPos(), "in the argument of the not operator")); // XXX: FIXME: !
}
@@ -1907,27 +1907,27 @@ void ExprOpNEq::eval(EvalState & state, Env & env, Value & v)
void ExprOpAnd::eval(EvalState & state, Env & env, Value & v)
{
- v.mkBool(state.evalBool(env, e1, pos, "in the left operand of the AND (&&) operator") && state.evalBool(env, e2, pos, "in the right operand of the AND (&&) operator"));
+ v.mkBool(state.evalBool(env, *e1, pos, "in the left operand of the AND (&&) operator") && state.evalBool(env, *e2, pos, "in the right operand of the AND (&&) operator"));
}
void ExprOpOr::eval(EvalState & state, Env & env, Value & v)
{
- v.mkBool(state.evalBool(env, e1, pos, "in the left operand of the OR (||) operator") || state.evalBool(env, e2, pos, "in the right operand of the OR (||) operator"));
+ v.mkBool(state.evalBool(env, *e1, pos, "in the left operand of the OR (||) operator") || state.evalBool(env, *e2, pos, "in the right operand of the OR (||) operator"));
}
void ExprOpImpl::eval(EvalState & state, Env & env, Value & v)
{
- v.mkBool(!state.evalBool(env, e1, pos, "in the left operand of the IMPL (->) operator") || state.evalBool(env, e2, pos, "in the right operand of the IMPL (->) operator"));
+ v.mkBool(!state.evalBool(env, *e1, pos, "in the left operand of the IMPL (->) operator") || state.evalBool(env, *e2, pos, "in the right operand of the IMPL (->) operator"));
}
void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v)
{
Value v1, v2;
- state.evalAttrs(env, e1, v1, pos, "in the left operand of the update (//) operator");
- state.evalAttrs(env, e2, v2, pos, "in the right operand of the update (//) operator");
+ state.evalAttrs(env, *e1, v1, pos, "in the left operand of the update (//) operator");
+ state.evalAttrs(env, *e2, v2, pos, "in the right operand of the update (//) operator");
state.nrOpUpdates++;
@@ -2748,39 +2748,39 @@ SourcePath resolveExprPath(SourcePath path)
}
-Expr * EvalState::parseExprFromFile(const SourcePath & path)
+Expr & EvalState::parseExprFromFile(const SourcePath & path)
{
return parseExprFromFile(path, staticBaseEnv);
}
-Expr * EvalState::parseExprFromFile(const SourcePath & path, std::shared_ptr<StaticEnv> & staticEnv)
+Expr & EvalState::parseExprFromFile(const SourcePath & path, std::shared_ptr<StaticEnv> & staticEnv)
{
auto buffer = path.readFile();
// readFile hopefully have left some extra space for terminators
buffer.append("\0\0", 2);
- return parse(buffer.data(), buffer.size(), Pos::Origin(path), path.parent(), staticEnv);
+ return *parse(buffer.data(), buffer.size(), Pos::Origin(path), path.parent(), staticEnv);
}
-Expr * EvalState::parseExprFromString(std::string s_, const SourcePath & basePath, std::shared_ptr<StaticEnv> & staticEnv)
+Expr & EvalState::parseExprFromString(std::string s_, const SourcePath & basePath, std::shared_ptr<StaticEnv> & staticEnv)
{
// NOTE this method (and parseStdin) must take care to *fully copy* their input
// into their respective Pos::Origin until the parser stops overwriting its input
// data.
auto s = make_ref<std::string>(s_);
s_.append("\0\0", 2);
- return parse(s_.data(), s_.size(), Pos::String{.source = s}, basePath, staticEnv);
+ return *parse(s_.data(), s_.size(), Pos::String{.source = s}, basePath, staticEnv);
}
-Expr * EvalState::parseExprFromString(std::string s, const SourcePath & basePath)
+Expr & EvalState::parseExprFromString(std::string s, const SourcePath & basePath)
{
return parseExprFromString(std::move(s), basePath, staticBaseEnv);
}
-Expr * EvalState::parseStdin()
+Expr & EvalState::parseStdin()
{
// NOTE this method (and parseExprFromString) must take care to *fully copy* their
// input into their respective Pos::Origin until the parser stops overwriting its
@@ -2790,7 +2790,7 @@ Expr * EvalState::parseStdin()
// drainFD should have left some extra space for terminators
auto s = make_ref<std::string>(buffer);
buffer.append("\0\0", 2);
- return parse(buffer.data(), buffer.size(), Pos::Stdin{.source = s}, rootPath(CanonPath::fromCwd()), staticBaseEnv);
+ return *parse(buffer.data(), buffer.size(), Pos::Stdin{.source = s}, rootPath(CanonPath::fromCwd()), staticBaseEnv);
}
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 411364d9f..ec6e2bb5e 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -340,16 +340,16 @@ public:
/**
* Parse a Nix expression from the specified file.
*/
- Expr * parseExprFromFile(const SourcePath & path);
- Expr * parseExprFromFile(const SourcePath & path, std::shared_ptr<StaticEnv> & staticEnv);
+ Expr & parseExprFromFile(const SourcePath & path);
+ Expr & parseExprFromFile(const SourcePath & path, std::shared_ptr<StaticEnv> & staticEnv);
/**
* Parse a Nix expression from the specified string.
*/
- Expr * parseExprFromString(std::string s, const SourcePath & basePath, std::shared_ptr<StaticEnv> & staticEnv);
- Expr * parseExprFromString(std::string s, const SourcePath & basePath);
+ Expr & parseExprFromString(std::string s, const SourcePath & basePath, std::shared_ptr<StaticEnv> & staticEnv);
+ Expr & parseExprFromString(std::string s, const SourcePath & basePath);
- Expr * parseStdin();
+ Expr & parseStdin();
/**
* Evaluate an expression read from the given file to normal
@@ -390,15 +390,15 @@ public:
*
* @param [out] v The resulting is stored here.
*/
- void eval(Expr * e, Value & v);
+ void eval(Expr & e, Value & v);
/**
* Evaluation the expression, then verify that it has the expected
* type.
*/
- inline bool evalBool(Env & env, Expr * e);
- inline bool evalBool(Env & env, Expr * e, const PosIdx pos, std::string_view errorCtx);
- inline void evalAttrs(Env & env, Expr * e, Value & v, const PosIdx pos, std::string_view errorCtx);
+ inline bool evalBool(Env & env, Expr & e);
+ inline bool evalBool(Env & env, Expr & e, const PosIdx pos, std::string_view errorCtx);
+ inline void evalAttrs(Env & env, Expr & e, Value & v, const PosIdx pos, std::string_view errorCtx);
/**
* If `v` is a thunk, enter it and overwrite `v` with the result
@@ -619,7 +619,7 @@ public:
}
void mkList(Value & v, size_t length);
- void mkThunk_(Value & v, Expr * expr);
+ void mkThunk_(Value & v, Expr & expr);
void mkPos(Value & v, PosIdx pos);
/**
diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh
index 8631445c9..91516c092 100644
--- a/src/libexpr/nixexpr.hh
+++ b/src/libexpr/nixexpr.hh
@@ -42,12 +42,21 @@ std::string showAttrPath(const SymbolTable & symbols, const AttrPath & attrPath)
struct Expr
{
+protected:
+ Expr(Expr &&) = default;
+ Expr & operator=(Expr &&) = default;
+
+public:
struct AstSymbols {
Symbol sub, lessThan, mul, div, or_, findFile, nixPath, body;
};
+ Expr() = default;
+ Expr(const Expr &) = delete;
+ Expr & operator=(const Expr &) = delete;
virtual ~Expr() { };
+
virtual void show(const SymbolTable & symbols, std::ostream & str) const;
virtual void bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env);
virtual void eval(EvalState & state, Env & env, Value & v);
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index dba56c011..720ab1a3f 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -244,9 +244,9 @@ static void import(EvalState & state, const PosIdx pos, Value & vPath, Value * v
// args[0]->attrs is already sorted.
debug("evaluating file '%1%'", path);
- Expr * e = state.parseExprFromFile(resolveExprPath(path), staticEnv);
+ Expr & e = state.parseExprFromFile(resolveExprPath(path), staticEnv);
- e->eval(state, *env, v);
+ e.eval(state, *env, v);
}
}
}
@@ -390,13 +390,13 @@ void prim_exec(EvalState & state, const PosIdx pos, Value * * args, Value & v)
auto output = runProgram(program, true, commandArgs);
Expr * parsed;
try {
- parsed = state.parseExprFromString(std::move(output), state.rootPath(CanonPath::root));
+ parsed = &state.parseExprFromString(std::move(output), state.rootPath(CanonPath::root));
} catch (Error & e) {
e.addTrace(state.positions[pos], "while parsing the output from '%1%'", program);
throw;
}
try {
- state.eval(parsed, v);
+ state.eval(*parsed, v);
} catch (Error & e) {
e.addTrace(state.positions[pos], "while evaluating the output from '%1%'", program);
throw;
@@ -4494,7 +4494,7 @@ void EvalState::createBaseEnv()
// the parser needs two NUL bytes as terminators; one of them
// is implied by being a C string.
"\0";
- eval(parse(code, sizeof(code), derivationInternal, {CanonPath::root}, staticBaseEnv), *vDerivation);
+ eval(*parse(code, sizeof(code), derivationInternal, {CanonPath::root}, staticBaseEnv), *vDerivation);
}
diff --git a/src/libexpr/value.hh b/src/libexpr/value.hh
index 17a85f1de..dcef82e40 100644
--- a/src/libexpr/value.hh
+++ b/src/libexpr/value.hh
@@ -323,11 +323,11 @@ public:
}
}
- inline void mkThunk(Env * e, Expr * ex)
+ inline void mkThunk(Env * e, Expr & ex)
{
internalType = tThunk;
thunk.env = e;
- thunk.expr = ex;
+ thunk.expr = &ex;
}
inline void mkApp(Value * l, Value * r)
diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc
index 31d4ac9ff..4cce33eb1 100644
--- a/src/nix-build/nix-build.cc
+++ b/src/nix-build/nix-build.cc
@@ -234,7 +234,7 @@ static void main_nix_build(int argc, char * * argv)
DrvInfos drvs;
/* Parse the expressions. */
- std::vector<Expr *> exprs;
+ std::vector<std::reference_wrapper<Expr>> exprs;
if (readStdin)
exprs = {state->parseStdin()};
@@ -337,7 +337,7 @@ static void main_nix_build(int argc, char * * argv)
if (!shell) {
try {
- auto expr = state->parseExprFromString(
+ auto & expr = state->parseExprFromString(
"(import <nixpkgs> {}).bashInteractive",
state->rootPath(CanonPath::fromCwd()));
diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc
index 227a3331c..283d3a3a7 100644
--- a/src/nix-env/nix-env.cc
+++ b/src/nix-env/nix-env.cc
@@ -413,7 +413,7 @@ static void queryInstSources(EvalState & state,
loadSourceExpr(state, *instSource.nixExprPath, vArg);
for (auto & i : args) {
- Expr * eFun = state.parseExprFromString(i, state.rootPath(CanonPath::fromCwd()));
+ Expr & eFun = state.parseExprFromString(i, state.rootPath(CanonPath::fromCwd()));
Value vFun, vTmp;
state.eval(eFun, vFun);
vTmp.mkApp(&vFun, &vArg);
diff --git a/src/nix-instantiate/nix-instantiate.cc b/src/nix-instantiate/nix-instantiate.cc
index c0b251ae4..7487af1c1 100644
--- a/src/nix-instantiate/nix-instantiate.cc
+++ b/src/nix-instantiate/nix-instantiate.cc
@@ -27,10 +27,10 @@ enum OutputKind { okPlain, okXML, okJSON };
void processExpr(EvalState & state, const Strings & attrPaths,
bool parseOnly, bool strict, Bindings & autoArgs,
- bool evalOnly, OutputKind output, bool location, Expr * e)
+ bool evalOnly, OutputKind output, bool location, Expr & e)
{
if (parseOnly) {
- e->show(state.symbols, std::cout);
+ e.show(state.symbols, std::cout);
std::cout << "\n";
return;
}
@@ -175,14 +175,14 @@ static int main_nix_instantiate(int argc, char * * argv)
}
if (readStdin) {
- Expr * e = state->parseStdin();
+ Expr & e = state->parseStdin();
processExpr(*state, attrPaths, parseOnly, strict, autoArgs,
evalOnly, outputKind, xmlOutputSourceLocation, e);
} else if (files.empty() && !fromArgs)
files.push_back("./default.nix");
for (auto & i : files) {
- Expr * e = fromArgs
+ Expr & e = fromArgs
? state->parseExprFromString(i, state->rootPath(CanonPath::fromCwd()))
: state->parseExprFromFile(resolveExprPath(state->checkSourcePath(lookupFileArg(*state, i))));
processExpr(*state, attrPaths, parseOnly, strict, autoArgs,
diff --git a/src/nix/main.cc b/src/nix/main.cc
index 074a59049..55f8d59ba 100644
--- a/src/nix/main.cc
+++ b/src/nix/main.cc
@@ -234,7 +234,7 @@ static void showHelp(std::vector<std::string> subcommand, NixArgs & toplevel)
auto vUtils = state.allocValue();
state.cacheFile(
CanonPath("/utils.nix"), CanonPath("/utils.nix"),
- state.parseExprFromString(
+ &state.parseExprFromString(
#include "utils.nix.gen.hh"
, CanonPath::root),
*vUtils);
diff --git a/tests/unit/libexpr-support/tests/libexpr.hh b/tests/unit/libexpr-support/tests/libexpr.hh
index 4055784ca..b820e3fab 100644
--- a/tests/unit/libexpr-support/tests/libexpr.hh
+++ b/tests/unit/libexpr-support/tests/libexpr.hh
@@ -28,8 +28,7 @@ namespace nix {
}
Value eval(std::string input, bool forceValue = true) {
Value v;
- Expr * e = state.parseExprFromString(input, state.rootPath(CanonPath::root));
- assert(e);
+ Expr & e = state.parseExprFromString(input, state.rootPath(CanonPath::root));
state.eval(e, v);
if (forceValue)
state.forceValue(v, noPos);
diff --git a/tests/unit/libexpr/value/print.cc b/tests/unit/libexpr/value/print.cc
index d2d699a64..feabc07c1 100644
--- a/tests/unit/libexpr/value/print.cc
+++ b/tests/unit/libexpr/value/print.cc
@@ -91,7 +91,8 @@ TEST_F(ValuePrintingTests, tList)
TEST_F(ValuePrintingTests, vThunk)
{
Value vThunk;
- vThunk.mkThunk(nullptr, nullptr);
+ ExprInt e(0);
+ vThunk.mkThunk(nullptr, e);
test(vThunk, "«thunk»");
}
@@ -521,7 +522,7 @@ TEST_F(ValuePrintingTests, ansiColorsAssert)
ExprAssert expr(noPos, &eFalse, &eInt);
Value v;
- state.mkThunk_(v, &expr);
+ state.mkThunk_(v, expr);
test(v,
ANSI_RED "«error: assertion 'false' failed»" ANSI_NORMAL,
@@ -621,7 +622,8 @@ TEST_F(ValuePrintingTests, ansiColorsPrimOpApp)
TEST_F(ValuePrintingTests, ansiColorsThunk)
{
Value v;
- v.mkThunk(nullptr, nullptr);
+ ExprInt e(0);
+ v.mkThunk(nullptr, e);
test(v,
ANSI_MAGENTA "«thunk»" ANSI_NORMAL,