mirror of
https://github.com/NixOS/nix
synced 2025-06-25 23:11:16 +02:00
Initial frames support
This commit is contained in:
parent
3f9f6ae127
commit
b945b844a9
5 changed files with 63 additions and 13 deletions
|
@ -836,6 +836,37 @@ void EvalState::runDebugRepl(const Error * error, const Env & env, const Expr &
|
|||
evaluator. So here are some helper functions for throwing
|
||||
exceptions. */
|
||||
|
||||
template <typename ErrorType>
|
||||
void EvalState::throwFrameErrorWithTrace(
|
||||
PosIdx pos, const char* format,
|
||||
const std::string_view s1, const std::string_view s2,
|
||||
const Symbol * sym1, const Symbol * sym2,
|
||||
Value * val1, Value * val2,
|
||||
PosIdx pos1,
|
||||
const std::string_view s3,
|
||||
const Suggestions * suggestions,
|
||||
PosIdx tracePos, const std::string_view traceStr,
|
||||
Env * env, Expr * expr)
|
||||
{
|
||||
hintformat f(format);
|
||||
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],
|
||||
.suggestions = suggestions ? *suggestions : Suggestions(),
|
||||
});
|
||||
e.addTrace(positions[tracePos], traceStr, true);
|
||||
debugThrow(e, env, expr);
|
||||
}
|
||||
|
||||
template <typename ErrorType>
|
||||
void EvalState::throwErrorWithTrace(
|
||||
PosIdx pos, const char* format,
|
||||
|
@ -901,9 +932,9 @@ void EvalState::addErrorTrace(Error & e, const char * s, const std::string & s2)
|
|||
e.addTrace(std::nullopt, s, s2);
|
||||
}
|
||||
|
||||
void EvalState::addErrorTrace(Error & e, const PosIdx pos, const char * s, const std::string & s2) const
|
||||
void EvalState::addErrorTrace(Error & e, const PosIdx pos, const char * s, const std::string & s2, bool frame) const
|
||||
{
|
||||
e.addTrace(positions[pos], s, s2);
|
||||
e.addTrace(positions[pos], hintfmt(s, s2), frame);
|
||||
}
|
||||
|
||||
static std::unique_ptr<DebugTraceStacker> makeDebugTraceStacker(
|
||||
|
@ -1164,7 +1195,7 @@ inline bool EvalState::evalBool(Env & env, Expr * e, const PosIdx pos, std::stri
|
|||
Value v;
|
||||
e->eval(*this, env, v);
|
||||
if (v.type() != nBool)
|
||||
throwError<TypeError>(pos, "value is %1% while a Boolean was expected", "", "", 0, 0, &v, 0, noPos, "", 0, &env, e);
|
||||
throwError<TypeError>(noPos, "value is %1% while a Boolean was expected", "", "", 0, 0, &v, 0, noPos, "", 0, &env, e);
|
||||
return v.boolean;
|
||||
} catch (Error & e) {
|
||||
e.addTrace(positions[pos], errorCtx);
|
||||
|
@ -1178,7 +1209,7 @@ inline void EvalState::evalAttrs(Env & env, Expr * e, Value & v, const PosIdx po
|
|||
try {
|
||||
e->eval(*this, env, v);
|
||||
if (v.type() != nAttrs)
|
||||
throwError<TypeError>(pos, "value is %1% while a set was expected", "", "", 0, 0, &v, 0, noPos, "", 0, &env, e);
|
||||
throwError<TypeError>(noPos, "value is %1% while a set was expected", "", "", 0, 0, &v, 0, noPos, "", 0, &env, e);
|
||||
} catch (Error & e) {
|
||||
e.addTrace(positions[pos], errorCtx);
|
||||
throw;
|
||||
|
@ -1502,7 +1533,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
|||
auto j = args[0]->attrs->get(i.name);
|
||||
if (!j) {
|
||||
if (!i.def) {
|
||||
throwErrorWithTrace<TypeError>(lambda.pos,
|
||||
throwFrameErrorWithTrace<TypeError>(lambda.pos,
|
||||
"function '%1%' called without required argument '%2%'",
|
||||
(lambda.name ? std::string(symbols[lambda.name]) : "anonymous lambda"), "",
|
||||
&i.name, 0, 0, 0, noPos, "", 0, pos, "from call site", fun.lambda.env, &lambda);
|
||||
|
@ -1525,7 +1556,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
|||
for (auto & formal : lambda.formals->formals)
|
||||
formalNames.insert(symbols[formal.name]);
|
||||
auto suggestions = Suggestions::bestMatches(formalNames, symbols[i.name]);
|
||||
throwErrorWithTrace<TypeError>(lambda.pos,
|
||||
throwFrameErrorWithTrace<TypeError>(lambda.pos,
|
||||
"function '%1%' called with unexpected argument '%2%'",
|
||||
(lambda.name ? std::string(symbols[lambda.name]) : "anonymous lambda"), "",
|
||||
&i.name, 0, 0, 0, noPos, "", &suggestions, pos, "from call site", fun.lambda.env, &lambda);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue