2 use clippy_utils
::diagnostics
::span_lint_and_sugg
;
4 use rustc_errors
::Applicability
;
5 use rustc_lint
::{LateContext, LateLintPass}
;
6 use rustc_session
::{declare_lint_pass, declare_tool_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))
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
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.
19 /// ### Why is this bad?
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.
27 /// #[allow(unused_mut)]
28 /// fn foo() -> usize {
29 /// let mut a = Vec::new();
35 /// #![feature(lint_reasons)]
36 /// #[expect(unused_mut)]
37 /// fn foo() -> usize {
38 /// let mut a = Vec::new();
42 #[clippy::version = "1.69.0"]
45 "`#[allow]` will not trigger if a warning isn't found. `#[expect]` triggers if there are no warnings."
48 declare_lint_pass
!(AllowAttribute
=> [ALLOW_ATTRIBUTES
]);
50 impl LateLintPass
<'_
> for AllowAttribute
{
51 // Separate each crate's features.
52 fn check_attribute(&mut self, cx
: &LateContext
<'_
>, attr
: &ast
::Attribute
) {
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
;
63 "#[allow] attribute found",
66 Applicability
::MachineApplicable
,