-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Uplift the invalid_atomic_ordering
lint from clippy to rustc
#79654
Uplift the invalid_atomic_ordering
lint from clippy to rustc
#79654
Conversation
r? @lcnr (rust-highfive has picked a reviewer for you, use r? to override) |
|
Thanks for notifying me! The lint is not yet properly deprecated. If this PR is approved from the Rust side, I can do this for you (either by providing you a patch file for it or by pushing a commit myself). Explaining how to do it is harder than doing it myself. Maybe we should write a tool for deprecating lints. 🤔 Currently every test in Clippy fails, because registering a lint as removed, registers the lint, which is a problem, because it is already registered.
Well this is exaclly the command to use to test Clippy. It should always pass without changes to Clippy. |
@flip1995 I undid it, which fixed the issue. Not sure how you want to do the rest of it though, I'm open to whatever, but sending a patch might be the easiest. |
@thomcc You can find the Clippy patch here: https://gist.github.com/flip1995/a9758736c0a71b33c3d579134af4dc17 (This patch is based on the branch of this PR rebased on top of 8080f54. I had to rebase to get it to compile locally. However, the patch probably also works without a rebase) |
f278453
to
ee38c89
Compare
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.
this seems mostly ready to me.
Can you use https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.is_diagnostic_item instead of comparing paths? You may have to add some #[rustc_diagnostic_item = "variant_name"]
to the variants for this
compiler/rustc_lint/src/types.rs
Outdated
} | ||
|
||
fn matches_ordering_def_path(cx: &LateContext<'_>, did: DefId, orderings: &[Symbol]) -> bool { | ||
orderings.iter().any(|ordering| { |
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.
can you use diagnostic items instead here?
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.
I get
error: unused attribute
--> library/core/src/sync/atomic.rs:223:5
|
223 | #[rustc_diagnostic_item = "atomic_ordering_relaxed"]
on each of these if I try to put it on a variant.
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.
I think (code's still compiling...) can fix this by adding
if let hir::ItemKind::Enum(e, _) = &item.kind {
for variant in e.variants {
self.observe_item(variant.attrs, variant.id);
}
}
after this
self.observe_item(&item.attrs, item.hir_id); |
#[cfg_attr(not(bootstrap), rustc_diagnostic_item = "atomic_ordering_florb")]
It's small enough for me to think that's okay (if it were a more invasive change I'd punt on it), but it's your call.
(I'll update this based on if the tests manage to pass after the rebuild)
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.
Had to run to work before the build finished, so I pushed it up so CI could sort it out for me. That is: the last two commits are just tentative.
let method = method_path.ident.name; | ||
if Self::type_is_atomic(cx, &args[0]); | ||
if method == sym::load || method == sym::store; | ||
let ordering_arg = if method == sym::load { &args[1] } else { &args[2] }; |
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.
diagnostic items instead of Symbol
equality
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.
This one seems tricky because there's not just one load
method, there's one for AtomicBool::load, one for AtomicU8::load, one for AtomicU16::load, etc.
I had thought that diagnostic items wouldn't work here (it didn't seem to, but maybe I'm mistaken)
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.
no, they do have to be unique afaik 🤔
I guess using names is fine in that case. Thanks for looking into this.
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.
I'm unsure how to solve this but it also seems like less of an issue (since we use rustc_diagnostic_item for the actual atomic type). I don't think it's worth having atomic_store_u8, atomic_store_u16, etc methods all have unique diagnostic items.
It feels like you kind of want a rustc_diagnostic_tag
which would be allowed to have multiple things that it applies to.
As is maybe this is fine though. What's the downside of not using rustc_diagnostic_item here?
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.
yeah, someting like rustc_doagnostic_tag
is what I would want here 👍
The main issue is when moving stuff in std which breaks lints like this. I think this may also cause issues if a user impls a trait like the following, or at least it's less obvious for people reading the code what's the expected behavior here
trait Foo {
fn load(self);
}
In this PR you can just keep using sym::load
for now
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.
can you add the following as an ui test?
// check-pass
use std::sync::atomic::{AtomicUsize, Ordering};
trait Foo {
fn store(self, ordering: Ordering);
}
impl Foo for AtomicUsize {
fn store(self, _ordering: Ordering) {
AtomicUsize::store(&self, 4, Ordering::SeqCst);
}
}
fn main() {
let x = AtomicUsize::new(3);
x.store(Ordering::Acquire);
}
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.
r=me regarding the Clippy changes.
☔ The latest upstream changes (presumably #79927) made this pull request unmergeable. Please resolve the merge conflicts. Note that reviewers usually do not review pull requests until merge conflicts are resolved! Once you resolve the conflicts, you should change the labels applied by bors to indicate that your PR is ready for review. Post this as a comment to change the labels:
|
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 implementation looks good to me, even if i personally dislike if chains because they break rustfmt but that isn't something worth blocking this PR on 🤷
@rust-lang/lang is now required for an fcp if i understand that correctly?
@@ -211,13 +213,15 @@ unsafe impl<T> Sync for AtomicPtr<T> {} | |||
#[stable(feature = "rust1", since = "1.0.0")] | |||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] | |||
#[non_exhaustive] | |||
#[allow(unused_attributes)] |
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.
#[allow(unused_attributes)] | |
#[cfg_attr(bootstrap, allow(unused_attributes))] |
let method = method_path.ident.name; | ||
if Self::type_is_atomic(cx, &args[0]); | ||
if method == sym::load || method == sym::store; | ||
let ordering_arg = if method == sym::load { &args[1] } else { &args[2] }; |
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.
can you add the following as an ui test?
// check-pass
use std::sync::atomic::{AtomicUsize, Ordering};
trait Foo {
fn store(self, ordering: Ordering);
}
impl Foo for AtomicUsize {
fn store(self, _ordering: Ordering) {
AtomicUsize::store(&self, 4, Ordering::SeqCst);
}
}
fn main() {
let x = AtomicUsize::new(3);
x.store(Ordering::Acquire);
}
Uhhhh sorry about the delay here. Have been away. Looking into what's needed of me here now. |
Ping from triage |
@rustbot label: -S-waiting-on-review +S-waiting-on-author |
Sorry, I ended up getting the flu and having no time to do what I said #79654 (comment). I'll try to get to this this week sometime. |
@thomcc Any updates on this? |
Triage: I'm gonna close this due to inactivity. Feel free to reopen or create a new PR when you've got time to work on this again. Thanks! |
…eywiser Uplift the invalid_atomic_ordering lint from clippy to rustc This is mostly just a rebase of rust-lang#79654; I've copy/pasted the text from that PR below. r? `@lcnr` since you reviewed the last one, but feel free to reassign. --- This is an implementation of rust-lang/compiler-team#390. As mentioned, in general this turns an unconditional runtime panic into a (compile time) lint failure. It has no false positives, and the only false negatives I'm aware of are if `Ordering` isn't specified directly and is comes from an argument/constant/whatever. As a result of it having no false positives, and the alternative always being strictly wrong, it's on as deny by default. This seems right. In the [zulip stream](https://rust-lang.zulipchat.com/#narrow/stream/233931-t-compiler.2Fmajor-changes/topic/Uplift.20the.20.60invalid_atomic_ordering.60.20lint.20from.20clippy/near/218483957) `@joshtriplett` suggested that lang team should FCP this before landing it. Perhaps libs team cares too? --- Some notes on the code for reviewers / others below ## Changes from clippy The code is changed from [the implementation in clippy](https://github.com/rust-lang/rust-clippy/blob/68cf94f6a66e47234e3adefc6dfbe806cd6ad164/clippy_lints/src/atomic_ordering.rs) in the following ways: 1. Uses `Symbols` and `rustc_diagnostic_item`s instead of string literals. - It's possible I should have just invoked Symbol::intern for some of these instead? Seems better to use symbol, but it did require adding several. 2. The functions are moved to static methods inside the lint struct, as a way to namespace them. - There's a lot of other code in that file — which I picked as the location for this lint because `@jyn514` told me that seemed reasonable. 3. Supports unstable AtomicU128/AtomicI128. - I did this because it was almost easier to support them than not — not supporting them would have (ideally) required finding a way not to give them a `rustc_diagnostic_item`, which would have complicated an already big macro. - These don't have tests since I wasn't sure if/how I should make tests conditional on whether or not the target has the atomic... This is to a certain extent an issue of 64bit atomics too, but 128-bit atomics are much less common. Regardless, the existing tests should be *more* than thorough enough here. 4. Minor changes like: - grammar tweaks ("loads cannot have `Release` **and** `AcqRel` ordering" => "loads cannot have `Release` **or** `AcqRel` ordering") - function renames (`match_ordering_def_path` => `matches_ordering_def_path`), - avoiding clippy-specific helper methods that don't exist in rustc_lint and didn't seem worth adding for this case (for example `cx.struct_span_lint` vs clippy's `span_lint_and_help` helper). ## Potential issues (This is just about the code in this PR, not conceptual issues with the lint or anything) 1. I'm not sure if I should have used a diagnostic item for `Ordering` and its variants (I couldn't figure out how really, so if I should do this some pointers would be appreciated). - It seems possible that failing to do this might possibly mean there are more cases this lint would miss, but I don't really know how `match_def_path` works and if it has any pitfalls like that, so maybe not. 2. I *think* I deprecated the lint in clippy (CC `@flip1995` who asked to be notified about clippy changes in the future in [this comment](rust-lang#75671 (comment))) but I'm not sure if I need to do anything else there. - I'm kind of hoping CI will catch if I missed anything, since `x.py test src/tools/clippy` fails with a lot of errors with and without my changes (and is probably a nonsense command regardless). Running `cargo test` from src/tools/clippy also fails with unrelated errors that seem like refactorings that didnt update clippy? So, honestly no clue. 3. I wasn't sure if the description/example I gave good. Hopefully it is. The example is less thorough than the one from clippy here: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_atomic_ordering. Let me know if/how I should change it if it needs changing. 4. It pulls in the `if_chain` crate. This crate was already used in clippy, and seems like it's used elsewhere in rustc, but I'm willing to rewrite it to not use this if needed (I'd prefer not to, all things being equal).
Uplift the invalid_atomic_ordering lint from clippy to rustc This is mostly just a rebase of rust-lang/rust#79654; I've copy/pasted the text from that PR below. r? `@lcnr` since you reviewed the last one, but feel free to reassign. --- This is an implementation of rust-lang/compiler-team#390. As mentioned, in general this turns an unconditional runtime panic into a (compile time) lint failure. It has no false positives, and the only false negatives I'm aware of are if `Ordering` isn't specified directly and is comes from an argument/constant/whatever. As a result of it having no false positives, and the alternative always being strictly wrong, it's on as deny by default. This seems right. In the [zulip stream](https://rust-lang.zulipchat.com/#narrow/stream/233931-t-compiler.2Fmajor-changes/topic/Uplift.20the.20.60invalid_atomic_ordering.60.20lint.20from.20clippy/near/218483957) `@joshtriplett` suggested that lang team should FCP this before landing it. Perhaps libs team cares too? --- Some notes on the code for reviewers / others below ## Changes from clippy The code is changed from [the implementation in clippy](https://github.com/rust-lang/rust-clippy/blob/68cf94f6a66e47234e3adefc6dfbe806cd6ad164/clippy_lints/src/atomic_ordering.rs) in the following ways: 1. Uses `Symbols` and `rustc_diagnostic_item`s instead of string literals. - It's possible I should have just invoked Symbol::intern for some of these instead? Seems better to use symbol, but it did require adding several. 2. The functions are moved to static methods inside the lint struct, as a way to namespace them. - There's a lot of other code in that file — which I picked as the location for this lint because `@jyn514` told me that seemed reasonable. 3. Supports unstable AtomicU128/AtomicI128. - I did this because it was almost easier to support them than not — not supporting them would have (ideally) required finding a way not to give them a `rustc_diagnostic_item`, which would have complicated an already big macro. - These don't have tests since I wasn't sure if/how I should make tests conditional on whether or not the target has the atomic... This is to a certain extent an issue of 64bit atomics too, but 128-bit atomics are much less common. Regardless, the existing tests should be *more* than thorough enough here. 4. Minor changes like: - grammar tweaks ("loads cannot have `Release` **and** `AcqRel` ordering" => "loads cannot have `Release` **or** `AcqRel` ordering") - function renames (`match_ordering_def_path` => `matches_ordering_def_path`), - avoiding clippy-specific helper methods that don't exist in rustc_lint and didn't seem worth adding for this case (for example `cx.struct_span_lint` vs clippy's `span_lint_and_help` helper). ## Potential issues (This is just about the code in this PR, not conceptual issues with the lint or anything) 1. I'm not sure if I should have used a diagnostic item for `Ordering` and its variants (I couldn't figure out how really, so if I should do this some pointers would be appreciated). - It seems possible that failing to do this might possibly mean there are more cases this lint would miss, but I don't really know how `match_def_path` works and if it has any pitfalls like that, so maybe not. 2. I *think* I deprecated the lint in clippy (CC `@flip1995` who asked to be notified about clippy changes in the future in [this comment](rust-lang/rust#75671 (comment))) but I'm not sure if I need to do anything else there. - I'm kind of hoping CI will catch if I missed anything, since `x.py test src/tools/clippy` fails with a lot of errors with and without my changes (and is probably a nonsense command regardless). Running `cargo test` from src/tools/clippy also fails with unrelated errors that seem like refactorings that didnt update clippy? So, honestly no clue. 3. I wasn't sure if the description/example I gave good. Hopefully it is. The example is less thorough than the one from clippy here: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_atomic_ordering. Let me know if/how I should change it if it needs changing. 4. It pulls in the `if_chain` crate. This crate was already used in clippy, and seems like it's used elsewhere in rustc, but I'm willing to rewrite it to not use this if needed (I'd prefer not to, all things being equal).
This is an implementation of rust-lang/compiler-team#390.
Nobody complained beyond noting that it doesn't seem like there's a good process here (I strongly agree!), and I had some time today, so I went and did it. I have no clue who to ask for review, so I'm hoping either reviewbot picks well or it sorts itself out (by way of someone telling me who to request or someone passing it off or whatever).
Maybe I should have waited to get a second or find a reviewer? If so, sorry. The process is pretty unclear, and I don't really see any downsides to this lint.
As mentioned, in general this turns an unconditional runtime panic into a (compile time) lint failure. It has no false positives, and the only false negatives I'm aware of are if
Ordering
isn't specified directly and is comes from an argument/constant/whatever.As a result of it having no false positives, and the alternative always being strictly wrong, it's on as deny by default. This seems right.
In the zulip stream @joshtriplett suggested that lang team should FCP this before landing it. Perhaps libs team cares too? I don't know how to ping either.
Some notes on the code for reviewers / others below
Changes from clippy
The code is changed from the implementation in clippy in the following ways:
Symbols
andrustc_diagnostic_item
s instead of string literals.rustc_diagnostic_item
, which would have complicated an already big macro.Release
andAcqRel
ordering" => "loads cannot haveRelease
orAcqRel
ordering")match_ordering_def_path
=>matches_ordering_def_path
),cx.struct_span_lint
vs clippy'sspan_lint_and_help
helper).Potential issues
(This is just about the code in this PR, not conceptual issues with the lint or anything)
I'm not sure if I should have used a diagnostic item for
Ordering
and its variants (I couldn't figure out how really, so if I should do this some pointers would be appreciated).match_def_path
works and if it has any pitfalls like that, so maybe not.I think I deprecated the lint in clippy (CC @flip1995 who asked to be notified about clippy changes in the future in this comment) but I'm not sure if I need to do anything else there.
x.py test src/tools/clippy
fails with a lot of errors with and without my changes (and is probably a nonsense command regardless). Runningcargo test
from src/tools/clippy also fails with unrelated errors that seem like refactorings that didnt update clippy? So, honestly no clue.I wasn't sure if the description/example I gave good. Hopefully it is. The example is less thorough than the one from clippy here: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_atomic_ordering. Let me know if/how I should change it if it needs changing.
It pulls in the
if_chain
crate. This crate was already used in clippy, and seems like it's used elsewhere in rustc, but I'm willing to rewrite it to not use this if needed (I'd prefer not to, all things being equal).