Skip to content

Commit e6d1816

Browse files
committed
Do not warn about feature-enabled items
If an item has been enabled through a feature, it will not be linted even though the MSRV is not compatible. This use case may happen when stable compilers are allowed to enable unstable features, e.g. in the Rust for Linux toolchain.
1 parent b9341b7 commit e6d1816

File tree

3 files changed

+55
-32
lines changed

3 files changed

+55
-32
lines changed

clippy_lints/src/incompatible_msrv.rs

+24-21
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use clippy_config::Conf;
22
use clippy_utils::diagnostics::span_lint_and_then;
33
use clippy_utils::is_in_test;
44
use clippy_utils::msrvs::Msrv;
5-
use rustc_attr_parsing::{RustcVersion, StabilityLevel, StableSince};
5+
use rustc_attr_parsing::{RustcVersion, Stability, StableSince};
66
use rustc_data_structures::fx::FxHashMap;
77
use rustc_hir::{Expr, ExprKind, HirId, QPath};
88
use rustc_lint::{LateContext, LateLintPass};
@@ -72,9 +72,15 @@ declare_clippy_lint! {
7272
"ensures that all items used in the crate are available for the current MSRV"
7373
}
7474

75+
#[derive(Clone, Copy)]
76+
enum Availability {
77+
FeatureEnabled,
78+
Since(RustcVersion),
79+
}
80+
7581
pub struct IncompatibleMsrv {
7682
msrv: Msrv,
77-
is_above_msrv: FxHashMap<DefId, RustcVersion>,
83+
availability_cache: FxHashMap<DefId, Availability>,
7884
check_in_tests: bool,
7985
}
8086

