@@ -12,9 +12,9 @@ use rustc_errors::Applicability;
1212use rustc_lint:: { EarlyContext , EarlyLintPass } ;
1313use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
1414use rustc_span:: DUMMY_SP ;
15-
1615use std:: cell:: Cell ;
1716use std:: mem;
17+ use thin_vec:: { thin_vec, ThinVec } ;
1818
1919declare_clippy_lint ! {
2020 /// ### What it does
@@ -214,7 +214,7 @@ macro_rules! always_pat {
214214/// Focus on `focus_idx` in `alternatives`,
215215/// attempting to extend it with elements of the same constructor `C`
216216/// 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 {
218218 // Extract the kind; we'll need to make some changes in it.
219219 let mut focus_kind = mem:: replace ( & mut alternatives[ focus_idx] . kind , PatKind :: Wild ) ;
220220 // We'll focus on `alternatives[focus_idx]`,
@@ -296,7 +296,7 @@ fn extend_with_struct_pat(
296296 fps1 : & mut [ ast:: PatField ] ,
297297 rest1 : bool ,
298298 start : usize ,
299- alternatives : & mut Vec < P < Pat > > ,
299+ alternatives : & mut ThinVec < P < Pat > > ,
300300) -> bool {
301301 ( 0 ..fps1. len ( ) ) . any ( |idx| {
302302 let pos_in_2 = Cell :: new ( None ) ; // The element `k`.
@@ -336,9 +336,9 @@ fn extend_with_struct_pat(
336336fn extend_with_matching_product (
337337 targets : & mut [ P < Pat > ] ,
338338 start : usize ,
339- alternatives : & mut Vec < P < Pat > > ,
339+ alternatives : & mut ThinVec < P < Pat > > ,
340340 predicate : impl Fn ( & PatKind , & [ P < Pat > ] , usize ) -> bool ,
341- extract : impl Fn ( PatKind ) -> Vec < P < Pat > > ,
341+ extract : impl Fn ( PatKind ) -> ThinVec < P < Pat > > ,
342342) -> bool {
343343 ( 0 ..targets. len ( ) ) . any ( |idx| {
344344 let tail_or = drain_matching (
@@ -365,14 +365,14 @@ fn take_pat(from: &mut Pat) -> Pat {
365365
366366/// Extend `target` as an or-pattern with the alternatives
367367/// 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 > > ) {
370370 match target {
371371 // On an existing or-pattern in the target, append to it.
372372 Pat { kind : Or ( ps) , .. } => ps. append ( & mut tail_or) ,
373373 // Otherwise convert the target to an or-pattern.
374374 target => {
375- let mut init_or = vec ! [ P ( take_pat( target) ) ] ;
375+ let mut init_or = thin_vec ! [ P ( take_pat( target) ) ] ;
376376 init_or. append ( & mut tail_or) ;
377377 target. kind = Or ( init_or) ;
378378 } ,
@@ -391,26 +391,42 @@ fn extend_with_tail_or(target: &mut Pat, tail_or: Vec<P<Pat>>) -> bool {
391391// Only elements beginning with `start` are considered for extraction.
392392fn drain_matching (
393393 start : usize ,
394- alternatives : & mut Vec < P < Pat > > ,
394+ alternatives : & mut ThinVec < P < Pat > > ,
395395 predicate : impl Fn ( & PatKind ) -> bool ,
396396 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 ( ) ;
399399 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 ( ) {
402413 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+ }
406421 }
422+
407423 tail_or
408424}
409425
410426fn extend_with_matching (
411427 target : & mut Pat ,
412428 start : usize ,
413- alternatives : & mut Vec < P < Pat > > ,
429+ alternatives : & mut ThinVec < P < Pat > > ,
414430 predicate : impl Fn ( & PatKind ) -> bool ,
415431 extract : impl Fn ( PatKind ) -> P < Pat > ,
416432) -> bool {
0 commit comments