Skip to content

Commit 4995b4e

Browse files
committed
Auto merge of #9046 - xFrednet:rust-97660-expection-something-something, r=Jarcho
Fix `#[expect]` for most clippy lints This PR fixes most `#[expect]` - lint interactions listed in rust-lang/rust#97660. [My comment in the issue](rust-lang/rust#97660 (comment)) shows the current progress (Once this is merged). I plan to work on `duplicate_mod` and `multiple_inherent_impl` and leave the rest for later. I feel like stabilizing the feature is more important than fixing the last few nits, which currently also don't work with `#[allow]`. --- changelog: none r? `@Jarcho` cc: rust-lang/rust#97660
2 parents a4130e1 + d11618e commit 4995b4e

34 files changed

+464
-231
lines changed

clippy_lints/src/attrs.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,17 @@ declare_clippy_lint! {
7878
/// Checks for `extern crate` and `use` items annotated with
7979
/// lint attributes.
8080
///
81-
/// This lint permits `#[allow(unused_imports)]`, `#[allow(deprecated)]`,
82-
/// `#[allow(unreachable_pub)]`, `#[allow(clippy::wildcard_imports)]` and
83-
/// `#[allow(clippy::enum_glob_use)]` on `use` items and `#[allow(unused_imports)]` on
84-
/// `extern crate` items with a `#[macro_use]` attribute.
81+
/// This lint permits lint attributes for lints emitted on the items themself.
82+
/// For `use` items these lints are:
83+
/// * deprecated
84+
/// * unreachable_pub
85+
/// * unused_imports
86+
/// * clippy::enum_glob_use
87+
/// * clippy::macro_use_imports
88+
/// * clippy::wildcard_imports
89+
///
90+
/// For `extern crate` items these lints are:
91+
/// * `unused_imports` on items with `#[macro_use]`
8592
///
8693
/// ### Why is this bad?
8794
/// Lint attributes have no effect on crate imports. Most
@@ -347,7 +354,10 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
347354
|| extract_clippy_lint(lint).map_or(false, |s| {
348355
matches!(
349356
s.as_str(),
350-
"wildcard_imports" | "enum_glob_use" | "redundant_pub_crate",
357+
"wildcard_imports"
358+
| "enum_glob_use"
359+
| "redundant_pub_crate"
360+
| "macro_use_imports",
351361
)
352362
})
353363
{

clippy_lints/src/booleans.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
1+
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
22
use clippy_utils::source::snippet_opt;
33
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
44
use clippy_utils::{eq_expr_value, get_trait_def_id, paths};
@@ -394,9 +394,10 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
394394
continue 'simplified;
395395
}
396396
if stats.terminals[i] != 0 && simplified_stats.terminals[i] == 0 {
397-
span_lint_and_then(
397+
span_lint_hir_and_then(
398398
self.cx,
399399
LOGIC_BUG,
400+
e.hir_id,
400401
e.span,
401402
"this boolean expression contains a logic bug",
402403
|diag| {
@@ -429,9 +430,10 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
429430
}
430431
}
431432
let nonminimal_bool_lint = |suggestions: Vec<_>| {
432-
span_lint_and_then(
433+
span_lint_hir_and_then(
433434
self.cx,
434435
NONMINIMAL_BOOL,
436+
e.hir_id,
435437
e.span,
436438
"this boolean expression can be simplified",
437439
|diag| {

clippy_lints/src/escape.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use clippy_utils::diagnostics::span_lint;
1+
use clippy_utils::diagnostics::span_lint_hir;
22
use clippy_utils::ty::contains_ty;
33
use rustc_hir::intravisit;
44
use rustc_hir::{self, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node};
@@ -118,9 +118,10 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
118118
});
119119

120120
for node in v.set {
121-
span_lint(
121+
span_lint_hir(
122122
cx,
123123
BOXED_LOCAL,
124+
node,
124125
cx.tcx.hir().span(node),
125126
"local variable doesn't need to be boxed here",
126127
);

clippy_lints/src/implicit_return.rs

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use clippy_utils::{
2-
diagnostics::span_lint_and_sugg,
2+
diagnostics::span_lint_hir_and_then,
33
get_async_fn_body, is_async_fn,
44
source::{snippet_with_applicability, snippet_with_context, walk_span_to_context},
55
visitors::expr_visitor_no_bodies,
@@ -43,31 +43,38 @@ declare_clippy_lint! {
4343

4444
declare_lint_pass!(ImplicitReturn => [IMPLICIT_RETURN]);
4545

46-
fn lint_return(cx: &LateContext<'_>, span: Span) {
46+
fn lint_return(cx: &LateContext<'_>, emission_place: HirId, span: Span) {
4747
let mut app = Applicability::MachineApplicable;
4848
let snip = snippet_with_applicability(cx, span, "..", &mut app);
49-
span_lint_and_sugg(
49+
span_lint_hir_and_then(
5050
cx,
5151
IMPLICIT_RETURN,
52+
emission_place,
5253
span,
5354
"missing `return` statement",
54-
"add `return` as shown",
55-
format!("return {}", snip),
56-
app,
55+
|diag| {
56+
diag.span_suggestion(span, "add `return` as shown", format!("return {}", snip), app);
57+
},
5758
);
5859
}
5960

60-
fn lint_break(cx: &LateContext<'_>, break_span: Span, expr_span: Span) {
61+
fn lint_break(cx: &LateContext<'_>, emission_place: HirId, break_span: Span, expr_span: Span) {
6162
let mut app = Applicability::MachineApplicable;
6263
let snip = snippet_with_context(cx, expr_span, break_span.ctxt(), "..", &mut app).0;
63-
span_lint_and_sugg(
64+
span_lint_hir_and_then(
6465
cx,
6566
IMPLICIT_RETURN,
67+
emission_place,
6668
break_span,
6769
"missing `return` statement",
68-
"change `break` to `return` as shown",
69-
format!("return {}", snip),
70-
app,
70+
|diag| {
71+
diag.span_suggestion(
72+
break_span,
73+
"change `break` to `return` as shown",
74+
format!("return {}", snip),
75+
app,
76+
);
77+
},
7178
);
7279
}
7380

@@ -152,7 +159,7 @@ fn lint_implicit_returns(
152159
// At this point sub_expr can be `None` in async functions which either diverge, or return
153160
// the unit type.
154161
if let Some(sub_expr) = sub_expr {
155-
lint_break(cx, e.span, sub_expr.span);
162+
lint_break(cx, e.hir_id, e.span, sub_expr.span);
156163
}
157164
} else {
158165
// the break expression is from a macro call, add a return to the loop
@@ -166,10 +173,10 @@ fn lint_implicit_returns(
166173
if add_return {
167174
#[expect(clippy::option_if_let_else)]
168175
if let Some(span) = call_site_span {
169-
lint_return(cx, span);
176+
lint_return(cx, expr.hir_id, span);
170177
LintLocation::Parent
171178
} else {
172-
lint_return(cx, expr.span);
179+
lint_return(cx, expr.hir_id, expr.span);
173180
LintLocation::Inner
174181
}
175182
} else {
@@ -198,10 +205,10 @@ fn lint_implicit_returns(
198205
{
199206
#[expect(clippy::option_if_let_else)]
200207
if let Some(span) = call_site_span {
201-
lint_return(cx, span);
208+
lint_return(cx, expr.hir_id, span);
202209
LintLocation::Parent
203210
} else {
204-
lint_return(cx, expr.span);
211+
lint_return(cx, expr.hir_id, expr.span);
205212
LintLocation::Inner
206213
}
207214
},

clippy_lints/src/macro_use.rs

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use clippy_utils::diagnostics::span_lint_and_sugg;
1+
use clippy_utils::diagnostics::span_lint_hir_and_then;
22
use clippy_utils::source::snippet;
33
use hir::def::{DefKind, Res};
44
use if_chain::if_chain;
@@ -51,8 +51,9 @@ impl MacroRefData {
5151
#[derive(Default)]
5252
#[expect(clippy::module_name_repetitions)]
5353
pub struct MacroUseImports {
54-
/// the actual import path used and the span of the attribute above it.
55-
imports: Vec<(String, Span)>,
54+
/// the actual import path used and the span of the attribute above it. The value is
55+
/// the location, where the lint should be emitted.
56+
imports: Vec<(String, Span, hir::HirId)>,
5657
/// the span of the macro reference, kept to ensure only one reference is used per macro call.
5758
collected: FxHashSet<Span>,
5859
mac_refs: Vec<MacroRefData>,
@@ -91,7 +92,8 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
9192
if_chain! {
9293
if cx.sess().opts.edition >= Edition::Edition2018;
9394
if let hir::ItemKind::Use(path, _kind) = &item.kind;
94-
let attrs = cx.tcx.hir().attrs(item.hir_id());
95+
let hir_id = item.hir_id();
96+
let attrs = cx.tcx.hir().attrs(hir_id);
9597
if let Some(mac_attr) = attrs.iter().find(|attr| attr.has_name(sym::macro_use));
9698
if let Res::Def(DefKind::Mod, id) = path.res;
9799
if !id.is_local();
@@ -100,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
100102
if let Res::Def(DefKind::Macro(_mac_type), mac_id) = kid.res {
101103
let span = mac_attr.span;
102104
let def_path = cx.tcx.def_path_str(mac_id);
103-
self.imports.push((def_path, span));
105+
self.imports.push((def_path, span, hir_id));
104106
}
105107
}
106108
} else {
@@ -138,7 +140,7 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
138140
fn check_crate_post(&mut self, cx: &LateContext<'_>) {
139141
let mut used = FxHashMap::default();
140142
let mut check_dup = vec![];
141-
for (import, span) in &self.imports {
143+
for (import, span, hir_id) in &self.imports {
142144
let found_idx = self.mac_refs.iter().position(|mac| import.ends_with(&mac.name));
143145

144146
if let Some(idx) = found_idx {
@@ -151,7 +153,7 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
151153
[] | [_] => return,
152154
[root, item] => {
153155
if !check_dup.contains(&(*item).to_string()) {
154-
used.entry(((*root).to_string(), span))
156+
used.entry(((*root).to_string(), span, hir_id))
155157
.or_insert_with(Vec::new)
156158
.push((*item).to_string());
157159
check_dup.push((*item).to_string());
@@ -169,13 +171,13 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
169171
}
170172
})
171173
.collect::<Vec<_>>();
172-
used.entry(((*root).to_string(), span))
174+
used.entry(((*root).to_string(), span, hir_id))
173175
.or_insert_with(Vec::new)
174176
.push(filtered.join("::"));
175177
check_dup.extend(filtered);
176178
} else {
177179
let rest = rest.to_vec();
178-
used.entry(((*root).to_string(), span))
180+
used.entry(((*root).to_string(), span, hir_id))
179181
.or_insert_with(Vec::new)
180182
.push(rest.join("::"));
181183
check_dup.extend(rest.iter().map(ToString::to_string));
@@ -186,27 +188,33 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
186188
}
187189

188190
let mut suggestions = vec![];
189-
for ((root, span), path) in used {
191+
for ((root, span, hir_id), path) in used {
190192
if path.len() == 1 {
191-
suggestions.push((span, format!("{}::{}", root, path[0])));
193+
suggestions.push((span, format!("{}::{}", root, path[0]), hir_id));
192194
} else {
193-
suggestions.push((span, format!("{}::{{{}}}", root, path.join(", "))));
195+
suggestions.push((span, format!("{}::{{{}}}", root, path.join(", ")), hir_id));
194196
}
195197
}
196198

197199
// If mac_refs is not empty we have encountered an import we could not handle
198200
// such as `std::prelude::v1::foo` or some other macro that expands to an import.
199201
if self.mac_refs.is_empty() {
200-
for (span, import) in suggestions {
202+
for (span, import, hir_id) in suggestions {
201203
let help = format!("use {};", import);
202-
span_lint_and_sugg(
204+
span_lint_hir_and_then(
203205
cx,
204206
MACRO_USE_IMPORTS,
207+
*hir_id,
205208
*span,
206209
"`macro_use` attributes are no longer needed in the Rust 2018 edition",
207-
"remove the attribute and import the macro directly, try",
208-
help,
209-
Applicability::MaybeIncorrect,
210+
|diag| {
211+
diag.span_suggestion(
212+
*span,
213+
"remove the attribute and import the macro directly, try",
214+
help,
215+
Applicability::MaybeIncorrect,
216+
);
217+
},
210218
);
211219
}
212220
}

clippy_lints/src/manual_non_exhaustive.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use clippy_utils::diagnostics::span_lint_and_then;
1+
use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
22
use clippy_utils::source::snippet_opt;
3-
use clippy_utils::{is_doc_hidden, is_lint_allowed, meets_msrv, msrvs};
3+
use clippy_utils::{is_doc_hidden, meets_msrv, msrvs};
44
use rustc_ast::ast::{self, VisibilityKind};
55
use rustc_data_structures::fx::FxHashSet;
66
use rustc_errors::Applicability;
@@ -190,12 +190,13 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustiveEnum {
190190
!self
191191
.constructed_enum_variants
192192
.contains(&(enum_id.to_def_id(), variant_id.to_def_id()))
193-
&& !is_lint_allowed(cx, MANUAL_NON_EXHAUSTIVE, cx.tcx.hir().local_def_id_to_hir_id(enum_id))
194193
})
195194
{
196-
span_lint_and_then(
195+
let hir_id = cx.tcx.hir().local_def_id_to_hir_id(enum_id);
196+
span_lint_hir_and_then(
197197
cx,
198198
MANUAL_NON_EXHAUSTIVE,
199+
hir_id,
199200
enum_span,
200201
"this seems like a manual implementation of the non-exhaustive pattern",
201202
|diag| {

0 commit comments

Comments
 (0)