@@ -84,35 +90,32 @@ impl IncompatibleMsrv {
8490
pub fn new(conf: &'static Conf) -> Self {
8591
Self {
8692
msrv: conf.msrv,
87-
is_above_msrv: FxHashMap::default(),
93+
availability_cache: FxHashMap::default(),
8894
check_in_tests: conf.check_incompatible_msrv_in_tests,
8995
}
9096
}
9197

92-
fn get_def_id_version(&mut self, tcx: TyCtxt<'_>, def_id: DefId) -> RustcVersion {
93-
if let Some(version) = self.is_above_msrv.get(&def_id) {
94-
return *version;
98+
/// Returns the availability of `def_id`, whether it is enabled through a feature or
99+
/// available since a given version (the default being Rust 1.0.0).
100+
fn get_def_id_availability(&mut self, tcx: TyCtxt<'_>, def_id: DefId) -> Availability {
101+
if let Some(availability) = self.availability_cache.get(&def_id) {
102+
return *availability;
95103
}
96-
let version = if let Some(version) = tcx
97-
.lookup_stability(def_id)
98-
.and_then(|stability| match stability.level {
99-
StabilityLevel::Stable {
100-
since: StableSince::Version(version),
101-
..
102-
} => Some(version),
103-
_ => None,
104-
}) {
105-
version
104+
let stability = tcx.lookup_stability(def_id);
105+
let version = if stability.is_some_and(|stability| tcx.features().enabled(stability.feature)) {
106+
Availability::FeatureEnabled
107+
} else if let Some(StableSince::Version(version)) = stability.as_ref().and_then(Stability::stable_since) {
108+
Availability::Since(version)
106109
} else if let Some(parent_def_id) = tcx.opt_parent(def_id) {
107-
self.get_def_id_version(tcx, parent_def_id)
110+
self.get_def_id_availability(tcx, parent_def_id)
108111
} else {
109-
RustcVersion {
112+
Availability::Since(RustcVersion {
110113
major: 1,
111114
minor: 0,
112115
patch: 0,
113-
}
116+
})
114117
};
115-
self.is_above_msrv.insert(def_id, version);
118+
self.availability_cache.insert(def_id, version);
116119
version
117120
}
118121

@@ -143,7 +146,7 @@ impl IncompatibleMsrv {
143146

144147
if (self.check_in_tests || !is_in_test(cx.tcx, node))
145148
&& let Some(current) = self.msrv.current(cx)
146-
&& let version = self.get_def_id_version(cx.tcx, def_id)
149+
&& let Availability::Since(version) = self.get_def_id_availability(cx.tcx, def_id)
147150
&& version > current
148151
{
149152
span_lint_and_then(

tests/ui/incompatible_msrv.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#![warn(clippy::incompatible_msrv)]
22
#![feature(custom_inner_attributes)]
3+
#![allow(stable_features)]
4+
#![feature(strict_provenance)] // For use in test
35
#![clippy::msrv = "1.3.0"]
46

57
use std::collections::HashMap;
@@ -91,4 +93,16 @@ fn local_msrv_change_suggestion() {
9193
}
9294
}
9395

96+
#[clippy::msrv = "1.78.0"]
97+
fn feature_enable_14425(ptr: *const u8) -> usize {
98+
// Do not warn, because it is enabled through a feature even though
99+
// it is stabilized only since Rust 1.84.0.
100+
let r = ptr.addr();
101+
102+
// Warn about this which has been introduced in the same Rust version
103+
// but is not allowed through a feature.
104+
r.isqrt()
105+
//~^ incompatible_msrv
106+
}
107+
94108
fn main() {}

tests/ui/incompatible_msrv.stderr

+17-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.10.0`
2-
--> tests/ui/incompatible_msrv.rs:13:39
2+
--> tests/ui/incompatible_msrv.rs:15:39
33
|
44
LL | assert_eq!(map.entry("poneyland").key(), &"poneyland");
55
| ^^^^^
@@ -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:19:11
11+
--> tests/ui/incompatible_msrv.rs:21: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:23:5
17+
--> tests/ui/incompatible_msrv.rs:25: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.43.0`
23-
--> tests/ui/incompatible_msrv.rs:47:17
23+
--> tests/ui/incompatible_msrv.rs:49:17
2424
|
2525
LL | let _ = core::iter::once_with(|| 0);
2626
| ^^^^^^^^^^^^^^^^^^^^^
2727

2828
error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.43.0`
29-
--> tests/ui/incompatible_msrv.rs:54:21
29+
--> tests/ui/incompatible_msrv.rs:56:21
3030
|
3131
LL | let _ = core::iter::once_with(|| $msg);
3232
| ^^^^^^^^^^^^^^^^^^^^^
@@ -37,36 +37,42 @@ 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.43.0`
40-
--> tests/ui/incompatible_msrv.rs:61:13
40+
--> tests/ui/incompatible_msrv.rs:63:13
4141
|
4242
LL | assert!(core::iter::once_with(|| 0).next().is_some());
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:74:13
46+
--> tests/ui/incompatible_msrv.rs:76:13
4747
|
4848
LL | let _ = std::iter::repeat_n((), 5);
4949
| ^^^^^^^^^^^^^^^^^^^
5050

5151
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
52+
--> tests/ui/incompatible_msrv.rs:81:13
5353
|
5454
LL | let _ = std::iter::repeat_n((), 5);
5555
| ^^^^^^^^^^^^^^^^^^^
5656

5757
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
58+
--> tests/ui/incompatible_msrv.rs:86:17
5959
|
6060
LL | let _ = std::iter::repeat_n((), 5);
6161
| ^^^^^^^^^^^^^^^^^^^
6262
|
6363
= note: you may want to conditionally increase the MSRV considered by Clippy using the `clippy::msrv` attribute
6464

6565
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
66+
--> tests/ui/incompatible_msrv.rs:91:17
6767
|
6868
LL | let _ = std::iter::repeat_n((), 5);
6969
| ^^^^^^^^^^^^^^^^^^^
7070

71-
error: aborting due to 10 previous errors
71+
error: current MSRV (Minimum Supported Rust Version) is `1.78.0` but this item is stable since `1.84.0`
72+
--> tests/ui/incompatible_msrv.rs:104:7
73+
|
74+
LL | r.isqrt()
75+
| ^^^^^^^
76+
77+
error: aborting due to 11 previous errors
7278

0 commit comments

Comments
 (0)