about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src/traits/vtable.rs
diff options
context:
space:
mode:
authorMaybe Waffle <waffle.lapkin@gmail.com>2023-07-19 10:34:35 +0000
committerMaybe Waffle <waffle.lapkin@gmail.com>2023-07-19 11:53:41 +0000
commitd87db8eb3f470d5cc8901dd74f6a25685511161a (patch)
tree34b77153004814b332d5d41f7d2e49fc91363105 /compiler/rustc_trait_selection/src/traits/vtable.rs
parentd567f0fc688411a8805c0187957b8bdcc84ef1d8 (diff)
downloadrust-d87db8eb3f470d5cc8901dd74f6a25685511161a.tar.gz
rust-d87db8eb3f470d5cc8901dd74f6a25685511161a.zip
Simplify last `prepare_vtable_segments` loop even more
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits/vtable.rs')
-rw-r--r--compiler/rustc_trait_selection/src/traits/vtable.rs47
1 files changed, 22 insertions, 25 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs
index c00161d158f..3a647b784cc 100644
--- a/compiler/rustc_trait_selection/src/traits/vtable.rs
+++ b/compiler/rustc_trait_selection/src/traits/vtable.rs
@@ -113,7 +113,7 @@ fn prepare_vtable_segments_inner<'tcx, T>(
     // Loop run #1: Emitting the slice [D C] (in reverse order). No one has a next-sibling node.
     // Loop run #1: Stack after exiting out is []. Now the function exits.
 
-    loop {
+    'outer: loop {
         // dive deeper into the stack, recording the path
         'diving_in: loop {
             let &(inner_most_trait_ref, _, _) = stack.last().unwrap();
@@ -151,32 +151,29 @@ fn prepare_vtable_segments_inner<'tcx, T>(
         emit_vptr_on_new_entry = true;
 
         // emit innermost item, move to next sibling and stop there if possible, otherwise jump to outer level.
-        'exiting_out: loop {
-            if let Some((inner_most_trait_ref, emit_vptr, siblings)) = stack.last_mut() {
-                segment_visitor(VtblSegment::TraitOwnEntries {
-                    trait_ref: *inner_most_trait_ref,
-                    emit_vptr: *emit_vptr,
-                })?;
-
-                match siblings.find(|&sibling| visited.insert(sibling.to_predicate(tcx))) {
-                    Some(next_inner_most_trait_ref) => {
-                        // We're throwing away potential constness of super traits here.
-                        // FIXME: handle ~const super traits
-                        let next_inner_most_trait_ref =
-                            next_inner_most_trait_ref.map_bound(|t| t.trait_ref);
-                        *inner_most_trait_ref = next_inner_most_trait_ref;
-                        *emit_vptr = emit_vptr_on_new_entry;
-                        break 'exiting_out;
-                    }
-                    None => {
-                        stack.pop();
-                        continue 'exiting_out;
-                    }
-                }
+        while let Some((inner_most_trait_ref, emit_vptr, mut siblings)) = stack.pop() {
+            segment_visitor(VtblSegment::TraitOwnEntries {
+                trait_ref: inner_most_trait_ref,
+                emit_vptr,
+            })?;
+
+            if let Some(next_inner_most_trait_ref) =
+                siblings.find(|&sibling| visited.insert(sibling.to_predicate(tcx)))
+            {
+                // We're throwing away potential constness of super traits here.
+                // FIXME: handle ~const super traits
+                let next_inner_most_trait_ref =
+                    next_inner_most_trait_ref.map_bound(|t| t.trait_ref);
+
+                stack.push((next_inner_most_trait_ref, emit_vptr_on_new_entry, siblings));
+
+                // just pushed a new trait onto the stack, so we need to go through its super traits
+                continue 'outer;
             }
-            // all done
-            return ControlFlow::Continue(());
         }
+
+        // the stack is empty, all done
+        return ControlFlow::Continue(());
     }
 }