Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustdoc: add --test-builder-wrapper arg to support wrappers such as RUSTC_WRAPPER when building doctests #114651

Merged
merged 4 commits into from
Mar 15, 2024

Conversation

tmfink
Copy link
Contributor

@tmfink tmfink commented Aug 9, 2023

Currently, rustdoc builds test crates with rustc directly instead of using RUSTC_WRAPPER (if any is set).

This causes build issues in build systems that use cargo but tweak linking flags by setting the RUSTC_WRAPPER environment variable.

This change is not meant to be final--it's only a minimal proof of concept.
Please advise on the best way to proceed.

Open questions:

  • Does supporting the rustc wrappers make sense?
    • yes, cargo-miri for example needs a "hack" to workaround the issue
  • What environment variable(s) should be read for the rustc wrapper? Should rustdoc use the same names as cargo?
    • None, since rustdoc takes arguments
  • What name should be used for a rustdoc CLI option?
    • --test-builder-wrapper
  • Should a separate workspace wrapper (like RUSTC_WORKSPACE_WRAPPER) be supported?
    • --test-builder-wrapper can be passed multiple times to get multiple wrappers passed
  • How/where should this be documented? It's not obvious to all users that cargo doc actually causes rustdoc to compile tests with rust
    • Added doc to src/doc/rustdoc/src/command-line-arguments.md per @GuillaumeGomez

@rustbot
Copy link
Collaborator

rustbot commented Aug 9, 2023

r? @jsha

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Aug 9, 2023
@rust-log-analyzer

This comment has been minimized.

@RalfJung
Copy link
Member

RalfJung commented Aug 9, 2023

To work around this when cargo miri test runs doctests, cargo-miri sets the RUSTDOC variable to itself, and then adjusts the --test-builder and --runtool flags. (--runtool is needed since rustdoc also ignores cargo's target.runner configuration.)

Would be very nice if those hacks were not needed any more. :)

@RalfJung
Copy link
Member

RalfJung commented Aug 9, 2023

What I wonder is... RUSTC_WRAPPER is applied by cargo, not rustc. So shouldn't it be cargo's job to also apply it when invoking rustdoc? cargo could supply appropriate values for --test-builder and --runtool.

@tmfink
Copy link
Contributor Author

tmfink commented Aug 10, 2023

To work around this when cargo miri test runs doctests, cargo-miri sets the RUSTDOC variable to itself, and then adjusts the --test-builder and --runtool flags. (--runtool is needed since rustdoc also ignores cargo's target.runner configuration.)

Would be very nice if those hacks were not needed any more. :)

That's a clever hack, but I don't want to implement it myself 😉

@tmfink
Copy link
Contributor Author

tmfink commented Aug 10, 2023

What I wonder is... RUSTC_WRAPPER is applied by cargo, not rustc. So shouldn't it be cargo's job to also apply it when invoking rustdoc? cargo could supply appropriate values for --test-builder and --runtool.

Yes, cargo actually applies RUSTC_WRAPPER. Of course, we need to add options to rustdoc that cargo can run.

In my next iteration, I'll add the equivalent rustdoc options for:

  • rustc-wrapper
  • runner

(Edited to fix mistakenly typing rustc instead of cargo)

@RalfJung
Copy link
Member

Yes, rustc actually applies RUSTC_WRAPPER.

No it doesn't. If you grep the compiler sources for RUSTC_WRAPPER you won't find any hit.

As I said, it's cargo applying RUSTC_WRAPPER.

I'll add the equivalent rustdoc options for:

rustdoc already has the necessary options: --test-builder and --runtool. Cargo just needs to use them.

I think this PR is on the wrong repo, it should be in https://github.com/rust-lang/cargo/.

@tmfink
Copy link
Contributor Author

tmfink commented Aug 10, 2023

Yes, rustc actually applies RUSTC_WRAPPER.

No it doesn't. If you grep the compiler sources for RUSTC_WRAPPER you won't find any hit.

I accidentally typed rustc instead of cargo--that's why my comment was not self consistent.
I edited my comment comment--be careful when writing responses late at night 😉 .

I'll add the equivalent rustdoc options for:

rustdoc already has the necessary options: --test-builder and --runtool. Cargo just needs to use them.

I think this PR is on the wrong repo, it should be in https://github.com/rust-lang/cargo/.

🤦 I missed this point--it should be easier to just edit cargo.

@tmfink
Copy link
Contributor Author

tmfink commented Aug 13, 2023

Actually, after some more investigation, I don't think a cargo change alone is enough (without some very hacky changes) since the expectations of cargo's RUSTC_WRAPPER and rustdoc's --test-builder are different.

For RUSTC_WRAPPER:

The first argument passed to the wrapper is the path to the actual executable to use

