-
Notifications
You must be signed in to change notification settings - Fork 434
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
Enable various new clippy lints #1025
base: rust-next
Are you sure you want to change the base?
Conversation
Currently, 'rustc_common_flags' lives in the top-level 'Makefile'. This means that we need to touch this whenever adjustments to Rust's CLI configuration are desired, such as changing what lints Clippy should emit. This patch moves these flags to a separate file within 'rust/' so that necessary changes can be made without affecting 'Makefile'. It copies the behavior currently used with 'bindgen_parameters', which accepts comments. Additionally, 'let_unit_value` is no longer specifically named as it is now part of the 'style' group [1]. [1]: rust-lang/rust-clippy#8563 Signed-off-by: Trevor Gross <[email protected]>
This patch selects a subset of lints from Clippy's 'pedantic' group and enables them. The only lints enabled here are those that do not show any errors with any of the files we currently have. Signed-off-by: Trevor Gross <[email protected]>
This patch enables the 'undocumented_unsafe_blocks' lint and adds comments where needed for this lint to pass. Clippy will now deny unsafe code that does not have an associated '// SAFETY: ' comment, which helps improve the maintainability of potentially dangerous code. Signed-off-by: Trevor Gross <[email protected]>
This patch enables three trivial lints and adds corrections so existing code passes. Lints added were: - 'expl_impl_clone_on_copy': check for implementing `Clone` when `Copy` already exists. - 'explicit_deref_methods': check for usage of `.deref()` to encourage cleaner code. - 'trivially_copy_pass_by_ref': check for small types that would be easier passed by value than by reference. Signed-off-by: Trevor Gross <[email protected]>
- 'ptr_as_ptr': enforce that '*const -> *const' and '*mut -> *mut' conversions be done via '.cast()' rather than 'as', to avoid accidental changes in mutability. - 'transmute_ptr_to_ptr': detect transumtes that could be written as lessi dangerous casts. Signed-off-by: Trevor Gross <[email protected]>
- 'manual_assert': detect combined usage of 'if' and 'panic' when 'assert' would have been more straightforward. - 'redundant_else': enforce that blocks are not nested within 'else' after conditional control flow statments. - 'semicolon_if_nothing_returned': enforce consistent style that makes it more clear that a statement is not used. Signed-off-by: Trevor Gross <[email protected]>
…for_...' - 'items_after_statements': prevent confusing scope since items and statements do not follow the same rules. - 'redundant_closure_for_method_calls': simplify closures that call a single method. This is the associated function equivalent of 'redundant_closure'. Signed-off-by: Trevor Gross <[email protected]>
--edition=2021 | ||
-Zbinary_dep_depinfo=y | ||
|
||
# Standard rust lints |
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.
Perhaps "rustc
lints"?
-Dclippy::needless_bitwise_bool | ||
-Dclippy::needless_continue | ||
|
||
# Clippy lints that we only warn on |
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.
Ideally, we would explain why we only warn on, but we can do that 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.
Well I didn't exactly know the reasoning :) what is it?
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.
For dbg_macro
(and todo
I guess), it is to avoid annoying people while developing. They could avoid CLIPPY=1
, but the intention is that you can use it all the time (except when building production kernels, since Clippy does not guarantee to generate the same code).
Also, perhaps consider if others should be -W
too for similar reasons. Or perhaps whether the reasoning is bad to being with! :)
@@ -7,6 +7,8 @@ | |||
//! - `macros/pin_data.rs` | |||
//! - `macros/pinned_drop.rs` | |||
|
|||
#![allow(clippy::undocumented_unsafe_blocks)] |
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 we should also document these 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.
It's only misssing two:
unsafe impl<T: ?Sized> InitData for AllData<T>
and
unsafe impl<T: ?Sized> HasInitData for T
Would you mind providing the comments for them?
// Since we are in the `if false` branch, this will never get executed. We abuse `slot` to | ||
// get the correct type inference here: | ||
|
||
// SAFETY: Since we are in the `if false` branch, this will never get executed. We abuse | ||
// `slot` to get the correct type inference 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 would leave the original comment and just add SAFETY: this code is never executed
.
// SAFETY: forgetting the guard is intentional | ||
unsafe { $crate::init::__internal::DropGuard::forget($field) }; |
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.
You can leave these (forgetting guards) with a SAFETY: TODO
, since this part will be rewritten in an update soon and then no unsafe
will be needed.
@@ -891,6 +896,7 @@ macro_rules! try_init { | |||
// no possibility of returning without `unsafe`. | |||
struct __InitOk; | |||
// Get the init data from the supplied type. | |||
// SAFETY: `HasInitData` is a marker trait which we are allowed to use in this context |
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.
// SAFETY: `HasInitData` is a marker trait which we are allowed to use in this context | |
// SAFETY: we are in one of the macros permitted to call `__init_data()` . |
// Since we are in the `if false` branch, this will never get executed. We abuse `slot` to | ||
// get the correct type inference here: | ||
// SAFETY: Since we are in the `if false` branch, this will never get | ||
// executed. We abuse `slot` to get the correct type inference 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.
same as above
/// # Safety | ||
/// | ||
/// This can only be used on types that meet `Zeroable`'s guidelines |
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.
/// # Safety | |
/// | |
/// This can only be used on types that meet `Zeroable`'s guidelines | |
/// # Safety | |
/// | |
/// This can only be used on types that meet `Zeroable`'s safety contract. |
@@ -974,6 +977,7 @@ macro_rules! __pin_data { | |||
slot: *mut $type, | |||
init: impl $crate::init::Init<$type, E>, | |||
) -> ::core::result::Result<(), E> { | |||
// SAFETY: `slot` is valid per this function's contract |
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 function has no # Safety
section, so it effectively has no contract. I think we should just give it the same contract as Init::__init
.
@@ -621,6 +621,7 @@ macro_rules! try_pin_init { | |||
// no possibility of returning without `unsafe`. | |||
struct __InitOk; | |||
// Get the pin data from the supplied type. | |||
// SAFETY: TODO |
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.
// SAFETY: TODO | |
// SAFETY: we are in one of the macros permitted to call `__pin_data()` . |
# FIXME: enable this at the next version bump. Disabled because of false | ||
# positive in macros: https://github.com/rust-lang/rust-clippy/issues/10084 | ||
# -Dclippy::unnecessary_safety_comment |
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 would explicitly mention the version it has started working instead; or otherwise not mention the FIXME
part if we don't know.
(We are upgrading to 1.70.0/1.71.0 soon)
Also, this should probably be in another commit.
I would add a note why this would be desirable, e.g. to be cleaner and/or because your later goal is to add new lints or to split the groups into individual lints which would take quite a bit of space. Also, please use
This should be a separate commit.
Yeah, please split them up more. You can split the move into a first patch, which allows to trivially check that the contents are the same with e.g. Git's Similarly, the commits like rust: clippy: enable 'undocumented_unsafe_blocks' lint should be either split into individual lints (if they require few / trivial changes to the code), so that they are as minimal as possible; or they should be split into commits that clean the code first before enabling the lint (if they are non-trivial changes).
Hard to say, but you are definitely enabling a lot of them! :) For the "pedantic" group ones, perhaps you can try to enable them in the Also, I think it would be good to understand why they are not already part of other Clippy groups already, i.e. why are they considered pedantic? Are they controversial? Do they conflict with |
-Wmissing_docs | ||
-Drustdoc::missing_crate_level_docs | ||
|
||
# Clippy groups |
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.
A different patch series should split these into individual lints, unless there is a way to prevent Clippy from breaking compilation due to newer lints.
Perhaps we should enable individual them with -D
, and keep the groups with -W
? That way the new ones would be warnings only (assuming the flags work that way).
I split off the first commit here #1026, I think I will get that prepared to send to the list before I refactor this PR too much. Thanks for all the suggestions - after the
Excellent thought, I will try that out.
If I recall correctly, they're mostly lints that can be noisy or have more false positives. Usually I compile all my code with pedantic - there are quite a few lints that make for more readable code after you've done a lot of refactoring ( I have also considered whether it might be good to have separate sets of lints somehow, so that e.g. |
I think it is best that, as much as possible, the majority of the kernel code uses the same set. The code is not yet written (or, for some of it, merged), so we are in the best situation possible to enforce these things (assuming they make sense and are not overly strict, of course). There may be some differences for e.g. host programs vs. kernel code, or for vendored code, of course. But apart from that, we should try to make the style (and the lints, in a sense) as consistent as possible.
I think, in general, if a lint is worth it for core components, then they are likely worth it for everything. In fact, the inverted situation can also happen: that some lints are worth it only for non-core components. For instance, consider the Having said that, for core code, even if we don't lint, what we may want is to require certain explanations to explain why something is OK, i.e. rather than disallow it. We have a couple In other words, instead of having, say, the Having said that, this overlaps with the unstable #[allow(unsafe_code, reason = "...")]
unsafe { ... } vs. // SAFETY: ...
unsafe { ... } ? (in some cases, multiline with lists etc.). And for macro invocations like #[allow(clippy::panic, reason = "...")]
{ panic!(); } vs. // PANIC: ...
panic!(); Perhaps some food for thought for rust-lang/rust#54503 -- I see the original RFC had some thoughts about comments in https://github.com/rust-lang/rfcs/blob/master/text/2383-lint-reasons.md#optional--yet-another-comment-syntax, but they are more about writing longer-form comments for a given attribute, rather than having a comment be interpreted as the |
@@ -610,24 +610,24 @@ impl<T: ?Sized> DerefMut for UniqueArc<T> { | |||
|
|||
impl<T: fmt::Display + ?Sized> fmt::Display for UniqueArc<T> { | |||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |||
fmt::Display::fmt(self.deref(), f) | |||
fmt::Display::fmt(&self, f) |
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.
Hmm.. I don't think this is an improve, &self
is of type &&UniqueArc<T>
, it's not very straight-forwards why does the compiler coerce it to a &T
. We could do the same as std:
fmt::Display::fmt(&**self, f);
But honestly, I don't think it's better.. could you explain what problem the old code has?
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.
There is no particular problem other than keeping consistency, this comes from the explicit_deref_methods
lint. I suspect that this is why std
does what it does (I neglected to check what they do before applying this).
I am indifferent about this lint and agree that there are many times where it makes more sense to be explicit, so I don't mind dropping it. However, even unrelated to the lint, maybe it would be good to match what std
does, just to avoid any possible confusion when syncing std
-> kernel
c9b5ce6
to
ce1c54f
Compare
9ee7197
to
6ce162a
Compare
This applies a most of what is discussed in #349.
Additionally, I enabled a large subset of lints from
pedantic
that shouldn't be too annoying, but should improve consistency and correctness.This patchset can be reviewed per-commit, each patch should build correctly. A few things I need feedback on:
// SAFETY: TODO
comments inrust/kernel/init
. I'm not too familiar with how this portion - could somebody more familiar to fill in those blanks and generally verify the safety comments ininit