Skip to content

Commit

Permalink
Revert "Merge pull request NixOS#6204 from layus/coerce-string"
Browse files Browse the repository at this point in the history
This reverts commit a75b7ba, reversing
changes made to 9af16c5.
roberth committed Jan 18, 2023
1 parent 98f57f4 commit 9b33ef3
Showing 31 changed files with 859 additions and 982 deletions.
4 changes: 0 additions & 4 deletions doc/manual/src/release-notes/rl-2.13.md
Original file line number Diff line number Diff line change
@@ -18,10 +18,6 @@
* Instead of "antiquotation", the more common term [string interpolation](../language/string-interpolation.md) is now used consistently.
Historical release notes were not changed.

* Error traces have been reworked to provide detailed explanations and more
accurate error locations. A short excerpt of the trace is now shown by
default when an error occurs.

* Allow explicitly selecting outputs in a store derivation installable, just like we can do with other sorts of installables.
For example,
```shell-session
4 changes: 2 additions & 2 deletions src/libcmd/installables.cc
Original file line number Diff line number Diff line change
@@ -554,7 +554,7 @@ ref<eval_cache::EvalCache> openEvalCache(
auto vFlake = state.allocValue();
flake::callFlake(state, *lockedFlake, *vFlake);

state.forceAttrs(*vFlake, noPos, "while parsing cached flake data");
state.forceAttrs(*vFlake, noPos);

auto aOutputs = vFlake->attrs->get(state.symbols.create("outputs"));
assert(aOutputs);
@@ -618,7 +618,7 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()

else if (v.type() == nString) {
PathSet context;
auto s = state->forceString(v, context, noPos, fmt("while evaluating the flake output attribute '%s'", attrPath));
auto s = state->forceString(v, context, noPos);
auto storePath = state->store->maybeParseStorePath(s);
if (storePath && context.count(std::string(s))) {
return {{
8 changes: 4 additions & 4 deletions src/libcmd/repl.cc
Original file line number Diff line number Diff line change
@@ -397,7 +397,7 @@ StringSet NixRepl::completePrefix(const std::string & prefix)
Expr * e = parseString(expr);
Value v;
e->eval(*state, *env, v);
state->forceAttrs(v, noPos, "nevermind, it is ignored anyway");
state->forceAttrs(v, noPos);

for (auto & i : *v.attrs) {
std::string_view name = state->symbols[i.name];
@@ -590,7 +590,7 @@ bool NixRepl::processLine(std::string line)
const auto [path, line] = [&] () -> std::pair<Path, uint32_t> {
if (v.type() == nPath || v.type() == nString) {
PathSet context;
auto path = state->coerceToPath(noPos, v, context, "while evaluating the filename to edit");
auto path = state->coerceToPath(noPos, v, context);
return {path, 0};
} else if (v.isLambda()) {
auto pos = state->positions[v.lambda.fun->pos];
@@ -839,7 +839,7 @@ void NixRepl::loadFiles()

void NixRepl::addAttrsToScope(Value & attrs)
{
state->forceAttrs(attrs, [&]() { return attrs.determinePos(noPos); }, "while evaluating an attribute set to be merged in the global scope");
state->forceAttrs(attrs, [&]() { return attrs.determinePos(noPos); });
if (displ + attrs.attrs->size() >= envSize)
throw Error("environment full; cannot add more variables");

@@ -944,7 +944,7 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m
Bindings::iterator i = v.attrs->find(state->sDrvPath);
PathSet context;
if (i != v.attrs->end())
str << state->store->printStorePath(state->coerceToStorePath(i->pos, *i->value, context, "while evaluating the drvPath of a derivation"));
str << state->store->printStorePath(state->coerceToStorePath(i->pos, *i->value, context));
else
str << "???";
str << "»";
2 changes: 1 addition & 1 deletion src/libexpr/attr-path.cc
Original file line number Diff line number Diff line change
@@ -118,7 +118,7 @@ std::pair<std::string, uint32_t> findPackageFilename(EvalState & state, Value &

// FIXME: is it possible to extract the Pos object instead of doing this
// toString + parsing?
auto pos = state.forceString(*v2, noPos, "while evaluating the 'meta.position' attribute of a derivation");
auto pos = state.forceString(*v2);

auto colon = pos.rfind(':');
if (colon == std::string::npos)
20 changes: 10 additions & 10 deletions src/libexpr/eval-cache.cc
Original file line number Diff line number Diff line change
@@ -385,7 +385,7 @@ Value & AttrCursor::getValue()
if (!_value) {
if (parent) {
auto & vParent = parent->first->getValue();
root->state.forceAttrs(vParent, noPos, "while searching for an attribute");
root->state.forceAttrs(vParent, noPos);
auto attr = vParent.attrs->get(parent->second);
if (!attr)
throw Error("attribute '%s' is unexpectedly missing", getAttrPathStr());
@@ -571,14 +571,14 @@ std::string AttrCursor::getString()
debug("using cached string attribute '%s'", getAttrPathStr());
return s->first;
} else
root->state.error("'%s' is not a string", getAttrPathStr()).debugThrow<TypeError>();
root->state.debugThrowLastTrace(TypeError("'%s' is not a string", getAttrPathStr()));
}
}

auto & v = forceValue();

if (v.type() != nString && v.type() != nPath)
root->state.error("'%s' is not a string but %s", getAttrPathStr()).debugThrow<TypeError>();
root->state.debugThrowLastTrace(TypeError("'%s' is not a string but %s", getAttrPathStr(), showType(v.type())));

return v.type() == nString ? v.string.s : v.path;
}
@@ -613,7 +613,7 @@ string_t AttrCursor::getStringWithContext()
return *s;
}
} else
root->state.error("'%s' is not a string", getAttrPathStr()).debugThrow<TypeError>();
root->state.debugThrowLastTrace(TypeError("'%s' is not a string", getAttrPathStr()));
}
}

@@ -624,7 +624,7 @@ string_t AttrCursor::getStringWithContext()
else if (v.type() == nPath)
return {v.path, {}};
else
root->state.error("'%s' is not a string but %s", getAttrPathStr()).debugThrow<TypeError>();
root->state.debugThrowLastTrace(TypeError("'%s' is not a string but %s", getAttrPathStr(), showType(v.type())));
}

bool AttrCursor::getBool()
@@ -637,14 +637,14 @@ bool AttrCursor::getBool()
debug("using cached Boolean attribute '%s'", getAttrPathStr());
return *b;
} else
root->state.error("'%s' is not a Boolean", getAttrPathStr()).debugThrow<TypeError>();
root->state.debugThrowLastTrace(TypeError("'%s' is not a Boolean", getAttrPathStr()));
}
}

auto & v = forceValue();

if (v.type() != nBool)
root->state.error("'%s' is not a Boolean", getAttrPathStr()).debugThrow<TypeError>();
root->state.debugThrowLastTrace(TypeError("'%s' is not a Boolean", getAttrPathStr()));

return v.boolean;
}
@@ -696,7 +696,7 @@ std::vector<std::string> AttrCursor::getListOfStrings()
std::vector<std::string> res;

for (auto & elem : v.listItems())
res.push_back(std::string(root->state.forceStringNoCtx(*elem, noPos, "while evaluating an attribute for caching")));
res.push_back(std::string(root->state.forceStringNoCtx(*elem)));

if (root->db)
cachedValue = {root->db->setListOfStrings(getKey(), res), res};
@@ -714,14 +714,14 @@ std::vector<Symbol> AttrCursor::getAttrs()
debug("using cached attrset attribute '%s'", getAttrPathStr());
return *attrs;
} else
root->state.error("'%s' is not an attribute set", getAttrPathStr()).debugThrow<TypeError>();
root->state.debugThrowLastTrace(TypeError("'%s' is not an attribute set", getAttrPathStr()));
}
}

auto & v = forceValue();

if (v.type() != nAttrs)
root->state.error("'%s' is not an attribute set", getAttrPathStr()).debugThrow<TypeError>();
root->state.debugThrowLastTrace(TypeError("'%s' is not an attribute set", getAttrPathStr()));

std::vector<Symbol> attrs;
for (auto & attr : *getValue().attrs)
25 changes: 11 additions & 14 deletions src/libexpr/eval-inline.hh
Original file line number Diff line number Diff line change
@@ -103,36 +103,33 @@ void EvalState::forceValue(Value & v, Callable getPos)
else if (v.isApp())
callFunction(*v.app.left, *v.app.right, v, noPos);
else if (v.isBlackhole())
error("infinite recursion encountered").atPos(getPos()).template debugThrow<EvalError>();
throwEvalError(getPos(), "infinite recursion encountered");
}


[[gnu::always_inline]]
inline void EvalState::forceAttrs(Value & v, const PosIdx pos, std::string_view errorCtx)
inline void EvalState::forceAttrs(Value & v, const PosIdx pos)
{
forceAttrs(v, [&]() { return pos; }, errorCtx);
forceAttrs(v, [&]() { return pos; });
}


template <typename Callable>
[[gnu::always_inline]]
inline void EvalState::forceAttrs(Value & v, Callable getPos, std::string_view errorCtx)
inline void EvalState::forceAttrs(Value & v, Callable getPos)
{
forceValue(v, noPos);
if (v.type() != nAttrs) {
PosIdx pos = getPos();
error("value is %1% while a set was expected", showType(v)).withTrace(pos, errorCtx).debugThrow<TypeError>();
}
forceValue(v, getPos);
if (v.type() != nAttrs)
throwTypeError(getPos(), "value is %1% while a set was expected", v);
}


[[gnu::always_inline]]
inline void EvalState::forceList(Value & v, const PosIdx pos, std::string_view errorCtx)
inline void EvalState::forceList(Value & v, const PosIdx pos)
{
forceValue(v, noPos);
if (!v.isList()) {
error("value is %1% while a list was expected", showType(v)).withTrace(pos, errorCtx).debugThrow<TypeError>();
}
forceValue(v, pos);
if (!v.isList())
throwTypeError(pos, "value is %1% while a list was expected", v);
}


Loading

0 comments on commit 9b33ef3

Please sign in to comment.