Skip to content

We should reject #[test] and cfg(test) in core #163045

Open

Description

@asquared31415

#[test] functions should not go in library/core, because they are not actually run. The crate library/coretests exists for this purpose instead. cfg(test) is similarly suspicious, because core doesn't end up being built under that cfg when running ./x.py test library.

We should have a lint against both of these constructs. It may also be desirable to lint in alloc and std, but there's significant use of the cfg in those crates, so presumably they're doing something.

This was discovered in practice due to the use of #[cfg(test)] in library/core/cell/covariant_unsafe_cell.rs causing CovariantUnsafeCell's variance to not actually be tested.

Activity

  1. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Sep 20, 2026
  2. asquared31415 commented on Sep 20, 2026

    @asquared31415
    Author
  3. added
    T-bootstrapRelevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap)
    on Sep 20, 2026
  4. theemathas commented on Sep 20, 2026

    @theemathas
    Contributor
  5. theemathas commented on Sep 20, 2026

    @theemathas
    Contributor

    #160687 (comment) added the following comment
    cc @bushrat011899

    #[cfg(not(test))] // FIXME: splat interacts poorly with the double linking of `core` in tests
  6. zachs18 commented on Sep 21, 2026

    @zachs18
    Contributor

    Hmm, under bare rustc, rustc --check-cfg 'cfg()' warns on cfg(test), so cargo is passing --check-cfg 'cfg(test)'.

    Ah, cargo had logic to mark test as an (un)expected cfg based on [lib] test = false in Cargo.toml (PR), but it wasn't clear exactly what test = false should mean, so the logic was reverted (PR), so currently test is always treated as expected. See this cargo issue for discussion

  7. added a commit that references this issue on Sep 22, 2026
  8. bushrat011899 commented on Sep 22, 2026

    @bushrat011899
    Contributor

    #160687 (comment) added the following comment cc @bushrat011899

    #[cfg(not(test))] // FIXME: splat interacts poorly with the double linking of core in tests

    Yeah I think this should be looked at in much more detail before rejecting cfg(test)/cfg(not(test)) in core. While it's specific to splat, clearly cfg(not(test)) does do something, even if it's not well understood or intended.

  9. asquared31415 commented on Sep 22, 2026

    @asquared31415
    ContributorAuthor

    I think that as long as the mechanism had a "i know what im doing" button, we could apply the restriction generally. The target audience for this is rustc internals, it can be a little rough. We just want to stop the people that assume "the test infrastructure works normally in core", and having to say the "i know what im doing" incantation would be enough friction IMO.

  10. asquared31415 commented on Sep 22, 2026

    @asquared31415
    ContributorAuthor

    The rustc dev guide says

    This can sometimes cause compilation errors while running tests. These errors can be avoided by using the cfg_attr attribute with the not(test) condition (it’s fine adding then for all rustc_diagnostic_item attributes as a preventive manner).

    During the initial implementation of diagnostic items, this pattern was also used, so this is definitely a known weirdness. Maybe we could have an exception for diagnostic items specifically? There's so few in core though, that I would be fine with case-by-case manual exceptions.

    Other than the diagnostics items though, there's a little bit of f16 and f128 code, and then the splat weirdness. All of these seem strange enough to me that it would be helpful to have a "i know what im doing, and here's why this is needed" (or i don't know why this is broken but it fixes it, put in a FIXME)

  11. asquared31415 commented on Sep 22, 2026

    @asquared31415
    ContributorAuthor

    Also this is all under the assumption that core cannot be built under the normal testing machinery for some reason. If someone figures out "oh we can just tweak a flag and it all works perfectly" then that would be great, and we wouldn't need to reject use of cfg(test).

  12. added a commit that references this issue on Sep 22, 2026
  13. added
    C-discussionCategory: Discussion or questions that doesn't represent real issues.
    on Sep 22, 2026
  14. bjorn3 commented on Sep 22, 2026

    @bjorn3
    Member

    Also this is all under the assumption that core cannot be built under the normal testing machinery for some reason.

    With a bunch of cfg to remove all lang items it technically can be, but we still shouldn't put tests in the same package as any standard library crate. The problem with that setup is that the cargo build for building the standard library and cargo test for testing need to use the exact same flags to prevent standard library crates getting duplicated between regular deps and libtest deps. That is why I also moved all liballoc tests into a separate crate and want to move all other tests out into separate packages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-discussionCategory: Discussion or questions that doesn't represent real issues.T-bootstrapRelevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap)needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions