Auto merge of #13168 - Alexendoo:std-instead-of-core-msrv, r=Manishearth
Make `std_instead_of_core` somewhat MSRV aware For #13158, this catches some things e.g. `core::net` and the recently stable `core::error` but not things moved individually like `UnwindSafe`, as far as I can see the version for those isn't easily available Beta nominating since ideally we'd get this change in the same version as `core::error` becomes stable cc `@kpreid` changelog: none
This commit is contained in:
commit
1ec502569e
@ -819,7 +819,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
|
|||||||
store.register_late_pass(move |_| Box::new(manual_retain::ManualRetain::new(conf)));
|
store.register_late_pass(move |_| Box::new(manual_retain::ManualRetain::new(conf)));
|
||||||
store.register_late_pass(move |_| Box::new(manual_rotate::ManualRotate));
|
store.register_late_pass(move |_| Box::new(manual_rotate::ManualRotate));
|
||||||
store.register_late_pass(move |_| Box::new(operators::Operators::new(conf)));
|
store.register_late_pass(move |_| Box::new(operators::Operators::new(conf)));
|
||||||
store.register_late_pass(|_| Box::<std_instead_of_core::StdReexports>::default());
|
store.register_late_pass(move |_| Box::new(std_instead_of_core::StdReexports::new(conf)));
|
||||||
store.register_late_pass(move |_| Box::new(instant_subtraction::InstantSubtraction::new(conf)));
|
store.register_late_pass(move |_| Box::new(instant_subtraction::InstantSubtraction::new(conf)));
|
||||||
store.register_late_pass(|_| Box::new(partialeq_to_none::PartialeqToNone));
|
store.register_late_pass(|_| Box::new(partialeq_to_none::PartialeqToNone));
|
||||||
store.register_late_pass(move |_| Box::new(manual_clamp::ManualClamp::new(conf)));
|
store.register_late_pass(move |_| Box::new(manual_clamp::ManualClamp::new(conf)));
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
|
use clippy_config::msrvs::Msrv;
|
||||||
|
use clippy_config::Conf;
|
||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
use clippy_utils::is_from_proc_macro;
|
use clippy_utils::is_from_proc_macro;
|
||||||
|
use rustc_attr::{StabilityLevel, StableSince};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::def::Res;
|
use rustc_hir::def::Res;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::{HirId, Path, PathSegment};
|
use rustc_hir::{HirId, Path, PathSegment};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
|
use rustc_semver::RustcVersion;
|
||||||
use rustc_session::impl_lint_pass;
|
use rustc_session::impl_lint_pass;
|
||||||
use rustc_span::symbol::kw;
|
use rustc_span::symbol::kw;
|
||||||
use rustc_span::{sym, Span};
|
use rustc_span::{sym, Span};
|
||||||
@ -66,6 +70,10 @@ declare_clippy_lint! {
|
|||||||
/// imported from core to ensure disabling `alloc` does not cause the crate to fail to compile. This lint
|
/// imported from core to ensure disabling `alloc` does not cause the crate to fail to compile. This lint
|
||||||
/// is also useful for crates migrating to become `no_std` compatible.
|
/// is also useful for crates migrating to become `no_std` compatible.
|
||||||
///
|
///
|
||||||
|
/// ### Known problems
|
||||||
|
/// The lint is only partially aware of the required MSRV for items that were originally in `std` but moved
|
||||||
|
/// to `core`.
|
||||||
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// # extern crate alloc;
|
/// # extern crate alloc;
|
||||||
@ -81,20 +89,30 @@ declare_clippy_lint! {
|
|||||||
"type is imported from alloc when available in core"
|
"type is imported from alloc when available in core"
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct StdReexports {
|
pub struct StdReexports {
|
||||||
// Paths which can be either a module or a macro (e.g. `std::env`) will cause this check to happen
|
// Paths which can be either a module or a macro (e.g. `std::env`) will cause this check to happen
|
||||||
// twice. First for the mod, second for the macro. This is used to avoid the lint reporting for the macro
|
// twice. First for the mod, second for the macro. This is used to avoid the lint reporting for the macro
|
||||||
// when the path could be also be used to access the module.
|
// when the path could be also be used to access the module.
|
||||||
prev_span: Span,
|
prev_span: Span,
|
||||||
|
msrv: Msrv,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl StdReexports {
|
||||||
|
pub fn new(conf: &'static Conf) -> Self {
|
||||||
|
Self {
|
||||||
|
prev_span: Span::default(),
|
||||||
|
msrv: conf.msrv.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl_lint_pass!(StdReexports => [STD_INSTEAD_OF_CORE, STD_INSTEAD_OF_ALLOC, ALLOC_INSTEAD_OF_CORE]);
|
impl_lint_pass!(StdReexports => [STD_INSTEAD_OF_CORE, STD_INSTEAD_OF_ALLOC, ALLOC_INSTEAD_OF_CORE]);
|
||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for StdReexports {
|
impl<'tcx> LateLintPass<'tcx> for StdReexports {
|
||||||
fn check_path(&mut self, cx: &LateContext<'tcx>, path: &Path<'tcx>, _: HirId) {
|
fn check_path(&mut self, cx: &LateContext<'tcx>, path: &Path<'tcx>, _: HirId) {
|
||||||
if let Res::Def(_, def_id) = path.res
|
if let Res::Def(_, def_id) = path.res
|
||||||
&& let Some(first_segment) = get_first_segment(path)
|
&& let Some(first_segment) = get_first_segment(path)
|
||||||
&& is_stable(cx, def_id)
|
&& is_stable(cx, def_id, &self.msrv)
|
||||||
&& !in_external_macro(cx.sess(), path.span)
|
&& !in_external_macro(cx.sess(), path.span)
|
||||||
&& !is_from_proc_macro(cx, &first_segment.ident)
|
&& !is_from_proc_macro(cx, &first_segment.ident)
|
||||||
{
|
{
|
||||||
@ -131,6 +149,8 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extract_msrv_attr!(LateContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the first named segment of a [`Path`].
|
/// Returns the first named segment of a [`Path`].
|
||||||
@ -146,17 +166,30 @@ fn get_first_segment<'tcx>(path: &Path<'tcx>) -> Option<&'tcx PathSegment<'tcx>>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if all ancestors of `def_id` are stable, to avoid linting
|
/// Checks if all ancestors of `def_id` meet `msrv` to avoid linting [unstable moves](https://github.com/rust-lang/rust/pull/95956)
|
||||||
/// [unstable moves](https://github.com/rust-lang/rust/pull/95956)
|
/// or now stable moves that were once unstable.
|
||||||
fn is_stable(cx: &LateContext<'_>, mut def_id: DefId) -> bool {
|
///
|
||||||
|
/// Does not catch individually moved items
|
||||||
|
fn is_stable(cx: &LateContext<'_>, mut def_id: DefId, msrv: &Msrv) -> bool {
|
||||||
loop {
|
loop {
|
||||||
if cx
|
if let Some(stability) = cx.tcx.lookup_stability(def_id)
|
||||||
.tcx
|
&& let StabilityLevel::Stable {
|
||||||
.lookup_stability(def_id)
|
since,
|
||||||
.map_or(false, |stability| stability.is_unstable())
|
allowed_through_unstable_modules: false,
|
||||||
|
} = stability.level
|
||||||
{
|
{
|
||||||
|
let stable = match since {
|
||||||
|
StableSince::Version(v) => {
|
||||||
|
msrv.meets(RustcVersion::new(v.major.into(), v.minor.into(), v.patch.into()))
|
||||||
|
},
|
||||||
|
StableSince::Current => msrv.current().is_none(),
|
||||||
|
StableSince::Err => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
if !stable {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match cx.tcx.opt_parent(def_id) {
|
match cx.tcx.opt_parent(def_id) {
|
||||||
Some(parent) => def_id = parent,
|
Some(parent) => def_id = parent,
|
||||||
|
@ -75,8 +75,17 @@ mod std_in_proc_macro_derive {
|
|||||||
struct B {}
|
struct B {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
// Some intrinsics are usable on stable but live in an unstable module, but should still suggest
|
||||||
std_instead_of_core();
|
// replacing std -> core
|
||||||
std_instead_of_alloc();
|
fn intrinsic(a: *mut u8, b: *mut u8) {
|
||||||
alloc_instead_of_core();
|
unsafe {
|
||||||
|
core::intrinsics::copy(a, b, 1);
|
||||||
|
//~^ std_instead_of_core
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[clippy::msrv = "1.76"]
|
||||||
|
fn msrv_1_76(_: std::net::IpAddr) {}
|
||||||
|
|
||||||
|
#[clippy::msrv = "1.77"]
|
||||||
|
fn msrv_1_77(_: core::net::IpAddr) {}
|
||||||
|
@ -75,8 +75,17 @@ mod std_in_proc_macro_derive {
|
|||||||
struct B {}
|
struct B {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
// Some intrinsics are usable on stable but live in an unstable module, but should still suggest
|
||||||
std_instead_of_core();
|
// replacing std -> core
|
||||||
std_instead_of_alloc();
|
fn intrinsic(a: *mut u8, b: *mut u8) {
|
||||||
alloc_instead_of_core();
|
unsafe {
|
||||||
|
std::intrinsics::copy(a, b, 1);
|
||||||
|
//~^ std_instead_of_core
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[clippy::msrv = "1.76"]
|
||||||
|
fn msrv_1_76(_: std::net::IpAddr) {}
|
||||||
|
|
||||||
|
#[clippy::msrv = "1.77"]
|
||||||
|
fn msrv_1_77(_: std::net::IpAddr) {}
|
||||||
|
@ -85,5 +85,17 @@ LL | use alloc::slice::from_ref;
|
|||||||
= note: `-D clippy::alloc-instead-of-core` implied by `-D warnings`
|
= note: `-D clippy::alloc-instead-of-core` implied by `-D warnings`
|
||||||
= help: to override `-D warnings` add `#[allow(clippy::alloc_instead_of_core)]`
|
= help: to override `-D warnings` add `#[allow(clippy::alloc_instead_of_core)]`
|
||||||
|
|
||||||
error: aborting due to 13 previous errors
|
error: used import from `std` instead of `core`
|
||||||
|
--> tests/ui/std_instead_of_core.rs:82:9
|
||||||
|
|
|
||||||
|
LL | std::intrinsics::copy(a, b, 1);
|
||||||
|
| ^^^ help: consider importing the item from `core`: `core`
|
||||||
|
|
||||||
|
error: used import from `std` instead of `core`
|
||||||
|
--> tests/ui/std_instead_of_core.rs:91:17
|
||||||
|
|
|
||||||
|
LL | fn msrv_1_77(_: std::net::IpAddr) {}
|
||||||
|
| ^^^ help: consider importing the item from `core`: `core`
|
||||||
|
|
||||||
|
error: aborting due to 15 previous errors
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user