From a8f78b7b042f5a264c672f94ce7d1ce95f491b4c Mon Sep 17 00:00:00 2001 From: MarcusGrass Date: Sat, 20 Apr 2024 17:58:40 +0200 Subject: [PATCH 1/8] Rebase merge --- clippy_lints/src/std_instead_of_core.rs | 113 ++++++++++++++++++++---- 1 file changed, 95 insertions(+), 18 deletions(-) diff --git a/clippy_lints/src/std_instead_of_core.rs b/clippy_lints/src/std_instead_of_core.rs index 926c56332cc1..9588b7a0dc02 100644 --- a/clippy_lints/src/std_instead_of_core.rs +++ b/clippy_lints/src/std_instead_of_core.rs @@ -1,9 +1,11 @@ +use std::hash::{Hash, Hasher}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::is_from_proc_macro; +use rustc_data_structures::fx::FxIndexSet; use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::def_id::DefId; -use rustc_hir::{HirId, Path, PathSegment}; +use rustc_hir::{HirId, Item, ItemKind, Path, PathSegment, UseKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::impl_lint_pass; @@ -93,9 +95,47 @@ pub struct StdReexports { // 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. prev_span: Span, + open_use: Option } + impl_lint_pass!(StdReexports => [STD_INSTEAD_OF_CORE, STD_INSTEAD_OF_ALLOC, ALLOC_INSTEAD_OF_CORE]); +#[derive(Debug)] +struct OpenUseSpan { + container: Span, + members: FxIndexSet +} + +#[derive(Debug, Copy, Clone)] +struct UseSpanMember { + inner: Span, + lint_data: LintData, +} + +impl PartialEq for UseSpanMember { + fn eq(&self, other: &Self) -> bool { + self.inner.eq(&other.inner) + } +} + +impl Eq for UseSpanMember {} + +impl Hash for UseSpanMember { + fn hash(&self, state: &mut H) { + self.inner.hash(state); + } +} + +#[derive(Debug, Copy, Clone)] +enum LintData { + CanReplace { + lint: &'static crate::Lint, + used_mod: &'static str, + replace_with: &'static str, + }, + NoReplace, +} + impl<'tcx> LateLintPass<'tcx> for StdReexports { fn check_path(&mut self, cx: &LateContext<'tcx>, path: &Path<'tcx>, _: HirId) { if let Res::Def(_, def_id) = path.res @@ -104,37 +144,74 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { && !in_external_macro(cx.sess(), path.span) && !is_from_proc_macro(cx, &first_segment.ident) { - let (lint, used_mod, replace_with) = match first_segment.ident.name { + let lint_data = match first_segment.ident.name { sym::std => match cx.tcx.crate_name(def_id.krate) { - sym::core => (STD_INSTEAD_OF_CORE, "std", "core"), - sym::alloc => (STD_INSTEAD_OF_ALLOC, "std", "alloc"), + sym::core => LintData::CanReplace { + lint: STD_INSTEAD_OF_CORE, + used_mod: "std", + replace_with: "core", + }, + sym::alloc => LintData::CanReplace { + lint: STD_INSTEAD_OF_ALLOC, + used_mod: "std", + replace_with: "alloc", + }, _ => { self.prev_span = first_segment.ident.span; - return; + LintData::NoReplace }, }, sym::alloc => { if cx.tcx.crate_name(def_id.krate) == sym::core { - (ALLOC_INSTEAD_OF_CORE, "alloc", "core") + LintData::CanReplace { + lint: ALLOC_INSTEAD_OF_CORE, + used_mod: "alloc", + replace_with: "core", + } } else { self.prev_span = first_segment.ident.span; - return; + LintData::NoReplace } }, _ => return, }; - if first_segment.ident.span != self.prev_span { - span_lint_and_sugg( - cx, - lint, - first_segment.ident.span, - format!("used import from `{used_mod}` instead of `{replace_with}`"), - format!("consider importing the item from `{replace_with}`"), - replace_with.to_string(), - Applicability::MachineApplicable, - ); - self.prev_span = first_segment.ident.span; + if let Some(in_use) = self.open_use.as_mut() { + in_use.members.insert(UseSpanMember { + inner: path.span, + lint_data, + }); + return; } + if let LintData::CanReplace { lint, used_mod, replace_with } = lint_data { + if first_segment.ident.span != self.prev_span { + span_lint_and_sugg( + cx, + lint, + first_segment.ident.span, + &format!("used import from `{used_mod}` instead of `{replace_with}`"), + &format!("consider importing the item from `{replace_with}`"), + replace_with.to_string(), + Applicability::MachineApplicable, + ); + self.prev_span = first_segment.ident.span; + } + } + } + } + + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { + if matches!(item.kind, ItemKind::Use(_, UseKind::ListStem)) { + self.open_use = Some(OpenUseSpan { + container: item.span, + members: FxIndexSet::default(), + }) + } + + } + + fn check_item_post(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { + if let Some(collected_use) = self.open_use.take() { + } } } From 93fb1a22d5f7f7cd20bb02ef44d1585473feae18 Mon Sep 17 00:00:00 2001 From: MarcusGrass Date: Tue, 12 Mar 2024 16:00:17 +0100 Subject: [PATCH 2/8] Backwards compat --- clippy_lints/src/std_instead_of_core.rs | 209 ++++++++++++++++++++++-- 1 file changed, 192 insertions(+), 17 deletions(-) diff --git a/clippy_lints/src/std_instead_of_core.rs b/clippy_lints/src/std_instead_of_core.rs index 9588b7a0dc02..77a9271502d2 100644 --- a/clippy_lints/src/std_instead_of_core.rs +++ b/clippy_lints/src/std_instead_of_core.rs @@ -1,16 +1,19 @@ use std::hash::{Hash, Hasher}; -use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then}; use clippy_utils::is_from_proc_macro; +use rustc_ast::Attribute; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::def_id::DefId; -use rustc_hir::{HirId, Item, ItemKind, Path, PathSegment, UseKind}; +use rustc_hir::{Arm, Block, Body, Expr, FieldDef, FnDecl, ForeignItem, GenericParam, Generics, HirId, ImplItem, Item, ItemKind, Local, Mod, Pat, Path, PathSegment, PolyTraitRef, Stmt, TraitItem, Ty, UseKind, Variant, VariantData}; +use rustc_hir::intravisit::FnKind; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::impl_lint_pass; use rustc_span::symbol::kw; use rustc_span::{sym, Span}; +use rustc_span::def_id::LocalDefId; declare_clippy_lint! { /// ### What it does @@ -109,6 +112,8 @@ struct OpenUseSpan { #[derive(Debug, Copy, Clone)] struct UseSpanMember { inner: Span, + hir_id: HirId, + first_seg_ident_span: Span, lint_data: LintData, } @@ -128,16 +133,79 @@ impl Hash for UseSpanMember { #[derive(Debug, Copy, Clone)] enum LintData { - CanReplace { - lint: &'static crate::Lint, - used_mod: &'static str, - replace_with: &'static str, - }, + CanReplace(ReplaceLintData), NoReplace, } +#[derive(Debug, Copy, Clone)] +struct ReplaceLintData { + lint: &'static crate::Lint, + used_mod: &'static str, + replace_with: &'static str, +} + +impl StdReexports { + fn suggest_for_open_use_item_if_after<'tcx>(&mut self, cx: &LateContext<'tcx>, span: Span) { + if let Some(collected_use) = self.open_use.take() { + // Still contains other span, throw it back + if collected_use.container.contains(span) { + self.open_use = Some(collected_use); + return; + } + let mut place_holder_unique_check: Option<(Span, ReplaceLintData)> = None; + let mut can_chunk = true; + for member in collected_use.members.iter() { + match &member.lint_data { + LintData::CanReplace(lint_data) => { + if let Some((_span, prev_lint_data)) = place_holder_unique_check.take() { + if prev_lint_data.lint.name == lint_data.lint.name && prev_lint_data.used_mod == lint_data.used_mod && prev_lint_data.replace_with == lint_data.replace_with { + place_holder_unique_check = Some((member.first_seg_ident_span, *lint_data)); + } else { + // Will have to warn for individual entries + can_chunk = false; + break; + } + } else { + place_holder_unique_check = Some((member.first_seg_ident_span, *lint_data)); + } + } + LintData::NoReplace => { + // Will have to warn for individual entries + can_chunk = false; + break; + } + } + } + // If they can all be replaced with the same thing, just lint and suggest, then + // clippy-fix works as well + if can_chunk { + if let Some((first_segment_ident_span, ReplaceLintData { lint, used_mod, replace_with })) = place_holder_unique_check { + span_lint_and_sugg( + cx, + lint, + first_segment_ident_span, + &format!("used import from `{used_mod}` instead of `{replace_with}`"), + &format!("consider importing the item from `{replace_with}`"), + replace_with.to_string(), + Applicability::MachineApplicable, + ); + } + } else { + for member in collected_use.members { + if let LintData::CanReplace(ReplaceLintData { lint, used_mod, replace_with }) = member.lint_data { + span_lint_hir_and_then(cx, lint, member.hir_id, member.inner, &format!("used import from `{used_mod}` instead of `{replace_with}`"), |diag| { + diag.help(format!("consider importing the item from `{replace_with}`")); + }) + } + } + } + } + } +} + 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>, hir_id: HirId) { + self.suggest_for_open_use_item_if_after(cx, path.span); if let Res::Def(_, def_id) = path.res && let Some(first_segment) = get_first_segment(path) && is_stable(cx, def_id) @@ -146,16 +214,16 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { { let lint_data = match first_segment.ident.name { sym::std => match cx.tcx.crate_name(def_id.krate) { - sym::core => LintData::CanReplace { + sym::core => LintData::CanReplace(ReplaceLintData{ lint: STD_INSTEAD_OF_CORE, used_mod: "std", replace_with: "core", - }, - sym::alloc => LintData::CanReplace { + }), + sym::alloc => LintData::CanReplace(ReplaceLintData{ lint: STD_INSTEAD_OF_ALLOC, used_mod: "std", replace_with: "alloc", - }, + }), _ => { self.prev_span = first_segment.ident.span; LintData::NoReplace @@ -163,11 +231,11 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { }, sym::alloc => { if cx.tcx.crate_name(def_id.krate) == sym::core { - LintData::CanReplace { + LintData::CanReplace(ReplaceLintData{ lint: ALLOC_INSTEAD_OF_CORE, used_mod: "alloc", replace_with: "core", - } + }) } else { self.prev_span = first_segment.ident.span; LintData::NoReplace @@ -178,11 +246,13 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { if let Some(in_use) = self.open_use.as_mut() { in_use.members.insert(UseSpanMember { inner: path.span, + hir_id, + first_seg_ident_span: first_segment.ident.span, lint_data, }); return; } - if let LintData::CanReplace { lint, used_mod, replace_with } = lint_data { + if let LintData::CanReplace(ReplaceLintData { lint, used_mod, replace_with }) = lint_data { if first_segment.ident.span != self.prev_span { span_lint_and_sugg( cx, @@ -200,6 +270,7 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { } fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { + self.suggest_for_open_use_item_if_after(cx, item.span); if matches!(item.kind, ItemKind::Use(_, UseKind::ListStem)) { self.open_use = Some(OpenUseSpan { container: item.span, @@ -209,10 +280,114 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { } + #[inline] fn check_item_post(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { - if let Some(collected_use) = self.open_use.take() { + self.suggest_for_open_use_item_if_after(cx, item.span); + } - } + #[inline] + fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'tcx>) { + self.suggest_for_open_use_item_if_after(cx, body.value.span); + } + + #[inline] + fn check_crate_post(&mut self, cx: &LateContext<'tcx>) { + self.suggest_for_open_use_item_if_after(cx, Span::default()); + } + + #[inline] + fn check_mod(&mut self, cx: &LateContext<'tcx>, _: &'tcx Mod<'tcx>, _: HirId) { + self.suggest_for_open_use_item_if_after(cx, Span::default()); + } + + #[inline] + fn check_foreign_item(&mut self, cx: &LateContext<'tcx>, f_item: &'tcx ForeignItem<'tcx>) { + self.suggest_for_open_use_item_if_after(cx, f_item.span); + } + + #[inline] + fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) { + self.suggest_for_open_use_item_if_after(cx, local.span); + } + + #[inline] + fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) { + self.suggest_for_open_use_item_if_after(cx, block.span); + } + + #[inline] + fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'tcx>) { + self.suggest_for_open_use_item_if_after(cx, stmt.span); + } + + #[inline] + fn check_arm(&mut self, cx: &LateContext<'tcx>, arm: &'tcx Arm<'tcx>) { + self.suggest_for_open_use_item_if_after(cx, arm.span); + } + + #[inline] + fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'tcx>) { + self.suggest_for_open_use_item_if_after(cx, pat.span); + } + + #[inline] + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { + self.suggest_for_open_use_item_if_after(cx, expr.span); + } + + #[inline] + fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx>) { + self.suggest_for_open_use_item_if_after(cx, ty.span); + } + + #[inline] + fn check_generic_param(&mut self, cx: &LateContext<'tcx>, gp: &'tcx GenericParam<'tcx>) { + self.suggest_for_open_use_item_if_after(cx, gp.span); + } + + #[inline] + fn check_generics(&mut self, cx: &LateContext<'tcx>, g: &'tcx Generics<'tcx>) { + self.suggest_for_open_use_item_if_after(cx, g.span); + } + + #[inline] + fn check_poly_trait_ref(&mut self, cx: &LateContext<'tcx>, ptr: &'tcx PolyTraitRef<'tcx>) { + self.suggest_for_open_use_item_if_after(cx, ptr.span); + } + + #[inline] + fn check_fn(&mut self, cx: &LateContext<'tcx>, _: FnKind<'tcx>, _: &'tcx FnDecl<'tcx>, _: &'tcx Body<'tcx>, s: Span, _: LocalDefId) { + self.suggest_for_open_use_item_if_after(cx, s); + } + + #[inline] + fn check_trait_item(&mut self, cx: &LateContext<'tcx>, ti: &'tcx TraitItem<'tcx>) { + self.suggest_for_open_use_item_if_after(cx, ti.span); + } + + #[inline] + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, imp: &'tcx ImplItem<'tcx>) { + self.suggest_for_open_use_item_if_after(cx, imp.span); + } + + #[inline] + fn check_struct_def(&mut self, cx: &LateContext<'tcx>, _: &'tcx VariantData<'tcx>) { + self.suggest_for_open_use_item_if_after(cx, Span::default()); + } + + #[inline] + fn check_field_def(&mut self, cx: &LateContext<'tcx>, fd: &'tcx FieldDef<'tcx>) { + self.suggest_for_open_use_item_if_after(cx, fd.span); + } + + #[inline] + fn check_variant(&mut self, cx: &LateContext<'tcx>, v: &'tcx Variant<'tcx>) { + self.suggest_for_open_use_item_if_after(cx, v.span); + } + + #[inline] + fn check_attribute(&mut self, cx: &LateContext<'tcx>, attr: &'tcx Attribute) { + self.suggest_for_open_use_item_if_after(cx, attr.span); } } From 400dcb35874b587deefd3ceacd9c53f1460b4296 Mon Sep 17 00:00:00 2001 From: MarcusGrass Date: Tue, 12 Mar 2024 16:10:12 +0100 Subject: [PATCH 3/8] Pre fixup multiline --- tests/ui/std_instead_of_core.fixed | 82 --------------------------- tests/ui/std_instead_of_core.rs | 37 +++++++++++++ tests/ui/std_instead_of_core.stderr | 86 ++++++++++++++++++++++++----- 3 files changed, 110 insertions(+), 95 deletions(-) delete mode 100644 tests/ui/std_instead_of_core.fixed diff --git a/tests/ui/std_instead_of_core.fixed b/tests/ui/std_instead_of_core.fixed deleted file mode 100644 index ec4ae2ea13c5..000000000000 --- a/tests/ui/std_instead_of_core.fixed +++ /dev/null @@ -1,82 +0,0 @@ -//@aux-build:proc_macro_derive.rs - -#![warn(clippy::std_instead_of_core)] -#![allow(unused_imports)] - -extern crate alloc; - -#[macro_use] -extern crate proc_macro_derive; - -#[warn(clippy::std_instead_of_core)] -fn std_instead_of_core() { - // Regular import - use core::hash::Hasher; - //~^ ERROR: used import from `std` instead of `core` - // Absolute path - use ::core::hash::Hash; - //~^ ERROR: used import from `std` instead of `core` - // Don't lint on `env` macro - use std::env; - - // Multiple imports - use core::fmt::{Debug, Result}; - //~^ ERROR: used import from `std` instead of `core` - - // Multiple imports multiline - #[rustfmt::skip] - use core::{ - //~^ ERROR: used import from `std` instead of `core` - fmt::Write as _, - ptr::read_unaligned, - }; - - // Function calls - let ptr = core::ptr::null::(); - //~^ ERROR: used import from `std` instead of `core` - let ptr_mut = ::core::ptr::null_mut::(); - //~^ ERROR: used import from `std` instead of `core` - - // Types - let cell = core::cell::Cell::new(8u32); - //~^ ERROR: used import from `std` instead of `core` - let cell_absolute = ::core::cell::Cell::new(8u32); - //~^ ERROR: used import from `std` instead of `core` - - let _ = std::env!("PATH"); - - // do not lint until `error_in_core` is stable - use std::error::Error; - - // lint items re-exported from private modules, `core::iter::traits::iterator::Iterator` - use core::iter::Iterator; - //~^ ERROR: used import from `std` instead of `core` -} - -#[warn(clippy::std_instead_of_alloc)] -fn std_instead_of_alloc() { - // Only lint once. - use alloc::vec; - //~^ ERROR: used import from `std` instead of `alloc` - use alloc::vec::Vec; - //~^ ERROR: used import from `std` instead of `alloc` -} - -#[warn(clippy::alloc_instead_of_core)] -fn alloc_instead_of_core() { - use core::slice::from_ref; - //~^ ERROR: used import from `alloc` instead of `core` -} - -mod std_in_proc_macro_derive { - #[warn(clippy::alloc_instead_of_core)] - #[allow(unused)] - #[derive(ImplStructWithStdDisplay)] - struct B {} -} - -fn main() { - std_instead_of_core(); - std_instead_of_alloc(); - alloc_instead_of_core(); -} diff --git a/tests/ui/std_instead_of_core.rs b/tests/ui/std_instead_of_core.rs index c12c459c7eb4..120893c26557 100644 --- a/tests/ui/std_instead_of_core.rs +++ b/tests/ui/std_instead_of_core.rs @@ -1,4 +1,5 @@ //@aux-build:proc_macro_derive.rs +//@no-rustfix #![warn(clippy::std_instead_of_core)] #![allow(unused_imports)] @@ -31,6 +32,42 @@ fn std_instead_of_core() { ptr::read_unaligned, }; + // Multiple import, some not in core/alloc, first pos + use std::{io::Write as _, fmt::Debug as _, fmt::Alignment as _}; + //~^ ERROR: used import from `std` instead of `core` + + // Second pos + use std::{fmt::Alignment as _, io::Write as _, fmt::Debug as _}; + //~^ ERROR: used import from `std` instead of `core` + + // Third pos + use std::{fmt::Debug as _, fmt::Alignment as _, io::Write as _}; + //~^ ERROR: used import from `std` instead of `core` + + // Multiple import, multi-line, same procedure as above + #[rustfmt::skip] + use std::{ + io::Write as _, + fmt::Debug as _, + fmt::Alignment as _, + }; + + // Second pos + #[rustfmt::skip] + use std::{ + fmt::Alignment as _, + io::Write as _, + fmt::Debug as _, + }; + + // Third pos + #[rustfmt::skip] + use std::{ + fmt::Alignment as _, + fmt::Debug as _, + io::Write as _, + }; + // Function calls let ptr = std::ptr::null::(); //~^ ERROR: used import from `std` instead of `core` diff --git a/tests/ui/std_instead_of_core.stderr b/tests/ui/std_instead_of_core.stderr index 8f920511cc5d..f63e3d08123a 100644 --- a/tests/ui/std_instead_of_core.stderr +++ b/tests/ui/std_instead_of_core.stderr @@ -1,5 +1,5 @@ error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:14:9 + --> tests/ui/std_instead_of_core.rs:15:9 | LL | use std::hash::Hasher; | ^^^ help: consider importing the item from `core`: `core` @@ -8,55 +8,115 @@ LL | use std::hash::Hasher; = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_core)]` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:17:11 + --> tests/ui/std_instead_of_core.rs:18:11 | LL | use ::std::hash::Hash; | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:23:9 + --> tests/ui/std_instead_of_core.rs:24:9 | LL | use std::fmt::{Debug, Result}; | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:28:9 + --> tests/ui/std_instead_of_core.rs:29:9 | LL | use std::{ | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:35:15 + --> tests/ui/std_instead_of_core.rs:36:31 + | +LL | use std::{io::Write as _, fmt::Debug as _, fmt::Alignment as _}; + | ^^^^^^^^^^ + | + = help: consider importing the item from `core` + +error: used import from `std` instead of `core` + --> tests/ui/std_instead_of_core.rs:36:48 + | +LL | use std::{io::Write as _, fmt::Debug as _, fmt::Alignment as _}; + | ^^^^^^^^^^^^^^ + | + = help: consider importing the item from `core` + +error: used import from `std` instead of `core` + --> tests/ui/std_instead_of_core.rs:40:15 + | +LL | use std::{fmt::Alignment as _, io::Write as _, fmt::Debug as _}; + | ^^^^^^^^^^^^^^ + | + = help: consider importing the item from `core` + +error: used import from `std` instead of `core` + --> tests/ui/std_instead_of_core.rs:40:52 + | +LL | use std::{fmt::Alignment as _, io::Write as _, fmt::Debug as _}; + | ^^^^^^^^^^ + | + = help: consider importing the item from `core` + +error: used import from `std` instead of `core` + --> tests/ui/std_instead_of_core.rs:44:15 + | +LL | use std::{fmt::Debug as _, fmt::Alignment as _, io::Write as _}; + | ^^^^^^^^^^ + | + = help: consider importing the item from `core` + +error: used import from `std` instead of `core` + --> tests/ui/std_instead_of_core.rs:44:32 + | +LL | use std::{fmt::Debug as _, fmt::Alignment as _, io::Write as _}; + | ^^^^^^^^^^^^^^ + | + = help: consider importing the item from `core` + +error: used import from `std` instead of `core` + --> tests/ui/std_instead_of_core.rs:57:9 + | +LL | use std::{ + | ^^^ help: consider importing the item from `core`: `core` + +error: used import from `std` instead of `core` + --> tests/ui/std_instead_of_core.rs:65:9 + | +LL | use std::{ + | ^^^ help: consider importing the item from `core`: `core` + +error: used import from `std` instead of `core` + --> tests/ui/std_instead_of_core.rs:72:15 | LL | let ptr = std::ptr::null::(); | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:37:21 + --> tests/ui/std_instead_of_core.rs:74:21 | LL | let ptr_mut = ::std::ptr::null_mut::(); | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:41:16 + --> tests/ui/std_instead_of_core.rs:78:16 | LL | let cell = std::cell::Cell::new(8u32); | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:43:27 + --> tests/ui/std_instead_of_core.rs:80:27 | LL | let cell_absolute = ::std::cell::Cell::new(8u32); | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:52:9 + --> tests/ui/std_instead_of_core.rs:89:9 | LL | use std::iter::Iterator; | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `alloc` - --> tests/ui/std_instead_of_core.rs:59:9 + --> tests/ui/std_instead_of_core.rs:96:9 | LL | use std::vec; | ^^^ help: consider importing the item from `alloc`: `alloc` @@ -65,13 +125,13 @@ LL | use std::vec; = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_alloc)]` error: used import from `std` instead of `alloc` - --> tests/ui/std_instead_of_core.rs:61:9 + --> tests/ui/std_instead_of_core.rs:98:9 | LL | use std::vec::Vec; | ^^^ help: consider importing the item from `alloc`: `alloc` error: used import from `alloc` instead of `core` - --> tests/ui/std_instead_of_core.rs:67:9 + --> tests/ui/std_instead_of_core.rs:104:9 | LL | use alloc::slice::from_ref; | ^^^^^ help: consider importing the item from `core`: `core` @@ -79,5 +139,5 @@ LL | use alloc::slice::from_ref; = note: `-D clippy::alloc-instead-of-core` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::alloc_instead_of_core)]` -error: aborting due to 12 previous errors +error: aborting due to 20 previous errors From 3b33d69af74dfe2dcaebf19cc34226b9c63ae7d4 Mon Sep 17 00:00:00 2001 From: MarcusGrass Date: Tue, 12 Mar 2024 16:18:45 +0100 Subject: [PATCH 4/8] Multiline working --- clippy_lints/src/std_instead_of_core.rs | 8 ++-- tests/ui/std_instead_of_core.stderr | 50 +++++++++++++++++++++---- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/clippy_lints/src/std_instead_of_core.rs b/clippy_lints/src/std_instead_of_core.rs index 77a9271502d2..80a60234f653 100644 --- a/clippy_lints/src/std_instead_of_core.rs +++ b/clippy_lints/src/std_instead_of_core.rs @@ -152,6 +152,9 @@ impl StdReexports { self.open_use = Some(collected_use); return; } + if collected_use.members.is_empty() { + return; + } let mut place_holder_unique_check: Option<(Span, ReplaceLintData)> = None; let mut can_chunk = true; for member in collected_use.members.iter() { @@ -384,11 +387,6 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { fn check_variant(&mut self, cx: &LateContext<'tcx>, v: &'tcx Variant<'tcx>) { self.suggest_for_open_use_item_if_after(cx, v.span); } - - #[inline] - fn check_attribute(&mut self, cx: &LateContext<'tcx>, attr: &'tcx Attribute) { - self.suggest_for_open_use_item_if_after(cx, attr.span); - } } /// Returns the first named segment of a [`Path`]. diff --git a/tests/ui/std_instead_of_core.stderr b/tests/ui/std_instead_of_core.stderr index f63e3d08123a..e3e179e3d8f1 100644 --- a/tests/ui/std_instead_of_core.stderr +++ b/tests/ui/std_instead_of_core.stderr @@ -74,16 +74,52 @@ LL | use std::{fmt::Debug as _, fmt::Alignment as _, io::Write as _}; = help: consider importing the item from `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:57:9 + --> tests/ui/std_instead_of_core.rs:51:9 | -LL | use std::{ - | ^^^ help: consider importing the item from `core`: `core` +LL | fmt::Debug as _, + | ^^^^^^^^^^ + | + = help: consider importing the item from `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:65:9 + --> tests/ui/std_instead_of_core.rs:52:9 | -LL | use std::{ - | ^^^ help: consider importing the item from `core`: `core` +LL | fmt::Alignment as _, + | ^^^^^^^^^^^^^^ + | + = help: consider importing the item from `core` + +error: used import from `std` instead of `core` + --> tests/ui/std_instead_of_core.rs:58:9 + | +LL | fmt::Alignment as _, + | ^^^^^^^^^^^^^^ + | + = help: consider importing the item from `core` + +error: used import from `std` instead of `core` + --> tests/ui/std_instead_of_core.rs:60:9 + | +LL | fmt::Debug as _, + | ^^^^^^^^^^ + | + = help: consider importing the item from `core` + +error: used import from `std` instead of `core` + --> tests/ui/std_instead_of_core.rs:66:9 + | +LL | fmt::Alignment as _, + | ^^^^^^^^^^^^^^ + | + = help: consider importing the item from `core` + +error: used import from `std` instead of `core` + --> tests/ui/std_instead_of_core.rs:67:9 + | +LL | fmt::Debug as _, + | ^^^^^^^^^^ + | + = help: consider importing the item from `core` error: used import from `std` instead of `core` --> tests/ui/std_instead_of_core.rs:72:15 @@ -139,5 +175,5 @@ LL | use alloc::slice::from_ref; = note: `-D clippy::alloc-instead-of-core` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::alloc_instead_of_core)]` -error: aborting due to 20 previous errors +error: aborting due to 24 previous errors From 86cbce39f5a0758427ef4ba7b71bf14e96da090f Mon Sep 17 00:00:00 2001 From: MarcusGrass Date: Tue, 12 Mar 2024 16:41:51 +0100 Subject: [PATCH 5/8] Add a test for the last entry --- clippy_lints/src/std_instead_of_core.rs | 7 +++---- tests/ui/std_instead_of_core.rs | 3 +++ tests/ui/std_instead_of_core.stderr | 8 +++++++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/clippy_lints/src/std_instead_of_core.rs b/clippy_lints/src/std_instead_of_core.rs index 80a60234f653..844a070d56ae 100644 --- a/clippy_lints/src/std_instead_of_core.rs +++ b/clippy_lints/src/std_instead_of_core.rs @@ -283,10 +283,9 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { } - #[inline] - fn check_item_post(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { - self.suggest_for_open_use_item_if_after(cx, item.span); - } + // Essentially, check every other parsable thing's start (except for attributes), + // If it starts, wrap up the last path lint. Lookahead would be nice but I don't + // know if that's possible. #[inline] fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'tcx>) { diff --git a/tests/ui/std_instead_of_core.rs b/tests/ui/std_instead_of_core.rs index 120893c26557..cff4217e9f29 100644 --- a/tests/ui/std_instead_of_core.rs +++ b/tests/ui/std_instead_of_core.rs @@ -117,3 +117,6 @@ fn main() { std_instead_of_alloc(); alloc_instead_of_core(); } + +use std::fmt::{Debug as _, Result as _}; +//~^ ERROR: used import from `std` instead of `core` diff --git a/tests/ui/std_instead_of_core.stderr b/tests/ui/std_instead_of_core.stderr index e3e179e3d8f1..f6dd46f0d8ad 100644 --- a/tests/ui/std_instead_of_core.stderr +++ b/tests/ui/std_instead_of_core.stderr @@ -175,5 +175,11 @@ LL | use alloc::slice::from_ref; = note: `-D clippy::alloc-instead-of-core` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::alloc_instead_of_core)]` -error: aborting due to 24 previous errors +error: used import from `std` instead of `core` + --> tests/ui/std_instead_of_core.rs:121:5 + | +LL | use std::fmt::{Debug as _, Result as _}; + | ^^^ help: consider importing the item from `core`: `core` + +error: aborting due to 25 previous errors From e0461e73354f7376cecac5bf3d270e2e23553395 Mon Sep 17 00:00:00 2001 From: MarcusGrass Date: Tue, 12 Mar 2024 16:50:19 +0100 Subject: [PATCH 6/8] Add some comments --- clippy_lints/src/std_instead_of_core.rs | 94 +++++++++++++++++++------ tests/ui/std_instead_of_core.rs | 3 + 2 files changed, 74 insertions(+), 23 deletions(-) diff --git a/clippy_lints/src/std_instead_of_core.rs b/clippy_lints/src/std_instead_of_core.rs index 844a070d56ae..cfc46d941a2b 100644 --- a/clippy_lints/src/std_instead_of_core.rs +++ b/clippy_lints/src/std_instead_of_core.rs @@ -1,4 +1,3 @@ -use std::hash::{Hash, Hasher}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then}; use clippy_utils::is_from_proc_macro; use rustc_ast::Attribute; @@ -6,14 +5,18 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::def_id::DefId; -use rustc_hir::{Arm, Block, Body, Expr, FieldDef, FnDecl, ForeignItem, GenericParam, Generics, HirId, ImplItem, Item, ItemKind, Local, Mod, Pat, Path, PathSegment, PolyTraitRef, Stmt, TraitItem, Ty, UseKind, Variant, VariantData}; use rustc_hir::intravisit::FnKind; +use rustc_hir::{ + Arm, Block, Body, Expr, FieldDef, FnDecl, ForeignItem, GenericParam, Generics, HirId, ImplItem, Item, ItemKind, + Local, Mod, Pat, Path, PathSegment, PolyTraitRef, Stmt, TraitItem, Ty, UseKind, Variant, VariantData, +}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::impl_lint_pass; +use rustc_span::def_id::LocalDefId; use rustc_span::symbol::kw; use rustc_span::{sym, Span}; -use rustc_span::def_id::LocalDefId; +use std::hash::{Hash, Hasher}; declare_clippy_lint! { /// ### What it does @@ -98,15 +101,21 @@ pub struct StdReexports { // 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. prev_span: Span, - open_use: Option + // When inside of a UseKind::ListStem the previous check + // isn't enough to ensure correct parsing + open_use: Option, } impl_lint_pass!(StdReexports => [STD_INSTEAD_OF_CORE, STD_INSTEAD_OF_ALLOC, ALLOC_INSTEAD_OF_CORE]); +/// Save all members of a UseKind::ListStem `use std::fmt::{Debug, Result};` +/// Lint when the ListStem closes. However, since there's no look-ahead (that I know of). +/// Close whenever something is encountered that's outside of the container `Span`. #[derive(Debug)] struct OpenUseSpan { container: Span, - members: FxIndexSet + // Preserve insert order on iteration, so that lints come out in 'source order' + members: FxIndexSet, } #[derive(Debug, Copy, Clone)] @@ -152,37 +161,51 @@ impl StdReexports { self.open_use = Some(collected_use); return; } + // Short circuit if collected_use.members.is_empty() { return; } let mut place_holder_unique_check: Option<(Span, ReplaceLintData)> = None; - let mut can_chunk = true; + // If true after checking all members, the lint is 'fixable'. + // Otherwise, just warn + let mut all_same_valid_lint = true; for member in collected_use.members.iter() { match &member.lint_data { LintData::CanReplace(lint_data) => { if let Some((_span, prev_lint_data)) = place_holder_unique_check.take() { - if prev_lint_data.lint.name == lint_data.lint.name && prev_lint_data.used_mod == lint_data.used_mod && prev_lint_data.replace_with == lint_data.replace_with { + if prev_lint_data.lint.name == lint_data.lint.name + && prev_lint_data.used_mod == lint_data.used_mod + && prev_lint_data.replace_with == lint_data.replace_with + { place_holder_unique_check = Some((member.first_seg_ident_span, *lint_data)); } else { // Will have to warn for individual entries - can_chunk = false; + all_same_valid_lint = false; break; } } else { place_holder_unique_check = Some((member.first_seg_ident_span, *lint_data)); } - } + }, LintData::NoReplace => { // Will have to warn for individual entries - can_chunk = false; + all_same_valid_lint = false; break; - } + }, } } // If they can all be replaced with the same thing, just lint and suggest, then // clippy-fix works as well - if can_chunk { - if let Some((first_segment_ident_span, ReplaceLintData { lint, used_mod, replace_with })) = place_holder_unique_check { + if all_same_valid_lint { + if let Some(( + first_segment_ident_span, + ReplaceLintData { + lint, + used_mod, + replace_with, + }, + )) = place_holder_unique_check + { span_lint_and_sugg( cx, lint, @@ -195,10 +218,23 @@ impl StdReexports { } } else { for member in collected_use.members { - if let LintData::CanReplace(ReplaceLintData { lint, used_mod, replace_with }) = member.lint_data { - span_lint_hir_and_then(cx, lint, member.hir_id, member.inner, &format!("used import from `{used_mod}` instead of `{replace_with}`"), |diag| { - diag.help(format!("consider importing the item from `{replace_with}`")); - }) + if let LintData::CanReplace(ReplaceLintData { + lint, + used_mod, + replace_with, + }) = member.lint_data + { + // Just lint, don't suggest a change + span_lint_hir_and_then( + cx, + lint, + member.hir_id, + member.inner, + &format!("used import from `{used_mod}` instead of `{replace_with}`"), + |diag| { + diag.help(format!("consider importing the item from `{replace_with}`")); + }, + ) } } } @@ -217,12 +253,12 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { { let lint_data = match first_segment.ident.name { sym::std => match cx.tcx.crate_name(def_id.krate) { - sym::core => LintData::CanReplace(ReplaceLintData{ + sym::core => LintData::CanReplace(ReplaceLintData { lint: STD_INSTEAD_OF_CORE, used_mod: "std", replace_with: "core", }), - sym::alloc => LintData::CanReplace(ReplaceLintData{ + sym::alloc => LintData::CanReplace(ReplaceLintData { lint: STD_INSTEAD_OF_ALLOC, used_mod: "std", replace_with: "alloc", @@ -234,7 +270,7 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { }, sym::alloc => { if cx.tcx.crate_name(def_id.krate) == sym::core { - LintData::CanReplace(ReplaceLintData{ + LintData::CanReplace(ReplaceLintData { lint: ALLOC_INSTEAD_OF_CORE, used_mod: "alloc", replace_with: "core", @@ -255,7 +291,12 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { }); return; } - if let LintData::CanReplace(ReplaceLintData { lint, used_mod, replace_with }) = lint_data { + if let LintData::CanReplace(ReplaceLintData { + lint, + used_mod, + replace_with, + }) = lint_data + { if first_segment.ident.span != self.prev_span { span_lint_and_sugg( cx, @@ -280,7 +321,6 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { members: FxIndexSet::default(), }) } - } // Essentially, check every other parsable thing's start (except for attributes), @@ -358,7 +398,15 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { } #[inline] - fn check_fn(&mut self, cx: &LateContext<'tcx>, _: FnKind<'tcx>, _: &'tcx FnDecl<'tcx>, _: &'tcx Body<'tcx>, s: Span, _: LocalDefId) { + fn check_fn( + &mut self, + cx: &LateContext<'tcx>, + _: FnKind<'tcx>, + _: &'tcx FnDecl<'tcx>, + _: &'tcx Body<'tcx>, + s: Span, + _: LocalDefId, + ) { self.suggest_for_open_use_item_if_after(cx, s); } diff --git a/tests/ui/std_instead_of_core.rs b/tests/ui/std_instead_of_core.rs index cff4217e9f29..29691f727074 100644 --- a/tests/ui/std_instead_of_core.rs +++ b/tests/ui/std_instead_of_core.rs @@ -33,14 +33,17 @@ fn std_instead_of_core() { }; // Multiple import, some not in core/alloc, first pos + #[rustfmt::skip] use std::{io::Write as _, fmt::Debug as _, fmt::Alignment as _}; //~^ ERROR: used import from `std` instead of `core` // Second pos + #[rustfmt::skip] use std::{fmt::Alignment as _, io::Write as _, fmt::Debug as _}; //~^ ERROR: used import from `std` instead of `core` // Third pos + #[rustfmt::skip] use std::{fmt::Debug as _, fmt::Alignment as _, io::Write as _}; //~^ ERROR: used import from `std` instead of `core` From efddc6a7da3b9e59d0d5a9725b6403d09720ae2f Mon Sep 17 00:00:00 2001 From: MarcusGrass Date: Tue, 12 Mar 2024 17:18:51 +0100 Subject: [PATCH 7/8] Lint and update stderr --- clippy_lints/src/std_instead_of_core.rs | 13 ++++---- tests/ui/std_instead_of_core.stderr | 42 ++++++++++++------------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/clippy_lints/src/std_instead_of_core.rs b/clippy_lints/src/std_instead_of_core.rs index cfc46d941a2b..04950bb1edb9 100644 --- a/clippy_lints/src/std_instead_of_core.rs +++ b/clippy_lints/src/std_instead_of_core.rs @@ -1,6 +1,5 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then}; use clippy_utils::is_from_proc_macro; -use rustc_ast::Attribute; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::Applicability; use rustc_hir::def::Res; @@ -108,8 +107,8 @@ pub struct StdReexports { impl_lint_pass!(StdReexports => [STD_INSTEAD_OF_CORE, STD_INSTEAD_OF_ALLOC, ALLOC_INSTEAD_OF_CORE]); -/// Save all members of a UseKind::ListStem `use std::fmt::{Debug, Result};` -/// Lint when the ListStem closes. However, since there's no look-ahead (that I know of). +/// Save all members of a `UseKind::ListStem` `use std::fmt::{Debug, Result};` +/// Lint when the `ListStem` closes. However, since there's no look-ahead (that I know of). /// Close whenever something is encountered that's outside of the container `Span`. #[derive(Debug)] struct OpenUseSpan { @@ -154,7 +153,7 @@ struct ReplaceLintData { } impl StdReexports { - fn suggest_for_open_use_item_if_after<'tcx>(&mut self, cx: &LateContext<'tcx>, span: Span) { + fn suggest_for_open_use_item_if_after(&mut self, cx: &LateContext<'_>, span: Span) { if let Some(collected_use) = self.open_use.take() { // Still contains other span, throw it back if collected_use.container.contains(span) { @@ -169,7 +168,7 @@ impl StdReexports { // If true after checking all members, the lint is 'fixable'. // Otherwise, just warn let mut all_same_valid_lint = true; - for member in collected_use.members.iter() { + for member in &collected_use.members { match &member.lint_data { LintData::CanReplace(lint_data) => { if let Some((_span, prev_lint_data)) = place_holder_unique_check.take() { @@ -234,7 +233,7 @@ impl StdReexports { |diag| { diag.help(format!("consider importing the item from `{replace_with}`")); }, - ) + ); } } } @@ -319,7 +318,7 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { self.open_use = Some(OpenUseSpan { container: item.span, members: FxIndexSet::default(), - }) + }); } } diff --git a/tests/ui/std_instead_of_core.stderr b/tests/ui/std_instead_of_core.stderr index f6dd46f0d8ad..c40b05fd3d49 100644 --- a/tests/ui/std_instead_of_core.stderr +++ b/tests/ui/std_instead_of_core.stderr @@ -26,7 +26,7 @@ LL | use std::{ | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:36:31 + --> tests/ui/std_instead_of_core.rs:37:31 | LL | use std::{io::Write as _, fmt::Debug as _, fmt::Alignment as _}; | ^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | use std::{io::Write as _, fmt::Debug as _, fmt::Alignment as _}; = help: consider importing the item from `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:36:48 + --> tests/ui/std_instead_of_core.rs:37:48 | LL | use std::{io::Write as _, fmt::Debug as _, fmt::Alignment as _}; | ^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL | use std::{io::Write as _, fmt::Debug as _, fmt::Alignment as _}; = help: consider importing the item from `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:40:15 + --> tests/ui/std_instead_of_core.rs:42:15 | LL | use std::{fmt::Alignment as _, io::Write as _, fmt::Debug as _}; | ^^^^^^^^^^^^^^ @@ -50,7 +50,7 @@ LL | use std::{fmt::Alignment as _, io::Write as _, fmt::Debug as _}; = help: consider importing the item from `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:40:52 + --> tests/ui/std_instead_of_core.rs:42:52 | LL | use std::{fmt::Alignment as _, io::Write as _, fmt::Debug as _}; | ^^^^^^^^^^ @@ -58,7 +58,7 @@ LL | use std::{fmt::Alignment as _, io::Write as _, fmt::Debug as _}; = help: consider importing the item from `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:44:15 + --> tests/ui/std_instead_of_core.rs:47:15 | LL | use std::{fmt::Debug as _, fmt::Alignment as _, io::Write as _}; | ^^^^^^^^^^ @@ -66,7 +66,7 @@ LL | use std::{fmt::Debug as _, fmt::Alignment as _, io::Write as _}; = help: consider importing the item from `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:44:32 + --> tests/ui/std_instead_of_core.rs:47:32 | LL | use std::{fmt::Debug as _, fmt::Alignment as _, io::Write as _}; | ^^^^^^^^^^^^^^ @@ -74,7 +74,7 @@ LL | use std::{fmt::Debug as _, fmt::Alignment as _, io::Write as _}; = help: consider importing the item from `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:51:9 + --> tests/ui/std_instead_of_core.rs:54:9 | LL | fmt::Debug as _, | ^^^^^^^^^^ @@ -82,7 +82,7 @@ LL | fmt::Debug as _, = help: consider importing the item from `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:52:9 + --> tests/ui/std_instead_of_core.rs:55:9 | LL | fmt::Alignment as _, | ^^^^^^^^^^^^^^ @@ -90,7 +90,7 @@ LL | fmt::Alignment as _, = help: consider importing the item from `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:58:9 + --> tests/ui/std_instead_of_core.rs:61:9 | LL | fmt::Alignment as _, | ^^^^^^^^^^^^^^ @@ -98,7 +98,7 @@ LL | fmt::Alignment as _, = help: consider importing the item from `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:60:9 + --> tests/ui/std_instead_of_core.rs:63:9 | LL | fmt::Debug as _, | ^^^^^^^^^^ @@ -106,7 +106,7 @@ LL | fmt::Debug as _, = help: consider importing the item from `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:66:9 + --> tests/ui/std_instead_of_core.rs:69:9 | LL | fmt::Alignment as _, | ^^^^^^^^^^^^^^ @@ -114,7 +114,7 @@ LL | fmt::Alignment as _, = help: consider importing the item from `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:67:9 + --> tests/ui/std_instead_of_core.rs:70:9 | LL | fmt::Debug as _, | ^^^^^^^^^^ @@ -122,37 +122,37 @@ LL | fmt::Debug as _, = help: consider importing the item from `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:72:15 + --> tests/ui/std_instead_of_core.rs:75:15 | LL | let ptr = std::ptr::null::(); | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:74:21 + --> tests/ui/std_instead_of_core.rs:77:21 | LL | let ptr_mut = ::std::ptr::null_mut::(); | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:78:16 + --> tests/ui/std_instead_of_core.rs:81:16 | LL | let cell = std::cell::Cell::new(8u32); | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:80:27 + --> tests/ui/std_instead_of_core.rs:83:27 | LL | let cell_absolute = ::std::cell::Cell::new(8u32); | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:89:9 + --> tests/ui/std_instead_of_core.rs:92:9 | LL | use std::iter::Iterator; | ^^^ help: consider importing the item from `core`: `core` error: used import from `std` instead of `alloc` - --> tests/ui/std_instead_of_core.rs:96:9 + --> tests/ui/std_instead_of_core.rs:99:9 | LL | use std::vec; | ^^^ help: consider importing the item from `alloc`: `alloc` @@ -161,13 +161,13 @@ LL | use std::vec; = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_alloc)]` error: used import from `std` instead of `alloc` - --> tests/ui/std_instead_of_core.rs:98:9 + --> tests/ui/std_instead_of_core.rs:101:9 | LL | use std::vec::Vec; | ^^^ help: consider importing the item from `alloc`: `alloc` error: used import from `alloc` instead of `core` - --> tests/ui/std_instead_of_core.rs:104:9 + --> tests/ui/std_instead_of_core.rs:107:9 | LL | use alloc::slice::from_ref; | ^^^^^ help: consider importing the item from `core`: `core` @@ -176,7 +176,7 @@ LL | use alloc::slice::from_ref; = help: to override `-D warnings` add `#[allow(clippy::alloc_instead_of_core)]` error: used import from `std` instead of `core` - --> tests/ui/std_instead_of_core.rs:121:5 + --> tests/ui/std_instead_of_core.rs:124:5 | LL | use std::fmt::{Debug as _, Result as _}; | ^^^ help: consider importing the item from `core`: `core` From d7af836d3616a5f649c63e7ddbf9e2bfae279b47 Mon Sep 17 00:00:00 2001 From: MarcusGrass Date: Sat, 20 Apr 2024 18:00:09 +0200 Subject: [PATCH 8/8] Fix main compatibility --- clippy_lints/src/std_instead_of_core.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/std_instead_of_core.rs b/clippy_lints/src/std_instead_of_core.rs index 04950bb1edb9..39f9789be48c 100644 --- a/clippy_lints/src/std_instead_of_core.rs +++ b/clippy_lints/src/std_instead_of_core.rs @@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::intravisit::FnKind; use rustc_hir::{ Arm, Block, Body, Expr, FieldDef, FnDecl, ForeignItem, GenericParam, Generics, HirId, ImplItem, Item, ItemKind, - Local, Mod, Pat, Path, PathSegment, PolyTraitRef, Stmt, TraitItem, Ty, UseKind, Variant, VariantData, + LetStmt, Mod, Pat, Path, PathSegment, PolyTraitRef, Stmt, TraitItem, Ty, UseKind, Variant, VariantData, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; @@ -209,8 +209,8 @@ impl StdReexports { cx, lint, first_segment_ident_span, - &format!("used import from `{used_mod}` instead of `{replace_with}`"), - &format!("consider importing the item from `{replace_with}`"), + format!("used import from `{used_mod}` instead of `{replace_with}`"), + format!("consider importing the item from `{replace_with}`"), replace_with.to_string(), Applicability::MachineApplicable, ); @@ -229,7 +229,7 @@ impl StdReexports { lint, member.hir_id, member.inner, - &format!("used import from `{used_mod}` instead of `{replace_with}`"), + format!("used import from `{used_mod}` instead of `{replace_with}`"), |diag| { diag.help(format!("consider importing the item from `{replace_with}`")); }, @@ -301,8 +301,8 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { cx, lint, first_segment.ident.span, - &format!("used import from `{used_mod}` instead of `{replace_with}`"), - &format!("consider importing the item from `{replace_with}`"), + format!("used import from `{used_mod}` instead of `{replace_with}`"), + format!("consider importing the item from `{replace_with}`"), replace_with.to_string(), Applicability::MachineApplicable, ); @@ -347,7 +347,7 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports { } #[inline] - fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) { + fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) { self.suggest_for_open_use_item_if_after(cx, local.span); }