@@ -12,9 +12,9 @@ use rustc_errors::Applicability;
12
12
use rustc_lint:: { EarlyContext , EarlyLintPass } ;
13
13
use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
14
14
use rustc_span:: DUMMY_SP ;
15
-
16
15
use std:: cell:: Cell ;
17
16
use std:: mem;
17
+ use thin_vec:: { thin_vec, ThinVec } ;
18
18
19
19
declare_clippy_lint ! {
20
20
/// ### What it does
@@ -214,7 +214,7 @@ macro_rules! always_pat {
214
214
/// Focus on `focus_idx` in `alternatives`,
215
215
/// attempting to extend it with elements of the same constructor `C`
216
216
/// in `alternatives[focus_idx + 1..]`.
217
- fn transform_with_focus_on_idx ( alternatives : & mut Vec < P < Pat > > , focus_idx : usize ) -> bool {
217
+ fn transform_with_focus_on_idx ( alternatives : & mut ThinVec < P < Pat > > , focus_idx : usize ) -> bool {
218
218
// Extract the kind; we'll need to make some changes in it.
219
219
let mut focus_kind = mem:: replace ( & mut alternatives[ focus_idx] . kind , PatKind :: Wild ) ;
220
220
// We'll focus on `alternatives[focus_idx]`,
@@ -296,7 +296,7 @@ fn extend_with_struct_pat(
296
296
fps1 : & mut [ ast:: PatField ] ,
297
297
rest1 : bool ,
298
298
start : usize ,
299
- alternatives : & mut Vec < P < Pat > > ,
299
+ alternatives : & mut ThinVec < P < Pat > > ,
300
300
) -> bool {
301
301
( 0 ..fps1. len ( ) ) . any ( |idx| {
302
302
let pos_in_2 = Cell :: new ( None ) ; // The element `k`.
@@ -336,9 +336,9 @@ fn extend_with_struct_pat(
336
336
fn extend_with_matching_product (
337
337
targets : & mut [ P < Pat > ] ,
338
338
start : usize ,
339
- alternatives : & mut Vec < P < Pat > > ,
339
+ alternatives : & mut ThinVec < P < Pat > > ,
340
340
predicate : impl Fn ( & PatKind , & [ P < Pat > ] , usize ) -> bool ,
341
- extract : impl Fn ( PatKind ) -> Vec < P < Pat > > ,
341
+ extract : impl Fn ( PatKind ) -> ThinVec < P < Pat > > ,
342
342
) -> bool {
343
343
( 0 ..targets. len ( ) ) . any ( |idx| {
344
344
let tail_or = drain_matching (
@@ -365,14 +365,14 @@ fn take_pat(from: &mut Pat) -> Pat {
365
365
366
366
/// Extend `target` as an or-pattern with the alternatives
367
367
/// in `tail_or` if there are any and return if there were.
368
- fn extend_with_tail_or ( target : & mut Pat , tail_or : Vec < P < Pat > > ) -> bool {
369
- fn extend ( target : & mut Pat , mut tail_or : Vec < P < Pat > > ) {
368
+ fn extend_with_tail_or ( target : & mut Pat , tail_or : ThinVec < P < Pat > > ) -> bool {
369
+ fn extend ( target : & mut Pat , mut tail_or : ThinVec < P < Pat > > ) {
370
370
match target {
371
371
// On an existing or-pattern in the target, append to it.
372
372
Pat { kind : Or ( ps) , .. } => ps. append ( & mut tail_or) ,
373
373
// Otherwise convert the target to an or-pattern.
374
374
target => {
375
- let mut init_or = vec ! [ P ( take_pat( target) ) ] ;
375
+ let mut init_or = thin_vec ! [ P ( take_pat( target) ) ] ;
376
376
init_or. append ( & mut tail_or) ;
377
377
target. kind = Or ( init_or) ;
378
378
} ,
@@ -391,26 +391,42 @@ fn extend_with_tail_or(target: &mut Pat, tail_or: Vec<P<Pat>>) -> bool {
391
391
// Only elements beginning with `start` are considered for extraction.
392
392
fn drain_matching (
393
393
start : usize ,
394
- alternatives : & mut Vec < P < Pat > > ,
394
+ alternatives : & mut ThinVec < P < Pat > > ,
395
395
predicate : impl Fn ( & PatKind ) -> bool ,
396
396
extract : impl Fn ( PatKind ) -> P < Pat > ,
397
- ) -> Vec < P < Pat > > {
398
- let mut tail_or = vec ! [ ] ;
397
+ ) -> ThinVec < P < Pat > > {
398
+ let mut tail_or = ThinVec :: new ( ) ;
399
399
let mut idx = 0 ;
400
- for pat in alternatives. drain_filter ( |p| {
401
- // Check if we should extract, but only if `idx >= start`.
400
+
401
+ // If `ThinVec` had the `drain_filter` method, this loop could be rewritten
402
+ // like so:
403
+ //
404
+ // for pat in alternatives.drain_filter(|p| {
405
+ // // Check if we should extract, but only if `idx >= start`.
406
+ // idx += 1;
407
+ // idx > start && predicate(&p.kind)
408
+ // }) {
409
+ // tail_or.push(extract(pat.into_inner().kind));
410
+ // }
411
+ let mut i = 0 ;
412
+ while i < alternatives. len ( ) {
402
413
idx += 1 ;
403
- idx > start && predicate ( & p. kind )
404
- } ) {
405
- tail_or. push ( extract ( pat. into_inner ( ) . kind ) ) ;
414
+ // Check if we should extract, but only if `idx >= start`.
415
+ if idx > start && predicate ( & alternatives[ i] . kind ) {
416
+ let pat = alternatives. remove ( i) ;
417
+ tail_or. push ( extract ( pat. into_inner ( ) . kind ) ) ;
418
+ } else {
419
+ i += 1 ;
420
+ }
406
421
}
422
+
407
423
tail_or
408
424
}
409
425
410
426
fn extend_with_matching (
411
427
target : & mut Pat ,
412
428
start : usize ,
413
- alternatives : & mut Vec < P < Pat > > ,
429
+ alternatives : & mut ThinVec < P < Pat > > ,
414
430
predicate : impl Fn ( & PatKind ) -> bool ,
415
431
extract : impl Fn ( PatKind ) -> P < Pat > ,
416
432
) -> bool {
0 commit comments