@@ -34,6 +34,7 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name:
3434 {
3535 let mut requires_copy = false ;
3636 let mut requires_deref = false ;
37+ let mut has_mut_use = false ;
3738
3839 // The number of unprocessed return expressions.
3940 let mut ret_count = 0u32 ;
@@ -47,7 +48,8 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name:
4748 // Nested closures don't need to treat returns specially.
4849 let _: Option < !> = for_each_expr ( cx, cx. tcx . hir ( ) . body ( c. body ) . value , |e| {
4950 if path_to_local_id ( e, arg_id) {
50- let ( kind, same_ctxt) = check_use ( cx, e) ;
51+ let ( kind, mutbl, same_ctxt) = check_use ( cx, e) ;
52+ has_mut_use |= mutbl. is_mut ( ) ;
5153 match ( kind, same_ctxt && e. span . ctxt ( ) == ctxt) {
5254 ( _, false ) | ( UseKind :: Deref | UseKind :: Return ( ..) , true ) => {
5355 requires_copy = true ;
@@ -65,7 +67,8 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name:
6567 } else if matches ! ( e. kind, ExprKind :: Ret ( _) ) {
6668 ret_count += 1 ;
6769 } else if path_to_local_id ( e, arg_id) {
68- let ( kind, same_ctxt) = check_use ( cx, e) ;
70+ let ( kind, mutbl, same_ctxt) = check_use ( cx, e) ;
71+ has_mut_use |= mutbl. is_mut ( ) ;
6972 match ( kind, same_ctxt && e. span . ctxt ( ) == ctxt) {
7073 ( UseKind :: Return ( ..) , false ) => {
7174 return ControlFlow :: Break ( ( ) ) ;
@@ -161,6 +164,7 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name:
161164 && ( !requires_copy || cx. type_is_copy_modulo_regions ( arg_ty) )
162165 // This case could be handled, but a fair bit of care would need to be taken.
163166 && ( !requires_deref || arg_ty. is_freeze ( cx. tcx , cx. typing_env ( ) ) )
167+ && !has_mut_use
164168 {
165169 if requires_deref {
166170 edits. push ( ( param. span . shrink_to_lo ( ) , "&" . into ( ) ) ) ;
@@ -207,36 +211,37 @@ enum UseKind<'tcx> {
207211 FieldAccess ( Symbol , & ' tcx Expr < ' tcx > ) ,
208212}
209213
210- /// Checks how the value is used, and whether it was used in the same `SyntaxContext`.
211- fn check_use < ' tcx > ( cx : & LateContext < ' tcx > , e : & ' tcx Expr < ' _ > ) -> ( UseKind < ' tcx > , bool ) {
214+ /// Checks how the value is used, mutability, and whether it was used in the same `SyntaxContext`.
215+ fn check_use < ' tcx > ( cx : & LateContext < ' tcx > , e : & ' tcx Expr < ' _ > ) -> ( UseKind < ' tcx > , Mutability , bool ) {
212216 let use_cx = expr_use_ctxt ( cx, e) ;
217+ let mutbl = use_cx. use_mutability ( cx) ;
213218 if use_cx
214219 . adjustments
215220 . first ( )
216221 . is_some_and ( |a| matches ! ( a. kind, Adjust :: Deref ( _) ) )
217222 {
218- return ( UseKind :: AutoBorrowed , use_cx. same_ctxt ) ;
223+ return ( UseKind :: AutoBorrowed , mutbl , use_cx. same_ctxt ) ;
219224 }
220225 let res = match use_cx. use_node ( cx) {
221226 ExprUseNode :: Return ( _) => {
222227 if let ExprKind :: Ret ( Some ( e) ) = use_cx. node . expect_expr ( ) . kind {
223228 UseKind :: Return ( e. span )
224229 } else {
225- return ( UseKind :: Return ( DUMMY_SP ) , false ) ;
230+ return ( UseKind :: Return ( DUMMY_SP ) , mutbl , false ) ;
226231 }
227232 } ,
228- ExprUseNode :: FieldAccess ( name) => UseKind :: FieldAccess ( name. name , use_cx. node . expect_expr ( ) ) ,
233+ ExprUseNode :: FieldAccess ( _ , name) => UseKind :: FieldAccess ( name. name , use_cx. node . expect_expr ( ) ) ,
229234 ExprUseNode :: Callee | ExprUseNode :: MethodArg ( _, _, 0 )
230235 if use_cx
231236 . adjustments
232237 . first ( )
233- . is_some_and ( |a| matches ! ( a. kind, Adjust :: Borrow ( AutoBorrow :: Ref ( AutoBorrowMutability :: Not ) ) ) ) =>
238+ . is_some_and ( |a| matches ! ( a. kind, Adjust :: Borrow ( AutoBorrow :: Ref ( _ ) ) ) ) =>
234239 {
235240 UseKind :: AutoBorrowed
236241 } ,
237242 ExprUseNode :: Callee | ExprUseNode :: MethodArg ( _, _, 0 ) => UseKind :: WillAutoDeref ,
238243 ExprUseNode :: AddrOf ( BorrowKind :: Ref , _) => UseKind :: Borrowed ( use_cx. node . expect_expr ( ) . span ) ,
239244 _ => UseKind :: Deref ,
240245 } ;
241- ( res, use_cx. same_ctxt )
246+ ( res, mutbl , use_cx. same_ctxt )
242247}
0 commit comments