@@ -56,14 +56,30 @@ impl<'tcx> LateLintPass<'tcx> for MutMut {
5656 }
5757 self . seen_tys . insert ( mty. ty . hir_id ) ;
5858
59+ // if there is an even longer chain, like `&mut &mut &mut x`, suggest peeling off
60+ // all extra ones at once
61+ let ( mut t, mut t2) = ( mty. ty , mty2. ty ) ;
62+ let mut many_muts = false ;
63+ loop {
64+ if let TyKind :: Ref ( _, next) = t2. kind
65+ && next. mutbl == Mutability :: Mut
66+ {
67+ ( t, t2) = ( t2, next. ty ) ;
68+ many_muts = true ;
69+ } else {
70+ break ;
71+ }
72+ }
73+
5974 let mut applicability = Applicability :: MaybeIncorrect ;
60- let sugg = snippet_with_applicability ( cx. sess ( ) , mty. ty . span , ".." , & mut applicability) ;
75+ let sugg = snippet_with_applicability ( cx. sess ( ) , t. span , ".." , & mut applicability) ;
76+ let suffix = if many_muts { "s" } else { "" } ;
6177 span_lint_and_sugg (
6278 cx,
6379 MUT_MUT ,
6480 ty. span ,
6581 "a type of form `&mut &mut _`" ,
66- "remove the extra `&mut`" ,
82+ format ! ( "remove the extra `&mut`{suffix}" ) ,
6783 sugg. to_string ( ) ,
6884 applicability,
6985 ) ;
@@ -91,20 +107,43 @@ impl<'tcx> intravisit::Visitor<'tcx> for MutVisitor<'_, 'tcx> {
91107 intravisit:: walk_expr ( self , arg) ;
92108 intravisit:: walk_expr ( self , body) ;
93109 } else if let ExprKind :: AddrOf ( BorrowKind :: Ref , Mutability :: Mut , e) = expr. kind {
94- if let ExprKind :: AddrOf ( BorrowKind :: Ref , Mutability :: Mut , _ ) = e. kind {
110+ if let ExprKind :: AddrOf ( BorrowKind :: Ref , Mutability :: Mut , e2 ) = e. kind {
95111 if !expr. span . eq_ctxt ( e. span ) {
96112 return ;
97113 }
114+
115+ // if there is an even longer chain, like `&mut &mut &mut x`, suggest peeling off
116+ // all extra ones at once
117+ let ( mut e, mut e2) = ( e, e2) ;
118+ let mut many_muts = false ;
119+ loop {
120+ if !e. span . eq_ctxt ( e2. span ) {
121+ return ;
122+ }
123+ if let ExprKind :: AddrOf ( BorrowKind :: Ref , Mutability :: Mut , next) = e2. kind {
124+ ( e, e2) = ( e2, next) ;
125+ many_muts = true ;
126+ } else {
127+ break ;
128+ }
129+ }
130+
98131 let mut applicability = Applicability :: MaybeIncorrect ;
99132 let sugg = Sugg :: hir_with_applicability ( self . cx , e, ".." , & mut applicability) ;
133+ let suffix = if many_muts { "s" } else { "" } ;
100134 span_lint_hir_and_then (
101135 self . cx ,
102136 MUT_MUT ,
103137 expr. hir_id ,
104138 expr. span ,
105139 "an expression of form `&mut &mut _`" ,
106140 |diag| {
107- diag. span_suggestion ( expr. span , "remove the extra `&mut`" , sugg, applicability) ;
141+ diag. span_suggestion (
142+ expr. span ,
143+ format ! ( "remove the extra `&mut`{suffix}" ) ,
144+ sugg,
145+ applicability,
146+ ) ;
108147 } ,
109148 ) ;
110149 } else if let ty:: Ref ( _, ty, Mutability :: Mut ) = self . cx . typeck_results ( ) . expr_ty ( e) . kind ( )
0 commit comments