mirror of
https://github.com/rust-lang/rust-clippy
synced 2025-02-26 04:17:21 +00:00
The `restriction` group contains many lints which are not about necessarily “bad” things, but style choices — perhaps even style choices which contradict conventional Rust style — or are otherwise very situational. This results in silly wording like “Why is this bad? It isn't, but ...”, which I’ve seen confuse a newcomer at least once. To improve this situation, this commit replaces the “Why is this bad?” section heading with “Why restrict this?”, for most, but not all, restriction lints. I left alone the ones whose placement in the restriction group is more incidental. In order to make this make sense, I had to remove the “It isn't, but” texts from the contents of the sections. Sometimes further changes were needed, or there were obvious fixes to make, and I went ahead and made those changes without attempting to split them into another commit, even though many of them are not strictly necessary for the “Why restrict this?” project.
74 lines
2.6 KiB
Rust
74 lines
2.6 KiB
Rust
use ast::{AttrStyle, Attribute};
|
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
|
use clippy_utils::is_from_proc_macro;
|
|
use rustc_ast as ast;
|
|
use rustc_errors::Applicability;
|
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
|
use rustc_middle::lint::in_external_macro;
|
|
use rustc_session::declare_lint_pass;
|
|
|
|
declare_clippy_lint! {
|
|
/// ### What it does
|
|
/// Checks for usage of the `#[allow]` attribute and suggests replacing it with
|
|
/// the `#[expect]` (See [RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reasons.html))
|
|
///
|
|
/// The expect attribute is still unstable and requires the `lint_reasons`
|
|
/// on nightly. It can be enabled by adding `#![feature(lint_reasons)]` to
|
|
/// the crate root.
|
|
///
|
|
/// This lint only warns outer attributes (`#[allow]`), as inner attributes
|
|
/// (`#![allow]`) are usually used to enable or disable lints on a global scale.
|
|
///
|
|
/// ### Why restrict this?
|
|
/// `#[allow]` attributes can linger after their reason for existence is gone.
|
|
/// `#[expect]` attributes suppress the lint emission, but emit a warning if
|
|
/// the expectation is unfulfilled. This can be useful to be notified when the
|
|
/// lint is no longer triggered, which may indicate the attribute can be removed.
|
|
///
|
|
/// ### Example
|
|
/// ```rust,ignore
|
|
/// #[allow(unused_mut)]
|
|
/// fn foo() -> usize {
|
|
/// let mut a = Vec::new();
|
|
/// a.len()
|
|
/// }
|
|
/// ```
|
|
/// Use instead:
|
|
/// ```rust,ignore
|
|
/// #![feature(lint_reasons)]
|
|
/// #[expect(unused_mut)]
|
|
/// fn foo() -> usize {
|
|
/// let mut a = Vec::new();
|
|
/// a.len()
|
|
/// }
|
|
/// ```
|
|
#[clippy::version = "1.70.0"]
|
|
pub ALLOW_ATTRIBUTES,
|
|
restriction,
|
|
"`#[allow]` will not trigger if a warning isn't found. `#[expect]` triggers if there are no warnings."
|
|
}
|
|
|
|
declare_lint_pass!(AllowAttribute => [ALLOW_ATTRIBUTES]);
|
|
|
|
impl LateLintPass<'_> for AllowAttribute {
|
|
// Separate each crate's features.
|
|
fn check_attribute<'cx>(&mut self, cx: &LateContext<'cx>, attr: &'cx Attribute) {
|
|
if !in_external_macro(cx.sess(), attr.span)
|
|
&& cx.tcx.features().lint_reasons
|
|
&& let AttrStyle::Outer = attr.style
|
|
&& let Some(ident) = attr.ident()
|
|
&& ident.name == rustc_span::symbol::sym::allow
|
|
&& !is_from_proc_macro(cx, &attr)
|
|
{
|
|
span_lint_and_sugg(
|
|
cx,
|
|
ALLOW_ATTRIBUTES,
|
|
ident.span,
|
|
"#[allow] attribute found",
|
|
"replace it with",
|
|
"expect".into(),
|
|
Applicability::MachineApplicable,
|
|
);
|
|
}
|
|
}
|
|
}
|