mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-15 01:17:16 +00:00
Auto merge of #8504 - xFrednet:8502-allow-lint-without-reason, r=flip1995
Add lint to detect `allow` attributes without reason I was considering putting this lint into the pedantic group. However, that would result in countless warnings for existing projects. Having it in restriction also seems good to me 🙃 (And now I need sleep 💤 ) --- changelog: New lint [`allow_lint_without_reason`] (Requires the `lint_reasons` feature) Closes: rust-lang/rust-clippy#8502
This commit is contained in:
commit
48d54942f5
6 changed files with 99 additions and 1 deletions
|
@ -3042,6 +3042,7 @@ Released 2018-09-13
|
|||
<!-- lint disable no-unused-definitions -->
|
||||
<!-- begin autogenerated links to lint list -->
|
||||
[`absurd_extreme_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#absurd_extreme_comparisons
|
||||
[`allow_attributes_without_reason`]: https://rust-lang.github.io/rust-clippy/master/index.html#allow_attributes_without_reason
|
||||
[`almost_swapped`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_swapped
|
||||
[`approx_constant`]: https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant
|
||||
[`as_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions
|
||||
|
|
|
@ -255,7 +255,38 @@ declare_clippy_lint! {
|
|||
"usage of `cfg(operating_system)` instead of `cfg(target_os = \"operating_system\")`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for attributes that allow lints without a reason.
|
||||
///
|
||||
/// (This requires the `lint_reasons` feature)
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// Allowing a lint should always have a reason. This reason should be documented to
|
||||
/// ensure that others understand the reasoning
|
||||
///
|
||||
/// ### Example
|
||||
/// Bad:
|
||||
/// ```rust
|
||||
/// #![feature(lint_reasons)]
|
||||
///
|
||||
/// #![allow(clippy::some_lint)]
|
||||
/// ```
|
||||
///
|
||||
/// Good:
|
||||
/// ```rust
|
||||
/// #![feature(lint_reasons)]
|
||||
///
|
||||
/// #![allow(clippy::some_lint, reason = "False positive rust-lang/rust-clippy#1002020")]
|
||||
/// ```
|
||||
#[clippy::version = "1.61.0"]
|
||||
pub ALLOW_ATTRIBUTES_WITHOUT_REASON,
|
||||
restriction,
|
||||
"ensures that all `allow` and `expect` attributes have a reason"
|
||||
}
|
||||
|
||||
declare_lint_pass!(Attributes => [
|
||||
ALLOW_ATTRIBUTES_WITHOUT_REASON,
|
||||
INLINE_ALWAYS,
|
||||
DEPRECATED_SEMVER,
|
||||
USELESS_ATTRIBUTE,
|
||||
|
@ -269,6 +300,9 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
|
|||
if is_lint_level(ident.name) {
|
||||
check_clippy_lint_names(cx, ident.name, items);
|
||||
}
|
||||
if matches!(ident.name, sym::allow | sym::expect) {
|
||||
check_lint_reason(cx, ident.name, items, attr);
|
||||
}
|
||||
if items.is_empty() || !attr.has_name(sym::deprecated) {
|
||||
return;
|
||||
}
|
||||
|
@ -404,6 +438,30 @@ fn check_clippy_lint_names(cx: &LateContext<'_>, name: Symbol, items: &[NestedMe
|
|||
}
|
||||
}
|
||||
|
||||
fn check_lint_reason(cx: &LateContext<'_>, name: Symbol, items: &[NestedMetaItem], attr: &'_ Attribute) {
|
||||
// Check for the feature
|
||||
if !cx.tcx.sess.features_untracked().lint_reasons {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the reason is present
|
||||
if let Some(item) = items.last().and_then(NestedMetaItem::meta_item)
|
||||
&& let MetaItemKind::NameValue(_) = &item.kind
|
||||
&& item.path == sym::reason
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
span_lint_and_help(
|
||||
cx,
|
||||
ALLOW_ATTRIBUTES_WITHOUT_REASON,
|
||||
attr.span,
|
||||
&format!("`{}` attribute without specifying a reason", name.as_str()),
|
||||
None,
|
||||
"try adding a reason at the end with `, reason = \"..\"`",
|
||||
);
|
||||
}
|
||||
|
||||
fn is_relevant_item(cx: &LateContext<'_>, item: &Item<'_>) -> bool {
|
||||
if let ItemKind::Fn(_, _, eid) = item.kind {
|
||||
is_relevant_expr(cx, cx.tcx.typeck_body(eid), &cx.tcx.hir().body(eid).value)
|
||||
|
@ -659,5 +717,5 @@ fn check_mismatched_target_os(cx: &EarlyContext<'_>, attr: &Attribute) {
|
|||
}
|
||||
|
||||
fn is_lint_level(symbol: Symbol) -> bool {
|
||||
matches!(symbol, sym::allow | sym::warn | sym::deny | sym::forbid)
|
||||
matches!(symbol, sym::allow | sym::expect | sym::warn | sym::deny | sym::forbid)
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ store.register_lints(&[
|
|||
assign_ops::ASSIGN_OP_PATTERN,
|
||||
assign_ops::MISREFACTORED_ASSIGN_OP,
|
||||
async_yields_async::ASYNC_YIELDS_ASYNC,
|
||||
attrs::ALLOW_ATTRIBUTES_WITHOUT_REASON,
|
||||
attrs::BLANKET_CLIPPY_RESTRICTION_LINTS,
|
||||
attrs::DEPRECATED_CFG_ATTR,
|
||||
attrs::DEPRECATED_SEMVER,
|
||||
|
|
|
@ -8,6 +8,7 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
|
|||
LintId::of(as_conversions::AS_CONVERSIONS),
|
||||
LintId::of(asm_syntax::INLINE_ASM_X86_ATT_SYNTAX),
|
||||
LintId::of(asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX),
|
||||
LintId::of(attrs::ALLOW_ATTRIBUTES_WITHOUT_REASON),
|
||||
LintId::of(casts::FN_TO_NUMERIC_CAST_ANY),
|
||||
LintId::of(create_dir::CREATE_DIR),
|
||||
LintId::of(dbg_macro::DBG_MACRO),
|
||||
|
|
14
tests/ui/allow_attributes_without_reason.rs
Normal file
14
tests/ui/allow_attributes_without_reason.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
#![feature(lint_reasons)]
|
||||
#![deny(clippy::allow_attributes_without_reason)]
|
||||
|
||||
// These should trigger the lint
|
||||
#[allow(dead_code)]
|
||||
#[allow(dead_code, deprecated)]
|
||||
// These should be fine
|
||||
#[allow(dead_code, reason = "This should be allowed")]
|
||||
#[warn(dyn_drop, reason = "Warnings can also have reasons")]
|
||||
#[warn(deref_nullptr)]
|
||||
#[deny(deref_nullptr)]
|
||||
#[forbid(deref_nullptr)]
|
||||
|
||||
fn main() {}
|
23
tests/ui/allow_attributes_without_reason.stderr
Normal file
23
tests/ui/allow_attributes_without_reason.stderr
Normal file
|
@ -0,0 +1,23 @@
|
|||
error: `allow` attribute without specifying a reason
|
||||
--> $DIR/allow_attributes_without_reason.rs:5:1
|
||||
|
|
||||
LL | #[allow(dead_code)]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/allow_attributes_without_reason.rs:2:9
|
||||
|
|
||||
LL | #![deny(clippy::allow_attributes_without_reason)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= help: try adding a reason at the end with `, reason = ".."`
|
||||
|
||||
error: `allow` attribute without specifying a reason
|
||||
--> $DIR/allow_attributes_without_reason.rs:6:1
|
||||
|
|
||||
LL | #[allow(dead_code, deprecated)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a reason at the end with `, reason = ".."`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
Loading…
Reference in a new issue