diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index d91b2e1f448..02fb6b79dc4 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -8,6 +8,7 @@ #![feature(rustc_private)] #![feature(stmt_expr_attributes)] #![feature(control_flow_enum)] +#![feature(let_else)] #![recursion_limit = "512"] #![cfg_attr(feature = "deny-warnings", deny(warnings))] #![allow(clippy::missing_docs_in_private_items, clippy::must_use_candidate)] diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs index ef26de5b6b9..bd779124dee 100644 --- a/clippy_lints/src/swap.rs +++ b/clippy_lints/src/swap.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::source::snippet_with_applicability; use clippy_utils::sugg::Sugg; use clippy_utils::ty::is_type_diagnostic_item; -use clippy_utils::{can_mut_borrow_both, differing_macro_contexts, eq_expr_value}; +use clippy_utils::{can_mut_borrow_both, differing_macro_contexts, eq_expr_value, std_or_core}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Block, Expr, ExprKind, PatKind, QPath, Stmt, StmtKind}; @@ -113,6 +113,8 @@ fn generate_swap_warning(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>, spa let first = Sugg::hir_with_applicability(cx, e1, "..", &mut applicability); let second = Sugg::hir_with_applicability(cx, e2, "..", &mut applicability); + let Some(sugg) = std_or_core(cx) else { return }; + span_lint_and_then( cx, MANUAL_SWAP, @@ -122,11 +124,11 @@ fn generate_swap_warning(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>, spa diag.span_suggestion( span, "try", - format!("std::mem::swap({}, {})", first.mut_addr(), second.mut_addr()), + format!("{}::mem::swap({}, {})", sugg, first.mut_addr(), second.mut_addr()), applicability, ); if !is_xor_based { - diag.note("or maybe you should use `std::mem::replace`?"); + diag.note(&format!("or maybe you should use `{}::mem::replace`?", sugg)); } }, ); @@ -187,26 +189,30 @@ fn check_suspicious_swap(cx: &LateContext<'_>, block: &Block<'_>) { }; let span = first.span.to(second.span); + let Some(sugg) = std_or_core(cx) else { return }; span_lint_and_then(cx, - ALMOST_SWAPPED, - span, - &format!("this looks like you are trying to swap{}", what), - |diag| { - if !what.is_empty() { - diag.span_suggestion( - span, - "try", - format!( - "std::mem::swap({}, {})", - lhs, - rhs, - ), - Applicability::MaybeIncorrect, - ); - diag.note("or maybe you should use `std::mem::replace`?"); - } - }); + ALMOST_SWAPPED, + span, + &format!("this looks like you are trying to swap{}", what), + |diag| { + if !what.is_empty() { + diag.span_suggestion( + span, + "try", + format!( + "{}::mem::swap({}, {})", + sugg, + lhs, + rhs, + ), + Applicability::MaybeIncorrect, + ); + diag.note( + &format!("or maybe you should use `{}::mem::replace`?", sugg) + ); + } + }); } } } diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index 95642adeff6..3fdea55aaa1 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -1809,6 +1809,16 @@ pub fn is_expr_final_block_expr(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool { matches!(get_parent_node(tcx, expr.hir_id), Some(Node::Block(..))) } +pub fn std_or_core(cx: &LateContext<'_>) -> Option<&'static str> { + if !is_no_std_crate(cx) { + Some("std") + } else if !is_no_core_crate(cx) { + Some("core") + } else { + None + } +} + pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool { cx.tcx.hir().attrs(hir::CRATE_HIR_ID).iter().any(|attr| { if let ast::AttrKind::Normal(ref attr, _) = attr.kind { @@ -1819,6 +1829,16 @@ pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool { }) } +pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool { + cx.tcx.hir().attrs(hir::CRATE_HIR_ID).iter().any(|attr| { + if let ast::AttrKind::Normal(ref attr, _) = attr.kind { + attr.path == sym::no_core + } else { + false + } + }) +} + /// Check if parent of a hir node is a trait implementation block. /// For example, `f` in /// ```rust,ignore