@@ -680,49 +680,37 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
680
680
// `tests/ui/closures/2229_closure_analysis/preserve_field_drop_order.rs`.
681
681
for ( _, captures) in & mut root_var_min_capture_list {
682
682
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) {
684
700
// We do not need to look at the `Projection.ty` fields here because at each
685
701
// step of the iteration, the projections will either be the same and therefore
686
702
// the types must be as well or the current projection will be different and
687
703
// we will return the result of comparing the field indexes.
688
704
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.
696
705
( 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
+ }
698
711
}
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) ,
726
714
}
727
715
}
728
716
0 commit comments