about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_mir/build/matches/mod.rs12
-rw-r--r--src/librustc_mir/build/mod.rs21
-rw-r--r--src/librustc_mir/build/scope.rs16
-rw-r--r--src/test/ui/async-await/await-unsize.rs16
-rw-r--r--src/test/ui/loops/loop-break-unsize.rs8
5 files changed, 52 insertions, 21 deletions
diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index f831f5105a4..75c64bb2644 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -228,10 +228,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         };
 
         // Step 5. Create everything else: the guards and the arms.
+        let match_scope = self.scopes.topmost();
+
         let arm_end_blocks: Vec<_> = arm_candidates.into_iter().map(|(arm, mut candidates)| {
             let arm_source_info = self.source_info(arm.span);
-            let region_scope = (arm.scope, arm_source_info);
-            self.in_scope(region_scope, arm.lint_level, |this| {
+            let arm_scope = (arm.scope, arm_source_info);
+            self.in_scope(arm_scope, arm.lint_level, |this| {
                 let body = this.hir.mirror(arm.body.clone());
                 let scope = this.declare_bindings(
                     None,
@@ -248,7 +250,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         arm.guard.clone(),
                         &fake_borrow_temps,
                         scrutinee_span,
-                        region_scope,
+                        match_scope,
                     );
                 } else {
                     arm_block = this.cfg.start_new_block();
@@ -259,7 +261,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                             arm.guard.clone(),
                             &fake_borrow_temps,
                             scrutinee_span,
-                            region_scope,
+                            match_scope,
                         );
                         this.cfg.terminate(
                             binding_end,
@@ -1339,7 +1341,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         guard: Option<Guard<'tcx>>,
         fake_borrows: &Vec<(&Place<'tcx>, Local)>,
         scrutinee_span: Span,
-        region_scope: (region::Scope, SourceInfo),
+        region_scope: region::Scope,
     ) -> BasicBlock {
         debug!("bind_and_guard_matched_candidate(candidate={:?})", candidate);
 
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 80a035d8287..bdcde5b33dc 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -604,9 +604,18 @@ where
         }
 
         let arg_scope_s = (arg_scope, source_info);
-        unpack!(block = builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
-            builder.args_and_body(block, &arguments, arg_scope, &body.value)
-        }));
+        // `return_block` is called when we evaluate a `return` expression, so
+        // we just use `START_BLOCK` here.
+        unpack!(block = builder.in_breakable_scope(
+            None,
+            START_BLOCK,
+            Place::RETURN_PLACE,
+            |builder| {
+                builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
+                    builder.args_and_body(block, &arguments, arg_scope, &body.value)
+                })
+            },
+        ));
         // Attribute epilogue to function's closing brace
         let fn_end = span.shrink_to_hi();
         let source_info = builder.source_info(fn_end);
@@ -860,11 +869,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
 
         let body = self.hir.mirror(ast_body);
-        // `return_block` is called when we evaluate a `return` expression, so
-        // we just use `START_BLOCK` here.
-        self.in_breakable_scope(None, START_BLOCK, Place::RETURN_PLACE, |this| {
-            this.into(&Place::RETURN_PLACE, block, body)
-        })
+        self.into(&Place::RETURN_PLACE, block, body)
     }
 
     fn get_unit_temp(&mut self) -> Place<'tcx> {
diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs
index 1b5fa1c9770..a74d5d7ab2d 100644
--- a/src/librustc_mir/build/scope.rs
+++ b/src/librustc_mir/build/scope.rs
@@ -332,9 +332,9 @@ impl<'tcx> Scopes<'tcx> {
         }
     }
 
-    fn num_scopes_to(&self, region_scope: (region::Scope, SourceInfo), span: Span) -> usize {
-        let scope_count = 1 + self.scopes.iter().rev()
-            .position(|scope| scope.region_scope == region_scope.0)
+    fn num_scopes_above(&self, region_scope: region::Scope, span: Span) -> usize {
+        let scope_count = self.scopes.iter().rev()
+            .position(|scope| scope.region_scope == region_scope)
             .unwrap_or_else(|| {
                 span_bug!(span, "region_scope {:?} does not enclose", region_scope)
             });
@@ -354,7 +354,7 @@ impl<'tcx> Scopes<'tcx> {
 
     /// Returns the topmost active scope, which is known to be alive until
     /// the next scope expression.
-    fn topmost(&self) -> region::Scope {
+    pub(super) fn topmost(&self) -> region::Scope {
         self.scopes.last().expect("topmost_scope: no scopes present").region_scope
     }
 
@@ -514,7 +514,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         } else {
             assert!(value.is_none(), "`return` and `break` should have a destination");
         }
-        self.exit_scope(source_info.span, (region_scope, source_info), block, target_block);
+        self.exit_scope(source_info.span, region_scope, block, target_block);
         self.cfg.start_new_block().unit()
     }
 
@@ -523,12 +523,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// needed. See module comment for details.
     pub fn exit_scope(&mut self,
                       span: Span,
-                      region_scope: (region::Scope, SourceInfo),
+                      region_scope: region::Scope,
                       mut block: BasicBlock,
                       target: BasicBlock) {
         debug!("exit_scope(region_scope={:?}, block={:?}, target={:?})",
                region_scope, block, target);
-        let scope_count = self.scopes.num_scopes_to(region_scope, span);
+        let scope_count = self.scopes.num_scopes_above(region_scope, span);
 
         // If we are emitting a `drop` statement, we need to have the cached
         // diverge cleanup pads ready in case that drop panics.
@@ -545,7 +545,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 continue;
             }
             let source_info = scope.source_info(span);
-            block = match scope.cached_exits.entry((target, region_scope.0)) {
+            block = match scope.cached_exits.entry((target, region_scope)) {
                 Entry::Occupied(e) => {
                     self.cfg.terminate(block, source_info,
                                     TerminatorKind::Goto { target: *e.get() });
diff --git a/src/test/ui/async-await/await-unsize.rs b/src/test/ui/async-await/await-unsize.rs
new file mode 100644
index 00000000000..d5e21257f4f
--- /dev/null
+++ b/src/test/ui/async-await/await-unsize.rs
@@ -0,0 +1,16 @@
+// Regression test for #62312
+
+// check-pass
+// edition:2018
+
+#![feature(async_await)]
+
+async fn make_boxed_object() -> Box<dyn Send> {
+    Box::new(()) as _
+}
+
+async fn await_object() {
+    let _ = make_boxed_object().await;
+}
+
+fn main() {}
diff --git a/src/test/ui/loops/loop-break-unsize.rs b/src/test/ui/loops/loop-break-unsize.rs
new file mode 100644
index 00000000000..974c63cea85
--- /dev/null
+++ b/src/test/ui/loops/loop-break-unsize.rs
@@ -0,0 +1,8 @@
+// Regression test for #62312
+// check-pass
+
+fn main() {
+    let _ = loop {
+        break Box::new(()) as Box<dyn Send>;
+    };
+}