@@ -159,8 +159,16 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
159
159
}
160
160
}
161
161
162
- fn suggest ( cx : & LateContext , suggestion : & Bool , terminals : & [ & Expr ] ) -> String {
163
- fn recurse ( brackets : bool , cx : & LateContext , suggestion : & Bool , terminals : & [ & Expr ] , mut s : String ) -> String {
162
+ // The boolean part of the return indicates whether some simplifications have been applied.
163
+ fn suggest ( cx : & LateContext , suggestion : & Bool , terminals : & [ & Expr ] ) -> ( String , bool ) {
164
+ fn recurse (
165
+ brackets : bool ,
166
+ cx : & LateContext ,
167
+ suggestion : & Bool ,
168
+ terminals : & [ & Expr ] ,
169
+ mut s : String ,
170
+ simplified : & mut bool ,
171
+ ) -> String {
164
172
use quine_mc_cluskey:: Bool :: * ;
165
173
let snip = |e : & Expr | snippet_opt ( cx, e. span ) . expect ( "don't try to improve booleans created by macros" ) ;
166
174
match * suggestion {
@@ -175,7 +183,7 @@ fn suggest(cx: &LateContext, suggestion: &Bool, terminals: &[&Expr]) -> String {
175
183
Not ( ref inner) => match * * inner {
176
184
And ( _) | Or ( _) => {
177
185
s. push ( '!' ) ;
178
- recurse ( true , cx, inner, terminals, s)
186
+ recurse ( true , cx, inner, terminals, s, simplified )
179
187
} ,
180
188
Term ( n) => match terminals[ n as usize ] . node {
181
189
ExprBinary ( binop, ref lhs, ref rhs) => {
@@ -188,9 +196,10 @@ fn suggest(cx: &LateContext, suggestion: &Bool, terminals: &[&Expr]) -> String {
188
196
BiGe => " < " ,
189
197
_ => {
190
198
s. push ( '!' ) ;
191
- return recurse ( true , cx, inner, terminals, s) ;
199
+ return recurse ( true , cx, inner, terminals, s, simplified ) ;
192
200
} ,
193
201
} ;
202
+ * simplified = true ;
194
203
s. push_str ( & snip ( lhs) ) ;
195
204
s. push_str ( op) ;
196
205
s. push_str ( & snip ( rhs) ) ;
@@ -202,41 +211,42 @@ fn suggest(cx: &LateContext, suggestion: &Bool, terminals: &[&Expr]) -> String {
202
211
. flat_map ( |( a, b) | vec ! [ ( a, b) , ( b, a) ] )
203
212
. find ( |& ( a, _) | a == path. name . as_str ( ) ) ;
204
213
if let Some ( ( _, negation_method) ) = negation {
214
+ * simplified = true ;
205
215
s. push_str ( & snip ( & args[ 0 ] ) ) ;
206
216
s. push ( '.' ) ;
207
217
s. push_str ( negation_method) ;
208
218
s. push_str ( "()" ) ;
209
219
s
210
220
} else {
211
221
s. push ( '!' ) ;
212
- recurse ( false , cx, inner, terminals, s)
222
+ recurse ( false , cx, inner, terminals, s, simplified )
213
223
}
214
224
} ,
215
225
_ => {
216
226
s. push ( '!' ) ;
217
- recurse ( false , cx, inner, terminals, s)
227
+ recurse ( false , cx, inner, terminals, s, simplified )
218
228
} ,
219
229
} ,
220
230
_ => {
221
231
s. push ( '!' ) ;
222
- recurse ( false , cx, inner, terminals, s)
232
+ recurse ( false , cx, inner, terminals, s, simplified )
223
233
} ,
224
234
} ,
225
235
And ( ref v) => {
226
236
if brackets {
227
237
s. push ( '(' ) ;
228
238
}
229
239
if let Or ( _) = v[ 0 ] {
230
- s = recurse ( true , cx, & v[ 0 ] , terminals, s) ;
240
+ s = recurse ( true , cx, & v[ 0 ] , terminals, s, simplified ) ;
231
241
} else {
232
- s = recurse ( false , cx, & v[ 0 ] , terminals, s) ;
242
+ s = recurse ( false , cx, & v[ 0 ] , terminals, s, simplified ) ;
233
243
}
234
244
for inner in & v[ 1 ..] {
235
245
s. push_str ( " && " ) ;
236
246
if let Or ( _) = * inner {
237
- s = recurse ( true , cx, inner, terminals, s) ;
247
+ s = recurse ( true , cx, inner, terminals, s, simplified ) ;
238
248
} else {
239
- s = recurse ( false , cx, inner, terminals, s) ;
249
+ s = recurse ( false , cx, inner, terminals, s, simplified ) ;
240
250
}
241
251
}
242
252
if brackets {
@@ -248,10 +258,10 @@ fn suggest(cx: &LateContext, suggestion: &Bool, terminals: &[&Expr]) -> String {
248
258
if brackets {
249
259
s. push ( '(' ) ;
250
260
}
251
- s = recurse ( false , cx, & v[ 0 ] , terminals, s) ;
261
+ s = recurse ( false , cx, & v[ 0 ] , terminals, s, simplified ) ;
252
262
for inner in & v[ 1 ..] {
253
263
s. push_str ( " || " ) ;
254
- s = recurse ( false , cx, inner, terminals, s) ;
264
+ s = recurse ( false , cx, inner, terminals, s, simplified ) ;
255
265
}
256
266
if brackets {
257
267
s. push ( ')' ) ;
@@ -274,7 +284,9 @@ fn suggest(cx: &LateContext, suggestion: &Bool, terminals: &[&Expr]) -> String {
274
284
} ,
275
285
}
276
286
}
277
- recurse ( false , cx, suggestion, terminals, String :: new ( ) )
287
+ let mut simplified = false ;
288
+ let s = recurse ( false , cx, suggestion, terminals, String :: new ( ) , & mut simplified) ;
289
+ ( s, simplified)
278
290
}
279
291
280
292
fn simple_negate ( b : Bool ) -> Bool {
@@ -384,7 +396,7 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
384
396
db. span_suggestion (
385
397
e. span ,
386
398
"it would look like the following" ,
387
- suggest ( self . cx , suggestion, & h2q. terminals ) ,
399
+ suggest ( self . cx , suggestion, & h2q. terminals ) . 0 ,
388
400
) ;
389
401
} ,
390
402
) ;
@@ -401,22 +413,26 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
401
413
improvements. push ( suggestion) ;
402
414
}
403
415
}
404
- if !improvements . is_empty ( ) {
416
+ let nonminimal_bool_lint = |suggestions| {
405
417
span_lint_and_then (
406
418
self . cx ,
407
419
NONMINIMAL_BOOL ,
408
420
e. span ,
409
421
"this boolean expression can be simplified" ,
410
- |db| {
411
- db. span_suggestions (
412
- e. span ,
413
- "try" ,
414
- improvements
415
- . into_iter ( )
416
- . map ( |suggestion| suggest ( self . cx , suggestion, & h2q. terminals ) )
417
- . collect ( ) ,
418
- ) ;
419
- } ,
422
+ |db| { db. span_suggestions ( e. span , "try" , suggestions) ; } ,
423
+ ) ;
424
+ } ;
425
+ if improvements. is_empty ( ) {
426
+ let suggest = suggest ( self . cx , & expr, & h2q. terminals ) ;
427
+ if suggest. 1 {
428
+ nonminimal_bool_lint ( vec ! [ suggest. 0 ] )
429
+ }
430
+ } else {
431
+ nonminimal_bool_lint (
432
+ improvements
433
+ . into_iter ( )
434
+ . map ( |suggestion| suggest ( self . cx , suggestion, & h2q. terminals ) . 0 )
435
+ . collect ( )
420
436
) ;
421
437
}
422
438
}
0 commit comments