about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2016-04-14 17:17:37 +0300
committerEduard Burtescu <edy.burt@gmail.com>2016-04-16 21:51:30 +0300
commite2ac9895d68b7bed9a8fc3d9ce270ae0129d2b74 (patch)
tree56b7f2c794cc946d1e005c4d42b0143a129aa323 /src
parentf06bab77586e377a24393b9e2e49d1bb7003dc0b (diff)
downloadrust-e2ac9895d68b7bed9a8fc3d9ce270ae0129d2b74.tar.gz
rust-e2ac9895d68b7bed9a8fc3d9ce270ae0129d2b74.zip
mir: place match pattern bindings in their respective arms.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/build/matches/mod.rs39
-rw-r--r--src/test/debuginfo/associated-types.rs3
2 files changed, 24 insertions, 18 deletions
diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index ccb2099dcc7..080183ae1da 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -37,25 +37,28 @@ impl<'a,'tcx> Builder<'a,'tcx> {
                       -> BlockAnd<()> {
         let discriminant_lvalue = unpack!(block = self.as_lvalue(block, discriminant));
 
-        // Before we do anything, create uninitialized variables with
-        // suitable extent for all of the bindings in this match. It's
-        // easiest to do this up front because some of these arms may
-        // be unreachable or reachable multiple times.
-        let var_scope_id = self.innermost_scope_id();
-        for arm in &arms {
-            self.declare_bindings(var_scope_id, &arm.patterns[0]);
-        }
-
         let mut arm_blocks = ArmBlocks {
             blocks: arms.iter()
                         .map(|_| self.cfg.start_new_block())
                         .collect(),
         };
 
-        let arm_bodies: Vec<ExprRef<'tcx>> =
-            arms.iter()
-                .map(|arm| arm.body.clone())
-                .collect();
+        // Get the body expressions and their scopes, while declaring bindings.
+        let arm_bodies: Vec<_> = arms.iter().enumerate().map(|(i, arm)| {
+            // Assume that all expressions are wrapped in Scope.
+            let body = self.hir.mirror(arm.body.clone());
+            match body.kind {
+                ExprKind::Scope { extent, value } => {
+                    let scope_id = self.push_scope(extent, arm_blocks.blocks[i]);
+                    self.declare_bindings(scope_id, &arm.patterns[0]);
+                    (extent, self.scopes.pop().unwrap(), value)
+                }
+                _ => {
+                    span_bug!(body.span, "arm body is not wrapped in Scope {:?}",
+                              body.kind);
+                }
+            }
+        }).collect();
 
         // assemble a list of candidates: there is one candidate per
         // pattern, which means there may be more than one candidate
@@ -95,11 +98,15 @@ impl<'a,'tcx> Builder<'a,'tcx> {
         // all the arm blocks will rejoin here
         let end_block = self.cfg.start_new_block();
 
-        for (arm_index, arm_body) in arm_bodies.into_iter().enumerate() {
+        let scope_id = self.innermost_scope_id();
+        for (arm_index, (extent, scope, body)) in arm_bodies.into_iter().enumerate() {
             let mut arm_block = arm_blocks.blocks[arm_index];
-            unpack!(arm_block = self.into(destination, arm_block, arm_body));
+            // Re-enter the scope we created the bindings in.
+            self.scopes.push(scope);
+            unpack!(arm_block = self.into(destination, arm_block, body));
+            unpack!(arm_block = self.pop_scope(extent, arm_block));
             self.cfg.terminate(arm_block,
-                               var_scope_id,
+                               scope_id,
                                span,
                                TerminatorKind::Goto { target: end_block });
         }
diff --git a/src/test/debuginfo/associated-types.rs b/src/test/debuginfo/associated-types.rs
index 8615c8a7ef6..ebaad663bb4 100644
--- a/src/test/debuginfo/associated-types.rs
+++ b/src/test/debuginfo/associated-types.rs
@@ -80,7 +80,7 @@
 
 #![allow(unused_variables)]
 #![allow(dead_code)]
-#![feature(omit_gdb_pretty_printer_section, rustc_attrs)]
+#![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
 trait TraitWithAssocType {
@@ -127,7 +127,6 @@ fn assoc_tuple<T: TraitWithAssocType>(arg: (T, T::Type)) {
     zzz(); // #break
 }
 
-#[rustc_no_mir] // FIXME(#32790) MIR reuses scopes for match arms.
 fn assoc_enum<T: TraitWithAssocType>(arg: Enum<T>) {
 
     match arg {