Cleanup error strings rebase
This commit is contained in:
parent
eb460a9529
commit
c7b901fd33
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -127,3 +127,4 @@ nix-rust/target
|
||||||
result
|
result
|
||||||
|
|
||||||
.vscode/
|
.vscode/
|
||||||
|
baseline
|
||||||
|
|
|
@ -571,14 +571,14 @@ std::string AttrCursor::getString()
|
||||||
debug("using cached string attribute '%s'", getAttrPathStr());
|
debug("using cached string attribute '%s'", getAttrPathStr());
|
||||||
return s->first;
|
return s->first;
|
||||||
} else
|
} else
|
||||||
root->state.debugThrowLastTrace(TypeError("'%s' is not a string", getAttrPathStr()));
|
throw EvalError("foo"); //root->state.debugThrowLastTrace(TypeError("'%s' is not a string", getAttrPathStr()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto & v = forceValue();
|
auto & v = forceValue();
|
||||||
|
|
||||||
if (v.type() != nString && v.type() != nPath)
|
if (v.type() != nString && v.type() != nPath)
|
||||||
root->state.debugThrowLastTrace(TypeError("'%s' is not a string but %s", getAttrPathStr(), showType(v.type())));
|
throw EvalError("foo"); //root->state.debugThrowLastTrace(TypeError("'%s' is not a string but %s", getAttrPathStr(), showType(v.type())));
|
||||||
|
|
||||||
return v.type() == nString ? v.string.s : v.path;
|
return v.type() == nString ? v.string.s : v.path;
|
||||||
}
|
}
|
||||||
|
@ -602,7 +602,7 @@ string_t AttrCursor::getStringWithContext()
|
||||||
return *s;
|
return *s;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
root->state.debugThrowLastTrace(TypeError("'%s' is not a string", getAttrPathStr()));
|
throw EvalError("foo"); //root->state.debugThrowLastTrace(TypeError("'%s' is not a string", getAttrPathStr()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,7 +613,7 @@ string_t AttrCursor::getStringWithContext()
|
||||||
else if (v.type() == nPath)
|
else if (v.type() == nPath)
|
||||||
return {v.path, {}};
|
return {v.path, {}};
|
||||||
else
|
else
|
||||||
root->state.debugThrowLastTrace(TypeError("'%s' is not a string but %s", getAttrPathStr(), showType(v.type())));
|
throw EvalError("foo"); //root->state.debugThrowLastTrace(TypeError("'%s' is not a string but %s", getAttrPathStr(), showType(v.type())));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AttrCursor::getBool()
|
bool AttrCursor::getBool()
|
||||||
|
@ -626,14 +626,14 @@ bool AttrCursor::getBool()
|
||||||
debug("using cached Boolean attribute '%s'", getAttrPathStr());
|
debug("using cached Boolean attribute '%s'", getAttrPathStr());
|
||||||
return *b;
|
return *b;
|
||||||
} else
|
} else
|
||||||
root->state.debugThrowLastTrace(TypeError("'%s' is not a Boolean", getAttrPathStr()));
|
throw EvalError("foo"); //root->state.debugThrowLastTrace(TypeError("'%s' is not a Boolean", getAttrPathStr()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto & v = forceValue();
|
auto & v = forceValue();
|
||||||
|
|
||||||
if (v.type() != nBool)
|
if (v.type() != nBool)
|
||||||
root->state.debugThrowLastTrace(TypeError("'%s' is not a Boolean", getAttrPathStr()));
|
throw EvalError("foo"); //root->state.debugThrowLastTrace(TypeError("'%s' is not a Boolean", getAttrPathStr()));
|
||||||
|
|
||||||
return v.boolean;
|
return v.boolean;
|
||||||
}
|
}
|
||||||
|
@ -685,7 +685,7 @@ std::vector<std::string> AttrCursor::getListOfStrings()
|
||||||
std::vector<std::string> res;
|
std::vector<std::string> res;
|
||||||
|
|
||||||
for (auto & elem : v.listItems())
|
for (auto & elem : v.listItems())
|
||||||
res.push_back(std::string(root->state.forceStringNoCtx(*elem)));
|
res.push_back(std::string(root->state.forceStringNoCtx(*elem, noPos, "while evaluating an attribute for caching")));
|
||||||
|
|
||||||
if (root->db)
|
if (root->db)
|
||||||
cachedValue = {root->db->setListOfStrings(getKey(), res), res};
|
cachedValue = {root->db->setListOfStrings(getKey(), res), res};
|
||||||
|
@ -703,14 +703,14 @@ std::vector<Symbol> AttrCursor::getAttrs()
|
||||||
debug("using cached attrset attribute '%s'", getAttrPathStr());
|
debug("using cached attrset attribute '%s'", getAttrPathStr());
|
||||||
return *attrs;
|
return *attrs;
|
||||||
} else
|
} else
|
||||||
root->state.debugThrowLastTrace(TypeError("'%s' is not an attribute set", getAttrPathStr()));
|
throw EvalError("foo"); //root->state.debugThrowLastTrace(TypeError("'%s' is not an attribute set", getAttrPathStr()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto & v = forceValue();
|
auto & v = forceValue();
|
||||||
|
|
||||||
if (v.type() != nAttrs)
|
if (v.type() != nAttrs)
|
||||||
root->state.debugThrowLastTrace(TypeError("'%s' is not an attribute set", getAttrPathStr()));
|
throw EvalError("foo"); //root->state.debugThrowLastTrace(TypeError("'%s' is not an attribute set", getAttrPathStr()));
|
||||||
|
|
||||||
std::vector<Symbol> attrs;
|
std::vector<Symbol> attrs;
|
||||||
for (auto & attr : *getValue().attrs)
|
for (auto & attr : *getValue().attrs)
|
||||||
|
|
|
@ -103,7 +103,7 @@ void EvalState::forceValue(Value & v, Callable getPos)
|
||||||
else if (v.isApp())
|
else if (v.isApp())
|
||||||
callFunction(*v.app.left, *v.app.right, v, noPos);
|
callFunction(*v.app.left, *v.app.right, v, noPos);
|
||||||
else if (v.isBlackhole())
|
else if (v.isBlackhole())
|
||||||
throwEvalError(getPos(), "infinite recursion encountered");
|
throwError<EvalError>(getPos(), "infinite recursion encountered", "", "", 0, 0, 0, 0, noPos, "", 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -118,15 +118,10 @@ template <typename Callable>
|
||||||
[[gnu::always_inline]]
|
[[gnu::always_inline]]
|
||||||
inline void EvalState::forceAttrs(Value & v, Callable getPos, std::string_view errorCtx)
|
inline void EvalState::forceAttrs(Value & v, Callable getPos, std::string_view errorCtx)
|
||||||
{
|
{
|
||||||
try {
|
|
||||||
forceValue(v, noPos);
|
forceValue(v, noPos);
|
||||||
if (v.type() != nAttrs) {
|
if (v.type() != nAttrs) {
|
||||||
throwTypeError(noPos, "value is %1% while a set was expected", v);
|
|
||||||
}
|
|
||||||
} catch (Error & e) {
|
|
||||||
PosIdx pos = getPos();
|
PosIdx pos = getPos();
|
||||||
e.addTrace(positions[pos], errorCtx);
|
this->throwErrorWithTrace<TypeError>(noPos, "value is %1% while a set was expected", "", "", 0, 0, &v, 0, noPos, "", 0, pos, errorCtx, 0, 0);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,14 +129,9 @@ inline void EvalState::forceAttrs(Value & v, Callable getPos, std::string_view e
|
||||||
[[gnu::always_inline]]
|
[[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, std::string_view errorCtx)
|
||||||
{
|
{
|
||||||
try {
|
|
||||||
forceValue(v, noPos);
|
forceValue(v, noPos);
|
||||||
if (!v.isList()) {
|
if (!v.isList()) {
|
||||||
throwTypeError(noPos, "value is %1% while a list was expected", v);
|
this->throwErrorWithTrace<TypeError>(noPos, "value is %1% while a list was expected", "", "", 0, 0, &v, 0, noPos, "", 0, pos, errorCtx, 0, 0);
|
||||||
}
|
|
||||||
} catch (Error & e) {
|
|
||||||
e.addTrace(positions[pos], errorCtx);
|
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -836,327 +836,64 @@ void EvalState::runDebugRepl(const Error * error, const Env & env, const Expr &
|
||||||
evaluator. So here are some helper functions for throwing
|
evaluator. So here are some helper functions for throwing
|
||||||
exceptions. */
|
exceptions. */
|
||||||
|
|
||||||
// *WithTrace
|
template <typename ErrorType>
|
||||||
void EvalState::throwTypeErrorWithTrace(
|
void EvalState::throwErrorWithTrace(
|
||||||
const PosIdx pos,
|
PosIdx pos, const char* format,
|
||||||
const char * s,
|
const std::string_view s1, const std::string_view s2,
|
||||||
const std::string_view s2,
|
const Symbol * sym1, const Symbol * sym2,
|
||||||
const Symbol & sym,
|
Value * val1, Value * val2,
|
||||||
const PosIdx p2,
|
PosIdx pos1,
|
||||||
const std::string_view s3) const
|
const std::string_view s3,
|
||||||
|
const Suggestions * suggestions,
|
||||||
|
PosIdx tracePos, const std::string_view traceStr,
|
||||||
|
Env * env, Expr * expr)
|
||||||
{
|
{
|
||||||
auto e = TypeError(ErrorInfo {
|
hintformat f(format);
|
||||||
.msg = hintfmt(s, s2, symbols[sym]),
|
if (!s1.empty()) { f = f % s1; }
|
||||||
|
if (!s2.empty()) { f = f % s2; }
|
||||||
|
if (sym1) { f = f % symbols[*sym1]; }
|
||||||
|
if (sym2) { f = f % symbols[*sym2]; }
|
||||||
|
if (val1) { f = f % showType(*val1); }
|
||||||
|
if (val2) { f = f % showType(*val2); }
|
||||||
|
if (pos1) { f = f % positions[pos1]; }
|
||||||
|
if (!s3.empty()) { f = f % s3; }
|
||||||
|
|
||||||
|
auto e = ErrorType(ErrorInfo {
|
||||||
|
.msg = f,
|
||||||
.errPos = positions[pos],
|
.errPos = positions[pos],
|
||||||
|
.suggestions = suggestions ? *suggestions : Suggestions(),
|
||||||
});
|
});
|
||||||
e.addTrace(positions[p2], s3);
|
e.addTrace(positions[tracePos], traceStr);
|
||||||
throw e;
|
debugThrow(e, env, expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvalState::throwTypeErrorWithTrace(
|
template <typename ErrorType>
|
||||||
const PosIdx pos,
|
void EvalState::throwError(
|
||||||
const Suggestions & suggestions,
|
PosIdx pos, const char* format,
|
||||||
const char * s,
|
const std::string_view s1, const std::string_view s2,
|
||||||
const std::string_view s2,
|
const Symbol * sym1, const Symbol * sym2,
|
||||||
const Symbol & sym,
|
Value * val1, Value * val2,
|
||||||
const PosIdx p2,
|
PosIdx pos1,
|
||||||
const std::string_view s3) const
|
const std::string_view s3,
|
||||||
|
const Suggestions * suggestions,
|
||||||
|
Env * env, Expr * expr)
|
||||||
{
|
{
|
||||||
auto e = TypeError(ErrorInfo {
|
hintformat f(format);
|
||||||
.msg = hintfmt(s, s2, symbols[sym]),
|
if (!s1.empty()) { f = f % s1; }
|
||||||
|
if (!s2.empty()) { f = f % s2; }
|
||||||
|
if (sym1) { f = f % symbols[*sym1]; }
|
||||||
|
if (sym2) { f = f % symbols[*sym2]; }
|
||||||
|
if (val1) { f = f % showType(*val1); }
|
||||||
|
if (val2) { f = f % showType(*val2); }
|
||||||
|
if (pos1) { f = f % positions[pos1]; }
|
||||||
|
if (!s3.empty()) { f = f % s3; }
|
||||||
|
|
||||||
|
auto e = ErrorType(ErrorInfo {
|
||||||
|
.msg = f,
|
||||||
.errPos = positions[pos],
|
.errPos = positions[pos],
|
||||||
.suggestions = suggestions
|
.suggestions = suggestions ? *suggestions : Suggestions(),
|
||||||
});
|
});
|
||||||
e.addTrace(positions[p2], s3);
|
debugThrow(e, env, expr);
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwTypeErrorWithTrace(const char * s, const std::string_view s2, const PosIdx p2, const std::string_view s3) const
|
|
||||||
{
|
|
||||||
auto e = TypeError(ErrorInfo {
|
|
||||||
.msg = hintfmt(s, s2),
|
|
||||||
});
|
|
||||||
e.addTrace(positions[p2], s3);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwEvalErrorWithTrace(const char * s, const std::string_view s2, const PosIdx p2, const std::string_view s3) const
|
|
||||||
{
|
|
||||||
auto e = EvalError(ErrorInfo {
|
|
||||||
.msg = hintfmt(s, s2),
|
|
||||||
});
|
|
||||||
e.addTrace(positions[p2], s3);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwEvalErrorWithTrace(const char * s, const std::string_view s2, const std::string_view s3, const PosIdx p2, const std::string_view s4) const
|
|
||||||
{
|
|
||||||
auto e = EvalError(ErrorInfo {
|
|
||||||
.msg = hintfmt(s, s2, s3),
|
|
||||||
});
|
|
||||||
e.addTrace(positions[p2], s4);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// *WithoutTrace coerce-strings
|
|
||||||
|
|
||||||
void EvalState::throwEvalError(const PosIdx pos, const char * s, Env & env, Expr & expr)
|
|
||||||
{
|
|
||||||
debugThrow(EvalError({
|
|
||||||
.msg = hintfmt(s),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
}), env, expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s, const std::string_view s2) const
|
|
||||||
{
|
|
||||||
throw EvalError(ErrorInfo {
|
|
||||||
.msg = hintfmt(s, s2),
|
|
||||||
.errPos = positions[pos],
|
|
||||||
.suggestions = suggestions,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwEvalError(const PosIdx pos, const char * s) const
|
|
||||||
{
|
|
||||||
throw EvalError(ErrorInfo {
|
|
||||||
.msg = hintfmt(s),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwEvalError(const PosIdx pos, const char * s, const Value & v) const
|
|
||||||
{
|
|
||||||
throw EvalError(ErrorInfo {
|
|
||||||
.msg = hintfmt(s, showType(v)),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string_view s2) const
|
|
||||||
{
|
|
||||||
throw EvalError(ErrorInfo {
|
|
||||||
.msg = hintfmt(s, s2),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2) const
|
|
||||||
{
|
|
||||||
// p1 is where the error occurred; p2 is a position mentioned in the message.
|
|
||||||
throw EvalError(ErrorInfo {
|
|
||||||
.msg = hintfmt(s, symbols[sym], positions[p2]),
|
|
||||||
.errPos = positions[p1]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwEvalError(const char * s, const std::string_view s1) const
|
|
||||||
{
|
|
||||||
throw EvalError(s, s1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwEvalError(const char * s, const std::string_view s1, const std::string_view s2) const
|
|
||||||
{
|
|
||||||
throw EvalError(s, s1, s2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwTypeError(const char * s, const Value & v) const
|
|
||||||
{
|
|
||||||
throw TypeError(s, showType(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v) const
|
|
||||||
{
|
|
||||||
throw TypeError(ErrorInfo {
|
|
||||||
.msg = hintfmt(s, showType(v)),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwAssertionError(const PosIdx pos, const char * s, const std::string & s1) const
|
|
||||||
{
|
|
||||||
throw AssertionError({
|
|
||||||
.msg = hintfmt(s, s1),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwUndefinedVarError(const PosIdx pos, const char * s, const std::string & s1) const
|
|
||||||
{
|
|
||||||
throw UndefinedVarError({
|
|
||||||
.msg = hintfmt(s, s1),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwMissingArgumentError(const PosIdx pos, const char * s, const std::string & s1) const
|
|
||||||
{
|
|
||||||
throw MissingArgumentError({
|
|
||||||
.msg = hintfmt(s, s1),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// master
|
|
||||||
|
|
||||||
void EvalState::throwEvalError(const PosIdx pos, const char * s, Env & env, Expr & expr)
|
|
||||||
{
|
|
||||||
debugThrow(EvalError({
|
|
||||||
.msg = hintfmt(s),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
}), env, expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwEvalError(const PosIdx pos, const char * s)
|
|
||||||
{
|
|
||||||
debugThrowLastTrace(EvalError({
|
|
||||||
.msg = hintfmt(s),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwEvalError(const char * s, const std::string & s2)
|
|
||||||
{
|
|
||||||
debugThrowLastTrace(EvalError(s, s2));
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s,
|
|
||||||
const std::string & s2, Env & env, Expr & expr)
|
|
||||||
{
|
|
||||||
debugThrow(EvalError(ErrorInfo{
|
|
||||||
.msg = hintfmt(s, s2),
|
|
||||||
.errPos = positions[pos],
|
|
||||||
.suggestions = suggestions,
|
|
||||||
}), env, expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2)
|
|
||||||
{
|
|
||||||
debugThrowLastTrace(EvalError({
|
|
||||||
.msg = hintfmt(s, s2),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2, Env & env, Expr & expr)
|
|
||||||
{
|
|
||||||
debugThrow(EvalError({
|
|
||||||
.msg = hintfmt(s, s2),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
}), env, expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwEvalError(const char * s, const std::string & s2,
|
|
||||||
const std::string & s3)
|
|
||||||
{
|
|
||||||
debugThrowLastTrace(EvalError({
|
|
||||||
.msg = hintfmt(s, s2),
|
|
||||||
.errPos = positions[noPos]
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2,
|
|
||||||
const std::string & s3)
|
|
||||||
{
|
|
||||||
debugThrowLastTrace(EvalError({
|
|
||||||
.msg = hintfmt(s, s2),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwEvalError(const PosIdx pos, const char * s, const std::string & s2,
|
|
||||||
const std::string & s3, Env & env, Expr & expr)
|
|
||||||
{
|
|
||||||
debugThrow(EvalError({
|
|
||||||
.msg = hintfmt(s, s2),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
}), env, expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2, Env & env, Expr & expr)
|
|
||||||
{
|
|
||||||
// p1 is where the error occurred; p2 is a position mentioned in the message.
|
|
||||||
debugThrow(EvalError({
|
|
||||||
.msg = hintfmt(s, symbols[sym], positions[p2]),
|
|
||||||
.errPos = positions[p1]
|
|
||||||
}), env, expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v)
|
|
||||||
{
|
|
||||||
debugThrowLastTrace(TypeError({
|
|
||||||
.msg = hintfmt(s, showType(v)),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwTypeError(const PosIdx pos, const char * s, const Value & v, Env & env, Expr & expr)
|
|
||||||
{
|
|
||||||
debugThrow(TypeError({
|
|
||||||
.msg = hintfmt(s, showType(v)),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
}), env, expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwTypeError(const PosIdx pos, const char * s)
|
|
||||||
{
|
|
||||||
debugThrowLastTrace(TypeError({
|
|
||||||
.msg = hintfmt(s),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwTypeError(const PosIdx pos, const char * s, const ExprLambda & fun,
|
|
||||||
const Symbol s2, Env & env, Expr &expr)
|
|
||||||
{
|
|
||||||
debugThrow(TypeError({
|
|
||||||
.msg = hintfmt(s, fun.showNamePos(*this), symbols[s2]),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
}), env, expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwTypeError(const PosIdx pos, const Suggestions & suggestions, const char * s,
|
|
||||||
const ExprLambda & fun, const Symbol s2, Env & env, Expr &expr)
|
|
||||||
{
|
|
||||||
debugThrow(TypeError(ErrorInfo {
|
|
||||||
.msg = hintfmt(s, fun.showNamePos(*this), symbols[s2]),
|
|
||||||
.errPos = positions[pos],
|
|
||||||
.suggestions = suggestions,
|
|
||||||
}), env, expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwTypeError(const char * s, const Value & v, Env & env, Expr &expr)
|
|
||||||
{
|
|
||||||
debugThrow(TypeError({
|
|
||||||
.msg = hintfmt(s, showType(v)),
|
|
||||||
.errPos = positions[expr.getPos()],
|
|
||||||
}), env, expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwAssertionError(const PosIdx pos, const char * s, const std::string & s1, Env & env, Expr &expr)
|
|
||||||
{
|
|
||||||
debugThrow(AssertionError({
|
|
||||||
.msg = hintfmt(s, s1),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
}), env, expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwUndefinedVarError(const PosIdx pos, const char * s, const std::string & s1, Env & env, Expr &expr)
|
|
||||||
{
|
|
||||||
debugThrow(UndefinedVarError({
|
|
||||||
.msg = hintfmt(s, s1),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
}), env, expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EvalState::throwMissingArgumentError(const PosIdx pos, const char * s, const std::string & s1, Env & env, Expr &expr)
|
|
||||||
{
|
|
||||||
debugThrow(MissingArgumentError({
|
|
||||||
.msg = hintfmt(s, s1),
|
|
||||||
.errPos = positions[pos]
|
|
||||||
}), env, expr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvalState::addErrorTrace(Error & e, const char * s, const std::string & s2) const
|
void EvalState::addErrorTrace(Error & e, const char * s, const std::string & s2) const
|
||||||
|
@ -1253,7 +990,7 @@ inline Value * EvalState::lookupVar(Env * env, const ExprVar & var, bool noEval)
|
||||||
return j->value;
|
return j->value;
|
||||||
}
|
}
|
||||||
if (!env->prevWith)
|
if (!env->prevWith)
|
||||||
throwUndefinedVarError(var.pos, "undefined variable '%1%'", symbols[var.name], *env, const_cast<ExprVar&>(var));
|
throwError<UndefinedVarError>(var.pos, "undefined variable '%1%'", "", "", &var.name, 0, 0, 0, noPos, "", 0, env, const_cast<ExprVar*>(&var));
|
||||||
for (size_t l = env->prevWith; l; --l, env = env->up) ;
|
for (size_t l = env->prevWith; l; --l, env = env->up) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1403,7 +1140,7 @@ void EvalState::cacheFile(
|
||||||
// computation.
|
// computation.
|
||||||
if (mustBeTrivial &&
|
if (mustBeTrivial &&
|
||||||
!(dynamic_cast<ExprAttrs *>(e)))
|
!(dynamic_cast<ExprAttrs *>(e)))
|
||||||
throwEvalError("file '%s' must be an attribute set", path);
|
throwError<EvalError>(noPos, "file '%s' must be an attribute set", path, "", 0, 0, 0, 0, noPos, "", 0, 0, 0);
|
||||||
eval(e, v);
|
eval(e, v);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
addErrorTrace(e, "while evaluating the file '%1%':", resolvedPath);
|
addErrorTrace(e, "while evaluating the file '%1%':", resolvedPath);
|
||||||
|
@ -1427,7 +1164,7 @@ inline bool EvalState::evalBool(Env & env, Expr * e, const PosIdx pos, std::stri
|
||||||
Value v;
|
Value v;
|
||||||
e->eval(*this, env, v);
|
e->eval(*this, env, v);
|
||||||
if (v.type() != nBool)
|
if (v.type() != nBool)
|
||||||
throwTypeError("value is %1% while a Boolean was expected", v);
|
throwError<TypeError>(pos, "value is %1% while a Boolean was expected", "", "", 0, 0, &v, 0, noPos, "", 0, &env, e);
|
||||||
return v.boolean;
|
return v.boolean;
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(positions[pos], errorCtx);
|
e.addTrace(positions[pos], errorCtx);
|
||||||
|
@ -1441,7 +1178,7 @@ inline void EvalState::evalAttrs(Env & env, Expr * e, Value & v, const PosIdx po
|
||||||
try {
|
try {
|
||||||
e->eval(*this, env, v);
|
e->eval(*this, env, v);
|
||||||
if (v.type() != nAttrs)
|
if (v.type() != nAttrs)
|
||||||
throwTypeError("value is %1% while a set was expected", v, env, *e);
|
throwError<TypeError>(pos, "value is %1% while a set was expected", "", "", 0, 0, &v, 0, noPos, "", 0, &env, e);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(positions[pos], errorCtx);
|
e.addTrace(positions[pos], errorCtx);
|
||||||
throw;
|
throw;
|
||||||
|
@ -1550,7 +1287,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||||
auto nameSym = state.symbols.create(nameVal.string.s);
|
auto nameSym = state.symbols.create(nameVal.string.s);
|
||||||
Bindings::iterator j = v.attrs->find(nameSym);
|
Bindings::iterator j = v.attrs->find(nameSym);
|
||||||
if (j != v.attrs->end())
|
if (j != v.attrs->end())
|
||||||
state.throwEvalError(i.pos, "dynamic attribute '%1%' already defined at %2%", nameSym, j->pos, env, *this);
|
state.throwError<EvalError>(i.pos, "dynamic attribute '%1%' already defined at %2%", "", "", &nameSym, 0, 0, 0, j->pos, "", 0, &env, this);
|
||||||
|
|
||||||
i.valueExpr->setName(nameSym);
|
i.valueExpr->setName(nameSym);
|
||||||
/* Keep sorted order so find can catch duplicates */
|
/* Keep sorted order so find can catch duplicates */
|
||||||
|
@ -1652,10 +1389,11 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
||||||
std::set<std::string> allAttrNames;
|
std::set<std::string> allAttrNames;
|
||||||
for (auto & attr : *vAttrs->attrs)
|
for (auto & attr : *vAttrs->attrs)
|
||||||
allAttrNames.insert(state.symbols[attr.name]);
|
allAttrNames.insert(state.symbols[attr.name]);
|
||||||
state.throwEvalError(
|
throw EvalError("foo");
|
||||||
pos,
|
//tmp: state.throwEvalError(
|
||||||
Suggestions::bestMatches(allAttrNames, state.symbols[name]),
|
// pos,
|
||||||
"attribute '%1%' missing", state.symbols[name], env, *this);
|
// Suggestions::bestMatches(allAttrNames, state.symbols[name]),
|
||||||
|
// "attribute '%1%' missing", state.symbols[name], env, *this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vAttrs = j->value;
|
vAttrs = j->value;
|
||||||
|
@ -1750,7 +1488,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||||
try {
|
try {
|
||||||
forceAttrs(*args[0], lambda.pos, "while evaluating the value passed for the lambda argument");
|
forceAttrs(*args[0], lambda.pos, "while evaluating the value passed for the lambda argument");
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(positions[pos], "from call site");
|
if (pos) e.addTrace(positions[pos], "from call site");
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1765,10 +1503,13 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||||
auto j = args[0]->attrs->get(i.name);
|
auto j = args[0]->attrs->get(i.name);
|
||||||
if (!j) {
|
if (!j) {
|
||||||
if (!i.def) {
|
if (!i.def) {
|
||||||
|
throw EvalError("foo");
|
||||||
|
/*
|
||||||
throwTypeErrorWithTrace(lambda.pos,
|
throwTypeErrorWithTrace(lambda.pos,
|
||||||
"function '%1%' called without required argument '%2%'",
|
"function '%1%' called without required argument '%2%'",
|
||||||
(lambda.name ? std::string(symbols[lambda.name]) : "anonymous lambda"),
|
(lambda.name ? std::string(symbols[lambda.name]) : "anonymous lambda"),
|
||||||
i.name, pos, "from call site", *fun.lambda.env, lambda);
|
i.name, pos, "from call site", *fun.lambda.env, lambda);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
env2.values[displ++] = i.def->maybeThunk(*this, env2);
|
env2.values[displ++] = i.def->maybeThunk(*this, env2);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1787,11 +1528,14 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||||
std::set<std::string> formalNames;
|
std::set<std::string> formalNames;
|
||||||
for (auto & formal : lambda.formals->formals)
|
for (auto & formal : lambda.formals->formals)
|
||||||
formalNames.insert(symbols[formal.name]);
|
formalNames.insert(symbols[formal.name]);
|
||||||
|
throw EvalError("foo");
|
||||||
|
/*
|
||||||
throwTypeErrorWithTrace(lambda.pos,
|
throwTypeErrorWithTrace(lambda.pos,
|
||||||
Suggestions::bestMatches(formalNames, symbols[i.name]),
|
Suggestions::bestMatches(formalNames, symbols[i.name]),
|
||||||
"function '%1%' called with unexpected argument '%2%'",
|
"function '%1%' called with unexpected argument '%2%'",
|
||||||
(lambda.name ? std::string(symbols[lambda.name]) : "anonymous lambda"),
|
(lambda.name ? std::string(symbols[lambda.name]) : "anonymous lambda"),
|
||||||
i.name, pos, "from call site");
|
i.name, pos, "from call site");
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
abort(); // can't happen
|
abort(); // can't happen
|
||||||
}
|
}
|
||||||
|
@ -1816,7 +1560,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||||
if (loggerSettings.showTrace.get()) {
|
if (loggerSettings.showTrace.get()) {
|
||||||
addErrorTrace(e, lambda.pos, "while evaluating the '%s' function",
|
addErrorTrace(e, lambda.pos, "while evaluating the '%s' function",
|
||||||
(lambda.name ? std::string(symbols[lambda.name]) : "anonymous lambda"));
|
(lambda.name ? std::string(symbols[lambda.name]) : "anonymous lambda"));
|
||||||
addErrorTrace(e, pos, "from call site%s", "");
|
if (pos) addErrorTrace(e, pos, "from call site%s", "");
|
||||||
}
|
}
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
@ -1841,7 +1585,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||||
if (countCalls) primOpCalls[name]++;
|
if (countCalls) primOpCalls[name]++;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
vCur.primOp->fun(*this, pos, args, vCur);
|
vCur.primOp->fun(*this, noPos, args, vCur);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
addErrorTrace(e, pos, "while calling the '%1%' builtin", name);
|
addErrorTrace(e, pos, "while calling the '%1%' builtin", name);
|
||||||
throw;
|
throw;
|
||||||
|
@ -1885,6 +1629,10 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||||
if (countCalls) primOpCalls[name]++;
|
if (countCalls) primOpCalls[name]++;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// TODO:
|
||||||
|
// 1. Unify this and above code. Heavily redundant.
|
||||||
|
// 2. Create a fake env (arg1, arg2, etc.) and a fake expr (arg1: arg2: etc: builtins.name arg1 arg2 etc)
|
||||||
|
// so the debugger allows to inspect the wrong parameters passed to the builtin.
|
||||||
primOp->primOp->fun(*this, noPos, vArgs, vCur);
|
primOp->primOp->fun(*this, noPos, vArgs, vCur);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
addErrorTrace(e, pos, "while calling the '%1%' builtin", name);
|
addErrorTrace(e, pos, "while calling the '%1%' builtin", name);
|
||||||
|
@ -1913,7 +1661,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
throwTypeError(pos, "attempt to call something which is not a function but %1%", vCur);
|
throwError<TypeError>(pos, "attempt to call something which is not a function but %1%", "", "", 0, 0, &vCur, 0, noPos, "", 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
vRes = vCur;
|
vRes = vCur;
|
||||||
|
@ -1977,13 +1725,12 @@ void EvalState::autoCallFunction(Bindings & args, Value & fun, Value & res)
|
||||||
if (j != args.end()) {
|
if (j != args.end()) {
|
||||||
attrs.insert(*j);
|
attrs.insert(*j);
|
||||||
} else if (!i.def) {
|
} else if (!i.def) {
|
||||||
throwMissingArgumentError(i.pos, R"(cannot evaluate a function that has an argument without a value ('%1%')
|
throwError<MissingArgumentError>(i.pos, R"(cannot evaluate a function that has an argument without a value ('%1%')
|
||||||
|
|
||||||
Nix attempted to evaluate a function as a top level expression; in
|
Nix attempted to evaluate a function as a top level expression; in
|
||||||
this case it must have its arguments supplied either by default
|
this case it must have its arguments supplied either by default
|
||||||
values, or passed explicitly with '--arg' or '--argstr'. See
|
values, or passed explicitly with '--arg' or '--argstr'. See
|
||||||
https://nixos.org/manual/nix/stable/expressions/language-constructs.html#functions.)", symbols[i.name],
|
https://nixos.org/manual/nix/stable/expressions/language-constructs.html#functions.)", "", "", &i.name, 0, 0, 0, noPos, "", 0,
|
||||||
*fun.lambda.env, *fun.lambda.fun);
|
fun.lambda.env, fun.lambda.fun);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2016,7 +1763,7 @@ 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;
|
std::ostringstream out;
|
||||||
cond->show(state.symbols, out);
|
cond->show(state.symbols, out);
|
||||||
state.throwAssertionError(pos, "assertion '%1%' failed", out.str(), env, *this);
|
//tmp: state.throwAssertionError(pos, "assertion '%1%' failed", out.str(), env, *this);
|
||||||
}
|
}
|
||||||
body->eval(state, env, v);
|
body->eval(state, env, v);
|
||||||
}
|
}
|
||||||
|
@ -2193,14 +1940,14 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
||||||
nf = n;
|
nf = n;
|
||||||
nf += vTmp.fpoint;
|
nf += vTmp.fpoint;
|
||||||
} else
|
} else
|
||||||
state.throwEvalError(i_pos, "cannot add %1% to an integer", showType(vTmp), env, *this);
|
state.throwError<EvalError>(i_pos, "cannot add %1% to an integer", "", "", 0, 0, &vTmp, 0, noPos, "", 0, &env, this);
|
||||||
} else if (firstType == nFloat) {
|
} else if (firstType == nFloat) {
|
||||||
if (vTmp.type() == nInt) {
|
if (vTmp.type() == nInt) {
|
||||||
nf += vTmp.integer;
|
nf += vTmp.integer;
|
||||||
} else if (vTmp.type() == nFloat) {
|
} else if (vTmp.type() == nFloat) {
|
||||||
nf += vTmp.fpoint;
|
nf += vTmp.fpoint;
|
||||||
} else
|
} else
|
||||||
state.throwEvalError(i_pos, "cannot add %1% to a float", showType(vTmp), env, *this);
|
state.throwError<EvalError>(i_pos, "cannot add %1% to a float", "", "", 0, 0, &vTmp, 0, noPos, "", 0, &env, this);
|
||||||
} else {
|
} else {
|
||||||
if (s.empty()) s.reserve(es->size());
|
if (s.empty()) s.reserve(es->size());
|
||||||
/* skip canonization of first path, which would only be not
|
/* skip canonization of first path, which would only be not
|
||||||
|
@ -2220,7 +1967,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
||||||
v.mkFloat(nf);
|
v.mkFloat(nf);
|
||||||
else if (firstType == nPath) {
|
else if (firstType == nPath) {
|
||||||
if (!context.empty())
|
if (!context.empty())
|
||||||
state.throwEvalError(pos, "a string that refers to a store path cannot be appended to a path", env, *this);
|
state.throwError<EvalError>(pos, "a string that refers to a store path cannot be appended to a path", "", "", 0, 0, 0, 0, noPos, "", 0, &env, this);
|
||||||
v.mkPath(canonPath(str()));
|
v.mkPath(canonPath(str()));
|
||||||
} else
|
} else
|
||||||
v.mkStringMove(c_str(), context);
|
v.mkStringMove(c_str(), context);
|
||||||
|
@ -2275,7 +2022,7 @@ NixInt EvalState::forceInt(Value & v, const PosIdx pos, std::string_view errorCt
|
||||||
try {
|
try {
|
||||||
forceValue(v, pos);
|
forceValue(v, pos);
|
||||||
if (v.type() != nInt)
|
if (v.type() != nInt)
|
||||||
throwTypeError("value is %1% while an integer was expected", v);
|
throwError<TypeError>(noPos, "value is %1% while an integer was expected", "", "", 0, 0, &v, 0, noPos, "", 0, 0, 0);
|
||||||
return v.integer;
|
return v.integer;
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(positions[pos], errorCtx);
|
e.addTrace(positions[pos], errorCtx);
|
||||||
|
@ -2291,7 +2038,7 @@ NixFloat EvalState::forceFloat(Value & v, const PosIdx pos, std::string_view err
|
||||||
if (v.type() == nInt)
|
if (v.type() == nInt)
|
||||||
return v.integer;
|
return v.integer;
|
||||||
else if (v.type() != nFloat)
|
else if (v.type() != nFloat)
|
||||||
throwTypeError("value is %1% while a float was expected", v);
|
throwError<TypeError>(noPos, "value is %1% while a float was expected", "", "", 0, 0, &v, 0, noPos, "", 0, 0, 0);
|
||||||
return v.fpoint;
|
return v.fpoint;
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(positions[pos], errorCtx);
|
e.addTrace(positions[pos], errorCtx);
|
||||||
|
@ -2305,7 +2052,7 @@ bool EvalState::forceBool(Value & v, const PosIdx pos, std::string_view errorCtx
|
||||||
try {
|
try {
|
||||||
forceValue(v, pos);
|
forceValue(v, pos);
|
||||||
if (v.type() != nBool)
|
if (v.type() != nBool)
|
||||||
throwTypeError("value is %1% while a Boolean was expected", v);
|
throwError<TypeError>(noPos, "value is %1% while a Boolean was expected", "", "", 0, 0, &v, 0, noPos, "", 0, 0, 0);
|
||||||
return v.boolean;
|
return v.boolean;
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(positions[pos], errorCtx);
|
e.addTrace(positions[pos], errorCtx);
|
||||||
|
@ -2325,7 +2072,7 @@ void EvalState::forceFunction(Value & v, const PosIdx pos, std::string_view erro
|
||||||
try {
|
try {
|
||||||
forceValue(v, pos);
|
forceValue(v, pos);
|
||||||
if (v.type() != nFunction && !isFunctor(v))
|
if (v.type() != nFunction && !isFunctor(v))
|
||||||
throwTypeError("value is %1% while a function was expected", v);
|
throwError<TypeError>(noPos, "value is %1% while a function was expected", "", "", 0, 0, &v, 0, noPos, "", 0, 0, 0);
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(positions[pos], errorCtx);
|
e.addTrace(positions[pos], errorCtx);
|
||||||
throw;
|
throw;
|
||||||
|
@ -2338,7 +2085,7 @@ std::string_view EvalState::forceString(Value & v, const PosIdx pos, std::string
|
||||||
try {
|
try {
|
||||||
forceValue(v, pos);
|
forceValue(v, pos);
|
||||||
if (v.type() != nString)
|
if (v.type() != nString)
|
||||||
throwTypeError("value is %1% while a string was expected", v);
|
throwError<TypeError>(noPos, "value is %1% while a string was expected", "", "", 0, 0, &v, 0, noPos, "", 0, 0, 0);
|
||||||
return v.string.s;
|
return v.string.s;
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace(positions[pos], errorCtx);
|
e.addTrace(positions[pos], errorCtx);
|
||||||
|
@ -2401,9 +2148,9 @@ std::string_view EvalState::forceStringNoCtx(Value & v, const PosIdx pos, std::s
|
||||||
auto s = forceString(v, pos, errorCtx);
|
auto s = forceString(v, pos, errorCtx);
|
||||||
if (v.string.context) {
|
if (v.string.context) {
|
||||||
if (pos)
|
if (pos)
|
||||||
throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')", v.string.s, v.string.context[0]);
|
throwError<EvalError>(noPos, "the string '%1%' is not allowed to refer to a store path (such as '%2%')", v.string.s, v.string.context[0], 0, 0, 0, 0, noPos, "", 0, 0, 0);
|
||||||
else
|
else
|
||||||
throwEvalError("the string '%1%' is not allowed to refer to a store path (such as '%2%')", v.string.s, v.string.context[0]);
|
throwError<EvalError>(noPos, "the string '%1%' is not allowed to refer to a store path (such as '%2%')", v.string.s, v.string.context[0], 0, 0, 0, 0, noPos, "", 0, 0, 0);
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
|
@ -2463,7 +2210,7 @@ BackedStringView EvalState::coerceToString(const PosIdx pos, Value & v, PathSet
|
||||||
return std::move(*maybeString);
|
return std::move(*maybeString);
|
||||||
auto i = v.attrs->find(sOutPath);
|
auto i = v.attrs->find(sOutPath);
|
||||||
if (i == v.attrs->end())
|
if (i == v.attrs->end())
|
||||||
throwTypeErrorWithTrace("cannot coerce a set to a string", pos, errorCtx);
|
throwErrorWithTrace<TypeError>(noPos, "cannot coerce a set to a string", "", "", 0, 0, &v, 0, noPos, "", 0, pos, errorCtx, 0, 0);
|
||||||
return coerceToString(pos, *i->value, context, coerceMore, copyToStore, canonicalizePath, errorCtx);
|
return coerceToString(pos, *i->value, context, coerceMore, copyToStore, canonicalizePath, errorCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2498,14 +2245,14 @@ BackedStringView EvalState::coerceToString(const PosIdx pos, Value & v, PathSet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throwTypeErrorWithTrace("cannot coerce %1% to a string", showType(v), pos, errorCtx);
|
throwErrorWithTrace<TypeError>(noPos, "cannot coerce %1% to a string", "", "", 0, 0, &v, 0, noPos, "", 0, pos, errorCtx, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string EvalState::copyPathToStore(PathSet & context, const Path & path)
|
std::string EvalState::copyPathToStore(PathSet & context, const Path & path)
|
||||||
{
|
{
|
||||||
if (nix::isDerivation(path))
|
if (nix::isDerivation(path))
|
||||||
throwEvalError("file names are not allowed to end in '%1%'", drvExtension);
|
throwError<EvalError>(noPos, "file names are not allowed to end in '%1%'", drvExtension, "", 0, 0, 0, 0, noPos, "", 0, 0, 0);
|
||||||
|
|
||||||
Path dstPath;
|
Path dstPath;
|
||||||
auto i = srcToStore.find(path);
|
auto i = srcToStore.find(path);
|
||||||
|
@ -2530,7 +2277,7 @@ Path EvalState::coerceToPath(const PosIdx pos, Value & v, PathSet & context, std
|
||||||
{
|
{
|
||||||
auto path = coerceToString(pos, v, context, false, false, true, errorCtx).toOwned();
|
auto path = coerceToString(pos, v, context, false, false, true, errorCtx).toOwned();
|
||||||
if (path == "" || path[0] != '/')
|
if (path == "" || path[0] != '/')
|
||||||
throwEvalErrorWithTrace("string '%1%' doesn't represent an absolute path", path, pos, errorCtx);
|
throwErrorWithTrace<EvalError>(noPos, "string '%1%' doesn't represent an absolute path", path, "", 0, 0, 0, 0, noPos, "", 0, pos, errorCtx, 0, 0);
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2540,7 +2287,7 @@ StorePath EvalState::coerceToStorePath(const PosIdx pos, Value & v, PathSet & co
|
||||||
auto path = coerceToString(pos, v, context, false, false, true, errorCtx).toOwned();
|
auto path = coerceToString(pos, v, context, false, false, true, errorCtx).toOwned();
|
||||||
if (auto storePath = store->maybeParseStorePath(path))
|
if (auto storePath = store->maybeParseStorePath(path))
|
||||||
return *storePath;
|
return *storePath;
|
||||||
throwEvalErrorWithTrace("path '%1%' is not in the Nix store", path, pos, errorCtx);
|
throwErrorWithTrace<EvalError>(noPos, "path '%1%' is not in the Nix store", path, "", 0, 0, 0, 0, noPos, "", 0, pos, errorCtx, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2564,7 +2311,6 @@ bool EvalState::eqValues(Value & v1, Value & v2, const PosIdx pos, std::string_v
|
||||||
if (v1.type() != v2.type()) return false;
|
if (v1.type() != v2.type()) return false;
|
||||||
|
|
||||||
switch (v1.type()) {
|
switch (v1.type()) {
|
||||||
|
|
||||||
case nInt:
|
case nInt:
|
||||||
return v1.integer == v2.integer;
|
return v1.integer == v2.integer;
|
||||||
|
|
||||||
|
@ -2618,7 +2364,7 @@ bool EvalState::eqValues(Value & v1, Value & v2, const PosIdx pos, std::string_v
|
||||||
return v1.fpoint == v2.fpoint;
|
return v1.fpoint == v2.fpoint;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throwEvalErrorWithTrace("cannot compare %1% with %2%", showType(v1), showType(v2), pos, errorCtx);
|
throwErrorWithTrace<EvalError>(noPos, "cannot compare %1% with %2%", "", "", 0, 0, &v1, &v2, noPos, "", 0, pos, errorCtx, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -146,30 +146,27 @@ public:
|
||||||
|
|
||||||
template<class E>
|
template<class E>
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
void debugThrow(E && error, const Env & env, const Expr & expr)
|
void debugThrowLastTrace(E && error)
|
||||||
{
|
{
|
||||||
if (debugRepl)
|
debugThrow(error, nullptr, nullptr);
|
||||||
runDebugRepl(&error, env, expr);
|
|
||||||
|
|
||||||
throw std::move(error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class E>
|
template<class E>
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
void debugThrowLastTrace(E && e)
|
void debugThrow(E && error, const Env * env, const Expr * expr)
|
||||||
{
|
{
|
||||||
// Call this in the situation where Expr and Env are inaccessible.
|
if (debugRepl && ((env && expr) || !debugTraces.empty())) {
|
||||||
// The debugger will start in the last context that's in the
|
if (!env || !expr) {
|
||||||
// DebugTrace stack.
|
|
||||||
if (debugRepl && !debugTraces.empty()) {
|
|
||||||
const DebugTrace & last = debugTraces.front();
|
const DebugTrace & last = debugTraces.front();
|
||||||
runDebugRepl(&e, last.env, last.expr);
|
env = &last.env;
|
||||||
|
expr = &last.expr;
|
||||||
|
}
|
||||||
|
runDebugRepl(&error, *env, *expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw std::move(e);
|
throw std::move(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SrcToStore srcToStore;
|
SrcToStore srcToStore;
|
||||||
|
|
||||||
|
@ -315,118 +312,30 @@ public:
|
||||||
std::string_view forceString(Value & v, PathSet & context, const PosIdx pos, std::string_view errorCtx);
|
std::string_view forceString(Value & v, PathSet & context, const PosIdx pos, std::string_view errorCtx);
|
||||||
std::string_view forceStringNoCtx(Value & v, const PosIdx pos, std::string_view errorCtx);
|
std::string_view forceStringNoCtx(Value & v, const PosIdx pos, std::string_view errorCtx);
|
||||||
|
|
||||||
// coerce-strings
|
template <typename ErrorType>
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
void throwEvalError(const PosIdx pos, const char * s) const;
|
void throwErrorWithTrace(
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
PosIdx pos, const char* format,
|
||||||
void throwEvalError(const PosIdx pos, const char * s, const Value & v) const;
|
const std::string_view s1, const std::string_view s2,
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
const Symbol * sym1, const Symbol * sym2,
|
||||||
void throwEvalError(const char * s, const std::string_view s2) const;
|
Value * val1, Value * val2,
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
PosIdx pos1,
|
||||||
void throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s, const std::string_view s2) const;
|
const std::string_view s3,
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
const Suggestions * suggestions,
|
||||||
void throwEvalError(const PosIdx pos, const char * s, const std::string_view s2) const;
|
PosIdx tracePos, const std::string_view traceStr,
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
Env * env, Expr * expr);
|
||||||
void throwEvalError(const char * s, const std::string_view s2, const std::string_view s3) const;
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwEvalError(const PosIdx pos, const char * s, const std::string & s2, const std::string & s3) const;
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2) const;
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwEvalError(const char * s, const Value & v) const;
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwTypeError(const PosIdx pos, const char * s) const;
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwTypeError(const PosIdx pos, const char * s, const Value & v) const;
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwTypeError(const PosIdx pos, const char * s, const ExprLambda & fun, const Symbol s2) const;
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwTypeError(const PosIdx pos, const Suggestions & suggestions, const char * s, const ExprLambda & fun, const Symbol s2) const;
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwTypeError(const char * s, const Value & v) const;
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwTypeErrorWithTrace(const PosIdx, const char*, std::string_view, const nix::Symbol&, const PosIdx, std::string_view) const;
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwTypeErrorWithTrace(const PosIdx, const nix::Suggestions&, const char*, std::string_view, const nix::Symbol&, const PosIdx, std::string_view) const;
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwTypeErrorWithTrace(const char*, std::string_view, const Pos &, std::string_view) const;
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwTypeErrorWithTrace(const char*, std::string_view, const PosIdx, std::string_view) const;
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwEvalErrorWithTrace(const char*, std::string_view, const PosIdx, std::string_view) const;
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwEvalErrorWithTrace(const char*, std::string_view, std::string_view, nix::PosIdx, std::string_view) const;
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwAssertionError(const PosIdx pos, const char * s, const std::string & s1) const;
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwUndefinedVarError(const PosIdx pos, const char * s, const std::string & s1) const;
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwMissingArgumentError(const PosIdx pos, const char * s, const std::string & s1) const;
|
|
||||||
|
|
||||||
// origin/master
|
template <typename ErrorType>
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
[[gnu::noinline, gnu::noreturn]]
|
||||||
void throwEvalError(const PosIdx pos, const char * s);
|
void throwError(
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
PosIdx pos, const char* format,
|
||||||
void throwEvalError(const PosIdx pos, const char * s,
|
const std::string_view s1, const std::string_view s2,
|
||||||
Env & env, Expr & expr);
|
const Symbol * sym1, const Symbol * sym2,
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
Value * val1, Value * val2,
|
||||||
void throwEvalError(const char * s, const std::string & s2);
|
PosIdx pos1,
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
const std::string_view s3,
|
||||||
void throwEvalError(const PosIdx pos, const char * s, const std::string & s2);
|
const Suggestions * suggestions,
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
Env * env, Expr * expr);
|
||||||
void throwEvalError(const char * s, const std::string & s2,
|
|
||||||
Env & env, Expr & expr);
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwEvalError(const PosIdx pos, const char * s, const std::string & s2,
|
|
||||||
Env & env, Expr & expr);
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwEvalError(const char * s, const std::string & s2, const std::string & s3,
|
|
||||||
Env & env, Expr & expr);
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwEvalError(const PosIdx pos, const char * s, const std::string & s2, const std::string & s3,
|
|
||||||
Env & env, Expr & expr);
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwEvalError(const PosIdx pos, const char * s, const std::string & s2, const std::string & s3);
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwEvalError(const char * s, const std::string & s2, const std::string & s3);
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s, const std::string & s2,
|
|
||||||
Env & env, Expr & expr);
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2,
|
|
||||||
Env & env, Expr & expr);
|
|
||||||
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwTypeError(const PosIdx pos, const char * s, const Value & v);
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwTypeError(const PosIdx pos, const char * s, const Value & v,
|
|
||||||
Env & env, Expr & expr);
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwTypeError(const PosIdx pos, const char * s);
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwTypeError(const PosIdx pos, const char * s,
|
|
||||||
Env & env, Expr & expr);
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwTypeError(const PosIdx pos, const char * s, const ExprLambda & fun, const Symbol s2,
|
|
||||||
Env & env, Expr & expr);
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwTypeError(const PosIdx pos, const Suggestions & suggestions, const char * s, const ExprLambda & fun, const Symbol s2,
|
|
||||||
Env & env, Expr & expr);
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwTypeError(const char * s, const Value & v,
|
|
||||||
Env & env, Expr & expr);
|
|
||||||
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwAssertionError(const PosIdx pos, const char * s, const std::string & s1,
|
|
||||||
Env & env, Expr & expr);
|
|
||||||
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwUndefinedVarError(const PosIdx pos, const char * s, const std::string & s1,
|
|
||||||
Env & env, Expr & expr);
|
|
||||||
|
|
||||||
[[gnu::noinline, gnu::noreturn]]
|
|
||||||
void throwMissingArgumentError(const PosIdx pos, const char * s, const std::string & s1,
|
|
||||||
Env & env, Expr & expr);
|
|
||||||
|
|
||||||
[[gnu::noinline]]
|
[[gnu::noinline]]
|
||||||
void addErrorTrace(Error & e, const char * s, const std::string & s2) const;
|
void addErrorTrace(Error & e, const char * s, const std::string & s2) const;
|
||||||
|
|
|
@ -137,7 +137,7 @@ DrvInfo::Outputs DrvInfo::queryOutputs(bool withPaths, bool onlyOutputsToInstall
|
||||||
return outputs;
|
return outputs;
|
||||||
|
|
||||||
Bindings::iterator i;
|
Bindings::iterator i;
|
||||||
if (attrs && (i = attrs->find(state->sOutputSpecified)) != attrs->end() && state->forceBool(*i->value, i->pos)) {
|
if (attrs && (i = attrs->find(state->sOutputSpecified)) != attrs->end() && state->forceBool(*i->value, i->pos, "while evaluating the 'outputSpecified' attribute of a derivation")) {
|
||||||
Outputs result;
|
Outputs result;
|
||||||
auto out = outputs.find(queryOutputName());
|
auto out = outputs.find(queryOutputName());
|
||||||
if (out == outputs.end())
|
if (out == outputs.end())
|
||||||
|
|
|
@ -396,7 +396,7 @@ expr_function
|
||||||
;
|
;
|
||||||
|
|
||||||
expr_if
|
expr_if
|
||||||
: IF expr THEN expr ELSE expr { $$ = new ExprIf(CUR_POS, $2, $4, $6); }
|
: IF expr THEN expr ELSE expr { $$ = new ExprIf(makeCurPos(@2, data), $2, $4, $6); }
|
||||||
| expr_op
|
| expr_op
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -788,13 +788,13 @@ Path EvalState::findFile(SearchPath & searchPath, const std::string_view path, c
|
||||||
if (hasPrefix(path, "nix/"))
|
if (hasPrefix(path, "nix/"))
|
||||||
return concatStrings(corepkgsPrefix, path.substr(4));
|
return concatStrings(corepkgsPrefix, path.substr(4));
|
||||||
|
|
||||||
debugThrowLastTrace(ThrownError({
|
debugThrow(ThrownError({
|
||||||
.msg = hintfmt(evalSettings.pureEval
|
.msg = hintfmt(evalSettings.pureEval
|
||||||
? "cannot look up '<%s>' in pure evaluation mode (use '--impure' to override)"
|
? "cannot look up '<%s>' in pure evaluation mode (use '--impure' to override)"
|
||||||
: "file '%s' was not found in the Nix search path (add it using $NIX_PATH or -I)",
|
: "file '%s' was not found in the Nix search path (add it using $NIX_PATH or -I)",
|
||||||
path),
|
path),
|
||||||
.errPos = positions[pos]
|
.errPos = positions[pos]
|
||||||
}));
|
}), 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -561,7 +561,7 @@ struct CompareValues
|
||||||
return v1->integer < v2->fpoint;
|
return v1->integer < v2->fpoint;
|
||||||
if (v1->type() != v2->type())
|
if (v1->type() != v2->type())
|
||||||
state.debugThrowLastTrace(EvalError({
|
state.debugThrowLastTrace(EvalError({
|
||||||
."cannot compare %1% with %2%", showType(*v1), showType(*v2)));
|
.msg = hintfmt("%scannot compare %s with %s", errorCtx, showType(*v1), showType(*v2)),
|
||||||
.errPos = std::nullopt,
|
.errPos = std::nullopt,
|
||||||
}));
|
}));
|
||||||
switch (v1->type()) {
|
switch (v1->type()) {
|
||||||
|
@ -586,7 +586,7 @@ struct CompareValues
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
state.debugThrowLastTrace(EvalError({
|
state.debugThrowLastTrace(EvalError({
|
||||||
.msg = hintfmt("%scannot compare %s with %s", errorCtx, showType(*v1), showType(*v2)),
|
.msg = hintfmt("%scannot compare %s with %s: nix does not define an ordering for that type", errorCtx, showType(*v1), showType(*v2)),
|
||||||
.errPos = std::nullopt,
|
.errPos = std::nullopt,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -623,7 +623,6 @@ static Bindings::iterator getAttr(
|
||||||
//e.addTrace(state.positions[pos], hintfmt("while invoking '%s'", funcName));
|
//e.addTrace(state.positions[pos], hintfmt("while invoking '%s'", funcName));
|
||||||
//state.debugThrowLastTrace(e);
|
//state.debugThrowLastTrace(e);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue