-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Conditionally mark the test
cfg as a well known cfg
#15007
Open
Urgau
wants to merge
3
commits into
rust-lang:master
Choose a base branch
from
Urgau:check-cfg-target-test
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If user has specified
--lib
, doesn't it mean that they requested to test the lib crate socfg(test)
is expected to be there?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What the command line arguments are shouldn't matter, otherwise users would get a different behavior between a "normal"
cargo test
and one with arguments like--all-targets
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However,
lib.test = false
doesn't mean there is no test. It, as of today, is defined as "test" won't run by default.cfg(test)
is still relevant regardless if a test is in the default test set.Maybe I should put the question this way: Why is
cfg(test)
in atest=false
crate unexpected?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO having
test = false
meaning not tested by default compared to not tests at all is unexpected, at least before reading the documentation I would have assumed that it disabled all the testing.@jplatte made a further argument in his comment:
A similar comment was also put in the URLO thread.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for linking the thread here. Yeah I've read that, and agree that
lib.test = false
largely implies no test in lib crate at all. That is a valid use case and deserves a lint or warning.However, fields under Cargo targets are mostly about including in or excluding from the default crate set, and are largely affected by the command-line argument. If Cargo has started emitting unexpected warning for Cargo targets, it may also bite users that disabling tests for other reasons. For example, I've seen people setting
test=false
because some tests are not expected to run by default for daily development, but only on CI or other special environments.While that kind of scenario I guess is far less than who don't want tests at all, it is still a valid use case aligning with what the current doc describes. Treating
unexpected_cfgs
as an indirect way of banning tests in a crate doesn't seem to be the best venue. It is more like a hack because there is no lint for really banning tests.That being said, I am not surprised if Cargo targets settings don't meet people's expectation. It is always a source of confusions1 😞.
Footnotes
I can actually name a lot of issues here. Let's just have a little peek of them:
* https://github.com/rust-lang/cargo/issues/8338
* https://github.com/rust-lang/cargo/issues/10936
* https://github.com/rust-lang/cargo/issues/10958
* https://github.com/rust-lang/cargo/issues/13668
* https://github.com/rust-lang/cargo/issues/13437
* https://github.com/rust-lang/cargo/issues/13828 ↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current behavior is also unexpected and undesirable to me, I agree with the quote and linked comment. I've been keeping an eye on this series of PRs (thanks, @Urgau!) because I'd like to start using
lib.test = false
for crates that don't have unit tests without risking the silent failure mode mentioned by @jplatte.For tests that shouldn't run by default,
#[ignore]
is a more discoverable and more robust choice. Ignored tests are at least called out as such in libtest output, as long as the test binary containing them is built and run. In contrast,cfg(test)
code that is never compiled or run at all is mostly invisible. Even if you get in the habit ofcargo test --all-targets
, you'll have a similar problem with doctests not being run any more! Examples with#[test]
s have this problem by default, which the documentation highlights as a pitfall to avoid. The unexpected-cfg warning added by this PR also calls attention to cases where this has been missed.If any project intentionally uses
test = false
for crates with unit tests in them, they can still turn off the unexpected-cfg warning by addingcfg(test)
to the allowlist in[lints.rust]
or build script output. So it's not like this change would make it fundamentally harder to usetest = false
for tests not built by default -- it just adds the ability to distinguish that usage from "not intended to contain any tests at all".There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To clarify a bit, the proposed behavior may be worth for
lib.test = false
, as it often implies no unit tests. Fortest.test = false
it’s a bit harder to say. We could diverge the logic for different target kinds, but I think nobody wants another confusions added to Cargo targets 😓.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My argument is that this may deserve an
unexpected_tests
lint. Relying onunexpected_cfgs
only partially resolves the issue because people can still have#[test]
without anycfg(test)
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's a somewhat indirect way of achieving the goal, and it would be nice to also warn on bare
#[test]
not nested under an explicitcfg(test)
. Clippy has a lint for that, but ironically it only fires when you runcargo clippy -- --test
because otherwise these items are stripped out before Clippy can see them. For the same reason, a dedicatedunexpected_tests
lint would also have to warn on any occurrence ofcfg(... test ...)
, including nested inside complexcfg
expressions, just likeunexpected_cfgs
would after this PR. I'd also expect a warning for#[cfg_attr(... test ..., blah)]
in a crate where tests are "unexpected". So I guessunexpected_tests
would be identical tounexpected_cfgs
plus warning on#[test]
?But it also wouldn't be a bad solution to just treat bare
#[test]
as if it came with an impliedcfg(test)
and emit the same diagnostic ifcfg(test)
is unexpected. I don't know if that's implementable without unduly complicatingunexpected_cfgs
and/or#[test]
expansion, but it seems semantically appropriate: it matches how#[test]
is expanded, except for the subtle difference betweenrustc --test
andrustc --cfg test
(that nobody should be relying on). Tailored diagnostics that talk about unit tests in particular can be achieved without an entire new lint. The main thing that's lost is the ability to toggle the lint independently of otherunexpected_cfgs
warnings, but that seems strange whencfg(... test ...)
is part of what the lint would warn about.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
unexpected_cfgs
lint do trigger on#[test]
but only when passed with--test
.We can probably make the lint fire without the
--test
argument.