diff --git a/doc/manual/rl-next/builtins-warn.md b/doc/manual/rl-next/builtins-warn.md index ec9ffa6c0..b474866d0 100644 --- a/doc/manual/rl-next/builtins-warn.md +++ b/doc/manual/rl-next/builtins-warn.md @@ -9,3 +9,5 @@ Lix now has a builtin function for emitting warnings. Like `builtins.trace`, it takes two arguments: the message to emit, and the expression to return. _Unlike_ `builtins.trace`, `builtins.warn` requires the first argument — the message — to be a string. In the future we may extend `builtins.warn` to accept a more structured API. + +To go along with this, we also have a new config setting [`debugger-on-warn`](@docroot@/command-ref/conf-file.md#conf-debugger-on-warn), which, when used with `--debugger`, makes `builtins.warn` also function like [`builtins.break`](@docroot@/language/builtins.md#builtins-break). diff --git a/lix/libexpr/builtins/warn.md b/lix/libexpr/builtins/warn.md index a54187ffc..544f6b110 100644 --- a/lix/libexpr/builtins/warn.md +++ b/lix/libexpr/builtins/warn.md @@ -4,3 +4,4 @@ args: [msg, e2] --- Evaluate string *msg* and print it on standard error. Then return *e2*. This function is useful for warning about unexpected conditions without aborting evaluation. +If the [`debugger-on-warn`](@docroot@/command-ref/conf-file.md#conf-debugger-on-trace) option is set to `true` and the `--debugger` flag is given, the interactive debugger will be started when `warn` is called (like [`break`](@docroot@/language/builtins.md#builtins-break)). diff --git a/lix/libexpr/meson.build b/lix/libexpr/meson.build index e1a51e940..0e56b9139 100644 --- a/lix/libexpr/meson.build +++ b/lix/libexpr/meson.build @@ -19,6 +19,7 @@ libexpr_setting_definitions = files( 'settings/allow-unsafe-native-code-during-evaluation.md', 'settings/allowed-uris.md', 'settings/debugger-on-trace.md', + 'settings/debugger-on-warn.md', 'settings/eval-cache.md', 'settings/eval-system.md', 'settings/ignore-try.md', diff --git a/lix/libexpr/primops.cc b/lix/libexpr/primops.cc index f4f15fdab..32d65dbd7 100644 --- a/lix/libexpr/primops.cc +++ b/lix/libexpr/primops.cc @@ -779,6 +779,17 @@ static void prim_warn(EvalState & state, Value ** args, Value & v) printTaggedWarning("%s", Uncolored(msg)); + if (evalSettings.debuggerOnWarn) { + if (auto const trace = state.ctx.nextDebugTrace()) { + auto const error = EvalError(ErrorInfo{ + .level = lvlWarn, + .msg = HintFmt("builtins.warn reached"), + }); + + state.ctx.debug->onEvalError(&error, (*trace)->env, (*trace)->expr); + } + } + state.forceValue(*args[1], noPos); v = *args[1]; } diff --git a/lix/libexpr/settings/debugger-on-warn.md b/lix/libexpr/settings/debugger-on-warn.md new file mode 100644 index 000000000..2ee77ca85 --- /dev/null +++ b/lix/libexpr/settings/debugger-on-warn.md @@ -0,0 +1,9 @@ +--- +name: debugger-on-warn +internalName: debuggerOnWarn +type: bool +default: false +--- +If set to true and the `--debugger` flag is given, [`builtins.warn`](@docroot@/language/builtins.md#builtins-warn) will enter the debugger like [`builtins.break`](@docroot@/language/builtins.md#builtins-break). +This is useful for debugging warnings in third-party Nix code. +Use [`debugger-on-trace`](#conf-debugger-on-trace) to also enter the debugger on legacy warnings that are logged with [`builtins.trace`](@docroot@/language/builtins.md#builtins-trace). diff --git a/tests/functional/repl_characterization/data/builtins_warn.test b/tests/functional/repl_characterization/data/builtins_warn.test new file mode 100644 index 000000000..9955983f2 --- /dev/null +++ b/tests/functional/repl_characterization/data/builtins_warn.test @@ -0,0 +1,12 @@ +@args --debugger --option debugger-on-warn true +Enter debugger with debugger-on-warn set. + + nix-repl> let inspect = v: builtins.warn "inspect is deprecated" (throw "this happens after"); in inspect { } + + warning: inspect is deprecated! + warning: builtins.warn reached! + + nix-repl> :c + + { } + error: this happens after diff --git a/tests/functional/repl_characterization/repl_characterization.cc b/tests/functional/repl_characterization/repl_characterization.cc index 67abaf7dc..2ba529b7b 100644 --- a/tests/functional/repl_characterization/repl_characterization.cc +++ b/tests/functional/repl_characterization/repl_characterization.cc @@ -177,6 +177,7 @@ TEST_F(ReplSessionTest, tidy) } REPL_TEST(basic_repl); +REPL_TEST(builtins_warn) REPL_TEST(no_nested_debuggers); REPL_TEST(regression_9917); REPL_TEST(regression_9918);