extendr / extendr/rextendr

Cargo warnings on successful builds are silently dropped in rust_source() when echo = FALSE

Open
#511 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
R
Stars
263
Forks
35
Avg merge
8d 9h
Merged PRs (30d)
2

Description

## Summary

In the dynamic-compilation path (`rust_source()`, `rust_function()`, `rust_eval()`, and the `eng_extendr` / `eng_extendrsrc` knitr engines), `cargo` warnings emitted on a successful build are not surfaced to the user when `echo = FALSE` (the default).

## Where it happens

`R/source.R` invokes `cargo build --lib` with `--message-format=json-diagnostic-rendered-ansi` (source.R:354) and then runs it via `run_cargo()`:

```r
rlang::try_fetch(
run_cargo(args, echo = echo, wd = NULL),
error = function(cnd) {
cli::cli_abort(
"Rust code could not be compiled successfully. Aborting.",
parent = cnd,
class = "rextendr_error"
)
}
)
```

`run_cargo()` (`R/run_cargo.R`) only parses stdout when called with `parse_json = TRUE`; in the `rust_source` call site `parse_json` is left at its default `FALSE`. As a result:

- When `echo = TRUE`, cargo's rendered diagnostics stream to the terminal as usual.
- When `echo = FALSE` (default) **and** the build succeeds, the JSON diagnostics sit in `out$stdout` and are never re-emitted. Warnings (unused variables, deprecation notices, dead code, etc.) are invisible to the user.
- On failure, the chained `parent = cnd` carries `processx`'s captured stderr into the cli abort, so errors do surface — this issue is specifically about *success-with-warnings*.

## Proposed fix

Parse the JSON stdout from the successful `run_cargo()` invocation, filter for `reason == "compiler-message"` && `message.level == "warning"`, and emit each rendered message via `cli::cli_warn()` (or print directly when `quiet = FALSE`). ANSI handling should mirror `tty_has_colors()`, matching what's already done in the error path of older versions.

This keeps the default `echo = FALSE` quiet for routine cargo chatter (Compiling/Finished lines on stderr) while still showing the diagnostics users actually need to act on.

## Scope

Applies to anything that funnels through `rust_source()` — i.e. `rust_function()`, `rust_eval()` / `rust_eval_deferred()`, and both knitr engines in `R/knitr_engine.R`. The package-build path (Makevars + `cargo build --lib` + `cargo run --bin document`) is unaffected because compilation output is streamed live by `R CMD INSTALL`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.