Skip to content

Commit 50475e8

Browse files
committed
Merge commit 'd5e2a7aca55ed49fc943b7a07a8eba05ab5a0079' into clippyup
2 parents c763ece + d5e2a7a commit 50475e8

File tree

184 files changed

+2992
-1627
lines changed

Some content is hidden

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

184 files changed

+2992
-1627
lines changed

src/tools/clippy/CHANGELOG.md

+6-3
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ Current stable, released 2023-03-09
152152

153153
* `SYSROOT` and `--sysroot` can now be set at the same time
154154
[#10149](https://github.com/rust-lang/rust-clippy/pull/10149)
155+
* Fix error when providing an `array-size-threshold` in `clippy.toml`
156+
[#10423](https://github.com/rust-lang/rust-clippy/pull/10423)
155157

156158
## Rust 1.67
157159

@@ -186,8 +188,6 @@ Released 2023-01-26
186188

187189
### Moves and Deprecations
188190

189-
* Moved [`uninlined_format_args`] to `style` (Now warn-by-default)
190-
[#9865](https://github.com/rust-lang/rust-clippy/pull/9865)
191191
* Moved [`needless_collect`] to `nursery` (Now allow-by-default)
192192
[#9705](https://github.com/rust-lang/rust-clippy/pull/9705)
193193
* Moved [`or_fun_call`] to `nursery` (Now allow-by-default)
@@ -423,7 +423,7 @@ Released 2022-12-15
423423
[#9490](https://github.com/rust-lang/rust-clippy/pull/9490)
424424
* [`almost_complete_letter_range`]: No longer lints in external macros
425425
[#9467](https://github.com/rust-lang/rust-clippy/pull/9467)
426-
* [`drop_copy`]: No longer lints on idiomatic cases in match arms
426+
* [`drop_copy`]: No longer lints on idiomatic cases in match arms
427427
[#9491](https://github.com/rust-lang/rust-clippy/pull/9491)
428428
* [`question_mark`]: No longer lints in const context
429429
[#9487](https://github.com/rust-lang/rust-clippy/pull/9487)
@@ -4382,6 +4382,7 @@ Released 2018-09-13
43824382
<!-- begin autogenerated links to lint list -->
43834383
[`absurd_extreme_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#absurd_extreme_comparisons
43844384
[`alloc_instead_of_core`]: https://rust-lang.github.io/rust-clippy/master/index.html#alloc_instead_of_core
4385+
[`allow_attributes`]: https://rust-lang.github.io/rust-clippy/master/index.html#allow_attributes
43854386
[`allow_attributes_without_reason`]: https://rust-lang.github.io/rust-clippy/master/index.html#allow_attributes_without_reason
43864387
[`almost_complete_letter_range`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_letter_range
43874388
[`almost_complete_range`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_range
@@ -4661,6 +4662,7 @@ Released 2018-09-13
46614662
[`manual_instant_elapsed`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_instant_elapsed
46624663
[`manual_is_ascii_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check
46634664
[`manual_let_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else
4665+
[`manual_main_separator_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_main_separator_str
46644666
[`manual_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_map
46654667
[`manual_memcpy`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_memcpy
46664668
[`manual_non_exhaustive`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive
@@ -4985,6 +4987,7 @@ Released 2018-09-13
49854987
[`unnecessary_safety_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_safety_doc
49864988
[`unnecessary_self_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_self_imports
49874989
[`unnecessary_sort_by`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_sort_by
4990+
[`unnecessary_struct_initialization`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_struct_initialization
49884991
[`unnecessary_to_owned`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_to_owned
49894992
[`unnecessary_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap
49904993
[`unnecessary_wraps`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_wraps

src/tools/clippy/CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ a [developer guide] and is a good place to start your journey.
5050
All issues on Clippy are mentored, if you want help simply ask someone from the
5151
Clippy team directly by mentioning them in the issue or over on [Zulip]. All
5252
currently active team members can be found
53-
[here](https://github.com/rust-lang/highfive/blob/master/highfive/configs/rust-lang/rust-clippy.json#L3)
53+
[here](https://github.com/rust-lang/rust-clippy/blob/master/triagebot.toml#L18)
5454

5555
Some issues are easier than others. The [`good-first-issue`] label can be used to find the easy
5656
issues. You can use `@rustbot claim` to assign the issue to yourself.

src/tools/clippy/book/src/lint_configuration.md

+1
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@ for the generic parameters for determining interior mutability
519519
**Default Value:** `["bytes::Bytes"]` (`Vec<String>`)
520520

521521
* [mutable_key_type](https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type)
522+
* [ifs_same_cond](https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond)
522523

523524

524525
### allow-mixed-uninlined-format-args
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
use ast::AttrStyle;
2+
use clippy_utils::diagnostics::span_lint_and_sugg;
3+
use rustc_ast as ast;
4+
use rustc_errors::Applicability;
5+
use rustc_lint::{LateContext, LateLintPass};
6+
use rustc_session::{declare_lint_pass, declare_tool_lint};
7+
8+
declare_clippy_lint! {
9+
/// Detects uses of the `#[allow]` attribute and suggests replacing it with
10+
/// the `#[expect]` (See [RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reasons.html))
11+
///
12+
/// The expect attribute is still unstable and requires the `lint_reasons`
13+
/// on nightly. It can be enabled by adding `#![feature(lint_reasons)]` to
14+
/// the crate root.
15+
///
16+
/// This lint only warns outer attributes (`#[allow]`), as inner attributes
17+
/// (`#![allow]`) are usually used to enable or disable lints on a global scale.
18+
///
19+
/// ### Why is this bad?
20+
///
21+
/// `#[expect]` attributes suppress the lint emission, but emit a warning, if
22+
/// the expectation is unfulfilled. This can be useful to be notified when the
23+
/// lint is no longer triggered.
24+
///
25+
/// ### Example
26+
/// ```rust,ignore
27+
/// #[allow(unused_mut)]
28+
/// fn foo() -> usize {
29+
/// let mut a = Vec::new();
30+
/// a.len()
31+
/// }
32+
/// ```
33+
/// Use instead:
34+
/// ```rust,ignore
35+
/// #![feature(lint_reasons)]
36+
/// #[expect(unused_mut)]
37+
/// fn foo() -> usize {
38+
/// let mut a = Vec::new();
39+
/// a.len()
40+
/// }
41+
/// ```
42+
#[clippy::version = "1.69.0"]
43+
pub ALLOW_ATTRIBUTES,
44+
restriction,
45+
"`#[allow]` will not trigger if a warning isn't found. `#[expect]` triggers if there are no warnings."
46+
}
47+
48+
declare_lint_pass!(AllowAttribute => [ALLOW_ATTRIBUTES]);
49+
50+
impl LateLintPass<'_> for AllowAttribute {
51+
// Separate each crate's features.
52+
fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) {
53+
if_chain! {
54+
if cx.tcx.features().lint_reasons;
55+
if let AttrStyle::Outer = attr.style;
56+
if let Some(ident) = attr.ident();
57+
if ident.name == rustc_span::symbol::sym::allow;
58+
then {
59+
span_lint_and_sugg(
60+
cx,
61+
ALLOW_ATTRIBUTES,
62+
ident.span,
63+
"#[allow] attribute found",
64+
"replace it with",
65+
"expect".into(),
66+
Applicability::MachineApplicable,
67+
);
68+
}
69+
}
70+
}
71+
}

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

+13-12
Original file line numberDiff line numberDiff line change
@@ -495,18 +495,19 @@ struct NotSimplificationVisitor<'a, 'tcx> {
495495

496496
impl<'a, 'tcx> Visitor<'tcx> for NotSimplificationVisitor<'a, 'tcx> {
497497
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
498-
if let ExprKind::Unary(UnOp::Not, inner) = &expr.kind {
499-
if let Some(suggestion) = simplify_not(self.cx, inner) {
500-
span_lint_and_sugg(
501-
self.cx,
502-
NONMINIMAL_BOOL,
503-
expr.span,
504-
"this boolean expression can be simplified",
505-
"try",
506-
suggestion,
507-
Applicability::MachineApplicable,
508-
);
509-
}
498+
if let ExprKind::Unary(UnOp::Not, inner) = &expr.kind &&
499+
!inner.span.from_expansion() &&
500+
let Some(suggestion) = simplify_not(self.cx, inner)
501+
{
502+
span_lint_and_sugg(
503+
self.cx,
504+
NONMINIMAL_BOOL,
505+
expr.span,
506+
"this boolean expression can be simplified",
507+
"try",
508+
suggestion,
509+
Applicability::MachineApplicable,
510+
);
510511
}
511512

512513
walk_expr(self, expr);

src/tools/clippy/clippy_lints/src/copies.rs

+62-8
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_then};
22
use clippy_utils::source::{first_line_of_span, indent_of, reindent_multiline, snippet, snippet_opt};
3-
use clippy_utils::ty::needs_ordered_drop;
3+
use clippy_utils::ty::{is_interior_mut_ty, needs_ordered_drop};
44
use clippy_utils::visitors::for_each_expr;
55
use clippy_utils::{
6-
capture_local_usage, eq_expr_value, get_enclosing_block, hash_expr, hash_stmt, if_sequence, is_else_clause,
7-
is_lint_allowed, path_to_local, search_same, ContainsName, HirEqInterExpr, SpanlessEq,
6+
capture_local_usage, def_path_def_ids, eq_expr_value, find_binding_init, get_enclosing_block, hash_expr, hash_stmt,
7+
if_sequence, is_else_clause, is_lint_allowed, path_to_local, search_same, ContainsName, HirEqInterExpr, SpanlessEq,
88
};
99
use core::iter;
1010
use core::ops::ControlFlow;
1111
use rustc_errors::Applicability;
12+
use rustc_hir::def_id::DefIdSet;
1213
use rustc_hir::intravisit;
1314
use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, HirIdSet, Stmt, StmtKind};
1415
use rustc_lint::{LateContext, LateLintPass};
15-
use rustc_session::{declare_lint_pass, declare_tool_lint};
16+
use rustc_middle::query::Key;
17+
use rustc_session::{declare_tool_lint, impl_lint_pass};
1618
use rustc_span::hygiene::walk_chain;
1719
use rustc_span::source_map::SourceMap;
1820
use rustc_span::{BytePos, Span, Symbol};
@@ -159,18 +161,40 @@ declare_clippy_lint! {
159161
"`if` statement with shared code in all blocks"
160162
}
161163

162-
declare_lint_pass!(CopyAndPaste => [
164+
pub struct CopyAndPaste {
165+
ignore_interior_mutability: Vec<String>,
166+
ignored_ty_ids: DefIdSet,
167+
}
168+
169+
impl CopyAndPaste {
170+
pub fn new(ignore_interior_mutability: Vec<String>) -> Self {
171+
Self {
172+
ignore_interior_mutability,
173+
ignored_ty_ids: DefIdSet::new(),
174+
}
175+
}
176+
}
177+
178+
impl_lint_pass!(CopyAndPaste => [
163179
IFS_SAME_COND,
164180
SAME_FUNCTIONS_IN_IF_CONDITION,
165181
IF_SAME_THEN_ELSE,
166182
BRANCHES_SHARING_CODE
167183
]);
168184

169185
impl<'tcx> LateLintPass<'tcx> for CopyAndPaste {
186+
fn check_crate(&mut self, cx: &LateContext<'tcx>) {
187+
for ignored_ty in &self.ignore_interior_mutability {
188+
let path: Vec<&str> = ignored_ty.split("::").collect();
189+
for id in def_path_def_ids(cx, path.as_slice()) {
190+
self.ignored_ty_ids.insert(id);
191+
}
192+
}
193+
}
170194
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
171195
if !expr.span.from_expansion() && matches!(expr.kind, ExprKind::If(..)) && !is_else_clause(cx.tcx, expr) {
172196
let (conds, blocks) = if_sequence(expr);
173-
lint_same_cond(cx, &conds);
197+
lint_same_cond(cx, &conds, &self.ignored_ty_ids);
174198
lint_same_fns_in_if_cond(cx, &conds);
175199
let all_same =
176200
!is_lint_allowed(cx, IF_SAME_THEN_ELSE, expr.hir_id) && lint_if_same_then_else(cx, &conds, &blocks);
@@ -547,9 +571,39 @@ fn check_for_warn_of_moved_symbol(cx: &LateContext<'_>, symbols: &[(HirId, Symbo
547571
})
548572
}
549573

574+
fn method_caller_is_mutable(cx: &LateContext<'_>, caller_expr: &Expr<'_>, ignored_ty_ids: &DefIdSet) -> bool {
575+
let caller_ty = cx.typeck_results().expr_ty(caller_expr);
576+
// Check if given type has inner mutability and was not set to ignored by the configuration
577+
let is_inner_mut_ty = is_interior_mut_ty(cx, caller_ty)
578+
&& !matches!(caller_ty.ty_adt_id(), Some(adt_id) if ignored_ty_ids.contains(&adt_id));
579+
580+
is_inner_mut_ty
581+
|| caller_ty.is_mutable_ptr()
582+
// `find_binding_init` will return the binding iff its not mutable
583+
|| path_to_local(caller_expr)
584+
.and_then(|hid| find_binding_init(cx, hid))
585+
.is_none()
586+
}
587+
550588
/// Implementation of `IFS_SAME_COND`.
551-
fn lint_same_cond(cx: &LateContext<'_>, conds: &[&Expr<'_>]) {
552-
for (i, j) in search_same(conds, |e| hash_expr(cx, e), |lhs, rhs| eq_expr_value(cx, lhs, rhs)) {
589+
fn lint_same_cond(cx: &LateContext<'_>, conds: &[&Expr<'_>], ignored_ty_ids: &DefIdSet) {
590+
for (i, j) in search_same(
591+
conds,
592+
|e| hash_expr(cx, e),
593+
|lhs, rhs| {
594+
// Ignore eq_expr side effects iff one of the expressin kind is a method call
595+
// and the caller is not a mutable, including inner mutable type.
596+
if let ExprKind::MethodCall(_, caller, _, _) = lhs.kind {
597+
if method_caller_is_mutable(cx, caller, ignored_ty_ids) {
598+
false
599+
} else {
600+
SpanlessEq::new(cx).eq_expr(lhs, rhs)
601+
}
602+
} else {
603+
eq_expr_value(cx, lhs, rhs)
604+
}
605+
},
606+
) {
553607
span_lint_and_note(
554608
cx,
555609
IFS_SAME_COND,

src/tools/clippy/clippy_lints/src/declared_lints.rs

+3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
3535
crate::utils::internal_lints::produce_ice::PRODUCE_ICE_INFO,
3636
#[cfg(feature = "internal")]
3737
crate::utils::internal_lints::unnecessary_def_path::UNNECESSARY_DEF_PATH_INFO,
38+
crate::allow_attributes::ALLOW_ATTRIBUTES_INFO,
3839
crate::almost_complete_range::ALMOST_COMPLETE_RANGE_INFO,
3940
crate::approx_const::APPROX_CONSTANT_INFO,
4041
crate::as_conversions::AS_CONVERSIONS_INFO,
@@ -262,6 +263,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
262263
crate::manual_clamp::MANUAL_CLAMP_INFO,
263264
crate::manual_is_ascii_check::MANUAL_IS_ASCII_CHECK_INFO,
264265
crate::manual_let_else::MANUAL_LET_ELSE_INFO,
266+
crate::manual_main_separator_str::MANUAL_MAIN_SEPARATOR_STR_INFO,
265267
crate::manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE_INFO,
266268
crate::manual_rem_euclid::MANUAL_REM_EUCLID_INFO,
267269
crate::manual_retain::MANUAL_RETAIN_INFO,
@@ -616,6 +618,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
616618
crate::unnamed_address::VTABLE_ADDRESS_COMPARISONS_INFO,
617619
crate::unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS_INFO,
618620
crate::unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS_INFO,
621+
crate::unnecessary_struct_initialization::UNNECESSARY_STRUCT_INITIALIZATION_INFO,
619622
crate::unnecessary_wraps::UNNECESSARY_WRAPS_INFO,
620623
crate::unnested_or_patterns::UNNESTED_OR_PATTERNS_INFO,
621624
crate::unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME_INFO,

src/tools/clippy/clippy_lints/src/default.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg};
2-
use clippy_utils::source::snippet_with_macro_callsite;
2+
use clippy_utils::source::snippet_with_context;
33
use clippy_utils::ty::{has_drop, is_copy};
44
use clippy_utils::{
55
any_parent_is_automatically_derived, contains_name, get_parent_expr, is_from_proc_macro, match_def_path, paths,
@@ -160,6 +160,8 @@ impl<'tcx> LateLintPass<'tcx> for Default {
160160
}
161161
};
162162

163+
let init_ctxt = local.span.ctxt();
164+
163165
// find all "later statement"'s where the fields of the binding set as
164166
// Default::default() get reassigned, unless the reassignment refers to the original binding
165167
let mut first_assign = None;
@@ -169,7 +171,7 @@ impl<'tcx> LateLintPass<'tcx> for Default {
169171
// find out if and which field was set by this `consecutive_statement`
170172
if let Some((field_ident, assign_rhs)) = field_reassigned_by_stmt(consecutive_statement, binding_name) {
171173
// interrupt and cancel lint if assign_rhs references the original binding
172-
if contains_name(binding_name, assign_rhs, cx) {
174+
if contains_name(binding_name, assign_rhs, cx) || init_ctxt != consecutive_statement.span.ctxt() {
173175
cancel_lint = true;
174176
break;
175177
}
@@ -204,11 +206,12 @@ impl<'tcx> LateLintPass<'tcx> for Default {
204206
.iter()
205207
.all(|field| assigned_fields.iter().any(|(a, _)| a == &field.name));
206208

209+
let mut app = Applicability::Unspecified;
207210
let field_list = assigned_fields
208211
.into_iter()
209212
.map(|(field, rhs)| {
210213
// extract and store the assigned value for help message
211-
let value_snippet = snippet_with_macro_callsite(cx, rhs.span, "..");
214+
let value_snippet = snippet_with_context(cx, rhs.span, init_ctxt, "..", &mut app).0;
212215
format!("{field}: {value_snippet}")
213216
})
214217
.collect::<Vec<String>>()

src/tools/clippy/clippy_lints/src/derive.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ use rustc_span::sym;
2424

2525
declare_clippy_lint! {
2626
/// ### What it does
27-
/// Checks for deriving `Hash` but implementing `PartialEq`
28-
/// explicitly or vice versa.
27+
/// Lints against manual `PartialEq` implementations for types with a derived `Hash`
28+
/// implementation.
2929
///
3030
/// ### Why is this bad?
3131
/// The implementation of these traits must agree (for
@@ -54,8 +54,8 @@ declare_clippy_lint! {
5454

5555
declare_clippy_lint! {
5656
/// ### What it does
57-
/// Checks for deriving `Ord` but implementing `PartialOrd`
58-
/// explicitly or vice versa.
57+
/// Lints against manual `PartialOrd` and `Ord` implementations for types with a derived `Ord`
58+
/// or `PartialOrd` implementation.
5959
///
6060
/// ### Why is this bad?
6161
/// The implementation of these traits must agree (for

src/tools/clippy/clippy_lints/src/functions/must_use.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,7 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp
5050
let attr = cx.tcx.get_attr(item.owner_id, sym::must_use);
5151
if let Some(attr) = attr {
5252
check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr);
53-
} else if is_public
54-
&& !is_proc_macro(attrs)
55-
&& trait_ref_of_method(cx, item.owner_id.def_id).is_none()
56-
{
53+
} else if is_public && !is_proc_macro(attrs) && trait_ref_of_method(cx, item.owner_id.def_id).is_none() {
5754
check_must_use_candidate(
5855
cx,
5956
sig.decl,

0 commit comments

Comments
 (0)