Skip to content

Commit be23bd4

Browse files
committed
Unify return, break and continue handling
1 parent 82a1a89 commit be23bd4

File tree

3 files changed

+200
-181
lines changed

3 files changed

+200
-181
lines changed

src/librustc_mir/build/expr/stmt.rs

+4-61
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::build::scope::BreakableScope;
1+
use crate::build::scope::BreakableTarget;
22
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
33
use crate::hair::*;
44
use rustc::middle::region;
@@ -98,70 +98,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
9898
block.unit()
9999
}
100100
ExprKind::Continue { label } => {
101-
let BreakableScope {
102-
continue_block,
103-
region_scope,
104-
..
105-
} = *this.find_breakable_scope(expr_span, label);
106-
let continue_block = continue_block
107-
.expect("Attempted to continue in non-continuable breakable block");
108-
this.exit_scope(
109-
expr_span,
110-
(region_scope, source_info),
111-
block,
112-
continue_block,
113-
);
114-
this.cfg.start_new_block().unit()
101+
this.break_scope(block, None, BreakableTarget::Continue(label), source_info)
115102
}
116103
ExprKind::Break { label, value } => {
117-
let (break_block, region_scope, destination) = {
118-
let BreakableScope {
119-
break_block,
120-
region_scope,
121-
ref break_destination,
122-
..
123-
} = *this.find_breakable_scope(expr_span, label);
124-
(break_block, region_scope, break_destination.clone())
125-
};
126-
if let Some(value) = value {
127-
debug!("stmt_expr Break val block_context.push(SubExpr) : {:?}", expr2);
128-
this.block_context.push(BlockFrame::SubExpr);
129-
unpack!(block = this.into(&destination, block, value));
130-
this.block_context.pop();
131-
} else {
132-
this.cfg.push_assign_unit(block, source_info, &destination)
133-
}
134-
this.exit_scope(expr_span, (region_scope, source_info), block, break_block);
135-
this.cfg.start_new_block().unit()
104+
this.break_scope(block, value, BreakableTarget::Break(label), source_info)
136105
}
137106
ExprKind::Return { value } => {
138-
block = match value {
139-
Some(value) => {
140-
debug!("stmt_expr Return val block_context.push(SubExpr) : {:?}", expr2);
141-
this.block_context.push(BlockFrame::SubExpr);
142-
let result = unpack!(
143-
this.into(
144-
&Place::RETURN_PLACE,
145-
block,
146-
value
147-
)
148-
);
149-
this.block_context.pop();
150-
result
151-
}
152-
None => {
153-
this.cfg.push_assign_unit(
154-
block,
155-
source_info,
156-
&Place::RETURN_PLACE,
157-
);
158-
block
159-
}
160-
};
161-
let region_scope = this.region_scope_of_return_scope();
162-
let return_block = this.return_block();
163-
this.exit_scope(expr_span, (region_scope, source_info), block, return_block);
164-
this.cfg.start_new_block().unit()
107+
this.break_scope(block, value, BreakableTarget::Return, source_info)
165108
}
166109
ExprKind::InlineAsm {
167110
asm,

src/librustc_mir/build/mod.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ struct Builder<'a, 'tcx> {
251251

252252
/// The current set of scopes, updated as we traverse;
253253
/// see the `scope` module for more details.
254-
scopes: Vec<scope::Scope<'tcx>>,
254+
scopes: scope::Scopes<'tcx>,
255255

256256
/// The block-context: each time we build the code within an hair::Block,
257257
/// we push a frame here tracking whether we are building a statement or
@@ -274,10 +274,6 @@ struct Builder<'a, 'tcx> {
274274
/// The number of `push_unsafe_block` levels in scope.
275275
push_unsafe_count: usize,
276276

277-
/// The current set of breakables; see the `scope` module for more
278-
/// details.
279-
breakable_scopes: Vec<scope::BreakableScope<'tcx>>,
280-
281277
/// The vector of all scopes that we have created thus far;
282278
/// we track this for debuginfo later.
283279
source_scopes: IndexVec<SourceScope, SourceScopeData>,
@@ -714,15 +710,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
714710
fn_span: span,
715711
arg_count,
716712
is_generator,
717-
scopes: vec![],
713+
scopes: Default::default(),
718714
block_context: BlockContext::new(),
719715
source_scopes: IndexVec::new(),
720716
source_scope: OUTERMOST_SOURCE_SCOPE,
721717
source_scope_local_data: IndexVec::new(),
722718
guard_context: vec![],
723719
push_unsafe_count: 0,
724720
unpushed_unsafe: safety,
725-
breakable_scopes: vec![],
726721
local_decls: IndexVec::from_elem_n(
727722
LocalDecl::new_return_place(return_ty, return_span),
728723
1,
@@ -865,7 +860,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
865860
}
866861

867862
let body = self.hir.mirror(ast_body);
868-
self.into(&Place::RETURN_PLACE, block, body)
863+
// `return_block` is called when we evaluate a `return` expression, so
864+
// we just use `START_BLOCK` here.
865+
self.in_breakable_scope(None, START_BLOCK, Place::RETURN_PLACE, |this| {
866+
this.into(&Place::RETURN_PLACE, block, body)
867+
})
869868
}
870869

871870
fn get_unit_temp(&mut self) -> Place<'tcx> {

0 commit comments

Comments
 (0)