Tweak the post-order for multi-successor blocks

This commit is contained in:
Scott McMurray 2023-05-21 01:31:17 -07:00
parent fe76e14955
commit 57c5ac7894
6 changed files with 18 additions and 20 deletions

View File

@ -105,7 +105,7 @@ pub struct Terminator<'tcx> {
pub kind: TerminatorKind<'tcx>,
}
pub type Successors<'a> = impl Iterator<Item = BasicBlock> + 'a;
pub type Successors<'a> = impl DoubleEndedIterator<Item = BasicBlock> + 'a;
pub type SuccessorsMut<'a> =
iter::Chain<std::option::IntoIter<&'a mut BasicBlock>, slice::IterMut<'a, BasicBlock>>;

View File

@ -149,7 +149,7 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
// B C
// | |
// | |
// D |
// | D
// \ /
// \ /
// E
@ -159,26 +159,26 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
//
// When the first call to `traverse_successor` happens, the following happens:
//
// [(B, [D]), // `B` taken from the successors of `A`, pushed to the
// // top of the stack along with the successors of `B`
// (A, [C])]
// [(C, [D]), // `C` taken from the successors of `A`, pushed to the
// // top of the stack along with the successors of `C`
// (A, [B])]
//
// [(D, [E]), // `D` taken from successors of `B`, pushed to stack
// (B, []),
// (A, [C])]
// [(D, [E]), // `D` taken from successors of `C`, pushed to stack
// (C, []),
// (A, [B])]
//
// [(E, []), // `E` taken from successors of `D`, pushed to stack
// (D, []),
// (B, []),
// (A, [C])]
// (C, []),
// (A, [B])]
//
// Now that the top of the stack has no successors we can traverse, each item will
// be popped off during iteration until we get back to `A`. This yields [E, D, B].
// be popped off during iteration until we get back to `A`. This yields [E, D, C].
//
// When we yield `B` and call `traverse_successor`, we push `C` to the stack, but
// When we yield `C` and call `traverse_successor`, we push `B` to the stack, but
// since we've already visited `E`, that child isn't added to the stack. The last
// two iterations yield `C` and finally `A` for a final traversal of [E, D, B, C, A]
while let Some(&mut (_, ref mut iter)) = self.visit_stack.last_mut() && let Some(bb) = iter.next() {
// two iterations yield `B` and finally `A` for a final traversal of [E, D, C, B, A]
while let Some(&mut (_, ref mut iter)) = self.visit_stack.last_mut() && let Some(bb) = iter.next_back() {
if self.visited.insert(bb) {
if let Some(term) = &self.basic_blocks[bb].terminator {
self.visit_stack.push((bb, term.successors()));

View File

@ -4,7 +4,7 @@ error[E0712]: thread-local variable borrowed past end of function
LL | assert_static(&FOO);
| ^^^^ thread-local variables cannot be borrowed beyond the end of the function
LL | }
| - end of enclosing function is here
| - end of enclosing function is here
error: aborting due to previous error

View File

@ -5,7 +5,7 @@ LL | let a = &FOO;
| ^^^^ thread-local variables cannot be borrowed beyond the end of the function
...
LL | }
| - end of enclosing function is here
| - end of enclosing function is here
error: aborting due to previous error

View File

@ -2,12 +2,10 @@ error[E0716]: temporary value dropped while borrowed
--> $DIR/issue-52049.rs:6:10
|
LL | foo(&unpromotable(5u32));
| -----^^^^^^^^^^^^^^^^^^-
| -----^^^^^^^^^^^^^^^^^^-- temporary value is freed at the end of this statement
| | |
| | creates a temporary value which is freed while still in use
| argument requires that borrow lasts for `'static`
LL | }
| - temporary value is freed at the end of this statement
error: aborting due to previous error

View File

@ -10,7 +10,7 @@ LL | let read = &refcell as &RefCell<dyn Read>;
| -------- cast requires that `foo` is borrowed for `'static`
...
LL | }
| - `foo` dropped here while still borrowed
| - `foo` dropped here while still borrowed
error: lifetime may not live long enough
--> $DIR/issue-90600-expected-return-static-indirect.rs:9:16