about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2025-02-19 14:08:52 +1100
committerNicholas Nethercote <n.nethercote@gmail.com>2025-02-20 14:00:36 +1100
commitcae9ebbe1e09c2878d56ab1425d3765f450fd5fe (patch)
tree4fa24e59a387e696797d984d2e46000ec9756197
parent5986ff05d8480da038dd161b3a6aa79ff364a851 (diff)
downloadrust-cae9ebbe1e09c2878d56ab1425d3765f450fd5fe.tar.gz
rust-cae9ebbe1e09c2878d56ab1425d3765f450fd5fe.zip
Simplify `Postorder` customization.
`Postorder` has a `C: Customization<'tcx>` parameter, that gives it
flexibility about how it computes successors. But in practice, there are
only two `impls` of `Customization`, and one is for the unit type.

This commit simplifies things by removing the generic parameter and
replacing it with an `Option`.
-rw-r--r--compiler/rustc_middle/src/mir/basic_blocks.rs2
-rw-r--r--compiler/rustc_middle/src/mir/traversal.rs47
-rw-r--r--src/tools/clippy/clippy_utils/src/mir/mod.rs2
3 files changed, 15 insertions, 36 deletions
diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs
index 107c3198525..171542d1279 100644
--- a/compiler/rustc_middle/src/mir/basic_blocks.rs
+++ b/compiler/rustc_middle/src/mir/basic_blocks.rs
@@ -79,7 +79,7 @@ impl<'tcx> BasicBlocks<'tcx> {
     #[inline]
     pub fn reverse_postorder(&self) -> &[BasicBlock] {
         self.cache.reverse_postorder.get_or_init(|| {
-            let mut rpo: Vec<_> = Postorder::new(&self.basic_blocks, START_BLOCK, ()).collect();
+            let mut rpo: Vec<_> = Postorder::new(&self.basic_blocks, START_BLOCK, None).collect();
             rpo.reverse();
             rpo
         })
diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs
index 0e7dcc24daf..5950ac295af 100644
--- a/compiler/rustc_middle/src/mir/traversal.rs
+++ b/compiler/rustc_middle/src/mir/traversal.rs
@@ -104,23 +104,21 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
 /// ```
 ///
 /// A Postorder traversal of this graph is `D B C A` or `D C B A`
-pub struct Postorder<'a, 'tcx, C> {
+pub struct Postorder<'a, 'tcx> {
     basic_blocks: &'a IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
     visited: DenseBitSet<BasicBlock>,
     visit_stack: Vec<(BasicBlock, Successors<'a>)>,
     root_is_start_block: bool,
-    extra: C,
+    /// A non-empty `extra` allows for a precise calculation of the successors.
+    extra: Option<(TyCtxt<'tcx>, Instance<'tcx>)>,
 }
 
-impl<'a, 'tcx, C> Postorder<'a, 'tcx, C>
-where
-    C: Customization<'tcx>,
-{
+impl<'a, 'tcx> Postorder<'a, 'tcx> {
     pub fn new(
         basic_blocks: &'a IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
         root: BasicBlock,
-        extra: C,
-    ) -> Postorder<'a, 'tcx, C> {
+        extra: Option<(TyCtxt<'tcx>, Instance<'tcx>)>,
+    ) -> Postorder<'a, 'tcx> {
         let mut po = Postorder {
             basic_blocks,
             visited: DenseBitSet::new_empty(basic_blocks.len()),
@@ -140,7 +138,11 @@ where
             return;
         }
         let data = &self.basic_blocks[bb];
-        let successors = C::successors(data, self.extra);
+        let successors = if let Some(extra) = self.extra {
+            data.mono_successors(extra.0, extra.1)
+        } else {
+            data.terminator().successors()
+        };
         self.visit_stack.push((bb, successors));
     }
 
@@ -198,10 +200,7 @@ where
     }
 }
 
-impl<'tcx, C> Iterator for Postorder<'_, 'tcx, C>
-where
-    C: Customization<'tcx>,
-{
+impl<'tcx> Iterator for Postorder<'_, 'tcx> {
     type Item = BasicBlock;
 
     fn next(&mut self) -> Option<BasicBlock> {
@@ -241,32 +240,12 @@ pub fn postorder<'a, 'tcx>(
     reverse_postorder(body).rev()
 }
 
-/// Lets us plug in some additional logic and data into a Postorder traversal. Or not.
-pub trait Customization<'tcx>: Copy {
-    fn successors<'a>(_: &'a BasicBlockData<'tcx>, _: Self) -> Successors<'a>;
-}
-
-impl<'tcx> Customization<'tcx> for () {
-    fn successors<'a>(data: &'a BasicBlockData<'tcx>, _: ()) -> Successors<'a> {
-        data.terminator().successors()
-    }
-}
-
-impl<'tcx> Customization<'tcx> for (TyCtxt<'tcx>, Instance<'tcx>) {
-    fn successors<'a>(
-        data: &'a BasicBlockData<'tcx>,
-        (tcx, instance): (TyCtxt<'tcx>, Instance<'tcx>),
-    ) -> Successors<'a> {
-        data.mono_successors(tcx, instance)
-    }
-}
-
 pub fn mono_reachable_reverse_postorder<'a, 'tcx>(
     body: &'a Body<'tcx>,
     tcx: TyCtxt<'tcx>,
     instance: Instance<'tcx>,
 ) -> Vec<BasicBlock> {
-    let mut iter = Postorder::new(&body.basic_blocks, START_BLOCK, (tcx, instance));
+    let mut iter = Postorder::new(&body.basic_blocks, START_BLOCK, Some((tcx, instance)));
     let mut items = Vec::with_capacity(body.basic_blocks.len());
     while let Some(block) = iter.next() {
         items.push(block);
diff --git a/src/tools/clippy/clippy_utils/src/mir/mod.rs b/src/tools/clippy/clippy_utils/src/mir/mod.rs
index 637c0bafd96..ffcfcd240ea 100644
--- a/src/tools/clippy/clippy_utils/src/mir/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/mir/mod.rs
@@ -30,7 +30,7 @@ pub fn visit_local_usage(locals: &[Local], mir: &Body<'_>, location: Location) -
         locals.len()
     ];
 
-    traversal::Postorder::new(&mir.basic_blocks, location.block, ())
+    traversal::Postorder::new(&mir.basic_blocks, location.block, None)
         .collect::<Vec<_>>()
         .into_iter()
         .rev()