@@ -56,14 +56,30 @@ impl<'tcx> LateLintPass<'tcx> for MutMut {
56
56
}
57
57
self . seen_tys . insert ( mty. ty . hir_id ) ;
58
58
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
+
59
74
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 { "" } ;
61
77
span_lint_and_sugg (
62
78
cx,
63
79
MUT_MUT ,
64
80
ty. span ,
65
81
"a type of form `&mut &mut _`" ,
66
- "remove the extra `&mut`" ,
82
+ format ! ( "remove the extra `&mut`{suffix}" ) ,
67
83
sugg. to_string ( ) ,
68
84
applicability,
69
85
) ;
@@ -91,20 +107,43 @@ impl<'tcx> intravisit::Visitor<'tcx> for MutVisitor<'_, 'tcx> {
91
107
intravisit:: walk_expr ( self , arg) ;
92
108
intravisit:: walk_expr ( self , body) ;
93
109
} 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 {
95
111
if !expr. span . eq_ctxt ( e. span ) {
96
112
return ;
97
113
}
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
+
98
131
let mut applicability = Applicability :: MaybeIncorrect ;
99
132
let sugg = Sugg :: hir_with_applicability ( self . cx , e, ".." , & mut applicability) ;
133
+ let suffix = if many_muts { "s" } else { "" } ;
100
134
span_lint_hir_and_then (
101
135
self . cx ,
102
136
MUT_MUT ,
103
137
expr. hir_id ,
104
138
expr. span ,
105
139
"an expression of form `&mut &mut _`" ,
106
140
|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
+ ) ;
108
147
} ,
109
148
) ;
110
149
} else if let ty:: Ref ( _, ty, Mutability :: Mut ) = self . cx . typeck_results ( ) . expr_ty ( e) . kind ( )
0 commit comments