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