@@ -679,49 +679,37 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
679679 // `tests/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs`.
680680 for ( _, captures) in & mut root_var_min_capture_list {
681681 captures. sort_by ( |capture1, capture2| {
682- for ( p1, p2) in capture1. place . projections . iter ( ) . zip ( & capture2. place . projections ) {
682+ fn is_field < ' a > ( p : & & Projection < ' a > ) -> bool {
683+ match p. kind {
684+ ProjectionKind :: Field ( _, _) => true ,
685+ ProjectionKind :: Deref | ProjectionKind :: OpaqueCast => false ,
686+ p @ ( ProjectionKind :: Subslice | ProjectionKind :: Index ) => {
687+ bug ! ( "ProjectionKind {:?} was unexpected" , p)
688+ }
689+ }
690+ }
691+
692+ // Need to sort only by Field projections, so filter away others.
693+ // A previous implementation considered other projection types too
694+ // but that caused ICE #118144
695+ let capture1_field_projections = capture1. place . projections . iter ( ) . filter ( is_field) ;
696+ let capture2_field_projections = capture2. place . projections . iter ( ) . filter ( is_field) ;
697+
698+ for ( p1, p2) in capture1_field_projections. zip ( capture2_field_projections) {
683699 // We do not need to look at the `Projection.ty` fields here because at each
684700 // step of the iteration, the projections will either be the same and therefore
685701 // the types must be as well or the current projection will be different and
686702 // we will return the result of comparing the field indexes.
687703 match ( p1. kind , p2. kind ) {
688- // Paths are the same, continue to next loop.
689- ( ProjectionKind :: Deref , ProjectionKind :: Deref ) => { }
690- ( ProjectionKind :: OpaqueCast , ProjectionKind :: OpaqueCast ) => { }
691- ( ProjectionKind :: Field ( i1, _) , ProjectionKind :: Field ( i2, _) )
692- if i1 == i2 => { }
693-
694- // Fields are different, compare them.
695704 ( ProjectionKind :: Field ( i1, _) , ProjectionKind :: Field ( i2, _) ) => {
696- return i1. cmp ( & i2) ;
705+ // Compare only if paths are different.
706+ // Otherwise continue to the next iteration
707+ if i1 != i2 {
708+ return i1. cmp ( & i2) ;
709+ }
697710 }
698-
699- // We should have either a pair of `Deref`s or a pair of `Field`s.
700- // Anything else is a bug.
701- (
702- l @ ( ProjectionKind :: Deref | ProjectionKind :: Field ( ..) ) ,
703- r @ ( ProjectionKind :: Deref | ProjectionKind :: Field ( ..) ) ,
704- ) => bug ! (
705- "ProjectionKinds Deref and Field were mismatched: ({:?}, {:?})" ,
706- l,
707- r
708- ) ,
709- (
710- l @ ( ProjectionKind :: Index
711- | ProjectionKind :: Subslice
712- | ProjectionKind :: Deref
713- | ProjectionKind :: OpaqueCast
714- | ProjectionKind :: Field ( ..) ) ,
715- r @ ( ProjectionKind :: Index
716- | ProjectionKind :: Subslice
717- | ProjectionKind :: Deref
718- | ProjectionKind :: OpaqueCast
719- | ProjectionKind :: Field ( ..) ) ,
720- ) => bug ! (
721- "ProjectionKinds Index or Subslice were unexpected: ({:?}, {:?})" ,
722- l,
723- r
724- ) ,
711+ // Given the filter above, this arm should never be hit
712+ ( l, r) => bug ! ( "ProjectionKinds {:?} or {:?} were unexpected" , l, r) ,
725713 }
726714 }
727715
0 commit comments