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

Add new invalid_build_cfg lint #12862

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

GuillaumeGomez
Copy link
Member

Fixes #9419.

A few questions here though: I saw that the PRINT_STDOUT/PRINT_STDERR lints were only supposed to run on build.rs files (like this lint) and I assumed they were tested in tests/workspace_test/build.rs, but it seems I was wrong as I don't see any UI file. So question is: how could I test this lint?

Another important point: this lint can only be written before the expansion pass (because of the cfg! macro), forcing me to add it to this pass. Is it okay?

changelog: Add new invalid_build_cfg lint

@rustbot
Copy link
Collaborator

rustbot commented May 28, 2024

r? @y21

rustbot has assigned @y21.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label May 28, 2024
Copy link
Member

@Urgau Urgau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this. Great to progress around this area.

I left some comments about the implementation and the lint name.

/// if std::env::var("CARGO_CFG_WINDOWS").is_ok() {}
/// ```
#[clippy::version = "1.80.0"]
pub INVALID_BUILD_CFG,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that there are legitimate use cases for host-config in build.rs, I think it would be better if the lint name acknowledges it. the linked issue proposed misleading_cfg_in_build_script.

Suggested change
pub INVALID_BUILD_CFG,
pub MISLEADING_CFG_IN_BUILD_SCRIPT,

#[clippy::version = "1.80.0"]
pub INVALID_BUILD_CFG,
suspicious,
"invalid use of cfg in `build.rs`"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"invalid use of cfg in `build.rs`"
"use of host configs in `build.rs`"

Comment on lines +39 to +47
enum CfgAst {
Os(Symbol),
Any(Vec<CfgAst>),
All(Vec<CfgAst>),
Not(Box<CfgAst>),
TargetKeyValue(Symbol, Symbol),
Feature(Symbol),
OtherTarget(Symbol, Symbol),
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some documentation would be nice, it's not immediately clear why Feature, Os and OtherTarget exists.

Comment on lines +226 to +232
fn is_build_script(cx: &EarlyContext<'_>) -> bool {
cx.sess()
.opts
.crate_name
.as_ref()
.map_or(false, |crate_name| crate_name == "build_script_build")
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would also be good to check if we are actually being called by Cargo.
There is a nice function for that, rustc_session::utils::was_invoked_from_cargo.

if cfg!(not(all(target_os = "freebsd", windows))) {}
if cfg!(all(target_os = "freebsd", any(windows, not(feature = "red")))) {}

// Should not warn.
Copy link
Member

@Urgau Urgau May 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would also be good to add tests for custom cfgs, like loom, fuzzing, ...

Comment on lines +129 to +143
let mut tokens = tokens.trees().peekable();

while let Some(token) = tokens.next() {
match token {
TokenTree::Token(token, _) => {
match token.kind {
TokenKind::Ident(name, _) => {
if name == sym::feature || name.as_str().starts_with("target_") {
if let Some(next_token) = tokens.next()
&& let TokenTree::Token(next_token, _) = next_token
&& matches!(next_token.kind, TokenKind::Eq)
&& let Some(next_token) = tokens.next()
&& let TokenTree::Token(next_token, _) = next_token
&& let TokenKind::Literal(lit) = next_token.kind
&& matches!(lit.kind, LitKind::Str | LitKind::StrRaw(_))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of all this custom parsing logic could it be possible to use MetaItem::from_tokens? which is what I think the compiler is using internally; and then use meta_list_item.

@y21
Copy link
Member

y21 commented Jun 1, 2024

Re. pre expansion passes: I personally think it would be fine for something like build script-specific lints where I think the problems that those lints typically have (lint level attributes not properly propagating) isn't as much of a concern since a build script is its own crate with almost always just one module, but I'm gonna mention @flip1995 here because I think he has a stronger opinion on adding more pre expansion lints from what I've seen.

I am a little worried about this being fairly FP-heavy and warn-by-default at the same time since there are genuine use cases for cfg! in build scripts (e.g. for deciding whether to spawn powershell or a unix shell, it wouldn't make sense to use cargo env vars), but we can wait with the category until the FCP

@flip1995
Copy link
Member

flip1995 commented Jun 3, 2024

pre-expansion lints are indeed not my favorites. The allowing of those lints is the main problem. I can't quite remember if the problem was with outer, inner or crate level lint attributes though...

I am a little worried about this being fairly FP-heavy and warn-by-default at the same time since there are genuine use cases for cfg! in build scripts

That concern, I share.

@Urgau
Copy link
Member

Urgau commented Jun 3, 2024

It believe that #[cfg] attrs are not preserved after expansion, which I think is why all #[cfg] related lints run in pre-expension in EarlyAttributes.

Regarding the high risk of FP, that is a valid concern, which is in part why I didn't wanted this lint to be part of rustc.
Looking at GitHub there are currently around 3.3k build.rs with #[cfg(target.*, I looked at the first 3 pages and found 1 case that could be considered be a FP. That's nothing of a conclusion but I think is still draws a rough idea that FP would be low, perhaps less than 5%.

It's also worth nothing that in most cases I looked at, cross-compilation is broken for those crates (missing linking libraries, wrong cfgs, ...) and would in part be fixed by proper use of CARGO_* envs.

I also think if the lint clearly indicate in it's output that it may be fine to have #[cfg] on host and suggest a way to silence the lint (even if it's just #[allow]/#[expect] with a SAFETY:-like comment), that it would IMO considerably reduce the annoyance that the lint may cause and still provide some value.

In other word, even if it may be a FP (in the sense the cfg is really for the host and not the target) there would still be value for crate authors/maintainers, by indicating the reason for the host cfg, à la SAFETY: comment (similar to what is done with the unsafe-op-in-unsafe-fn lint).

@xFrednet
Copy link
Member

Hey @GuillaumeGomez , this is a ping from triage, since there hasn't been any activity in some time. Are you still planning to continue this implementation?

If you have any questions, you're always welcome to ask them in this PR or on Zulip.

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Jun 30, 2024
@GuillaumeGomez
Copy link
Member Author

I'm waiting to know if the clippy team is going to accept this lint and if so, with which changes. Could it be put on the calendar @xFrednet please?

@xFrednet xFrednet added the I-nominated Issue: Nominated to be discussed at the next Clippy meeting label Jul 1, 2024
@xFrednet
Copy link
Member

xFrednet commented Jul 1, 2024

Sure! The I-nominated label is used for that. I've added it now, but feel free to add it yourself, next time :)

@GuillaumeGomez
Copy link
Member Author

Noted, thanks!

@bors
Copy link
Collaborator

bors commented Jul 17, 2024

☔ The latest upstream changes (presumably #13088) made this pull request unmergeable. Please resolve the merge conflicts.

@flip1995 flip1995 removed the I-nominated Issue: Nominated to be discussed at the next Clippy meeting label Jul 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Lint for cfg usage which would provide a misleading result in a build script.
7 participants