Skip to content

Commit f90d702

Browse files
committed
Auto merge of rust-lang#120924 - xFrednet:rfc-2383-stabilization-party, r=Urgau,blyxyas
Let's `#[expect]` some lints: Stabilize `lint_reasons` (RFC 2383) Let's give this another try! The [previous stabilization attempt](rust-lang#99063) was stalled by some unresolved questions. These have been discussed in a [lang team](rust-lang/lang-team#191) meeting. The last open question, regarding the semantics of the `#[expect]` attribute was decided on in rust-lang#115980 I've just updated the [stabilization report](rust-lang#54503 (comment)) with the discussed questions and decisions. Luckily, the decision is inline with the current implementation. This hopefully covers everything. Let's hope that the CI will be green like the spring. fixes rust-lang#115980 fixes rust-lang#54503 --- r? `@wesleywiser` Tacking Issue: rust-lang#54503 Stabilization Report: rust-lang#54503 (comment) Documentation Update: rust-lang/reference#1237 <!-- For Clippy: changelog: [`allow_attributes`]: Is now available on stable, since the `lint_reasons` feature was stabilized changelog: [`allow_attributes_without_reason`]: Is now available on stable, since the `lint_reasons` feature was stabilized --> --- Roses are red, Violets are blue, Let's expect lints, With reason clues
2 parents 01b3c24 + 3bbec6a commit f90d702

File tree

74 files changed

+602
-573
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+602
-573
lines changed

Diff for: CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1943,7 +1943,7 @@ Released 2022-05-19
19431943
[#8218](https://github.com/rust-lang/rust-clippy/pull/8218)
19441944
* [`needless_match`]
19451945
[#8471](https://github.com/rust-lang/rust-clippy/pull/8471)
1946-
* [`allow_attributes_without_reason`] (Requires `#![feature(lint_reasons)]`)
1946+
* [`allow_attributes_without_reason`]
19471947
[#8504](https://github.com/rust-lang/rust-clippy/pull/8504)
19481948
* [`print_in_format_impl`]
19491949
[#8253](https://github.com/rust-lang/rust-clippy/pull/8253)

Diff for: book/src/lint_configuration.md

+2
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,8 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
669669

670670
---
671671
**Affected lints:**
672+
* [`allow_attributes`](https://rust-lang.github.io/rust-clippy/master/index.html#allow_attributes)
673+
* [`allow_attributes_without_reason`](https://rust-lang.github.io/rust-clippy/master/index.html#allow_attributes_without_reason)
672674
* [`almost_complete_range`](https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_range)
673675
* [`approx_constant`](https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant)
674676
* [`assigning_clones`](https://rust-lang.github.io/rust-clippy/master/index.html#assigning_clones)

Diff for: clippy_config/src/conf.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ define_Conf! {
265265
///
266266
/// Suppress lints whenever the suggested change would cause breakage for other crates.
267267
(avoid_breaking_exported_api: bool = true),
268-
/// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD, MANUAL_HASH_ONE, ITER_KV_MAP, MANUAL_C_STR_LITERALS, ASSIGNING_CLONES, LEGACY_NUMERIC_CONSTANTS.
268+
/// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD, MANUAL_HASH_ONE, ITER_KV_MAP, MANUAL_C_STR_LITERALS, ASSIGNING_CLONES, LEGACY_NUMERIC_CONSTANTS, ALLOW_ATTRIBUTES, ALLOW_ATTRIBUTES_WITHOUT_REASON.
269269
///
270270
/// The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`
271271
#[default_text = ""]

Diff for: clippy_config/src/msrvs.rs

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ macro_rules! msrv_aliases {
1717

1818
// names may refer to stabilized feature flags or library items
1919
msrv_aliases! {
20+
1,81,0 { LINT_REASONS_STABILIZATION }
2021
1,77,0 { C_STR_LITERALS }
2122
1,76,0 { PTR_FROM_REF }
2223
1,71,0 { TUPLE_ARRAY_CONVERSIONS, BUILD_HASHER_HASH_ONE }

Diff for: clippy_lints/src/allow_attributes.rs

-74
This file was deleted.

Diff for: clippy_lints/src/attrs/allow_attributes.rs

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use clippy_utils::diagnostics::span_lint_and_sugg;
2+
use clippy_utils::is_from_proc_macro;
3+
use rustc_ast::{AttrStyle, Attribute};
4+
use rustc_errors::Applicability;
5+
use rustc_lint::{LateContext, LintContext};
6+
use rustc_middle::lint::in_external_macro;
7+
use super::ALLOW_ATTRIBUTES;
8+
9+
// Separate each crate's features.
10+
pub fn check<'cx>(cx: &LateContext<'cx>, attr: &'cx Attribute) {
11+
if !in_external_macro(cx.sess(), attr.span)
12+
&& let AttrStyle::Outer = attr.style
13+
&& let Some(ident) = attr.ident()
14+
&& !is_from_proc_macro(cx, &attr)
15+
{
16+
span_lint_and_sugg(
17+
cx,
18+
ALLOW_ATTRIBUTES,
19+
ident.span,
20+
"#[allow] attribute found",
21+
"replace it with",
22+
"expect".into(),
23+
Applicability::MachineApplicable,
24+
);
25+
}
26+
}

Diff for: clippy_lints/src/attrs/allow_attributes_without_reason.rs

-5
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,6 @@ use rustc_span::sym;
88
use rustc_span::symbol::Symbol;
99

1010
pub(super) fn check<'cx>(cx: &LateContext<'cx>, name: Symbol, items: &[NestedMetaItem], attr: &'cx Attribute) {
11-
// Check for the feature
12-
if !cx.tcx.features().lint_reasons {
13-
return;
14-
}
15-
1611
// Check if the reason is present
1712
if let Some(item) = items.last().and_then(NestedMetaItem::meta_item)
1813
&& let MetaItemKind::NameValue(_) = &item.kind

Diff for: clippy_lints/src/attrs/mod.rs

+61-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! checks for attributes
22
33
mod allow_attributes_without_reason;
4+
mod allow_attributes;
45
mod blanket_clippy_restriction_lints;
56
mod deprecated_cfg_attr;
67
mod deprecated_semver;
@@ -14,11 +15,11 @@ mod unnecessary_clippy_cfg;
1415
mod useless_attribute;
1516
mod utils;
1617

17-
use clippy_config::msrvs::Msrv;
18+
use clippy_config::msrvs::{self, Msrv};
1819
use rustc_ast::{Attribute, MetaItemKind, NestedMetaItem};
1920
use rustc_hir::{ImplItem, Item, ItemKind, TraitItem};
2021
use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
21-
use rustc_session::{declare_lint_pass, impl_lint_pass};
22+
use rustc_session::impl_lint_pass;
2223
use rustc_span::sym;
2324
use utils::{is_lint_level, is_relevant_impl, is_relevant_item, is_relevant_trait};
2425

@@ -272,23 +273,17 @@ declare_clippy_lint! {
272273
/// ### What it does
273274
/// Checks for attributes that allow lints without a reason.
274275
///
275-
/// (This requires the `lint_reasons` feature)
276-
///
277276
/// ### Why restrict this?
278277
/// Justifying each `allow` helps readers understand the reasoning,
279278
/// and may allow removing `allow` attributes if their purpose is obsolete.
280279
///
281280
/// ### Example
282281
/// ```no_run
283-
/// #![feature(lint_reasons)]
284-
///
285282
/// #![allow(clippy::some_lint)]
286283
/// ```
287284
///
288285
/// Use instead:
289286
/// ```no_run
290-
/// #![feature(lint_reasons)]
291-
///
292287
/// #![allow(clippy::some_lint, reason = "False positive rust-lang/rust-clippy#1002020")]
293288
/// ```
294289
#[clippy::version = "1.61.0"]
@@ -297,6 +292,41 @@ declare_clippy_lint! {
297292
"ensures that all `allow` and `expect` attributes have a reason"
298293
}
299294

295+
declare_clippy_lint! {
296+
/// ### What it does
297+
/// Checks for usage of the `#[allow]` attribute and suggests replacing it with
298+
/// the `#[expect]` (See [RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reasons.html))
299+
///
300+
/// This lint only warns outer attributes (`#[allow]`), as inner attributes
301+
/// (`#![allow]`) are usually used to enable or disable lints on a global scale.
302+
///
303+
/// ### Why is this bad?
304+
/// `#[expect]` attributes suppress the lint emission, but emit a warning, if
305+
/// the expectation is unfulfilled. This can be useful to be notified when the
306+
/// lint is no longer triggered.
307+
///
308+
/// ### Example
309+
/// ```rust,ignore
310+
/// #[allow(unused_mut)]
311+
/// fn foo() -> usize {
312+
/// let mut a = Vec::new();
313+
/// a.len()
314+
/// }
315+
/// ```
316+
/// Use instead:
317+
/// ```rust,ignore
318+
/// #[expect(unused_mut)]
319+
/// fn foo() -> usize {
320+
/// let mut a = Vec::new();
321+
/// a.len()
322+
/// }
323+
/// ```
324+
#[clippy::version = "1.70.0"]
325+
pub ALLOW_ATTRIBUTES,
326+
restriction,
327+
"`#[allow]` will not trigger if a warning isn't found. `#[expect]` triggers if there are no warnings."
328+
}
329+
300330
declare_clippy_lint! {
301331
/// ### What it does
302332
/// Checks for `#[should_panic]` attributes without specifying the expected panic message.
@@ -469,7 +499,12 @@ declare_clippy_lint! {
469499
"duplicated attribute"
470500
}
471501

472-
declare_lint_pass!(Attributes => [
502+
#[derive(Clone)]
503+
pub struct Attributes {
504+
msrv: Msrv,
505+
}
506+
507+
impl_lint_pass!(Attributes => [
473508
ALLOW_ATTRIBUTES_WITHOUT_REASON,
474509
INLINE_ALWAYS,
475510
DEPRECATED_SEMVER,
@@ -480,6 +515,13 @@ declare_lint_pass!(Attributes => [
480515
DUPLICATED_ATTRIBUTES,
481516
]);
482517

518+
impl Attributes {
519+
#[must_use]
520+
pub fn new(msrv: Msrv) -> Self {
521+
Self { msrv }
522+
}
523+
}
524+
483525
impl<'tcx> LateLintPass<'tcx> for Attributes {
484526
fn check_crate(&mut self, cx: &LateContext<'tcx>) {
485527
blanket_clippy_restriction_lints::check_command_line(cx);
@@ -492,8 +534,15 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
492534
if is_lint_level(ident.name, attr.id) {
493535
blanket_clippy_restriction_lints::check(cx, ident.name, items);
494536
}
537+
if matches!(ident.name, sym::allow) {
538+
if self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION) {
539+
allow_attributes::check(cx, attr);
540+
}
541+
}
495542
if matches!(ident.name, sym::allow | sym::expect) {
496-
allow_attributes_without_reason::check(cx, ident.name, items, attr);
543+
if self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION) {
544+
allow_attributes_without_reason::check(cx, ident.name, items, attr);
545+
}
497546
}
498547
if items.is_empty() || !attr.has_name(sym::deprecated) {
499548
return;
@@ -537,6 +586,8 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
537586
inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id()));
538587
}
539588
}
589+
590+
extract_msrv_attr!(LateContext);
540591
}
541592

542593
pub struct EarlyAttributes {

Diff for: clippy_lints/src/declared_lints.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
3838
#[cfg(feature = "internal")]
3939
crate::utils::internal_lints::unsorted_clippy_utils_paths::UNSORTED_CLIPPY_UTILS_PATHS_INFO,
4040
crate::absolute_paths::ABSOLUTE_PATHS_INFO,
41-
crate::allow_attributes::ALLOW_ATTRIBUTES_INFO,
4241
crate::almost_complete_range::ALMOST_COMPLETE_RANGE_INFO,
4342
crate::approx_const::APPROX_CONSTANT_INFO,
4443
crate::arc_with_non_send_sync::ARC_WITH_NON_SEND_SYNC_INFO,
@@ -49,6 +48,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
4948
crate::assertions_on_result_states::ASSERTIONS_ON_RESULT_STATES_INFO,
5049
crate::assigning_clones::ASSIGNING_CLONES_INFO,
5150
crate::async_yields_async::ASYNC_YIELDS_ASYNC_INFO,
51+
crate::attrs::ALLOW_ATTRIBUTES_INFO,
5252
crate::attrs::ALLOW_ATTRIBUTES_WITHOUT_REASON_INFO,
5353
crate::attrs::BLANKET_CLIPPY_RESTRICTION_LINTS_INFO,
5454
crate::attrs::DEPRECATED_CFG_ATTR_INFO,

Diff for: clippy_lints/src/lib.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#![feature(if_let_guard)]
77
#![feature(iter_intersperse)]
88
#![feature(let_chains)]
9-
#![feature(lint_reasons)]
9+
#![cfg_attr(bootstrap, feature(lint_reasons))]
1010
#![feature(never_type)]
1111
#![feature(rustc_private)]
1212
#![feature(stmt_expr_attributes)]
@@ -73,7 +73,6 @@ mod renamed_lints;
7373

7474
// begin lints modules, do not remove this comment, it’s used in `update_lints`
7575
mod absolute_paths;
76-
mod allow_attributes;
7776
mod almost_complete_range;
7877
mod approx_const;
7978
mod arc_with_non_send_sync;
@@ -699,7 +698,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
699698
store.register_late_pass(|_| Box::new(mut_reference::UnnecessaryMutPassed));
700699
store.register_late_pass(|_| Box::<significant_drop_tightening::SignificantDropTightening<'_>>::default());
701700
store.register_late_pass(|_| Box::new(len_zero::LenZero));
702-
store.register_late_pass(|_| Box::new(attrs::Attributes));
701+
store.register_late_pass(move |_| Box::new(attrs::Attributes::new(msrv())));
703702
store.register_late_pass(|_| Box::new(blocks_in_conditions::BlocksInConditions));
704703
store.register_late_pass(|_| Box::new(unicode::Unicode));
705704
store.register_late_pass(|_| Box::new(uninit_vec::UninitVec));
@@ -1065,7 +1064,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
10651064
store.register_late_pass(|_| Box::new(needless_maybe_sized::NeedlessMaybeSized));
10661065
store.register_late_pass(|_| Box::new(redundant_async_block::RedundantAsyncBlock));
10671066
store.register_late_pass(|_| Box::new(let_with_type_underscore::UnderscoreTyped));
1068-
store.register_late_pass(|_| Box::new(allow_attributes::AllowAttribute));
10691067
store.register_late_pass(move |_| Box::new(manual_main_separator_str::ManualMainSeparatorStr::new(msrv())));
10701068
store.register_late_pass(|_| Box::new(unnecessary_struct_initialization::UnnecessaryStruct));
10711069
store.register_late_pass(move |_| {

Diff for: clippy_utils/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#![feature(f16)]
66
#![feature(if_let_guard)]
77
#![feature(let_chains)]
8-
#![feature(lint_reasons)]
8+
#![cfg_attr(bootstrap, feature(lint_reasons))]
99
#![feature(never_type)]
1010
#![feature(rustc_private)]
1111
#![feature(assert_matches)]

Diff for: src/driver.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#![allow(rustc::untranslatable_diagnostic)]
33
#![feature(rustc_private)]
44
#![feature(let_chains)]
5-
#![feature(lint_reasons)]
5+
#![cfg_attr(bootstrap, feature(lint_reasons))]
66
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
77
// warn on lints, that are included in `rust-lang/rust`s bootstrap
88
#![warn(rust_2018_idioms, unused_lifetimes)]

Diff for: tests/ui-cargo/duplicate_mod/fail/src/main.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#![feature(lint_reasons)]
21

32
mod a;
43

Diff for: tests/ui-toml/macro_metavars_in_unsafe/default/test.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! Tests macro_metavars_in_unsafe with default configuration
2-
#![feature(decl_macro, lint_reasons)]
2+
#![feature(decl_macro)]
33
#![warn(clippy::macro_metavars_in_unsafe)]
44
#![allow(clippy::no_effect)]
55

0 commit comments

Comments
 (0)