Remove path_to_local

This commit is contained in:
Jason Newcomb 2025-09-15 16:41:20 -04:00
parent 3f686a074d
commit 53675ce061
40 changed files with 133 additions and 129 deletions

View file

@ -2,8 +2,9 @@ use clippy_config::Conf;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::mir::{PossibleBorrowerMap, enclosing_mir};
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::res::MaybeResPath;
use clippy_utils::sugg::Sugg;
use clippy_utils::{is_diag_trait_item, is_in_test, last_path_segment, local_is_initialized, path_to_local, sym};
use clippy_utils::{is_diag_trait_item, is_in_test, last_path_segment, local_is_initialized, sym};
use rustc_errors::Applicability;
use rustc_hir::{self as hir, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
@ -97,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for AssigningClones {
// TODO: This check currently bails if the local variable has no initializer.
// That is overly conservative - the lint should fire even if there was no initializer,
// but the variable has been initialized before `lhs` was evaluated.
&& path_to_local(lhs).is_none_or(|lhs| local_is_initialized(cx, lhs))
&& lhs.res_local_id().is_none_or(|lhs| local_is_initialized(cx, lhs))
&& let Some(resolved_impl) = cx.tcx.impl_of_assoc(resolved_fn.def_id())
// Derived forms don't implement `clone_from`/`clone_into`.
// See https://github.com/rust-lang/rust/pull/98445#issuecomment-1190681305

View file

@ -1,8 +1,9 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::numeric_literal::NumericLiteral;
use clippy_utils::res::MaybeResPath;
use clippy_utils::source::{SpanRangeExt, snippet_opt};
use clippy_utils::visitors::{Visitable, for_each_expr_without_closures};
use clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant, is_ty_alias, path_to_local};
use clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant, is_ty_alias};
use rustc_ast::{LitFloatType, LitIntType, LitKind};
use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
@ -167,11 +168,11 @@ pub(super) fn check<'tcx>(
sym::assert_ne_macro,
sym::debug_assert_ne_macro,
];
matches!(expr.span.ctxt().outer_expn_data().macro_def_id, Some(def_id) if
matches!(expr.span.ctxt().outer_expn_data().macro_def_id, Some(def_id) if
cx.tcx.get_diagnostic_name(def_id).is_some_and(|sym| ALLOWED_MACROS.contains(&sym)))
}
if let Some(id) = path_to_local(cast_expr)
if let Some(id) = cast_expr.res_local_id()
&& !cx.tcx.hir_span(id).eq_ctxt(cast_expr.span)
{
// Binding context is different than the identifiers context.

View file

@ -1,10 +1,10 @@
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
use clippy_utils::res::MaybeResPath;
use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
use clippy_utils::sugg::has_enclosing_paren;
use clippy_utils::ty::{adjust_derefs_manually_drop, implements_trait, is_manually_drop, peel_and_count_ty_refs};
use clippy_utils::{
DefinedTy, ExprUseNode, expr_use_ctxt, get_parent_expr, is_block_like, is_from_proc_macro, is_lint_allowed,
path_to_local,
};
use rustc_ast::util::parser::ExprPrecedence;
use rustc_data_structures::fx::FxIndexMap;
@ -239,7 +239,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
return;
}
if let Some(local) = path_to_local(expr) {
if let Some(local) = expr.res_local_id() {
self.check_local_usage(cx, expr, local);
}

View file

@ -1,11 +1,9 @@
use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::higher::VecArgs;
use clippy_utils::res::MaybeDef;
use clippy_utils::res::{MaybeDef, MaybeResPath};
use clippy_utils::source::{snippet_opt, snippet_with_applicability};
use clippy_utils::usage::{local_used_after_expr, local_used_in};
use clippy_utils::{
get_path_from_caller_to_method_type, is_adjusted, is_no_std_crate, path_to_local, path_to_local_id,
};
use clippy_utils::{get_path_from_caller_to_method_type, is_adjusted, is_no_std_crate, path_to_local_id};
use rustc_abi::ExternAbi;
use rustc_errors::Applicability;
use rustc_hir::attrs::AttributeKind;
@ -218,7 +216,7 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
"redundant closure",
|diag| {
if let Some(mut snippet) = snippet_opt(cx, callee.span) {
if path_to_local(callee).is_some_and(|l| {
if callee.res_local_id().is_some_and(|l| {
// FIXME: Do we really need this `local_used_in` check?
// Isn't it checking something like... `callee(callee)`?
// If somehow this check is needed, add some test for it,

View file

@ -1,6 +1,7 @@
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
use clippy_utils::macros::{FormatArgsStorage, find_format_arg_expr, is_format_macro, root_macro_call_first_node};
use clippy_utils::{get_parent_as_impl, is_diag_trait_item, path_to_local, peel_ref_operators, sym};
use clippy_utils::res::MaybeResPath;
use clippy_utils::{get_parent_as_impl, is_diag_trait_item, peel_ref_operators, sym};
use rustc_ast::{FormatArgsPiece, FormatTrait};
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, Impl, ImplItem, ImplItemKind, QPath};
@ -210,7 +211,7 @@ impl FormatImplExpr<'_, '_> {
// Since the argument to fmt is itself a reference: &self
let reference = peel_ref_operators(self.cx, arg);
// Is the reference self?
if path_to_local(reference).map(|x| self.cx.tcx.hir_name(x)) == Some(kw::SelfLower) {
if reference.res_local_id().map(|x| self.cx.tcx.hir_name(x)) == Some(kw::SelfLower) {
let FormatTraitNames { name, .. } = self.format_trait_impl;
span_lint(
self.cx,

View file

@ -1,12 +1,13 @@
use clippy_utils::res::MaybeResPath;
use rustc_hir::{self as hir, HirId, HirIdSet, intravisit};
use rustc_lint::LateContext;
use rustc_middle::ty;
use rustc_span::def_id::LocalDefId;
use clippy_utils::diagnostics::span_lint;
use clippy_utils::iter_input_pats;
use clippy_utils::ty::is_unsafe_fn;
use clippy_utils::visitors::for_each_expr;
use clippy_utils::{iter_input_pats, path_to_local};
use core::ops::ControlFlow;
@ -87,7 +88,7 @@ fn raw_ptr_arg(cx: &LateContext<'_>, arg: &hir::Param<'_>) -> Option<HirId> {
}
fn check_arg(cx: &LateContext<'_>, raw_ptrs: &HirIdSet, arg: &hir::Expr<'_>) {
if path_to_local(arg).is_some_and(|id| raw_ptrs.contains(&id)) {
if arg.res_local_id().is_some_and(|id| raw_ptrs.contains(&id)) {
span_lint(
cx,
NOT_UNSAFE_PTR_ARG_DEREF,

View file

@ -1,10 +1,10 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::res::MaybeResPath;
use clippy_utils::source::{IntoSpan, SpanRangeExt, first_line_of_span, indent_of, reindent_multiline, snippet};
use clippy_utils::ty::needs_ordered_drop;
use clippy_utils::visitors::for_each_expr_without_closures;
use clippy_utils::{
ContainsName, HirEqInterExpr, SpanlessEq, capture_local_usage, get_enclosing_block, hash_expr, hash_stmt,
path_to_local,
};
use core::iter;
use core::ops::ControlFlow;
@ -149,7 +149,7 @@ fn eq_binding_names(s: &Stmt<'_>, names: &[(HirId, Symbol)]) -> bool {
/// Checks if the statement modifies or moves any of the given locals.
fn modifies_any_local<'tcx>(cx: &LateContext<'tcx>, s: &'tcx Stmt<'_>, locals: &HirIdSet) -> bool {
for_each_expr_without_closures(s, |e| {
if let Some(id) = path_to_local(e)
if let Some(id) = e.res_local_id()
&& locals.contains(&id)
&& !capture_local_usage(cx, e).is_imm_ref()
{
@ -198,7 +198,7 @@ fn scan_block_for_eq<'tcx>(
let mut cond_locals = HirIdSet::default();
for &cond in conds {
let _: Option<!> = for_each_expr_without_closures(cond, |e| {
if let Some(id) = path_to_local(e) {
if let Some(id) = e.res_local_id() {
cond_locals.insert(id);
}
ControlFlow::Continue(())

View file

@ -1,6 +1,7 @@
use clippy_utils::diagnostics::span_lint;
use clippy_utils::res::MaybeResPath;
use clippy_utils::ty::InteriorMut;
use clippy_utils::{SpanlessEq, eq_expr_value, find_binding_init, hash_expr, path_to_local, search_same};
use clippy_utils::{SpanlessEq, eq_expr_value, find_binding_init, hash_expr, search_same};
use rustc_hir::{Expr, ExprKind};
use rustc_lint::LateContext;
@ -16,7 +17,7 @@ fn method_caller_is_mutable<'tcx>(
interior_mut.is_interior_mut_ty(cx, caller_ty)
|| caller_ty.is_mutable_ptr()
// `find_binding_init` will return the binding iff its not mutable
|| path_to_local(caller_expr)
|| caller_expr.res_local_id()
.and_then(|hid| find_binding_init(cx, hid))
.is_none()
}

View file

@ -2,9 +2,10 @@ use clippy_config::Conf;
use clippy_utils::consts::{ConstEvalCtxt, Constant};
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::higher::IfLet;
use clippy_utils::is_lint_allowed;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::res::MaybeResPath;
use clippy_utils::ty::is_copy;
use clippy_utils::{is_lint_allowed, path_to_local};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::Applicability;
use rustc_hir as hir;
@ -225,7 +226,7 @@ impl<'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'_, 'tcx> {
}
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
if let Some(local_id) = path_to_local(expr) {
if let Some(local_id) = expr.res_local_id() {
let Self {
cx,
ref mut slice_lint_info,

View file

@ -1,10 +1,11 @@
use super::{IncrementVisitor, InitializeVisitor, MANUAL_MEMCPY};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::res::MaybeResPath;
use clippy_utils::source::snippet;
use clippy_utils::sugg::Sugg;
use clippy_utils::ty::is_copy;
use clippy_utils::usage::local_used_in;
use clippy_utils::{get_enclosing_block, higher, path_to_local, sugg};
use clippy_utils::{get_enclosing_block, higher, sugg};
use rustc_ast::ast;
use rustc_errors::Applicability;
use rustc_hir::intravisit::walk_block;
@ -67,7 +68,7 @@ pub(super) fn check<'tcx>(
&& !local_used_in(cx, canonical_id, base_left)
&& !local_used_in(cx, canonical_id, base_right)
// Source and destination must be different
&& path_to_local(base_left) != path_to_local(base_right)
&& base_left.res_local_id() != base_right.res_local_id()
{
Some((
ty,
@ -128,7 +129,7 @@ fn build_manual_memcpy_suggestion<'tcx>(
let print_limit = |end: &Expr<'_>, end_str: &str, base: &Expr<'_>, sugg: MinifyingSugg<'static>| {
if let ExprKind::MethodCall(method, recv, [], _) = end.kind
&& method.ident.name == sym::len
&& path_to_local(recv) == path_to_local(base)
&& recv.res_local_id() == base.res_local_id()
{
if sugg.to_string() == end_str {
sugg::EMPTY.into()
@ -364,7 +365,7 @@ fn get_details_from_idx<'tcx>(
starts: &[Start<'tcx>],
) -> Option<(StartKind<'tcx>, Offset)> {
fn get_start<'tcx>(e: &Expr<'_>, starts: &[Start<'tcx>]) -> Option<StartKind<'tcx>> {
let id = path_to_local(e)?;
let id = e.res_local_id()?;
starts.iter().find(|start| start.id == id).map(|start| start.kind)
}
@ -425,7 +426,7 @@ fn get_assignments<'a, 'tcx>(
.chain(*expr)
.filter(move |e| {
if let ExprKind::AssignOp(_, place, _) = e.kind {
path_to_local(place).is_some_and(|id| {
place.res_local_id().is_some_and(|id| {
!loop_counters
.iter()
// skip the first item which should be `StartKind::Range`

View file

@ -1,6 +1,7 @@
use super::MUT_RANGE_BOUND;
use clippy_utils::diagnostics::span_lint_and_note;
use clippy_utils::{get_enclosing_block, higher, path_to_local};
use clippy_utils::res::MaybeResPath;
use clippy_utils::{get_enclosing_block, higher};
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{BindingMode, Expr, ExprKind, HirId, Node, PatKind};
use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
@ -39,7 +40,7 @@ fn mut_warn_with_span(cx: &LateContext<'_>, span: Option<Span>) {
}
fn check_for_mutability(cx: &LateContext<'_>, bound: &Expr<'_>) -> Option<HirId> {
if let Some(hir_id) = path_to_local(bound)
if let Some(hir_id) = bound.res_local_id()
&& let Node::Pat(pat) = cx.tcx.hir_node(hir_id)
&& let PatKind::Binding(BindingMode::MUT, ..) = pat.kind
{

View file

@ -1,10 +1,10 @@
use super::SAME_ITEM_PUSH;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::msrvs::Msrv;
use clippy_utils::res::MaybeDef;
use clippy_utils::res::{MaybeDef, MaybeResPath};
use clippy_utils::source::snippet_with_context;
use clippy_utils::ty::implements_trait;
use clippy_utils::{msrvs, path_to_local, std_or_core, sym};
use clippy_utils::{msrvs, std_or_core, sym};
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
@ -126,7 +126,7 @@ impl<'a, 'tcx> SameItemPushVisitor<'a, 'tcx> {
if !self.non_deterministic_expr
&& !self.multiple_pushes
&& let Some((vec, _, _)) = self.vec_push
&& let Some(hir_id) = path_to_local(vec)
&& let Some(hir_id) = vec.res_local_id()
{
!self.used_locals.contains(&hir_id)
} else {
@ -142,7 +142,7 @@ impl<'tcx> Visitor<'tcx> for SameItemPushVisitor<'_, 'tcx> {
ExprKind::Loop(..) | ExprKind::Match(..) | ExprKind::If(..) => self.non_deterministic_expr = true,
ExprKind::Block(block, _) => self.visit_block(block),
_ => {
if let Some(hir_id) = path_to_local(expr) {
if let Some(hir_id) = expr.res_local_id() {
self.used_locals.insert(hir_id);
}
walk_expr(self, expr);

View file

@ -1,5 +1,6 @@
use clippy_utils::res::MaybeResPath;
use clippy_utils::ty::{has_iter_method, implements_trait};
use clippy_utils::{get_parent_expr, is_integer_const, path_to_local, path_to_local_id, sugg};
use clippy_utils::{get_parent_expr, is_integer_const, path_to_local_id, sugg};
use rustc_ast::ast::{LitIntType, LitKind};
use rustc_errors::Applicability;
use rustc_hir::intravisit::{Visitor, walk_expr, walk_local};
@ -47,7 +48,7 @@ impl<'a, 'tcx> IncrementVisitor<'a, 'tcx> {
impl<'tcx> Visitor<'tcx> for IncrementVisitor<'_, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
// If node is a variable
if let Some(def_id) = path_to_local(expr) {
if let Some(def_id) = expr.res_local_id() {
if let Some(parent) = get_parent_expr(self.cx, expr) {
let state = self.states.entry(def_id).or_insert(IncrementVisitorVarState::Initial);
if *state == IncrementVisitorVarState::IncrOnce {

View file

@ -1,9 +1,10 @@
use clippy_config::Conf;
use clippy_utils::consts::ConstEvalCtxt;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::is_from_proc_macro;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::res::MaybeResPath;
use clippy_utils::source::SpanRangeExt;
use clippy_utils::{is_from_proc_macro, path_to_local};
use rustc_errors::Applicability;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
@ -138,7 +139,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
// Checking all possible scenarios using a function would be a hopeless task, as we have
// 16 possible alignments of constants/operands. For now, let's use `partition`.
&& let mut exprs = [lhs_lhs, lhs_rhs, rhs_lhs, rhs_rhs]
&& exprs.iter_mut().partition_in_place(|i| path_to_local(i).is_some()) == 2
&& exprs.iter_mut().partition_in_place(|i| i.res_local_id().is_some()) == 2
&& !expr.span.in_external_macro(cx.sess().source_map())
&& (
is_not_const(cx.tcx, cx.tcx.hir_enclosing_body_owner(expr.hir_id).into())
@ -149,7 +150,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
&& let ctxt = expr.span.ctxt()
&& let Some(const_1) = ecx.eval_local(const_1, ctxt)
&& let Some(const_2) = ecx.eval_local(const_2, ctxt)
&& path_to_local(first).is_some_and(|f| path_to_local(second).is_some_and(|s| f == s))
&& first.res_local_id().is_some_and(|f| second.res_local_id().is_some_and(|s| f == s))
// The actual infinity check, we also allow `NEG_INFINITY` before` INFINITY` just in
// case somebody does that for some reason
&& (const_1.is_pos_infinity() && const_2.is_neg_infinity()

View file

@ -2,8 +2,9 @@ use clippy_config::Conf;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::macros::matching_root_macro_call;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::res::MaybeResPath;
use clippy_utils::sugg::Sugg;
use clippy_utils::{higher, is_in_const_context, path_to_local, peel_ref_operators, sym};
use clippy_utils::{higher, is_in_const_context, peel_ref_operators, sym};
use rustc_ast::LitKind::{Byte, Char};
use rustc_ast::ast::RangeLimits;
use rustc_errors::Applicability;
@ -125,7 +126,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck {
}
fn get_ty_sugg<'tcx>(cx: &LateContext<'tcx>, arg: &Expr<'_>) -> Option<(Span, Ty<'tcx>)> {
let local_hid = path_to_local(arg)?;
let local_hid = arg.res_local_id()?;
if let Node::Param(Param { ty_span, span, .. }) = cx.tcx.parent_hir_node(local_hid)
// `ty_span` and `span` are the same for inferred type, thus a type suggestion must be given
&& ty_span == span

View file

@ -1,9 +1,10 @@
use clippy_config::Conf;
use clippy_utils::consts::{ConstEvalCtxt, FullInt};
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::is_in_const_context;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::res::MaybeResPath;
use clippy_utils::source::snippet_with_context;
use clippy_utils::{is_in_const_context, path_to_local};
use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Expr, ExprKind, Node, TyKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
@ -64,7 +65,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
&& let ExprKind::Binary(rem2_op, rem2_lhs, rem2_rhs) = add_other.kind
&& rem2_op.node == BinOpKind::Rem
&& const1 == const2
&& let Some(hir_id) = path_to_local(rem2_lhs)
&& let Some(hir_id) = rem2_lhs.res_local_id()
&& let Some(const3) = check_for_unsigned_int_constant(cx, ctxt, rem2_rhs)
// Also ensures the const is nonzero since zero can't be a divisor
&& const2 == const3

View file

@ -1,12 +1,10 @@
use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::higher::IfLetOrMatch;
use clippy_utils::msrvs::Msrv;
use clippy_utils::res::MaybeDef;
use clippy_utils::res::{MaybeDef, MaybeResPath};
use clippy_utils::source::snippet;
use clippy_utils::visitors::is_local_used;
use clippy_utils::{
SpanlessEq, get_ref_operators, is_unit_expr, path_to_local, peel_blocks_with_stmt, peel_ref_operators,
};
use clippy_utils::{SpanlessEq, get_ref_operators, is_unit_expr, peel_blocks_with_stmt, peel_ref_operators};
use rustc_ast::BorrowKind;
use rustc_errors::MultiSpan;
use rustc_hir::LangItem::OptionNone;
@ -67,7 +65,7 @@ fn check_arm<'tcx>(
&& outer_pat.span.eq_ctxt(inner_scrutinee.span)
// match expression must be a local binding
// match <local> { .. }
&& let Some(binding_id) = path_to_local(peel_ref_operators(cx, inner_scrutinee))
&& let Some(binding_id) = peel_ref_operators(cx, inner_scrutinee).res_local_id()
&& !pat_contains_disallowed_or(cx, inner_then_pat, msrv)
// the binding must come from the pattern of the containing match arm
// ..<local>.. => match <local> { .. }

View file

@ -1,6 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::res::MaybeResPath;
use clippy_utils::source::SpanRangeExt;
use clippy_utils::{SpanlessEq, fulfill_or_allowed, hash_expr, is_lint_allowed, path_to_local, search_same};
use clippy_utils::{SpanlessEq, fulfill_or_allowed, hash_expr, is_lint_allowed, search_same};
use core::cmp::Ordering;
use core::{iter, slice};
use itertools::Itertools;
@ -61,8 +62,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
let check_eq_with_pat = |expr_a: &Expr<'_>, expr_b: &Expr<'_>| {
let mut local_map: HirIdMap<HirId> = HirIdMap::default();
let eq_fallback = |a: &Expr<'_>, b: &Expr<'_>| {
if let Some(a_id) = path_to_local(a)
&& let Some(b_id) = path_to_local(b)
if let Some(a_id) = a.res_local_id()
&& let Some(b_id) = b.res_local_id()
&& let entry = match local_map.entry(a_id) {
HirIdMapEntry::Vacant(entry) => entry,
// check if using the same bindings as before

View file

@ -1,9 +1,10 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::macros::matching_root_macro_call;
use clippy_utils::msrvs::Msrv;
use clippy_utils::res::MaybeResPath;
use clippy_utils::source::snippet;
use clippy_utils::visitors::{for_each_expr_without_closures, is_local_used};
use clippy_utils::{is_in_const_context, path_to_local, sym};
use clippy_utils::{is_in_const_context, sym};
use rustc_ast::{BorrowKind, LitKind};
use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
@ -164,7 +165,7 @@ fn get_pat_binding<'tcx>(
guard_expr: &Expr<'_>,
outer_arm: &Arm<'tcx>,
) -> Option<PatBindingInfo> {
if let Some(local) = path_to_local(guard_expr)
if let Some(local) = guard_expr.res_local_id()
&& !is_local_used(cx, outer_arm.body, local)
{
let mut span = None;

View file

@ -1,7 +1,8 @@
use clippy_utils::consts::ConstEvalCtxt;
use clippy_utils::diagnostics::span_lint;
use clippy_utils::macros::{is_assert_macro, root_macro_call};
use clippy_utils::{find_binding_init, get_parent_expr, is_inside_always_const_context, path_to_local};
use clippy_utils::res::MaybeResPath;
use clippy_utils::{find_binding_init, get_parent_expr, is_inside_always_const_context};
use rustc_hir::{Expr, HirId};
use rustc_lint::{LateContext, LintContext};
use rustc_span::sym;
@ -45,7 +46,8 @@ fn is_under_cfg(cx: &LateContext<'_>, id: HirId) -> bool {
/// Similar to [`clippy_utils::expr_or_init`], but does not go up the chain if the initialization
/// value depends on a `#[cfg(…)]` directive.
fn expr_or_init<'a, 'b, 'tcx: 'b>(cx: &LateContext<'tcx>, mut expr: &'a Expr<'b>) -> &'a Expr<'b> {
while let Some(init) = path_to_local(expr)
while let Some(init) = expr
.res_local_id()
.and_then(|id| find_binding_init(cx, id))
.filter(|init| cx.typeck_results().expr_adjustments(init).is_empty())
.filter(|init| !is_under_cfg(cx, init.hir_id))

View file

@ -1,6 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::is_trait_method;
use clippy_utils::res::MaybeResPath;
use clippy_utils::source::snippet;
use clippy_utils::{is_trait_method, path_to_local};
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::{BindingMode, Node, PatKind};
@ -19,7 +20,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
expr.span.trim_start(recv.span).unwrap(),
"called `skip(..).next()` on an iterator",
|diag| {
if let Some(id) = path_to_local(recv)
if let Some(id) = recv.res_local_id()
&& let Node::Pat(pat) = cx.tcx.hir_node(id)
&& let PatKind::Binding(ann, _, _, _) = pat.kind
&& ann != BindingMode::MUT

View file

@ -2,13 +2,13 @@ use std::ops::ControlFlow;
use super::NEEDLESS_COLLECT;
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
use clippy_utils::res::MaybeDef;
use clippy_utils::res::{MaybeDef, MaybeResPath};
use clippy_utils::source::{snippet, snippet_with_applicability};
use clippy_utils::sugg::Sugg;
use clippy_utils::ty::{has_non_owning_mutable_access, make_normalized_projection, make_projection};
use clippy_utils::{
CaptureKind, can_move_expr_to_closure, fn_def_id, get_enclosing_block, higher, is_trait_method, path_to_local,
path_to_local_id, sym,
CaptureKind, can_move_expr_to_closure, fn_def_id, get_enclosing_block, higher, is_trait_method, path_to_local_id,
sym,
};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{Applicability, MultiSpan};
@ -383,7 +383,7 @@ impl<'tcx> Visitor<'tcx> for IterFunctionVisitor<'_, 'tcx> {
return;
}
if let Some(hir_id) = path_to_local(recv)
if let Some(hir_id) = recv.res_local_id()
&& let Some(index) = self.hir_id_uses_map.remove(&hir_id)
{
if self
@ -554,7 +554,7 @@ impl<'tcx> Visitor<'tcx> for IteratorMethodCheckVisitor<'_, 'tcx> {
return ControlFlow::Break(());
} else if let ExprKind::Assign(place, value, _span) = &expr.kind
&& value.hir_id == self.hir_id_of_expr
&& let Some(id) = path_to_local(place)
&& let Some(id) = place.res_local_id()
{
// our iterator was directly assigned to a variable
self.hir_id_of_let_binding = Some(id);

View file

@ -1,7 +1,8 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::res::MaybeResPath;
use clippy_utils::source::SpanRangeExt;
use clippy_utils::{is_from_proc_macro, is_trait_method, path_to_local};
use clippy_utils::{is_from_proc_macro, is_trait_method};
use itertools::Itertools;
use rustc_ast::LitKind;
use rustc_errors::Applicability;
@ -25,8 +26,8 @@ pub(super) fn check<'tcx>(
&& let LitKind::Str(val, _) = lit_kind.node
&& let ExprKind::Binary(kind, lhs, rhs) = body.kind
&& let BinOpKind::Eq = kind.node
&& let Some(lhs_path) = path_to_local(lhs)
&& let Some(rhs_path) = path_to_local(rhs)
&& let Some(lhs_path) = lhs.res_local_id()
&& let Some(rhs_path) = rhs.res_local_id()
&& let scrutinee = match (lhs_path == arg, rhs_path == arg) {
(true, false) => rhs,
(false, true) => lhs,

View file

@ -1,10 +1,11 @@
use super::utils::clone_or_copy_needed;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::higher::ForLoop;
use clippy_utils::res::MaybeResPath;
use clippy_utils::source::SpanRangeExt;
use clippy_utils::ty::{get_iterator_item_ty, implements_trait};
use clippy_utils::visitors::for_each_expr_without_closures;
use clippy_utils::{can_mut_borrow_both, fn_def_id, get_parent_expr, path_to_local};
use clippy_utils::{can_mut_borrow_both, fn_def_id, get_parent_expr};
use core::ops::ControlFlow;
use itertools::Itertools;
use rustc_errors::Applicability;
@ -50,7 +51,7 @@ pub fn check_for_loop_iter(
// check whether `expr` is mutable
fn is_mutable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
if let Some(hir_id) = path_to_local(expr)
if let Some(hir_id) = expr.res_local_id()
&& let Node::Pat(pat) = cx.tcx.hir_node(hir_id)
{
matches!(pat.kind, PatKind::Binding(BindingMode::MUT, ..))

View file

@ -1,6 +1,7 @@
use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
use clippy_utils::macros::root_macro_call_first_node;
use clippy_utils::{get_parent_expr, path_to_local, path_to_local_id, sym};
use clippy_utils::res::MaybeResPath;
use clippy_utils::{get_parent_expr, path_to_local_id, sym};
use rustc_hir::intravisit::{Visitor, walk_expr};
use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, LetStmt, Node, Stmt, StmtKind};
use rustc_lint::{LateContext, LateLintPass};
@ -84,7 +85,7 @@ impl<'tcx> LateLintPass<'tcx> for EvalOrderDependence {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
// Find a write to a local variable.
let var = if let ExprKind::Assign(lhs, ..) | ExprKind::AssignOp(_, lhs, _) = expr.kind
&& let Some(var) = path_to_local(lhs)
&& let Some(var) = lhs.res_local_id()
&& expr.span.desugaring_kind().is_none()
{
var

View file

@ -1,5 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::path_to_local;
use clippy_utils::res::MaybeResPath;
use clippy_utils::source::{SourceText, SpanRangeExt, snippet};
use clippy_utils::ty::needs_ordered_drop;
use clippy_utils::visitors::{for_each_expr, for_each_expr_without_closures, is_local_used};
@ -116,7 +116,7 @@ impl LocalAssign {
}
Some(Self {
lhs_id: path_to_local(lhs)?,
lhs_id: lhs.res_local_id()?,
rhs_span: rhs.span.source_callsite(),
span,
})

View file

@ -1,9 +1,8 @@
use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
use clippy_utils::res::MaybeResPath;
use clippy_utils::source::SpanRangeExt;
use clippy_utils::ty::{expr_type_is_certain, has_drop};
use clippy_utils::{
in_automatically_derived, is_inside_always_const_context, is_lint_allowed, path_to_local, peel_blocks,
};
use clippy_utils::{in_automatically_derived, is_inside_always_const_context, is_lint_allowed, peel_blocks};
use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::{
@ -109,7 +108,7 @@ impl<'tcx> LateLintPass<'tcx> for NoEffect {
}
fn check_expr(&mut self, _: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
if let Some(def_id) = path_to_local(expr) {
if let Some(def_id) = expr.res_local_id() {
self.underscore_bindings.swap_remove(&def_id);
}
}

View file

@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::res::MaybeQPath;
use clippy_utils::{get_expr_use_or_unification_node, path_to_local, path_to_local_id};
use clippy_utils::res::{MaybeQPath, MaybeResPath};
use clippy_utils::{get_expr_use_or_unification_node, path_to_local_id};
use core::cell::Cell;
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::Applicability;
@ -359,7 +359,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
}
fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) {
if let Some(id) = path_to_local(e)
if let Some(id) = e.res_local_id()
&& let Some(param) = self.params.get_by_id_mut(id)
{
let typeck = cx.typeck_results();

View file

@ -3,7 +3,7 @@ use clippy_utils::res::{MaybeDef, MaybeResPath};
use clippy_utils::source::SpanRangeExt;
use clippy_utils::sugg::Sugg;
use clippy_utils::visitors::contains_unsafe_block;
use clippy_utils::{get_expr_use_or_unification_node, is_lint_allowed, path_to_local, std_or_core, sym};
use clippy_utils::{get_expr_use_or_unification_node, is_lint_allowed, std_or_core, sym};
use hir::LifetimeKind;
use rustc_abi::ExternAbi;
use rustc_errors::{Applicability, MultiSpan};
@ -562,7 +562,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &Body<'tcx>, args: &[
}
// Check if this is local we care about
let Some(&args_idx) = path_to_local(e).and_then(|id| self.bindings.get(&id)) else {
let Some(&args_idx) = e.res_local_id().and_then(|id| self.bindings.get(&id)) else {
return walk_expr(self, e);
};
let args = &self.args[args_idx];

View file

@ -4,15 +4,15 @@ use clippy_config::Conf;
use clippy_config::types::MatchLintBehaviour;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::res::{MaybeDef, MaybeQPath};
use clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath};
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::sugg::Sugg;
use clippy_utils::ty::{implements_trait, is_copy};
use clippy_utils::usage::local_used_after_expr;
use clippy_utils::{
eq_expr_value, fn_def_id_with_node_args, higher, is_else_clause, is_in_const_context, is_lint_allowed,
pat_and_expr_can_be_question_mark, path_to_local, path_to_local_id, peel_blocks, peel_blocks_with_stmt,
span_contains_cfg, span_contains_comment, sym,
pat_and_expr_can_be_question_mark, path_to_local_id, peel_blocks, peel_blocks_with_stmt, span_contains_cfg,
span_contains_comment, sym,
};
use rustc_errors::Applicability;
use rustc_hir::LangItem::{self, OptionNone, OptionSome, ResultErr, ResultOk};
@ -252,7 +252,7 @@ fn expr_return_none_or_err(
.qpath_res(qpath, expr.hir_id)
.ctor_parent(cx)
.is_lang_item(cx, OptionNone),
sym::Result => path_to_local(expr).is_some() && path_to_local(expr) == path_to_local(cond_expr),
sym::Result => expr.res_local_id().is_some() && expr.res_local_id() == cond_expr.res_local_id(),
_ => false,
},
ExprKind::Call(call_expr, [arg]) => {
@ -492,7 +492,7 @@ fn check_if_let_some_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr:
.is_none()
{
if !is_copy(cx, caller_ty)
&& let Some(hir_id) = path_to_local(let_expr)
&& let Some(hir_id) = let_expr.res_local_id()
&& local_used_after_expr(cx, hir_id, expr)
{
return;

View file

@ -2,13 +2,11 @@ use clippy_config::Conf;
use clippy_utils::consts::{ConstEvalCtxt, Constant};
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::res::MaybeQPath;
use clippy_utils::res::{MaybeQPath, MaybeResPath};
use clippy_utils::source::{SpanRangeExt, snippet, snippet_with_applicability};
use clippy_utils::sugg::Sugg;
use clippy_utils::ty::implements_trait;
use clippy_utils::{
expr_use_ctxt, fn_def_id, get_parent_expr, higher, is_in_const_context, is_integer_const, path_to_local,
};
use clippy_utils::{expr_use_ctxt, fn_def_id, get_parent_expr, higher, is_in_const_context, is_integer_const};
use rustc_ast::Mutability;
use rustc_ast::ast::RangeLimits;
use rustc_errors::Applicability;
@ -321,7 +319,7 @@ fn check_range_bounds<'a>(cx: &'a LateContext<'_>, ex: &'a Expr<'_>) -> Option<R
BinOpKind::Le => (true, Ordering::Less),
_ => return None,
};
if let Some(id) = path_to_local(l) {
if let Some(id) = l.res_local_id() {
if let Some(c) = ConstEvalCtxt::new(cx).eval(r) {
return Some(RangeBounds {
val: c,
@ -333,7 +331,7 @@ fn check_range_bounds<'a>(cx: &'a LateContext<'_>, ex: &'a Expr<'_>) -> Option<R
inc: inclusive,
});
}
} else if let Some(id) = path_to_local(r)
} else if let Some(id) = r.res_local_id()
&& let Some(c) = ConstEvalCtxt::new(cx).eval(l)
{
return Some(RangeBounds {

View file

@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::res::{MaybeDef, MaybeResPath};
use clippy_utils::sugg::Sugg;
use clippy_utils::ty::implements_trait;
use clippy_utils::{is_default_equivalent_call, local_is_initialized, path_to_local};
use clippy_utils::{is_default_equivalent_call, local_is_initialized};
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, LangItem, QPath};
use rustc_lint::{LateContext, LateLintPass};
@ -42,7 +42,7 @@ impl LateLintPass<'_> for ReplaceBox {
&& !rhs.span.from_expansion()
&& let lhs_ty = cx.typeck_results().expr_ty(lhs)
// No diagnostic for late-initialized locals
&& path_to_local(lhs).is_none_or(|local| local_is_initialized(cx, local))
&& lhs.res_local_id().is_none_or(|local| local_is_initialized(cx, local))
&& let Some(inner_ty) = lhs_ty.boxed_ty()
{
if let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default)

View file

@ -1,6 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::res::MaybeResPath;
use clippy_utils::source::{indent_of, snippet};
use clippy_utils::{expr_or_init, get_attr, path_to_local, peel_hir_expr_unary, sym};
use clippy_utils::{expr_or_init, get_attr, peel_hir_expr_unary, sym};
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
@ -276,7 +277,7 @@ impl<'tcx> Visitor<'tcx> for StmtsChecker<'_, '_, '_, '_, 'tcx> {
&& let hir::PatKind::Binding(_, hir_id, ident, _) = local.pat.kind
&& !self.ap.apas.contains_key(&hir_id)
&& {
if let Some(local_hir_id) = path_to_local(expr) {
if let Some(local_hir_id) = expr.res_local_id() {
local_hir_id == hir_id
} else {
true
@ -301,7 +302,7 @@ impl<'tcx> Visitor<'tcx> for StmtsChecker<'_, '_, '_, '_, 'tcx> {
modify_apa_params(&mut apa);
let _ = self.ap.apas.insert(hir_id, apa);
} else {
let Some(hir_id) = path_to_local(expr) else {
let Some(hir_id) = expr.res_local_id() else {
return;
};
let Some(apa) = self.ap.apas.get_mut(&hir_id) else {

View file

@ -2,9 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::macros::matching_root_macro_call;
use clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath};
use clippy_utils::sugg::Sugg;
use clippy_utils::{
SpanlessEq, get_enclosing_block, is_integer_literal, path_to_local, path_to_local_id, span_contains_comment, sym,
};
use clippy_utils::{SpanlessEq, get_enclosing_block, is_integer_literal, path_to_local_id, span_contains_comment, sym};
use rustc_errors::Applicability;
use rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_stmt};
use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, PatKind, Stmt, StmtKind};
@ -102,7 +100,7 @@ impl<'tcx> LateLintPass<'tcx> for SlowVectorInit {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
// Matches initialization on reassignments. For example: `vec = Vec::with_capacity(100)`
if let ExprKind::Assign(left, right, _) = expr.kind
&& let Some(local_id) = path_to_local(left)
&& let Some(local_id) = left.res_local_id()
&& let Some(size_expr) = Self::as_vec_initializer(cx, right)
{
let vi = VecAllocation {

View file

@ -1,9 +1,9 @@
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::res::MaybeDef;
use clippy_utils::res::{MaybeDef, MaybeResPath};
use clippy_utils::source::{snippet_indent, snippet_with_context};
use clippy_utils::sugg::Sugg;
use clippy_utils::{can_mut_borrow_both, eq_expr_value, is_in_const_context, path_to_local, std_or_core};
use clippy_utils::{can_mut_borrow_both, eq_expr_value, is_in_const_context, std_or_core};
use itertools::Itertools;
use rustc_data_structures::fx::FxIndexSet;
@ -361,7 +361,8 @@ impl<'tcx> IndexBinding<'_, 'tcx> {
// - Variable declaration is outside the suggestion span
// - Variable is not used as an index or elsewhere later
if !self.suggest_span.contains(init.span)
|| path_to_local(expr)
|| expr
.res_local_id()
.is_some_and(|hir_id| !self.suggest_span.contains(self.cx.tcx.hir_span(hir_id)))
|| !self.is_used_other_than_swapping(first_segment.ident)
{

View file

@ -1,8 +1,9 @@
use clippy_config::Conf;
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::is_from_proc_macro;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::res::MaybeResPath;
use clippy_utils::visitors::for_each_local_use_after_expr;
use clippy_utils::{is_from_proc_macro, path_to_local};
use itertools::Itertools;
use rustc_ast::LitKind;
use rustc_hir::{Expr, ExprKind, Node, PatKind};
@ -152,7 +153,7 @@ fn all_bindings_are_for_conv<'tcx>(
locals: &[&Expr<'_>],
kind: ToType,
) -> bool {
let Some(locals) = locals.iter().map(|e| path_to_local(e)).collect::<Option<Vec<_>>>() else {
let Some(locals) = locals.iter().map(|e| e.res_local_id()).collect::<Option<Vec<_>>>() else {
return false;
};
let local_parents = locals.iter().map(|l| cx.tcx.parent_hir_node(*l)).collect::<Vec<_>>();

View file

@ -1,7 +1,8 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::res::MaybeResPath;
use clippy_utils::source::snippet;
use clippy_utils::ty::is_copy;
use clippy_utils::{get_parent_expr, is_mutable, path_to_local};
use clippy_utils::{get_parent_expr, is_mutable};
use rustc_hir::{Expr, ExprField, ExprKind, Path, QPath, StructTailExpr, UnOp};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass;
@ -162,7 +163,7 @@ fn check_references(cx: &LateContext<'_>, expr_a: &Expr<'_>, expr_b: &Expr<'_>)
&& let parent_ty = cx.typeck_results().expr_ty_adjusted(parent)
&& parent_ty.is_any_ptr()
{
if is_copy(cx, cx.typeck_results().expr_ty(expr_a)) && path_to_local(expr_b).is_some() {
if is_copy(cx, cx.typeck_results().expr_ty(expr_a)) && expr_b.res_local_id().is_some() {
// When the type implements `Copy`, a reference to the new struct works on the
// copy. Using the original would borrow it.
return false;

View file

@ -1,9 +1,9 @@
use clippy_config::Conf;
use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::msrvs::Msrv;
use clippy_utils::res::MaybeDef;
use clippy_utils::res::{MaybeDef, MaybeResPath};
use clippy_utils::usage::is_potentially_local_place;
use clippy_utils::{can_use_if_let_chains, higher, path_to_local, sym};
use clippy_utils::{can_use_if_let_chains, higher, sym};
use rustc_errors::Applicability;
use rustc_hir::intravisit::{FnKind, Visitor, walk_expr, walk_fn};
use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, HirId, Node, UnOp};
@ -169,7 +169,7 @@ fn collect_unwrap_info<'tcx>(
},
ExprKind::Unary(UnOp::Not, expr) => collect_unwrap_info(cx, if_expr, expr, branch, !invert, false),
ExprKind::MethodCall(method_name, receiver, [], _)
if let Some(local_id) = path_to_local(receiver)
if let Some(local_id) = receiver.res_local_id()
&& let ty = cx.typeck_results().expr_ty(receiver)
&& let name = method_name.ident.name
&& let Some((kind, unwrappable)) = option_or_result_call(cx, ty, name) =>
@ -318,7 +318,7 @@ impl<'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'_, 'tcx> {
// find `unwrap[_err]()` or `expect("...")` calls:
if let ExprKind::MethodCall(method_name, self_arg, ..) = expr.kind
&& let (self_arg, as_ref_kind) = consume_option_as_ref(self_arg)
&& let Some(id) = path_to_local(self_arg)
&& let Some(id) = self_arg.res_local_id()
&& matches!(method_name.ident.name, sym::unwrap | sym::expect | sym::unwrap_err)
&& let call_to_unwrap = matches!(method_name.ident.name, sym::unwrap | sym::expect)
&& let Some(unwrappable) = self.unwrappables.iter()

View file

@ -1,11 +1,9 @@
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lint_and_then};
use clippy_utils::res::MaybeDef;
use clippy_utils::res::{MaybeDef, MaybeResPath};
use clippy_utils::source::{snippet, snippet_with_context};
use clippy_utils::sugg::{DiagExt as _, Sugg};
use clippy_utils::ty::{is_copy, same_type_modulo_regions};
use clippy_utils::{
get_parent_expr, is_inherent_method_call, is_trait_item, is_trait_method, is_ty_alias, path_to_local, sym,
};
use clippy_utils::{get_parent_expr, is_inherent_method_call, is_trait_item, is_trait_method, is_ty_alias, sym};
use rustc_errors::Applicability;
use rustc_hir::def_id::DefId;
use rustc_hir::{BindingMode, Expr, ExprKind, HirId, MatchSource, Mutability, Node, PatKind};
@ -309,7 +307,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
}
}
if let Some(id) = path_to_local(recv)
if let Some(id) = recv.res_local_id()
&& let Node::Pat(pat) = cx.tcx.hir_node(id)
&& let PatKind::Binding(ann, ..) = pat.kind
&& ann != BindingMode::MUT

View file

@ -174,7 +174,8 @@ macro_rules! extract_msrv_attr {
/// // ^^^ input
/// ```
pub fn expr_or_init<'a, 'b, 'tcx: 'b>(cx: &LateContext<'tcx>, mut expr: &'a Expr<'b>) -> &'a Expr<'b> {
while let Some(init) = path_to_local(expr)
while let Some(init) = expr
.res_local_id()
.and_then(|id| find_binding_init(cx, id))
.filter(|init| cx.typeck_results().expr_adjustments(init).is_empty())
{
@ -429,20 +430,10 @@ pub fn qpath_generic_tys<'tcx>(qpath: &QPath<'tcx>) -> impl Iterator<Item = &'tc
})
}
/// If the expression is a path to a local, returns the canonical `HirId` of the local.
pub fn path_to_local(expr: &Expr<'_>) -> Option<HirId> {
if let ExprKind::Path(QPath::Resolved(None, path)) = expr.kind
&& let Res::Local(id) = path.res
{
return Some(id);
}
None
}
/// Returns true if the expression is a path to a local with the specified `HirId`.
/// Use this function to see if an expression matches a function argument or a match binding.
pub fn path_to_local_id(expr: &Expr<'_>, id: HirId) -> bool {
path_to_local(expr) == Some(id)
expr.res_local_id() == Some(id)
}
/// If the expression is a path to a local (with optional projections),
@ -3438,7 +3429,7 @@ pub fn expr_requires_coercion<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -
/// Returns `true` if `expr` designates a mutable static, a mutable local binding, or an expression
/// that can be owned.
pub fn is_mutable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
if let Some(hir_id) = path_to_local(expr)
if let Some(hir_id) = expr.res_local_id()
&& let Node::Pat(pat) = cx.tcx.hir_node(hir_id)
{
matches!(pat.kind, PatKind::Binding(BindingMode::MUT, ..))