Skip to content

Commit e236bfc

Browse files
committed
Add a note to incompatible_msrv to suggest feature gating the MSRV
The first non-MSRV-compatible item located under a `#[cfg(…)]` or `#[cfg_attr(…)]` attribute will get an additional note suggesting changing `#[clippy::msrv]` locally.
1 parent 96ae10e commit e236bfc

File tree

4 files changed

+67
-9
lines changed

4 files changed

+67
-9
lines changed

clippy_lints/src/incompatible_msrv.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use clippy_config::Conf;
2-
use clippy_utils::diagnostics::span_lint;
2+
use clippy_utils::diagnostics::span_lint_and_then;
33
use clippy_utils::is_in_test;
44
use clippy_utils::msrvs::Msrv;
55
use rustc_attr_data_structures::{RustcVersion, StabilityLevel, StableSince};
@@ -146,13 +146,18 @@ impl IncompatibleMsrv {
146146
&& let version = self.get_def_id_version(cx.tcx, def_id)
147147
&& version > current
148148
{
149-
span_lint(
149+
span_lint_and_then(
150150
cx,
151151
INCOMPATIBLE_MSRV,
152152
span,
153153
format!(
154154
"current MSRV (Minimum Supported Rust Version) is `{current}` but this item is stable since `{version}`"
155155
),
156+
|diag| {
157+
if is_under_cfg_attribute(cx, node) {
158+
diag.note_once("you may want to conditionally increase the MSRV considered by Clippy using the `clippy::msrv` attribute");
159+
}
160+
},
156161
);
157162
}
158163
}
@@ -180,3 +185,16 @@ impl<'tcx> LateLintPass<'tcx> for IncompatibleMsrv {
180185
}
181186
}
182187
}
188+
189+
/// Heuristic checking if the node `hir_id` is under a `#[cfg()]` or `#[cfg_attr()]`
190+
/// attribute.
191+
fn is_under_cfg_attribute(cx: &LateContext<'_>, hir_id: HirId) -> bool {
192+
cx.tcx.hir_parent_id_iter(hir_id).any(|id| {
193+
cx.tcx.hir_attrs(id).iter().any(|attr| {
194+
matches!(
195+
attr.ident().map(|ident| ident.name),
196+
Some(sym::cfg_trace | sym::cfg_attr_trace)
197+
)
198+
})
199+
})
200+
}

tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.enabled.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is
1818
|
1919
LL | sleep(Duration::new(1, 0));
2020
| ^^^^^
21+
|
22+
= note: you may want to conditionally increase the MSRV considered by Clippy using the `clippy::msrv` attribute
2123

2224
error: aborting due to 3 previous errors
2325

tests/ui/incompatible_msrv.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ fn foo() {
1313
let mut map: HashMap<&str, u32> = HashMap::new();
1414
assert_eq!(map.entry("poneyland").key(), &"poneyland");
1515
//~^ incompatible_msrv
16+
//~| NOTE: `-D clippy::incompatible-msrv` implied by `-D warnings`
17+
//~| HELP: to override `-D warnings` add `#[allow(clippy::incompatible_msrv)]`
1618

1719
if let Entry::Vacant(v) = map.entry("poneyland") {
1820
v.into_key();
@@ -73,4 +75,20 @@ fn issue14212() {
7375
//~^ ERROR: is `1.80.0` but this item is stable since `1.82.0`
7476
}
7577

78+
fn local_msrv_change_suggestion() {
79+
let _ = std::iter::repeat_n((), 5);
80+
//~^ incompatible_msrv
81+
82+
#[cfg(any(test, not(test)))]
83+
{
84+
let _ = std::iter::repeat_n((), 5);
85+
//~^ incompatible_msrv
86+
//~| NOTE: you may want to conditionally increase the MSRV
87+
88+
// Emit the additional note only once
89+
let _ = std::iter::repeat_n((), 5);
90+
//~^ incompatible_msrv
91+
}
92+
}
93+
7694
fn main() {}

tests/ui/incompatible_msrv.stderr

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,25 @@ LL | assert_eq!(map.entry("poneyland").key(), &"poneyland");
88
= help: to override `-D warnings` add `#[allow(clippy::incompatible_msrv)]`
99

1010
error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.12.0`
11-
--> tests/ui/incompatible_msrv.rs:18:11
11+
--> tests/ui/incompatible_msrv.rs:20:11
1212
|
1313
LL | v.into_key();
1414
| ^^^^^^^^^^
1515

1616
error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.4.0`
17-
--> tests/ui/incompatible_msrv.rs:22:5
17+
--> tests/ui/incompatible_msrv.rs:24:5
1818
|
1919
LL | sleep(Duration::new(1, 0));
2020
| ^^^^^
2121

2222
error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.6.0`
23-
--> tests/ui/incompatible_msrv.rs:46:9
23+
--> tests/ui/incompatible_msrv.rs:48:9
2424
|
2525
LL | core::panicking::panic("foo");
2626
| ^^^^^^^^^^^^^^^^^^^^^^
2727

2828
error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.6.0`
29-
--> tests/ui/incompatible_msrv.rs:53:13
29+
--> tests/ui/incompatible_msrv.rs:55:13
3030
|
3131
LL | core::panicking::panic($msg)
3232
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -37,16 +37,36 @@ LL | my_panic!("foo");
3737
= note: this error originates in the macro `my_panic` (in Nightly builds, run with -Z macro-backtrace for more info)
3838

3939
error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.6.0`
40-
--> tests/ui/incompatible_msrv.rs:59:13
40+
--> tests/ui/incompatible_msrv.rs:61:13
4141
|
4242
LL | assert!(core::panicking::panic("out of luck"));
4343
| ^^^^^^^^^^^^^^^^^^^^^^
4444

4545
error: current MSRV (Minimum Supported Rust Version) is `1.80.0` but this item is stable since `1.82.0`
46-
--> tests/ui/incompatible_msrv.rs:72:13
46+
--> tests/ui/incompatible_msrv.rs:74:13
4747
|
4848
LL | let _ = std::iter::repeat_n((), 5);
4949
| ^^^^^^^^^^^^^^^^^^^
5050

51-
error: aborting due to 7 previous errors
51+
error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.82.0`
52+
--> tests/ui/incompatible_msrv.rs:79:13
53+
|
54+
LL | let _ = std::iter::repeat_n((), 5);
55+
| ^^^^^^^^^^^^^^^^^^^
56+
57+
error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.82.0`
58+
--> tests/ui/incompatible_msrv.rs:84:17
59+
|
60+
LL | let _ = std::iter::repeat_n((), 5);
61+
| ^^^^^^^^^^^^^^^^^^^
62+
|
63+
= note: you may want to conditionally increase the MSRV considered by Clippy using the `clippy::msrv` attribute
64+
65+
error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.82.0`
66+
--> tests/ui/incompatible_msrv.rs:89:17
67+
|
68+
LL | let _ = std::iter::repeat_n((), 5);
69+
| ^^^^^^^^^^^^^^^^^^^
70+
71+
error: aborting due to 10 previous errors
5272

0 commit comments

Comments
 (0)