But rustdoc treats the --test-builder option as if it were rustc itself--the actual path to rustc is not passed as the first argument. I think it would be desirable for existing rustc wrappers to "just work"TM without modification, so we can't simply use the existing --test-builder option.

I can think of a few ways to resolve the issue:

  1. Ship an additional program (such as rustdoc-rustc-wrapper-binary ) that understands how find RUSTC_WRAPPER. This binary could be passed to rustdoc's --test-builder. In turn, rustdoc-rustc-wrapper-binary would call RUSTC_WRAPPER with the path to rustc and other arguments.
    • Pretty hacky
    • It would be a big pain to ship an additional binary to support a "feature" that we should have already supported.
  2. Equivalently to the previous option, another existing toolchain program (e.g. cargo) could be taught to act like a rustdoc-style wrapper around the user's RUSTC_WRAPPER. It sounds like this is similar approach cargo-miri currently uses.
    • Pretty hacky. We would need to pass several environment variables (to indicate whether we are acting as a rustdoc-wrapper and the path to rustc).
    • This would have the benefit of not requiring a rustc change.
  3. Add an additional "wrap" arguments to rustdoc. For example, we could call the new option --test-builder-wrapper which would take RUSTC_WRAPPER style wrappers. In fact, this arg could be passed multiple times to support nested wrappers (like cargo supports already with RUSTC_WRAPPER and RUSTC_WORKSPACE_WRAPPER.
    • Seems to be the "proper" solution.

Folks have thoughts on the best way to proceed?

@RalfJung
Copy link
Member

--test-builder-wrapper makes most sense to me (and have cargo set that and/or --test-builder as controlled by env vars -- note that it is totally possible to have both set, in which case the wrapper should be passed the binary given by --test-builder), but this is up to @rust-lang/rustdoc

@Nemo157
Copy link
Member

Nemo157 commented Aug 13, 2023

Another idea could be to have a --test-builder-args that get prepended before rustdoc's generated args, that'd also be helpful for my cargo-rustdoc-clippy script to be able to not have to reinvoke itself and pass args through the environment. A difficulty there is how to encode multiple args, maybe multiple separate --test-builder-arg that each take a single argument to prepend in order 🤔.

@tmfink
Copy link
Contributor Author

tmfink commented Aug 20, 2023

Another idea could be to have a --test-builder-args that get prepended before rustdoc's generated args, that'd also be helpful for my cargo-rustdoc-clippy script to be able to not have to reinvoke itself and pass args through the environment. A difficulty there is how to encode multiple args, maybe multiple separate --test-builder-arg that each take a single argument to prepend in order 🤔.

My opinion is that since we would already support a wrapper, there's no need to support a separate rustdoc argument to pass rustc options. Anything that could be done with something like --test-builder-args could be handled by a wrapper program. Also, there could be cases where you need to modify the rustc arguments in a more complex way, such as appending arguments, modifying arguments, etc. I don't think it makes sense to add all these variants such as:

  • --test-builder-args-prepend
  • --test-builder-args-append

Of course, this is up to the rustdoc maintainers.

@tmfink
Copy link
Contributor Author

tmfink commented Aug 20, 2023

I updated the PR to add the --test-builder-wrapper argument as discussed--it's ready for review.

Is there some documentation that should also be updated?

@rust-log-analyzer

This comment has been minimized.

@RalfJung
Copy link
Member

I filed a bug tracking the cargo side of this at rust-lang/cargo#12532.

@tmfink tmfink changed the title [WIP] rustdoc: respect RUSTC_WRAPPER when building doctests rustdoc: add --test-builder-wrapper arg to support wrappers such as RUSTC_WRAPPER when building doctests Aug 20, 2023
@jsha jsha assigned GuillaumeGomez and unassigned jsha Mar 11, 2024
@GuillaumeGomez
Copy link
Member

Hi, sorry for the delay! The rustdoc team just talked about your PR and approved it. Just one thing missing: documentation about this new command option. You can add it in src/doc/rustdoc/src/command-line-arguments.md. Once done, I'll approve it.

Instead of executing the test builder directly, the test builder wrapper
will be called with test builder as the first argument and subsequent
arguments. This is similar to cargo's RUSTC_WRAPPER argument.

The `--test-builder-wrapper` argument can be passed multiple times to
allow "nesting" of wrappers.
Also reword "test-builder-wrapper" argument help.
This avoids unnecessary allocation with a temporary Vec.
@tmfink
Copy link
Contributor Author

tmfink commented Mar 15, 2024

@GuillaumeGomez I add docs for --test-builder/--test-builder-wrapper with d02e66d

@GuillaumeGomez
Copy link
Member

Thanks! I'll approve it when the CI is green.

@GuillaumeGomez
Copy link
Member

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Mar 15, 2024

📌 Commit d02e66d has been approved by GuillaumeGomez

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 15, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 15, 2024
…llaumeGomez

Rollup of 6 pull requests

Successful merges:

 - rust-lang#114651 (rustdoc: add `--test-builder-wrapper` arg to support wrappers such as RUSTC_WRAPPER when building doctests)
 - rust-lang#122468 (Cleanup `MirBorrowckCtxt::prefixes`)
 - rust-lang#122496 (Greatly reduce GCC build logs)
 - rust-lang#122512 (Cursor.rs documentation fix)
 - rust-lang#122513 (hir: Remove `opt_local_def_id_to_hir_id` and `opt_hir_node_by_def_id`)
 - rust-lang#122530 (less symbol interner locks)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 47be8e8 into rust-lang:master Mar 15, 2024
11 checks passed
@rustbot rustbot added this to the 1.78.0 milestone Mar 15, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Mar 15, 2024
Rollup merge of rust-lang#114651 - tmfink:rustdoc-rustc-wrapper, r=GuillaumeGomez

rustdoc: add `--test-builder-wrapper` arg to support wrappers such as RUSTC_WRAPPER when building doctests

Currently, `rustdoc` builds test crates with `rustc` directly instead of using [`RUSTC_WRAPPER`](https://doc.rust-lang.org/cargo/reference/config.html#buildrustc-wrapper) (if any is set).

This causes build issues in build systems that use `cargo` but tweak linking flags by setting the `RUSTC_WRAPPER` environment variable.

This change is not meant to be final--it's only a minimal proof of concept.
Please advise on the best way to proceed.

Open questions:
- [x] Does supporting the `rustc` wrappers make sense?
    - yes, `cargo-miri` for example needs a "hack" to workaround the issue
- [X] What environment variable(s) should be read for the rustc wrapper? Should `rustdoc` [use the same names as `cargo`](https://doc.rust-lang.org/cargo/reference/config.html#buildrustc-wrapper)?
    - None, since `rustdoc` takes arguments
- [X] What name should be used for a `rustdoc` CLI option?
    - `--test-builder-wrapper`
- [X] Should a separate workspace wrapper (like `RUSTC_WORKSPACE_WRAPPER`) be supported?
    - `--test-builder-wrapper` can be passed multiple times to get multiple wrappers passed
- [X] How/where should this be documented? It's not obvious to all users that `cargo doc` actually causes `rustdoc` to compile tests with rust
    - Added doc to `src/doc/rustdoc/src/command-line-arguments.md` per `@GuillaumeGomez`
wip-sync pushed a commit to NetBSD/pkgsrc-wip that referenced this pull request May 4, 2024
Pkgsrc changes:
 * Adapt checksums and patches, some have beene intregrated upstream.

Upstream chnages:

Version 1.78.0 (2024-05-02)
===========================

Language
--------
- [Stabilize `#[cfg(target_abi = ...)]`]
  (rust-lang/rust#119590)
- [Stabilize the `#[diagnostic]` namespace and
  `#[diagnostic::on_unimplemented]` attribute]
  (rust-lang/rust#119888)
- [Make async-fn-in-trait implementable with concrete signatures]
  (rust-lang/rust#120103)
- [Make matching on NaN a hard error, and remove the rest of
  `illegal_floating_point_literal_pattern`]
  (rust-lang/rust#116284)
- [static mut: allow mutable reference to arbitrary types, not just
  slices and arrays]
  (rust-lang/rust#117614)
- [Extend `invalid_reference_casting` to include references casting
  to bigger memory layout]
  (rust-lang/rust#118983)
- [Add `non_contiguous_range_endpoints` lint for singleton gaps
  after exclusive ranges]
  (rust-lang/rust#118879)
- [Add `wasm_c_abi` lint for use of older wasm-bindgen versions]
  (rust-lang/rust#117918)
  This lint currently only works when using Cargo.
- [Update `indirect_structural_match` and `pointer_structural_match`
  lints to match RFC]
  (rust-lang/rust#120423)
- [Make non-`PartialEq`-typed consts as patterns a hard error]
  (rust-lang/rust#120805)
- [Split `refining_impl_trait` lint into `_reachable`, `_internal` variants]
  (rust-lang/rust#121720)
- [Remove unnecessary type inference when using associated types
  inside of higher ranked `where`-bounds]
  (rust-lang/rust#119849)
- [Weaken eager detection of cyclic types during type inference]
  (rust-lang/rust#119989)
- [`trait Trait: Auto {}`: allow upcasting from `dyn Trait` to `dyn Auto`]
  (rust-lang/rust#119338)

Compiler
--------

- [Made `INVALID_DOC_ATTRIBUTES` lint deny by default]
  (rust-lang/rust#111505)
- [Increase accuracy of redundant `use` checking]
  (rust-lang/rust#117772)
- [Suggest moving definition if non-found macro_rules! is defined later]
  (rust-lang/rust#121130)
- [Lower transmutes from int to pointer type as gep on null]
  (rust-lang/rust#121282)

Target changes:

- [Windows tier 1 targets now require at least Windows 10]
  (rust-lang/rust#115141)
 - [Enable CMPXCHG16B, SSE3, SAHF/LAHF and 128-bit Atomics in tier 1 Windows]
  (rust-lang/rust#120820)
- [Add `wasm32-wasip1` tier 2 (without host tools) target]
  (rust-lang/rust#120468)
- [Add `wasm32-wasip2` tier 3 target]
  (rust-lang/rust#119616)
- [Rename `wasm32-wasi-preview1-threads` to `wasm32-wasip1-threads`]
  (rust-lang/rust#122170)
- [Add `arm64ec-pc-windows-msvc` tier 3 target]
  (rust-lang/rust#119199)
- [Add `armv8r-none-eabihf` tier 3 target for the Cortex-R52]
  (rust-lang/rust#110482)
- [Add `loongarch64-unknown-linux-musl` tier 3 target]
  (rust-lang/rust#121832)

Refer to Rust's [platform support page][platform-support-doc]
for more information on Rust's tiered platform support.

Libraries
---------

- [Bump Unicode to version 15.1.0, regenerate tables]
  (rust-lang/rust#120777)
- [Make align_offset, align_to well-behaved in all cases]
  (rust-lang/rust#121201)
- [PartialEq, PartialOrd: document expectations for transitive chains]
  (rust-lang/rust#115386)
- [Optimize away poison guards when std is built with panic=abort]
  (rust-lang/rust#100603)
- [Replace pthread `RwLock` with custom implementation]
  (rust-lang/rust#110211)
- [Implement unwind safety for Condvar on all platforms]
  (rust-lang/rust#121768)
- [Add ASCII fast-path for `char::is_grapheme_extended`]
  (rust-lang/rust#121138)

Stabilized APIs
---------------

- [`impl Read for &Stdin`]
  (https://doc.rust-lang.org/stable/std/io/struct.Stdin.html#impl-Read-for-%26Stdin)
- [Accept non `'static` lifetimes for several `std::error::Error`
  related implementations] (rust-lang/rust#113833)
- [Make `impl<Fd: AsFd>` impl take `?Sized`]
  (rust-lang/rust#114655)
- [`impl From<TryReserveError> for io::Error`]
  (https://doc.rust-lang.org/stable/std/io/struct.Error.html#impl-From%3CTryReserveError%3E-for-Error)

These APIs are now stable in const contexts:

- [`Barrier::new()`]
  (https://doc.rust-lang.org/stable/std/sync/struct.Barrier.html#method.new)

Cargo
-----

- [Stabilize lockfile v4](rust-lang/cargo#12852)
- [Respect `rust-version` when generating lockfile]
  (rust-lang/cargo#12861)
- [Control `--charset` via auto-detecting config value]
  (rust-lang/cargo#13337)
- [Support `target.<triple>.rustdocflags` officially]
  (rust-lang/cargo#13197)
- [Stabilize global cache data tracking]
  (rust-lang/cargo#13492)

Misc
----

- [rustdoc: add `--test-builder-wrapper` arg to support wrappers
  such as RUSTC_WRAPPER when building doctests]
  (rust-lang/rust#114651)

Compatibility Notes
-------------------

- [Many unsafe precondition checks now run for user code with debug
  assertions enabled] (rust-lang/rust#120594)
  This change helps users catch undefined behavior in their code,
  though the details of how much is checked are generally not
  stable.
- [riscv only supports split_debuginfo=off for now]
  (rust-lang/rust#120518)
- [Consistently check bounds on hidden types of `impl Trait`]
  (rust-lang/rust#121679)
- [Change equality of higher ranked types to not rely on subtyping]
  (rust-lang/rust#118247)
- [When called, additionally check bounds on normalized function return type]
  (rust-lang/rust#118882)
- [Expand coverage for `arithmetic_overflow` lint]
  (rust-lang/rust#119432)

Internal Changes
----------------

These changes do not affect any public interfaces of Rust, but they represent
significant improvements to the performance or internals of rustc and related
tools.

- [Update to LLVM 18](rust-lang/rust#120055)
- [Build `rustc` with 1CGU on `x86_64-pc-windows-msvc`]
  (rust-lang/rust#112267)
- [Build `rustc` with 1CGU on `x86_64-apple-darwin`]
  (rust-lang/rust#112268)
- [Introduce `run-make` V2 infrastructure, a `run_make_support`
  library and port over 2 tests as example]
  (rust-lang/rust#113026)
- [Windows: Implement condvar, mutex and rwlock using futex]
  (rust-lang/rust#121956)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants