Skip to content

Commit e2ac989

Browse files
committed
mir: place match pattern bindings in their respective arms.
1 parent f06bab7 commit e2ac989

File tree

2 files changed

+24
-18
lines changed

2 files changed

+24
-18
lines changed

src/librustc_mir/build/matches/mod.rs

+23-16
Original file line numberDiff line numberDiff line change
@@ -37,25 +37,28 @@ impl<'a,'tcx> Builder<'a,'tcx> {
3737
-> BlockAnd<()> {
3838
let discriminant_lvalue = unpack!(block = self.as_lvalue(block, discriminant));
3939

40-
// Before we do anything, create uninitialized variables with
41-
// suitable extent for all of the bindings in this match. It's
42-
// easiest to do this up front because some of these arms may
43-
// be unreachable or reachable multiple times.
44-
let var_scope_id = self.innermost_scope_id();
45-
for arm in &arms {
46-
self.declare_bindings(var_scope_id, &arm.patterns[0]);
47-
}
48-
4940
let mut arm_blocks = ArmBlocks {
5041
blocks: arms.iter()
5142
.map(|_| self.cfg.start_new_block())
5243
.collect(),
5344
};
5445

55-
let arm_bodies: Vec<ExprRef<'tcx>> =
56-
arms.iter()
57-
.map(|arm| arm.body.clone())
58-
.collect();
46+
// Get the body expressions and their scopes, while declaring bindings.
47+
let arm_bodies: Vec<_> = arms.iter().enumerate().map(|(i, arm)| {
48+
// Assume that all expressions are wrapped in Scope.
49+
let body = self.hir.mirror(arm.body.clone());
50+
match body.kind {
51+
ExprKind::Scope { extent, value } => {
52+
let scope_id = self.push_scope(extent, arm_blocks.blocks[i]);
53+
self.declare_bindings(scope_id, &arm.patterns[0]);
54+
(extent, self.scopes.pop().unwrap(), value)
55+
}
56+
_ => {
57+
span_bug!(body.span, "arm body is not wrapped in Scope {:?}",
58+
body.kind);
59+
}
60+
}
61+
}).collect();
5962

6063
// assemble a list of candidates: there is one candidate per
6164
// pattern, which means there may be more than one candidate
@@ -95,11 +98,15 @@ impl<'a,'tcx> Builder<'a,'tcx> {
9598
// all the arm blocks will rejoin here
9699
let end_block = self.cfg.start_new_block();
97100

98-
for (arm_index, arm_body) in arm_bodies.into_iter().enumerate() {
101+
let scope_id = self.innermost_scope_id();
102+
for (arm_index, (extent, scope, body)) in arm_bodies.into_iter().enumerate() {
99103
let mut arm_block = arm_blocks.blocks[arm_index];
100-
unpack!(arm_block = self.into(destination, arm_block, arm_body));
104+
// Re-enter the scope we created the bindings in.
105+
self.scopes.push(scope);
106+
unpack!(arm_block = self.into(destination, arm_block, body));
107+
unpack!(arm_block = self.pop_scope(extent, arm_block));
101108
self.cfg.terminate(arm_block,
102-
var_scope_id,
109+
scope_id,
103110
span,
104111
TerminatorKind::Goto { target: end_block });
105112
}

src/test/debuginfo/associated-types.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080

8181
#![allow(unused_variables)]
8282
#![allow(dead_code)]
83-
#![feature(omit_gdb_pretty_printer_section, rustc_attrs)]
83+
#![feature(omit_gdb_pretty_printer_section)]
8484
#![omit_gdb_pretty_printer_section]
8585

8686
trait TraitWithAssocType {
@@ -127,7 +127,6 @@ fn assoc_tuple<T: TraitWithAssocType>(arg: (T, T::Type)) {
127127
zzz(); // #break
128128
}
129129

130-
#[rustc_no_mir] // FIXME(#32790) MIR reuses scopes for match arms.
131130
fn assoc_enum<T: TraitWithAssocType>(arg: Enum<T>) {
132131

133132
match arg {

0 commit comments

Comments
 (0)