Skip to content

Commit 758f196

Browse files
committed
Auto merge of #103337 - flip1995:clippyup, r=Manishearth
Update Clippy r? `@Manishearth`
2 parents c07a6a9 + da9755b commit 758f196

File tree

284 files changed

+8511
-4206
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

284 files changed

+8511
-4206
lines changed

src/tools/clippy/.github/workflows/clippy.yml

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ env:
2525
CARGO_TARGET_DIR: '${{ github.workspace }}/target'
2626
NO_FMT_TEST: 1
2727
CARGO_INCREMENTAL: 0
28+
CARGO_UNSTABLE_SPARSE_REGISTRY: true
2829

2930
jobs:
3031
base:

src/tools/clippy/.github/workflows/clippy_bors.yml

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ env:
1111
CARGO_TARGET_DIR: '${{ github.workspace }}/target'
1212
NO_FMT_TEST: 1
1313
CARGO_INCREMENTAL: 0
14+
CARGO_UNSTABLE_SPARSE_REGISTRY: true
1415

1516
defaults:
1617
run:

src/tools/clippy/.github/workflows/clippy_dev.yml

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ on:
1515

1616
env:
1717
RUST_BACKTRACE: 1
18+
CARGO_INCREMENTAL: 0
19+
CARGO_UNSTABLE_SPARSE_REGISTRY: true
1820

1921
jobs:
2022
clippy_dev:

