Skip to content

Commit 899d10e

Browse files
committed
Merge last_cached_unwind and diverge_blocks
1 parent 4667439 commit 899d10e

File tree

2 files changed

+53
-42
lines changed

2 files changed

+53
-42
lines changed

src/librustc_mir/build/scope.rs

+25-25
Original file line numberDiff line numberDiff line change
@@ -107,15 +107,14 @@ struct BreakableScope<'tcx> {
107107
region_scope: region::Scope,
108108
/// Where the body of the loop begins. `None` if block
109109
continue_block: Option<BasicBlock>,
110-
/// Block to branch into when the loop or block terminates (either by being `break`-en out
111-
/// from, or by having its condition to become false)
110+
/// Block to branch into when the loop or block terminates (either by being
111+
/// `break`-en out from, or by having its condition to become false)
112112
break_block: BasicBlock,
113-
/// The destination of the loop/block expression itself (i.e., where to put the result of a
114-
/// `break` expression)
113+
/// The destination of the loop/block expression itself (i.e., where to put
114+
/// the result of a `break` expression)
115115
break_destination: Place<'tcx>,
116116
}
117117

118-
119118
#[derive(Debug)]
120119
struct DropData {
121120
/// span where drop obligation was incurred (typically where place was declared)
@@ -131,7 +130,6 @@ struct DropData {
131130
cached_block: CachedBlock,
132131
}
133132

134-
135133
/// The target of an expression that breaks out of a scope
136134
#[derive(Clone, Copy, Debug)]
137135
pub enum BreakableTarget {
@@ -526,25 +524,27 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
526524
// to left reading the cached results but never created anything.
527525

528526
// Find the last cached block
529-
debug!("diverge_cleanup_gen(self.scopes = {:?})", self.scopes);
530-
let cached_cleanup = self.scopes.last_cached_unwind(generator_drop);
531-
let (mut target, first_uncached) = cached_cleanup
532-
.unwrap_or_else(|| (self.resume_block(), 0));
533-
534-
let scopes = self.scopes.diverge_blocks(first_uncached, generator_drop);
535-
for (source_scope, drops, cached_unwind) in scopes {
536-
target = build_diverge_scope(
537-
&mut self.cfg,
538-
source_scope,
539-
drops,
540-
target,
541-
generator_drop,
542-
self.is_generator,
543-
);
544-
*cached_unwind = Some(target);
545-
}
546-
547-
target
527+
debug!("diverge_cleanup_gen(self.scopes = {:#?})", self.scopes);
528+
let resume_block = self.resume_block();
529+
let cfg = &mut self.cfg;
530+
let is_generator = self.is_generator;
531+
532+
self.scopes.for_each_diverge_block(
533+
generator_drop,
534+
resume_block,
535+
|source_scope, drops, cached_unwind, mut target| {
536+
target = build_diverge_scope(
537+
cfg,
538+
source_scope,
539+
drops,
540+
target,
541+
generator_drop,
542+
is_generator,
543+
);
544+
*cached_unwind = Some(target);
545+
target
546+
}
547+
)
548548
}
549549

550550
/// Utility function for *non*-scope code to build their own drops

src/librustc_mir/build/scope/stack.rs

+28-17
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,11 @@ impl<'tcx> Scopes<'tcx> {
140140
self.scopes.len()
141141
}
142142

143-
pub(super) fn push_scope(&mut self, region_scope: (region::Scope, SourceInfo), vis_scope: SourceScope) {
143+
pub(super) fn push_scope(
144+
&mut self,
145+
region_scope: (region::Scope, SourceInfo),
146+
vis_scope: SourceScope,
147+
) {
144148
debug!("push_scope({:?})", region_scope);
145149
self.scopes.push(Scope {
146150
source_scope: vis_scope,
@@ -217,24 +221,31 @@ impl<'tcx> Scopes<'tcx> {
217221
scope_count
218222
}
219223

220-
pub(super) fn last_cached_unwind(
221-
&mut self,
222-
generator_drop: bool,
223-
) -> Option<(BasicBlock, usize)> {
224-
self.scopes.iter_mut().enumerate().rev().find_map(move |(idx, scope)| {
225-
let cached_block = scope.cached_unwind.get(generator_drop)?;
226-
Some((cached_block, idx + 1))
227-
})
228-
}
229-
230-
pub(super) fn diverge_blocks(
224+
/// Call the given action for each scope that doesn't already have a cached
225+
/// unwind block. Scopes are iterated going up the scope stack.
226+
pub(super) fn for_each_diverge_block<F>(
231227
&mut self,
232-
start_at: usize,
233228
generator_drop: bool,
234-
) -> impl Iterator<Item=(SourceScope, &mut [DropData], &mut Option<BasicBlock>)> {
235-
self.scopes[start_at..].iter_mut().map(move |scope| {
236-
(scope.source_scope, &mut *scope.drops, scope.cached_unwind.ref_mut(generator_drop))
237-
})
229+
resume_block: BasicBlock,
230+
mut action: F,
231+
) -> BasicBlock
232+
where
233+
F: FnMut(SourceScope, &mut [DropData], &mut Option<BasicBlock>, BasicBlock) -> BasicBlock
234+
{
235+
let (mut target, start_at) = self.scopes.iter().enumerate().rev()
236+
.find_map(move |(idx, scope)| {
237+
let cached_block = scope.cached_unwind.get(generator_drop)?;
238+
Some((cached_block, idx + 1))
239+
}).unwrap_or((resume_block, 0));
240+
self.scopes[start_at..].iter_mut().for_each(|scope| {
241+
target = action(
242+
scope.source_scope,
243+
&mut *scope.drops,
244+
scope.cached_unwind.ref_mut(generator_drop),
245+
target,
246+
)
247+
});
248+
target
238249
}
239250

240251
/// Iterate over the [ScopeInfo] for exiting to the given target.

0 commit comments

Comments
 (0)