rust-lang / rust-lang/rust

Doctests should not inherit features

Open
#149,583 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-cfg A-doctests C-discussion T-rustdoc
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Code

Have a crate that

  • has feature(s), like with Cargo.toml:
    ❯ cat Cargo.toml 
     [package]
     name = "macro_def"
     version = "0.1.0"
     edition = "2024"
      
     [dependencies]
      
     [features]
     macro_def_cfg = []
    
  • exports a macro_rules! that (incorrectly, of course) generates code conditional on such feature(s), like
       #[macro_export]
       macro_rules! generate_unknown_cfg {
         () => {
             #[cfg(feature="macro_def_cfg")]
             let _ = {};
          }
       }
    
  • have a doctest in that crate
    • containing #![forbid(unexpected_cfgs)] (or a deny), and
    • invoking that macro
      /// ```
      /// #![forbid(unexpected_cfgs)]
      ///
      /// use macro_def::generate_unknown_cfg;
      ///
      /// let _: () = {
      ///     generate_unknown_cfg!();
      /// };
      /// ```    
      
  • OR, if the doctest itself doesn't define forbid or deny, then have the crate's src/lib.rs contain: #![doc(test(attr(forbid(unexpected_cfgs))))] (or a deny)
```

Reproduction Steps

cargo test

Expected Outcome

---- src/lib.rs - generate_unknown_cfg (line 3) stdout ----
error: unexpected `cfg` condition value: `macro_def_cfg`
 --> src/lib.rs:8:5
  |
8 |     generate_unknown_cfg!();
  |     ^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: no expected values for `feature`

---- YES, expecting NO features to be inherited from the crate

  = note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
  = help: try referring to `generate_unknown_cfg` crate for guidance on how handle this unexpected cfg
  = help: the macro `generate_unknown_cfg` may come from an old version of the `macro_def` crate, try updating your dependency with `cargo update -p macro_def`
  = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
note: the lint level is defined here
 --> src/lib.rs:1:11
  |
1 | #![forbid(unexpected_cfgs)]

Expecting this error, because as https://doc.rust-lang.org/nightly/rustdoc/write-documentation/the-doc-attribute.html#testno_crate_inject clearly implies that doctests are build in a separate crate. PLUS, since doctests can't test non-public functionality, they shouldn't inherit any features at all.

Actual Output

Compiles fine - so it hides the error in the macro.

Version

1.89.0 (and probably also older); 1.91.1; and December 1, 2025 nightly

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the issue from the shown Cargo.toml and src/lib.rs example by running cargo test. Trace how the doctest crate receives feature configuration when it invokes the exported macro, and compare that with the expected unexpected_cfgs diagnostic. Done means the doctest no longer inherits the defining crate's features and reports the expected lint error.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers, testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.