diff --git a/lix/libexpr/eval.cc b/lix/libexpr/eval.cc index 83bc533a4..e7be083d5 100644 --- a/lix/libexpr/eval.cc +++ b/lix/libexpr/eval.cc @@ -1205,19 +1205,6 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v) *i.second.chooseByKind(&env2, &env, inheritEnv)); } - auto dts = state.ctx.debug - ? makeDebugTraceStacker( - state, - *this, - env2, - getPos() - ? std::make_shared(state.ctx.positions[getPos()]) - : nullptr, - "while evaluating a '%1%' expression", - "let" - ) - : nullptr; - body->eval(state, env2, v); } @@ -1308,16 +1295,6 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) } try { - auto dts = state.ctx.debug - ? makeDebugTraceStacker( - state, - *this, - env, - state.ctx.positions[getPos()], - "while evaluating the attribute '%1%'", - showAttrPath(state, env, attrPath)) - : nullptr; - for (auto const & [partIdx, currentAttrName] : enumerate(attrPath)) { state.ctx.stats.nrLookups++; @@ -1619,13 +1596,6 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & /* Evaluate the body. */ try { - auto dts = ctx.debug - ? makeDebugTraceStacker( - *this, *lambda.body, env2, ctx.positions[lambda.pos], - "while calling %s", - lambda.getQuotedName(ctx.symbols)) - : nullptr; - lambda.body->eval(*this, env2, vCur); } catch (Error & e) { if (loggerSettings.showTrace.get()) { @@ -1758,18 +1728,6 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value & void ExprCall::eval(EvalState & state, Env & env, Value & v) { - auto dts = state.ctx.debug - ? makeDebugTraceStacker( - state, - *this, - env, - getPos() - ? std::make_shared(state.ctx.positions[getPos()]) - : nullptr, - "while calling a function" - ) - : nullptr; - Value vFun; fun->eval(state, env, vFun); @@ -2116,6 +2074,13 @@ void ExprBlackHole::eval(EvalState & state, Env & env, Value & v) .debugThrow(); } +void ExprDebugFrame::eval(EvalState & state, Env & env, Value & v) +{ + auto dts = + makeDebugTraceStacker(state, *inner, env, state.ctx.positions[pos], message); + inner->eval(state, env, v); +} + // always force this to be separate, otherwise forceValue may inline it and take // a massive perf hit [[gnu::noinline]] diff --git a/lix/libexpr/nixexpr.cc b/lix/libexpr/nixexpr.cc index edd92c4ca..14e30a934 100644 --- a/lix/libexpr/nixexpr.cc +++ b/lix/libexpr/nixexpr.cc @@ -330,6 +330,10 @@ struct VarBinder : ExprVisitor using ExprVisitor::visit; + void visit(ExprDebugFrame & e, std::unique_ptr & ptr) override + { + visit(e.inner); + } void visit(ExprLiteral & e, std::unique_ptr & ptr) override; void visit(ExprVar & e, std::unique_ptr & ptr) override; void visit(ExprInheritFrom & e, std::unique_ptr & ptr) override; @@ -380,13 +384,41 @@ struct DebugVarBinder : VarBinder OVERRIDE(ExprLiteral) OVERRIDE(ExprVar) OVERRIDE(ExprInheritFrom) - OVERRIDE(ExprSelect) + void visit(ExprSelect & e, std::unique_ptr & ptr) override + { + es.debug->exprEnvs.insert(std::make_pair(&e, env)); + VarBinder::visit(e, ptr); + + ptr = std::make_unique(e.pos, std::move(ptr), "while evaluating an attribute"); + } OVERRIDE(ExprOpHasAttr) OVERRIDE(ExprSet) OVERRIDE(ExprList) - OVERRIDE(ExprLambda) - OVERRIDE(ExprCall) - OVERRIDE(ExprLet) + void visit(ExprLambda & e, std::unique_ptr & ptr) override + { + es.debug->exprEnvs.insert(std::make_pair(&e, env)); + VarBinder::visit(e, ptr); + + e.body = std::make_unique( + e.pos, std::move(e.body), HintFmt("while calling %s", e.getQuotedName(es.symbols)).str() + ); + } + void visit(ExprCall & e, std::unique_ptr & ptr) override + { + es.debug->exprEnvs.insert(std::make_pair(&e, env)); + VarBinder::visit(e, ptr); + + ptr = std::make_unique(e.pos, std::move(ptr), "while calling a function"); + } + void visit(ExprLet & e, std::unique_ptr & ptr) override + { + es.debug->exprEnvs.insert(std::make_pair(&e, env)); + VarBinder::visit(e, ptr); + + e.body = std::make_unique( + e.pos, std::move(e.body), HintFmt("while evaluating a '%1%' expression", "let").str() + ); + } OVERRIDE(ExprWith) OVERRIDE(ExprIf) OVERRIDE(ExprAssert) diff --git a/lix/libexpr/nixexpr.hh b/lix/libexpr/nixexpr.hh index 93bb04e90..0adea91bb 100644 --- a/lix/libexpr/nixexpr.hh +++ b/lix/libexpr/nixexpr.hh @@ -41,6 +41,7 @@ JSON printAttrPathToJson(const SymbolTable & symbols, const AttrPath & attrPath) /* Abstract syntax of Nix expressions. */ +struct ExprDebugFrame; struct ExprLiteral; struct ExprString; struct ExprPath; @@ -70,6 +71,7 @@ struct ExprBlackHole; struct ExprVisitor { + virtual void visit(ExprDebugFrame & e, std::unique_ptr & ptr) = 0; virtual void visit(ExprLiteral & e, std::unique_ptr & ptr) = 0; virtual void visit(ExprVar & e, std::unique_ptr & ptr) = 0; virtual void visit(ExprInheritFrom & e, std::unique_ptr & ptr) = 0; @@ -146,6 +148,26 @@ inline void ExprVisitor::visit(std::unique_ptr & ptr) ptr->accept(*this, ptr); } +struct ExprDebugFrame : Expr +{ + std::unique_ptr inner; + std::string message; + + ExprDebugFrame(PosIdx pos, std::unique_ptr inner, std::string message) + : Expr(pos) + , inner(std::move(inner)) + , message(std::move(message)) + { + } + + JSON toJSON(const SymbolTable & symbols) const override + { + return inner->toJSON(symbols); + } + void eval(EvalState & state, Env & env, Value & v) override; + void accept(ExprVisitor & ev, std::unique_ptr & ptr) override { ev.visit(*this, ptr); } +}; + struct ExprLiteral : Expr { protected: