@@ -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