@@ -20,16 +20,15 @@ use rustc_hir::{
2020} ;
2121use rustc_index:: bit_set:: BitSet ;
2222use rustc_infer:: infer:: TyCtxtInferExt ;
23- use rustc_lint:: { LateContext , LateLintPass , LintArray , LintPass } ;
24- use rustc_lint_defs:: lint_array;
23+ use rustc_lint:: { LateContext , LateLintPass } ;
2524use rustc_middle:: mir:: { Rvalue , StatementKind } ;
2625use rustc_middle:: ty:: adjustment:: { Adjust , Adjustment , AutoBorrow , AutoBorrowMutability } ;
2726use rustc_middle:: ty:: {
2827 self , Binder , BoundVariableKind , EarlyBinder , FnSig , GenericArgKind , List , ParamTy , PredicateKind ,
2928 ProjectionPredicate , Ty , TyCtxt , TypeVisitable , TypeckResults ,
3029} ;
3130use rustc_semver:: RustcVersion ;
32- use rustc_session:: declare_tool_lint;
31+ use rustc_session:: { declare_tool_lint, impl_lint_pass } ;
3332use rustc_span:: { symbol:: sym, Span , Symbol , DUMMY_SP } ;
3433use rustc_trait_selection:: infer:: InferCtxtExt as _;
3534use rustc_trait_selection:: traits:: { query:: evaluate_obligation:: InferCtxtExt as _, Obligation , ObligationCause } ;
@@ -146,24 +145,12 @@ declare_clippy_lint! {
146145 "dereferencing when the compiler would automatically dereference"
147146}
148147
149- #[ expect( rustc:: internal) ]
150- impl < ' tcx > LintPass for Dereferencing < ' tcx > {
151- fn name ( & self ) -> & ' static str {
152- stringify ! ( $ty)
153- }
154- }
155-
156- impl < ' tcx > Dereferencing < ' tcx > {
157- #[ expect( dead_code) ]
158- pub fn get_lints ( ) -> LintArray {
159- lint_array ! (
160- EXPLICIT_DEREF_METHODS ,
161- NEEDLESS_BORROW ,
162- REF_BINDING_TO_REFERENCE ,
163- EXPLICIT_AUTO_DEREF ,
164- )
165- }
166- }
148+ impl_lint_pass ! ( Dereferencing <' _> => [
149+ EXPLICIT_DEREF_METHODS ,
150+ NEEDLESS_BORROW ,
151+ REF_BINDING_TO_REFERENCE ,
152+ EXPLICIT_AUTO_DEREF ,
153+ ] ) ;
167154
168155#[ derive( Default ) ]
169156pub struct Dereferencing < ' tcx > {
@@ -189,7 +176,7 @@ pub struct Dereferencing<'tcx> {
189176
190177 /// Map from body owners to `PossibleBorrowerMap`s. Used by `needless_borrow_impl_arg_position`
191178 /// to determine when a borrowed expression can instead be moved.
192- possible_borrowers : FxIndexMap < LocalDefId , PossibleBorrowerMap < ' tcx , ' tcx > > ,
179+ possible_borrowers : Vec < ( LocalDefId , PossibleBorrowerMap < ' tcx , ' tcx > ) > ,
193180
194181 // `IntoIterator` for arrays requires Rust 1.53.
195182 msrv : Option < RustcVersion > ,
@@ -571,6 +558,12 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
571558 }
572559
573560 fn check_body_post ( & mut self , cx : & LateContext < ' tcx > , body : & ' tcx Body < ' _ > ) {
561+ if self . possible_borrowers . last ( ) . map_or ( false , |& ( local_def_id, _) | {
562+ local_def_id == cx. tcx . hir ( ) . body_owner_def_id ( body. id ( ) )
563+ } ) {
564+ self . possible_borrowers . pop ( ) ;
565+ }
566+
574567 if Some ( body. id ( ) ) == self . current_body {
575568 for pat in self . ref_locals . drain ( ..) . filter_map ( |( _, x) | x) {
576569 let replacements = pat. replacements ;
@@ -703,7 +696,7 @@ impl Position {
703696#[ expect( clippy:: too_many_lines) ]
704697fn walk_parents < ' tcx > (
705698 cx : & LateContext < ' tcx > ,
706- possible_borrowers : & mut FxIndexMap < LocalDefId , PossibleBorrowerMap < ' tcx , ' tcx > > ,
699+ possible_borrowers : & mut Vec < ( LocalDefId , PossibleBorrowerMap < ' tcx , ' tcx > ) > ,
707700 e : & ' tcx Expr < ' _ > ,
708701 msrv : Option < RustcVersion > ,
709702) -> ( Position , & ' tcx [ Adjustment < ' tcx > ] ) {
@@ -1061,7 +1054,7 @@ fn ty_contains_infer(ty: &hir::Ty<'_>) -> bool {
10611054#[ expect( clippy:: too_many_arguments) ]
10621055fn needless_borrow_impl_arg_position < ' tcx > (
10631056 cx : & LateContext < ' tcx > ,
1064- possible_borrowers : & mut FxIndexMap < LocalDefId , PossibleBorrowerMap < ' tcx , ' tcx > > ,
1057+ possible_borrowers : & mut Vec < ( LocalDefId , PossibleBorrowerMap < ' tcx , ' tcx > ) > ,
10651058 parent : & Expr < ' tcx > ,
10661059 arg_index : usize ,
10671060 param_ty : ParamTy ,
@@ -1202,7 +1195,7 @@ fn has_ref_mut_self_method(cx: &LateContext<'_>, trait_def_id: DefId) -> bool {
12021195
12031196fn referent_used_exactly_once < ' a , ' tcx > (
12041197 cx : & ' a LateContext < ' tcx > ,
1205- possible_borrower : & mut FxIndexMap < LocalDefId , PossibleBorrowerMap < ' tcx , ' tcx > > ,
1198+ possible_borrowers : & mut Vec < ( LocalDefId , PossibleBorrowerMap < ' tcx , ' tcx > ) > ,
12061199 reference : & Expr < ' tcx > ,
12071200) -> bool {
12081201 let mir = enclosing_mir ( cx. tcx , reference. hir_id ) ;
@@ -1213,9 +1206,13 @@ fn referent_used_exactly_once<'a, 'tcx>(
12131206 && !place. has_deref ( )
12141207 {
12151208 let body_owner_local_def_id = cx. tcx . hir ( ) . enclosing_body_owner ( reference. hir_id ) ;
1216- let possible_borrower = possible_borrower
1217- . entry ( body_owner_local_def_id)
1218- . or_insert_with ( || PossibleBorrowerMap :: new ( cx, mir) ) ;
1209+ if possible_borrowers
1210+ . last ( )
1211+ . map_or ( true , |& ( local_def_id, _) | local_def_id != body_owner_local_def_id)
1212+ {
1213+ possible_borrowers. push ( ( body_owner_local_def_id, PossibleBorrowerMap :: new ( cx, mir) ) ) ;
1214+ }
1215+ let possible_borrower = & mut possible_borrowers. last_mut ( ) . unwrap ( ) . 1 ;
12191216 // If `only_borrowers` were used here, the `copyable_iterator::warn` test would fail. The reason is
12201217 // that `PossibleBorrowerVisitor::visit_terminator` considers `place.local` a possible borrower of
12211218 // itself. See the comment in that method for an explanation as to why.
0 commit comments