bazelbuild / bazelbuild/rules_rust

rust_doc_test: no way to set environment variables for the test runner (generated script does `exec env -`)

Open
#4,209 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Starlark
Stars
843
Forks
651
Avg merge
2d 18h
Merged PRs (30d)
15

Description

## Problem

`rust_doc_test` is the only test rule in rules_rust that execs a toolchain tool
(`rustdoc`) at **test runtime** rather than build time. The script generated by
`rustdoc_test_writer` begins with:

```bash
exec env - \
CARGO_CRATE_NAME='...' \
... \
'.../process_wrapper' ... '.../bin/rustdoc' ...
```

`env -` clears the entire environment and re-sets only the writer's explicit
list (`CARGO_*`, plus the hardcoded `--action_env` passthroughs: DEVELOPER_DIR,
PATHEXT, SDKROOT, SYSROOT). There is no user-facing way to add to that list:

- `rust_doc_test` has no `env` attribute (checked on 0.70.0 and current `main`).
- Bazel's `--test_env` doesn't help: the variables reach the test action, but
the generated script's own `env -` discards them before rustdoc runs.

## Why this matters: remote execution on NixOS-style images

On RBE worker images where the prebuilt Rust toolchain runs through a loader
shim such as [nix-ld](https://github.com/nix-community/nix-ld) (the FHS ELF
interpreter path is a shim that resolves the real dynamic loader via the
`NIX_LD` env var), every rustdoc invocation from the generated script dies
instantly:

```
[nix-ld] FATAL: panicked at src/main.rs:187:55:
called `Result::unwrap()` on an `Err` value: Posix(2)
```

Build-time rustc/rustdoc actions on the same workers are fine — build actions
can carry the needed variables via `--action_env` / the image environment. The
doc-test runner is the one place where the environment is force-cleared with
no escape hatch, so `rust_doc_test` targets pass locally and hard-fail on RBE.

## Feature request

Support the conventional `env` (and ideally `env_inherit`) attributes on
`rust_doc_test`, merged into the variable list the test writer bakes into the
generated script (i.e. flowing into `_construct_writer_arguments` /
`--action_env`), with `env` subject to the usual location/make-variable
expansion like `rust_test.env`.

That would make this work:

```starlark
rust_doc_test(
name = "mycrate_doc_test",
crate = ":mycrate",
env = {"NIX_LD": "/lib/my-real-ld.so"},
)
```

## Workaround we settled on

Not really a workaround for doc tests in general: we removed the
`rust_doc_test` target and restated the invariant our `compile_fail` doctest
proved (a type must not implement `Clone`) as an in-crate impl-ambiguity
assertion, keeping the doctest as documentation only (run via
`cargo test --doc` outside Bazel). Crates that rely on doc tests for real
example coverage have no equivalent escape.

## Versions

- rules_rust 0.70.0 (bzlmod), also inspected `rust/private/rustdoc_test.bzl`
on `main` — attrs are still `crate`, `crate_features`, `deps`,
`proc_macro_deps`, `rustdoc_flags` + privates; no `env`.
- Bazel 8, remote execution via REAPI, Linux x86_64 workers on a
Nix-built container image using nix-ld for FHS binaries.

Contributor guide

Open the contributing guide

Research direction

Start with rust/private/rustdoc_test.bzl and the rustdoc_test_writer path, then trace _construct_writer_arguments and the existing rust_test env handling. Confirm how the generated script assembles its --action_env variables. Done means rust_doc_test accepts the requested environment attributes, preserves the variables in the runtime environment, and supports the NIX_LD example without weakening the existing environment clearing.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
build-system
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.