Skip to content

Commit d65c9a5

Browse files
committed
Extend tests + improve description + general improvement
1 parent 2d572d4 commit d65c9a5

File tree

5 files changed

+59
-57
lines changed

5 files changed

+59
-57
lines changed

clippy_lints/src/allow_attribute.rs

Lines changed: 35 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
1-
use ast::{AttrStyle, MetaItemKind};
2-
use clippy_utils::{diagnostics::span_lint_and_sugg, source::snippet};
1+
use ast::AttrStyle;
2+
use clippy_utils::diagnostics::span_lint_and_sugg;
33
use rustc_ast as ast;
44
use rustc_errors::Applicability;
55
use rustc_lint::{LateContext, LateLintPass};
6-
use rustc_session::{declare_tool_lint, impl_lint_pass};
7-
use rustc_span::{symbol::Ident, BytePos};
6+
use rustc_session::{declare_lint_pass, declare_tool_lint};
87

98
declare_clippy_lint! {
10-
/// ### What it does
11-
/// Detects uses of the `#[allow]` attribute and suggests to replace it with the new `#[expect]` attribute implemented by `#![feature(lint_reasons)]` ([RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reasons.html))
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+
///
1219
/// ### Why is this bad?
13-
/// Using `#[allow]` isn't bad, but `#[expect]` may be preferred as it lints if the code **doesn't** produce a warning.
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+
///
1425
/// ### Example
1526
/// ```rust,ignore
1627
/// #[allow(unused_mut)]
@@ -34,59 +45,34 @@ declare_clippy_lint! {
3445
"`#[allow]` will not trigger if a warning isn't found. `#[expect]` triggers if there are no warnings."
3546
}
3647

37-
pub struct AllowAttribute {
38-
pub lint_reasons_active: bool,
39-
}
40-
41-
impl_lint_pass!(AllowAttribute => [ALLOW_ATTRIBUTE]);
48+
declare_lint_pass!(AllowAttribute => [ALLOW_ATTRIBUTE]);
4249

4350
impl LateLintPass<'_> for AllowAttribute {
4451
// Separate each crate's features.
45-
fn check_crate_post(&mut self, _: &LateContext<'_>) {
46-
self.lint_reasons_active = false;
47-
}
4852
fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) {
49-
// Check inner attributes
50-
51-
if_chain! {
52-
if let AttrStyle::Inner = attr.style;
53-
if attr.ident()
54-
.unwrap_or(Ident::with_dummy_span(sym!(empty))) // Will not trigger if doesn't have an ident.
55-
.name == sym!(feature);
56-
if let ast::AttrKind::Normal(normal) = &attr.kind;
57-
if let Some(MetaItemKind::List(list)) = normal.item.meta_kind();
58-
if let Some(symbol) = list.get(0);
59-
if symbol.ident().unwrap().name == sym!(lint_reasons);
60-
then {
61-
self.lint_reasons_active = true;
62-
}
63-
}
64-
65-
// Check outer attributes
66-
6753
if_chain! {
54+
if cx.tcx.features().lint_reasons;
6855
if let AttrStyle::Outer = attr.style;
69-
if attr.ident()
70-
.unwrap_or(Ident::with_dummy_span(sym!(empty))) // Will not trigger if doesn't have an ident.
71-
.name == sym!(allow);
72-
if self.lint_reasons_active;
56+
if let Some(ident) = attr.ident();
57+
if ident.name == rustc_span::symbol::sym::allow;
7358
then {
7459
span_lint_and_sugg(
7560
cx,
7661
ALLOW_ATTRIBUTE,
77-
attr.span,
62+
ident.span,
7863
"#[allow] attribute found",
79-
"replace it with",
80-
format!("#[expect{})]", snippet(
81-
cx,
82-
attr.ident().unwrap().span
83-
.with_lo(
84-
attr.ident().unwrap().span.hi() + BytePos(2) // Cut [(
85-
)
86-
.with_hi(
87-
attr.meta().unwrap().span.hi() - BytePos(2) // Cut )]
88-
)
89-
, "...")), Applicability::MachineApplicable);
64+
"replace it with", "expect".into()
65+
// format!("expect{}", snippet(
66+
// cx,
67+
// ident.span
68+
// .with_lo(
69+
// ident.span.hi() + BytePos(2) // Cut *(
70+
// )
71+
// .with_hi(
72+
// attr.meta().unwrap().span.hi() - BytePos(1) // Cut )
73+
// )
74+
// , "..."))
75+
, Applicability::MachineApplicable);
9076
}
9177
}
9278
}

clippy_lints/src/lib.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -934,11 +934,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
934934
store.register_late_pass(|_| Box::new(missing_assert_message::MissingAssertMessage));
935935
store.register_early_pass(|| Box::new(redundant_async_block::RedundantAsyncBlock));
936936
store.register_late_pass(|_| Box::new(let_with_type_underscore::UnderscoreTyped));
937-
store.register_late_pass(|_| {
938-
Box::new(allow_attribute::AllowAttribute {
939-
lint_reasons_active: false,
940-
})
941-
});
937+
store.register_late_pass(|_| Box::new(allow_attribute::AllowAttribute));
942938
// add lints here, do not remove this comment, it's used in `new_lint`
943939
}
944940

tests/ui/allow_attribute.fixed

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,10 @@ struct T2; // Should not lint
1616
struct T3;
1717
#[warn(clippy::needless_borrow)] // Should not lint
1818
struct T4;
19+
// `panic = "unwind"` should always be true
20+
#[cfg_attr(panic = "unwind", expect(dead_code))]
21+
struct CfgT;
22+
23+
fn ignore_inner_attr() {
24+
#![allow(unused)] // Should not lint
25+
}

tests/ui/allow_attribute.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,10 @@ struct T2; // Should not lint
1616
struct T3;
1717
#[warn(clippy::needless_borrow)] // Should not lint
1818
struct T4;
19+
// `panic = "unwind"` should always be true
20+
#[cfg_attr(panic = "unwind", allow(dead_code))]
21+
struct CfgT;
22+
23+
fn ignore_inner_attr() {
24+
#![allow(unused)] // Should not lint
25+
}

tests/ui/allow_attribute.stderr

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
error: #[allow] attribute found
2-
--> $DIR/allow_attribute.rs:11:1
2+
--> $DIR/allow_attribute.rs:11:3
33
|
44
LL | #[allow(dead_code)]
5-
| ^^^^^^^^^^^^^^^^^^^ help: replace it with: `#[expect(dead_code)]`
5+
| ^^^^^ help: replace it with: `expect`
66
|
77
= note: `-D clippy::allow-attribute` implied by `-D warnings`
88

9-
error: aborting due to previous error
9+
error: #[allow] attribute found
10+
--> $DIR/allow_attribute.rs:20:30
11+
|
12+
LL | #[cfg_attr(panic = "unwind", allow(dead_code))]
13+
| ^^^^^ help: replace it with: `expect`
14+
15+
error: aborting due to 2 previous errors
1016

0 commit comments

Comments
 (0)