src/tools/clippy/CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -3735,6 +3735,7 @@ Released 2018-09-13
37353735
[`approx_constant`]: https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant
37363736
[`arithmetic_side_effects`]: https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects
37373737
[`as_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions
3738+
[`as_ptr_cast_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_ptr_cast_mut
37383739
[`as_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_underscore
37393740
[`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_constants
37403741
[`assertions_on_result_states`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_result_states
@@ -3772,6 +3773,7 @@ Released 2018-09-13
37723773
[`cast_enum_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_enum_constructor
37733774
[`cast_enum_truncation`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_enum_truncation
37743775
[`cast_lossless`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_lossless
3776+
[`cast_nan_to_int`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_nan_to_int
37753777
[`cast_possible_truncation`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_possible_truncation
37763778
[`cast_possible_wrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_possible_wrap
37773779
[`cast_precision_loss`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_precision_loss
@@ -3988,6 +3990,7 @@ Released 2018-09-13
39883990
[`manual_async_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_async_fn
39893991
[`manual_bits`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits
39903992
[`manual_clamp`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp
3993+
[`manual_filter`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_filter
39913994
[`manual_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_filter_map
39923995
[`manual_find`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_find
39933996
[`manual_find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_find_map
@@ -4046,6 +4049,7 @@ Released 2018-09-13
40464049
[`missing_panics_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_panics_doc
40474050
[`missing_safety_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc
40484051
[`missing_spin_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_spin_loop
4052+
[`missing_trait_methods`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_trait_methods
40494053
[`mistyped_literal_suffixes`]: https://rust-lang.github.io/rust-clippy/master/index.html#mistyped_literal_suffixes
40504054
[`mixed_case_hex_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_case_hex_literals
40514055
[`mixed_read_write_in_expression`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_read_write_in_expression
@@ -4131,6 +4135,7 @@ Released 2018-09-13
41314135
[`panic_in_result_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic_in_result_fn
41324136
[`panic_params`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic_params
41334137
[`panicking_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#panicking_unwrap
4138+
[`partial_pub_fields`]: https://rust-lang.github.io/rust-clippy/master/index.html#partial_pub_fields
41344139
[`partialeq_ne_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_ne_impl
41354140
[`partialeq_to_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_to_none
41364141
[`path_buf_push_overwrite`]: https://rust-lang.github.io/rust-clippy/master/index.html#path_buf_push_overwrite
@@ -4312,6 +4317,7 @@ Released 2018-09-13
43124317
[`unstable_as_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#unstable_as_slice
43134318
[`unused_async`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_async
43144319
[`unused_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_collect
4320+
[`unused_format_specs`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_format_specs
43154321
[`unused_io_amount`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_io_amount
43164322
[`unused_label`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_label
43174323
[`unused_peekable`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_peekable

src/tools/clippy/CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ All contributors are expected to follow the [Rust Code of Conduct].
2929

3030
## The Clippy book
3131

32-
If you're new to Clippy and don't know where to start the [Clippy book] includes
32+
If you're new to Clippy and don't know where to start, the [Clippy book] includes
3333
a [developer guide] and is a good place to start your journey.
3434

3535
[Clippy book]: https://doc.rust-lang.org/nightly/clippy/index.html

src/tools/clippy/book/src/development/adding_lints.md

+21-2
Original file line numberDiff line numberDiff line change
@@ -478,8 +478,27 @@ impl<'tcx> LateLintPass<'tcx> for ManualStrip {
478478
```
479479

480480
Once the `msrv` is added to the lint, a relevant test case should be added to
481-
`tests/ui/min_rust_version_attr.rs` which verifies that the lint isn't emitted
482-
if the project's MSRV is lower.
481+
the lint's test file, `tests/ui/manual_strip.rs` in this example. It should
482+
have a case for the version below the MSRV and one with the same contents but
483+
for the MSRV version itself.
484+
485+
```rust
486+
#![feature(custom_inner_attributes)]
487+
488+
...
489+
490+
fn msrv_1_44() {
491+
#![clippy::msrv = "1.44"]
492+
493+
/* something that would trigger the lint */
494+
}
495+
496+
fn msrv_1_45() {
497+
#![clippy::msrv = "1.45"]
498+
499+
/* something that would trigger the lint */
500+
}
501+
```
483502

484503
As a last step, the lint should be added to the lint documentation. This is done
485504
in `clippy_lints/src/utils/conf.rs`:

src/tools/clippy/book/src/development/basics.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ the reference file with:
6969
cargo dev bless
7070
```
7171

72-
For example, this is necessary, if you fix a typo in an error message of a lint
72+
For example, this is necessary if you fix a typo in an error message of a lint,
7373
or if you modify a test file to add a test case.
7474

7575
> _Note:_ This command may update more files than you intended. In that case
@@ -101,8 +101,9 @@ cargo dev setup intellij
101101
cargo dev dogfood
102102
```
103103

104-
More about intellij command usage and reasons
105-
[here](https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md#intellij-rust)
104+
More about [intellij] command usage and reasons.
105+
106+
[intellij]: https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md#intellij-rust
106107

107108
## lintcheck
108109

src/tools/clippy/clippy_dev/src/serve.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ fn mtime(path: impl AsRef<Path>) -> SystemTime {
4949
.into_iter()
5050
.flatten()
5151
.flatten()
52-
.map(|entry| mtime(&entry.path()))
52+
.map(|entry| mtime(entry.path()))
5353
.max()
5454
.unwrap_or(SystemTime::UNIX_EPOCH)
5555
} else {

src/tools/clippy/clippy_dev/src/setup/intellij.rs

+5-12
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,8 @@ impl ClippyProjectInfo {
3636
}
3737

3838
pub fn setup_rustc_src(rustc_path: &str) {
39-
let rustc_source_dir = match check_and_get_rustc_dir(rustc_path) {
40-
Ok(path) => path,
41-
Err(_) => return,
39+
let Ok(rustc_source_dir) = check_and_get_rustc_dir(rustc_path) else {
40+
return
4241
};
4342

4443
for project in CLIPPY_PROJECTS {
@@ -172,24 +171,18 @@ pub fn remove_rustc_src() {
172171
}
173172

174173
fn remove_rustc_src_from_project(project: &ClippyProjectInfo) -> bool {
175-
let mut cargo_content = if let Ok(content) = read_project_file(project.cargo_file) {
176-
content
177-
} else {
174+
let Ok(mut cargo_content) = read_project_file(project.cargo_file) else {
178175
return false;
179176
};
180-
let section_start = if let Some(section_start) = cargo_content.find(RUSTC_PATH_SECTION) {
181-
section_start
182-
} else {
177+
let Some(section_start) = cargo_content.find(RUSTC_PATH_SECTION) else {
183178
println!(
184179
"info: dependencies could not be found in `{}` for {}, skipping file",
185180
project.cargo_file, project.name
186181
);
187182
return true;
188183
};
189184

190-
let end_point = if let Some(end_point) = cargo_content.find(DEPENDENCIES_SECTION) {
191-
end_point
192-
} else {
185+
let Some(end_point) = cargo_content.find(DEPENDENCIES_SECTION) else {
193186
eprintln!(
194187
"error: the end of the rustc dependencies section could not be found in `{}`",
195188
project.cargo_file

src/tools/clippy/clippy_dev/src/update_lints.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ fn generate_lint_files(
128128
for (lint_group, lints) in Lint::by_lint_group(usable_lints.into_iter().chain(internal_lints)) {
129129
let content = gen_lint_group_list(&lint_group, lints.iter());
130130
process_file(
131-
&format!("clippy_lints/src/lib.register_{lint_group}.rs"),
131+
format!("clippy_lints/src/lib.register_{lint_group}.rs"),
132132
update_mode,
133133
&content,
134134
);
@@ -869,13 +869,11 @@ fn clippy_lints_src_files() -> impl Iterator<Item = (PathBuf, DirEntry)> {
869869
macro_rules! match_tokens {
870870
($iter:ident, $($token:ident $({$($fields:tt)*})? $(($capture:ident))?)*) => {
871871
{
872-
$($(let $capture =)? if let Some(LintDeclSearchResult {
872+
$(#[allow(clippy::redundant_pattern)] let Some(LintDeclSearchResult {
873873
token_kind: TokenKind::$token $({$($fields)*})?,
874-
content: _x,
874+
content: $($capture @)? _,
875875
..
876-
}) = $iter.next() {
877-
_x
878-
} else {
876+
}) = $iter.next() else {
879877
continue;
880878
};)*
881879
#[allow(clippy::unused_unit)]

src/tools/clippy/clippy_lints/src/booleans.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
2+
use clippy_utils::eq_expr_value;
23
use clippy_utils::source::snippet_opt;
34
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
4-
use clippy_utils::{eq_expr_value, get_trait_def_id, paths};
55
use if_chain::if_chain;
66
use rustc_ast::ast::LitKind;
77
use rustc_errors::Applicability;
@@ -483,7 +483,9 @@ impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> {
483483

484484
fn implements_ord<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> bool {
485485
let ty = cx.typeck_results().expr_ty(expr);
486-
get_trait_def_id(cx, &paths::ORD).map_or(false, |id| implements_trait(cx, ty, id, &[]))
486+
cx.tcx
487+
.get_diagnostic_item(sym::Ord)
488+
.map_or(false, |id| implements_trait(cx, ty, id, &[]))
487489
}
488490

489491
struct NotSimplificationVisitor<'a, 'tcx> {

src/tools/clippy/clippy_lints/src/box_default.rs

+82-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1-
use clippy_utils::{diagnostics::span_lint_and_help, is_default_equivalent, path_def_id};
2-
use rustc_hir::{Expr, ExprKind, QPath};
1+
use clippy_utils::{
2+
diagnostics::span_lint_and_sugg, get_parent_node, is_default_equivalent, macros::macro_backtrace, match_path,
3+
path_def_id, paths, ty::expr_sig,
4+
};
5+
use rustc_errors::Applicability;
6+
use rustc_hir::{
7+
intravisit::{walk_ty, Visitor},
8+
Block, Expr, ExprKind, Local, Node, QPath, TyKind,
9+
};
310
use rustc_lint::{LateContext, LateLintPass, LintContext};
411
use rustc_middle::lint::in_external_macro;
512
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -15,12 +22,6 @@ declare_clippy_lint! {
1522
/// Second, `Box::default()` can be faster
1623
/// [in certain cases](https://nnethercote.github.io/perf-book/standard-library-types.html#box).
1724
///
18-
/// ### Known problems
19-
/// The lint may miss some cases (e.g. Box::new(String::from(""))).
20-
/// On the other hand, it will trigger on cases where the `default`
21-
/// code comes from a macro that does something different based on
22-
/// e.g. target operating system.
23-
///
2425
/// ### Example
2526
/// ```rust
2627
/// let x: Box<String> = Box::new(Default::default());
@@ -41,21 +42,88 @@ impl LateLintPass<'_> for BoxDefault {
4142
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
4243
if let ExprKind::Call(box_new, [arg]) = expr.kind
4344
&& let ExprKind::Path(QPath::TypeRelative(ty, seg)) = box_new.kind
44-
&& let ExprKind::Call(..) = arg.kind
45+
&& let ExprKind::Call(arg_path, ..) = arg.kind
4546
&& !in_external_macro(cx.sess(), expr.span)
46-
&& expr.span.eq_ctxt(arg.span)
47+
&& (expr.span.eq_ctxt(arg.span) || is_vec_expn(cx, arg))
4748
&& seg.ident.name == sym::new
48-
&& path_def_id(cx, ty) == cx.tcx.lang_items().owned_box()
49+
&& path_def_id(cx, ty).map_or(false, |id| Some(id) == cx.tcx.lang_items().owned_box())
4950
&& is_default_equivalent(cx, arg)
5051
{
51-
span_lint_and_help(
52+
let arg_ty = cx.typeck_results().expr_ty(arg);
53+
span_lint_and_sugg(
5254
cx,
5355
BOX_DEFAULT,
5456
expr.span,
5557
"`Box::new(_)` of default value",
56-
None,
57-
"use `Box::default()` instead",
58+
"try",
59+
if is_plain_default(arg_path) || given_type(cx, expr) {
60+
"Box::default()".into()
61+
} else {
62+
format!("Box::<{arg_ty}>::default()")
63+
},
64+
Applicability::MachineApplicable
5865
);
5966
}
6067
}
6168
}
69+
70+
fn is_plain_default(arg_path: &Expr<'_>) -> bool {
71+
// we need to match the actual path so we don't match e.g. "u8::default"
72+
if let ExprKind::Path(QPath::Resolved(None, path)) = &arg_path.kind {
73+
// avoid generic parameters
74+
match_path(path, &paths::DEFAULT_TRAIT_METHOD) && path.segments.iter().all(|seg| seg.args.is_none())
75+
} else {
76+
false
77+
}
78+
}
79+
80+
fn is_vec_expn(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
81+
macro_backtrace(expr.span)
82+
.next()
83+
.map_or(false, |call| cx.tcx.is_diagnostic_item(sym::vec_macro, call.def_id))
84+
}
85+
86+
#[derive(Default)]
87+
struct InferVisitor(bool);
88+
89+
impl<'tcx> Visitor<'tcx> for InferVisitor {
90+
fn visit_ty(&mut self, t: &rustc_hir::Ty<'_>) {
91+
self.0 |= matches!(t.kind, TyKind::Infer | TyKind::OpaqueDef(..) | TyKind::TraitObject(..));
92+
if !self.0 {
93+
walk_ty(self, t);
94+
}
95+
}
96+
}
97+
98+
fn given_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
99+
match get_parent_node(cx.tcx, expr.hir_id) {
100+
Some(Node::Local(Local { ty: Some(ty), .. })) => {
101+
let mut v = InferVisitor::default();
102+
v.visit_ty(ty);
103+
!v.0
104+
},
105+
Some(
106+
Node::Expr(Expr {
107+
kind: ExprKind::Call(path, args),
108+
..
109+
}) | Node::Block(Block {
110+
expr:
111+
Some(Expr {
112+
kind: ExprKind::Call(path, args),
113+
..
114+
}),
115+
..
116+
}),
117+
) => {
118+
if let Some(index) = args.iter().position(|arg| arg.hir_id == expr.hir_id) &&
119+
let Some(sig) = expr_sig(cx, path) &&
120+
let Some(input) = sig.input(index)
121+
{
122+
input.no_bound_vars().is_some()
123+
} else {
124+
false
125+
}
126+
},
127+
_ => false,
128+
}
129+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use clippy_utils::diagnostics::span_lint_and_sugg;
2+
use clippy_utils::source::snippet_opt;
3+
use rustc_errors::Applicability;
4+
use rustc_hir::{Expr, ExprKind};
5+
use rustc_lint::LateContext;
6+
use rustc_middle::{
7+
mir::Mutability,
8+
ty::{self, Ty, TypeAndMut},
9+
};
10+
11+
use super::AS_PTR_CAST_MUT;
12+
13+
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_to: Ty<'_>) {
14+
if let ty::RawPtr(ptrty @ TypeAndMut { mutbl: Mutability::Mut, .. }) = cast_to.kind()
15+
&& let ty::RawPtr(TypeAndMut { mutbl: Mutability::Not, .. }) =
16+
cx.typeck_results().node_type(cast_expr.hir_id).kind()
17+
&& let ExprKind::MethodCall(method_name, receiver, [], _) = cast_expr.peel_blocks().kind
18+
&& method_name.ident.name == rustc_span::sym::as_ptr
19+
&& let Some(as_ptr_did) = cx.typeck_results().type_dependent_def_id(cast_expr.peel_blocks().hir_id)
20+
&& let as_ptr_sig = cx.tcx.fn_sig(as_ptr_did)
21+
&& let Some(first_param_ty) = as_ptr_sig.skip_binder().inputs().iter().next()
22+
&& let ty::Ref(_, _, Mutability::Not) = first_param_ty.kind()
23+
&& let Some(recv) = snippet_opt(cx, receiver.span)
24+
{
25+
// `as_mut_ptr` might not exist
26+
let applicability = Applicability::MaybeIncorrect;
27+
28+
span_lint_and_sugg(
29+
cx,
30+
AS_PTR_CAST_MUT,
31+
expr.span,
32+
&format!("casting the result of `as_ptr` to *{ptrty}"),
33+
"replace with",
34+
format!("{recv}.as_mut_ptr()"),
35+
applicability
36+
);
37+
}
38+
}

0 commit comments

Comments
 (0)