forked from lix-project/lix
forceValue: make pos mandatory
- Make passing the position to `forceValue` mandatory, this way we remember people that the position is important for better error messages - Add pos to all `forceValue` calls
This commit is contained in:
parent
5f08db69d1
commit
49b0bb0206
|
@ -198,8 +198,9 @@ void SourceExprCommand::completeInstallable(std::string_view prefix)
|
||||||
prefix_ = "";
|
prefix_ = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
Value &v1(*findAlongAttrPath(*state, prefix_, *autoArgs, root).first);
|
auto [v, pos] = findAlongAttrPath(*state, prefix_, *autoArgs, root);
|
||||||
state->forceValue(v1);
|
Value &v1(*v);
|
||||||
|
state->forceValue(v1, pos);
|
||||||
Value v2;
|
Value v2;
|
||||||
state->autoCallFunction(*autoArgs, v1, v2);
|
state->autoCallFunction(*autoArgs, v1, v2);
|
||||||
|
|
||||||
|
@ -446,7 +447,7 @@ struct InstallableAttrPath : InstallableValue
|
||||||
std::pair<Value *, Pos> toValue(EvalState & state) override
|
std::pair<Value *, Pos> toValue(EvalState & state) override
|
||||||
{
|
{
|
||||||
auto [vRes, pos] = findAlongAttrPath(state, attrPath, *cmd.getAutoArgs(state), **v);
|
auto [vRes, pos] = findAlongAttrPath(state, attrPath, *cmd.getAutoArgs(state), **v);
|
||||||
state.forceValue(*vRes);
|
state.forceValue(*vRes, pos);
|
||||||
return {vRes, pos};
|
return {vRes, pos};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,7 +497,7 @@ Value * InstallableFlake::getFlakeOutputs(EvalState & state, const flake::Locked
|
||||||
auto aOutputs = vFlake->attrs->get(state.symbols.create("outputs"));
|
auto aOutputs = vFlake->attrs->get(state.symbols.create("outputs"));
|
||||||
assert(aOutputs);
|
assert(aOutputs);
|
||||||
|
|
||||||
state.forceValue(*aOutputs->value);
|
state.forceValue(*aOutputs->value, aOutputs->value->determinePos(noPos));
|
||||||
|
|
||||||
return aOutputs->value;
|
return aOutputs->value;
|
||||||
}
|
}
|
||||||
|
@ -608,7 +609,7 @@ std::pair<Value *, Pos> InstallableFlake::toValue(EvalState & state)
|
||||||
for (auto & attrPath : getActualAttrPaths()) {
|
for (auto & attrPath : getActualAttrPaths()) {
|
||||||
try {
|
try {
|
||||||
auto [v, pos] = findAlongAttrPath(state, attrPath, *emptyArgs, *vOutputs);
|
auto [v, pos] = findAlongAttrPath(state, attrPath, *emptyArgs, *vOutputs);
|
||||||
state.forceValue(*v);
|
state.forceValue(*v, pos);
|
||||||
return {v, pos};
|
return {v, pos};
|
||||||
} catch (AttrPathNotFound & e) {
|
} catch (AttrPathNotFound & e) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ std::pair<Value *, Pos> findAlongAttrPath(EvalState & state, const string & attr
|
||||||
Value * vNew = state.allocValue();
|
Value * vNew = state.allocValue();
|
||||||
state.autoCallFunction(autoArgs, *v, *vNew);
|
state.autoCallFunction(autoArgs, *v, *vNew);
|
||||||
v = vNew;
|
v = vNew;
|
||||||
state.forceValue(*v);
|
state.forceValue(*v, v->determinePos(vIn.determinePos(noPos)));
|
||||||
|
|
||||||
/* It should evaluate to either a set or an expression,
|
/* It should evaluate to either a set or an expression,
|
||||||
according to what is specified in the attrPath. */
|
according to what is specified in the attrPath. */
|
||||||
|
|
|
@ -381,7 +381,7 @@ Value & AttrCursor::forceValue()
|
||||||
auto & v = getValue();
|
auto & v = getValue();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
root->state.forceValue(v);
|
root->state.forceValue(v, v.determinePos(noPos));
|
||||||
} catch (EvalError &) {
|
} catch (EvalError &) {
|
||||||
debug("setting '%s' to failed", getAttrPathStr());
|
debug("setting '%s' to failed", getAttrPathStr());
|
||||||
if (root->db)
|
if (root->db)
|
||||||
|
|
|
@ -53,7 +53,7 @@ void EvalState::forceValue(Value & v, const Pos & pos)
|
||||||
|
|
||||||
inline void EvalState::forceAttrs(Value & v)
|
inline void EvalState::forceAttrs(Value & v)
|
||||||
{
|
{
|
||||||
forceValue(v);
|
forceValue(v, v.determinePos(noPos));
|
||||||
if (v.type() != nAttrs)
|
if (v.type() != nAttrs)
|
||||||
throwTypeError("value is %1% while a set was expected", v);
|
throwTypeError("value is %1% while a set was expected", v);
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ inline void EvalState::forceAttrs(Value & v, const Pos & pos)
|
||||||
|
|
||||||
inline void EvalState::forceList(Value & v)
|
inline void EvalState::forceList(Value & v)
|
||||||
{
|
{
|
||||||
forceValue(v);
|
forceValue(v, v.determinePos(noPos));
|
||||||
if (!v.isList())
|
if (!v.isList())
|
||||||
throwTypeError("value is %1% while a list was expected", v);
|
throwTypeError("value is %1% while a list was expected", v);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1280,7 +1280,7 @@ void ExprOpHasAttr::eval(EvalState & state, Env & env, Value & v)
|
||||||
e->eval(state, env, vTmp);
|
e->eval(state, env, vTmp);
|
||||||
|
|
||||||
for (auto & i : attrPath) {
|
for (auto & i : attrPath) {
|
||||||
state.forceValue(*vAttrs);
|
state.forceValue(*vAttrs, vAttrs->determinePos(noPos));
|
||||||
Bindings::iterator j;
|
Bindings::iterator j;
|
||||||
Symbol name = getName(i, state, env);
|
Symbol name = getName(i, state, env);
|
||||||
if (vAttrs->type() != nAttrs ||
|
if (vAttrs->type() != nAttrs ||
|
||||||
|
@ -1494,14 +1494,15 @@ void EvalState::incrFunctionCall(ExprLambda * fun)
|
||||||
|
|
||||||
void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res)
|
void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res)
|
||||||
{
|
{
|
||||||
forceValue(fun);
|
Pos pos = fun.determinePos(noPos);
|
||||||
|
forceValue(fun, pos);
|
||||||
|
|
||||||
if (fun.type() == nAttrs) {
|
if (fun.type() == nAttrs) {
|
||||||
auto found = fun.attrs->find(sFunctor);
|
auto found = fun.attrs->find(sFunctor);
|
||||||
if (found != fun.attrs->end()) {
|
if (found != fun.attrs->end()) {
|
||||||
Value * v = allocValue();
|
Value * v = allocValue();
|
||||||
callFunction(*found->value, fun, *v, noPos);
|
callFunction(*found->value, fun, *v, pos);
|
||||||
forceValue(*v);
|
forceValue(*v, pos);
|
||||||
return autoCallFunction(args, *v, res);
|
return autoCallFunction(args, *v, res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1787,7 +1788,7 @@ void EvalState::forceValueDeep(Value & v)
|
||||||
recurse = [&](Value & v) {
|
recurse = [&](Value & v) {
|
||||||
if (!seen.insert(&v).second) return;
|
if (!seen.insert(&v).second) return;
|
||||||
|
|
||||||
forceValue(v);
|
forceValue(v, v.determinePos(noPos));
|
||||||
|
|
||||||
if (v.type() == nAttrs) {
|
if (v.type() == nAttrs) {
|
||||||
for (auto & i : *v.attrs)
|
for (auto & i : *v.attrs)
|
||||||
|
@ -1924,7 +1925,7 @@ bool EvalState::isDerivation(Value & v)
|
||||||
if (v.type() != nAttrs) return false;
|
if (v.type() != nAttrs) return false;
|
||||||
Bindings::iterator i = v.attrs->find(sType);
|
Bindings::iterator i = v.attrs->find(sType);
|
||||||
if (i == v.attrs->end()) return false;
|
if (i == v.attrs->end()) return false;
|
||||||
forceValue(*i->value);
|
forceValue(*i->value, *i->pos);
|
||||||
if (i->value->type() != nString) return false;
|
if (i->value->type() != nString) return false;
|
||||||
return strcmp(i->value->string.s, "derivation") == 0;
|
return strcmp(i->value->string.s, "derivation") == 0;
|
||||||
}
|
}
|
||||||
|
@ -2036,8 +2037,8 @@ Path EvalState::coerceToPath(const Pos & pos, Value & v, PathSet & context)
|
||||||
|
|
||||||
bool EvalState::eqValues(Value & v1, Value & v2)
|
bool EvalState::eqValues(Value & v1, Value & v2)
|
||||||
{
|
{
|
||||||
forceValue(v1);
|
forceValue(v1, v1.determinePos(noPos));
|
||||||
forceValue(v2);
|
forceValue(v2, v2.determinePos(noPos));
|
||||||
|
|
||||||
/* !!! Hack to support some old broken code that relies on pointer
|
/* !!! Hack to support some old broken code that relies on pointer
|
||||||
equality tests between sets. (Specifically, builderDefs calls
|
equality tests between sets. (Specifically, builderDefs calls
|
||||||
|
|
|
@ -221,7 +221,7 @@ public:
|
||||||
of the evaluation of the thunk. If `v' is a delayed function
|
of the evaluation of the thunk. If `v' is a delayed function
|
||||||
application, call the function and overwrite `v' with the
|
application, call the function and overwrite `v' with the
|
||||||
result. Otherwise, this is a no-op. */
|
result. Otherwise, this is a no-op. */
|
||||||
inline void forceValue(Value & v, const Pos & pos = noPos);
|
inline void forceValue(Value & v, const Pos & pos);
|
||||||
|
|
||||||
/* Force a value, then recursively force list elements and
|
/* Force a value, then recursively force list elements and
|
||||||
attributes. */
|
attributes. */
|
||||||
|
|
|
@ -172,7 +172,7 @@ StringSet DrvInfo::queryMetaNames()
|
||||||
|
|
||||||
bool DrvInfo::checkMeta(Value & v)
|
bool DrvInfo::checkMeta(Value & v)
|
||||||
{
|
{
|
||||||
state->forceValue(v);
|
state->forceValue(v, v.determinePos(noPos));
|
||||||
if (v.type() == nList) {
|
if (v.type() == nList) {
|
||||||
for (auto elem : v.listItems())
|
for (auto elem : v.listItems())
|
||||||
if (!checkMeta(*elem)) return false;
|
if (!checkMeta(*elem)) return false;
|
||||||
|
@ -278,7 +278,7 @@ static bool getDerivation(EvalState & state, Value & v,
|
||||||
bool ignoreAssertionFailures)
|
bool ignoreAssertionFailures)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
state.forceValue(v);
|
state.forceValue(v, v.determinePos(noPos));
|
||||||
if (!state.isDerivation(v)) return true;
|
if (!state.isDerivation(v)) return true;
|
||||||
|
|
||||||
/* Remove spurious duplicates (e.g., a set like `rec { x =
|
/* Remove spurious duplicates (e.g., a set like `rec { x =
|
||||||
|
|
|
@ -318,7 +318,7 @@ static void main_nix_build(int argc, char * * argv)
|
||||||
|
|
||||||
for (auto & i : attrPaths) {
|
for (auto & i : attrPaths) {
|
||||||
Value & v(*findAlongAttrPath(*state, i, *autoArgs, vRoot).first);
|
Value & v(*findAlongAttrPath(*state, i, *autoArgs, vRoot).first);
|
||||||
state->forceValue(v);
|
state->forceValue(v, v.determinePos(noPos));
|
||||||
getDerivations(*state, v, "", *autoArgs, drvs, false);
|
getDerivations(*state, v, "", *autoArgs, drvs, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,7 +129,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
|
||||||
|
|
||||||
/* Evaluate it. */
|
/* Evaluate it. */
|
||||||
debug("evaluating user environment builder");
|
debug("evaluating user environment builder");
|
||||||
state.forceValue(topLevel);
|
state.forceValue(topLevel, topLevel.determinePos(noPos));
|
||||||
PathSet context;
|
PathSet context;
|
||||||
Attr & aDrvPath(*topLevel.attrs->find(state.sDrvPath));
|
Attr & aDrvPath(*topLevel.attrs->find(state.sDrvPath));
|
||||||
auto topLevelDrv = state.store->parseStorePath(state.coerceToPath(*aDrvPath.pos, *aDrvPath.value, context));
|
auto topLevelDrv = state.store->parseStorePath(state.coerceToPath(*aDrvPath.pos, *aDrvPath.value, context));
|
||||||
|
|
|
@ -40,7 +40,7 @@ void processExpr(EvalState & state, const Strings & attrPaths,
|
||||||
|
|
||||||
for (auto & i : attrPaths) {
|
for (auto & i : attrPaths) {
|
||||||
Value & v(*findAlongAttrPath(state, i, autoArgs, vRoot).first);
|
Value & v(*findAlongAttrPath(state, i, autoArgs, vRoot).first);
|
||||||
state.forceValue(v);
|
state.forceValue(v, v.determinePos(noPos));
|
||||||
|
|
||||||
PathSet context;
|
PathSet context;
|
||||||
if (evalOnly) {
|
if (evalOnly) {
|
||||||
|
|
|
@ -81,7 +81,7 @@ struct CmdEval : MixJSON, InstallableCommand
|
||||||
|
|
||||||
recurse = [&](Value & v, const Pos & pos, const Path & path)
|
recurse = [&](Value & v, const Pos & pos, const Path & path)
|
||||||
{
|
{
|
||||||
state->forceValue(v);
|
state->forceValue(v, pos);
|
||||||
if (v.type() == nString)
|
if (v.type() == nString)
|
||||||
// FIXME: disallow strings with contexts?
|
// FIXME: disallow strings with contexts?
|
||||||
writeFile(path, v.string.s);
|
writeFile(path, v.string.s);
|
||||||
|
|
|
@ -712,7 +712,7 @@ void NixRepl::evalString(string s, Value & v)
|
||||||
{
|
{
|
||||||
Expr * e = parseString(s);
|
Expr * e = parseString(s);
|
||||||
e->eval(*state, *env, v);
|
e->eval(*state, *env, v);
|
||||||
state->forceValue(v);
|
state->forceValue(v, v.determinePos(noPos));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -742,7 +742,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m
|
||||||
str.flush();
|
str.flush();
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
|
||||||
state->forceValue(v);
|
state->forceValue(v, v.determinePos(noPos));
|
||||||
|
|
||||||
switch (v.type()) {
|
switch (v.type()) {
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue