about summary refs log tree commit diff
path: root/compiler/rustc_mir_build/src/build/expr
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_mir_build/src/build/expr')
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_operand.rs23
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_place.rs3
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs14
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_temp.rs21
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs18
-rw-r--r--compiler/rustc_mir_build/src/build/expr/stmt.rs13
6 files changed, 57 insertions, 35 deletions
diff --git a/compiler/rustc_mir_build/src/build/expr/as_operand.rs b/compiler/rustc_mir_build/src/build/expr/as_operand.rs
index 159959d4f1f..0cab853196b 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_operand.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs
@@ -1,6 +1,5 @@
 //! See docs in build/expr/mod.rs
 
-use rustc_middle::middle::region;
 use rustc_middle::mir::*;
 use rustc_middle::thir::*;
 use tracing::{debug, instrument};
@@ -9,6 +8,12 @@ use crate::build::expr::category::Category;
 use crate::build::{BlockAnd, BlockAndExtension, Builder, NeedsTemporary};
 
 impl<'a, 'tcx> Builder<'a, 'tcx> {
+    /// Construct a temporary lifetime restricted to just the local scope
+    pub(crate) fn local_temp_lifetime(&self) -> TempLifetime {
+        let local_scope = self.local_scope();
+        TempLifetime { temp_lifetime: Some(local_scope), backwards_incompatible: None }
+    }
+
     /// Returns an operand suitable for use until the end of the current
     /// scope expression.
     ///
@@ -21,8 +26,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         block: BasicBlock,
         expr_id: ExprId,
     ) -> BlockAnd<Operand<'tcx>> {
-        let local_scope = self.local_scope();
-        self.as_operand(block, Some(local_scope), expr_id, LocalInfo::Boring, NeedsTemporary::Maybe)
+        self.as_operand(
+            block,
+            self.local_temp_lifetime(),
+            expr_id,
+            LocalInfo::Boring,
+            NeedsTemporary::Maybe,
+        )
     }
 
     /// Returns an operand suitable for use until the end of the current scope expression and
@@ -80,8 +90,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         block: BasicBlock,
         expr: ExprId,
     ) -> BlockAnd<Operand<'tcx>> {
-        let local_scope = self.local_scope();
-        self.as_call_operand(block, Some(local_scope), expr)
+        self.as_call_operand(block, self.local_temp_lifetime(), expr)
     }
 
     /// Compile `expr` into a value that can be used as an operand.
@@ -102,7 +111,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     pub(crate) fn as_operand(
         &mut self,
         mut block: BasicBlock,
-        scope: Option<region::Scope>,
+        scope: TempLifetime,
         expr_id: ExprId,
         local_info: LocalInfo<'tcx>,
         needs_temporary: NeedsTemporary,
@@ -146,7 +155,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     pub(crate) fn as_call_operand(
         &mut self,
         mut block: BasicBlock,
-        scope: Option<region::Scope>,
+        scope: TempLifetime,
         expr_id: ExprId,
     ) -> BlockAnd<Operand<'tcx>> {
         let this = self;
diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs
index 9f6e0735b48..6ce88cdc39d 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
@@ -6,7 +6,6 @@ use std::iter;
 use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx};
 use rustc_hir::def_id::LocalDefId;
 use rustc_middle::hir::place::{Projection as HirProjection, ProjectionKind as HirProjectionKind};
-use rustc_middle::middle::region;
 use rustc_middle::mir::AssertKind::BoundsCheck;
 use rustc_middle::mir::*;
 use rustc_middle::thir::*;
@@ -598,7 +597,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         index: ExprId,
         mutability: Mutability,
         fake_borrow_temps: Option<&mut Vec<Local>>,
-        temp_lifetime: Option<region::Scope>,
+        temp_lifetime: TempLifetime,
         expr_span: Span,
         source_info: SourceInfo,
     ) -> BlockAnd<PlaceBuilder<'tcx>> {
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index a3fee38908b..3f89e337781 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -33,14 +33,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         expr_id: ExprId,
     ) -> BlockAnd<Rvalue<'tcx>> {
         let local_scope = self.local_scope();
-        self.as_rvalue(block, Some(local_scope), expr_id)
+        self.as_rvalue(
+            block,
+            TempLifetime { temp_lifetime: Some(local_scope), backwards_incompatible: None },
+            expr_id,
+        )
     }
 
     /// Compile `expr`, yielding an rvalue.
     pub(crate) fn as_rvalue(
         &mut self,
         mut block: BasicBlock,
-        scope: Option<region::Scope>,
+        scope: TempLifetime,
         expr_id: ExprId,
     ) -> BlockAnd<Rvalue<'tcx>> {
         let this = self;
@@ -171,7 +175,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     source_info,
                     kind: StatementKind::StorageLive(result),
                 });
-                if let Some(scope) = scope {
+                if let Some(scope) = scope.temp_lifetime {
                     // schedule a shallow free of that memory, lest we unwind:
                     this.schedule_drop_storage_and_value(expr_span, scope, result);
                 }
@@ -445,7 +449,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                                         block = this.limit_capture_mutability(
                                             upvar_expr.span,
                                             upvar_expr.ty,
-                                            scope,
+                                            scope.temp_lifetime,
                                             block,
                                             arg,
                                         )
@@ -705,7 +709,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         &mut self,
         mut block: BasicBlock,
         value: ExprId,
-        scope: Option<region::Scope>,
+        scope: TempLifetime,
         outer_source_info: SourceInfo,
     ) -> BlockAnd<Rvalue<'tcx>> {
         let this = self;
diff --git a/compiler/rustc_mir_build/src/build/expr/as_temp.rs b/compiler/rustc_mir_build/src/build/expr/as_temp.rs
index b8b5e4634ed..466f67b1ba4 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_temp.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_temp.rs
@@ -2,7 +2,6 @@
 
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_hir::HirId;
-use rustc_middle::middle::region;
 use rustc_middle::middle::region::{Scope, ScopeData};
 use rustc_middle::mir::*;
 use rustc_middle::thir::*;
@@ -17,7 +16,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     pub(crate) fn as_temp(
         &mut self,
         block: BasicBlock,
-        temp_lifetime: Option<region::Scope>,
+        temp_lifetime: TempLifetime,
         expr_id: ExprId,
         mutability: Mutability,
     ) -> BlockAnd<Local> {
@@ -31,7 +30,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     fn as_temp_inner(
         &mut self,
         mut block: BasicBlock,
-        temp_lifetime: Option<region::Scope>,
+        temp_lifetime: TempLifetime,
         expr_id: ExprId,
         mutability: Mutability,
     ) -> BlockAnd<Local> {
@@ -47,8 +46,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
 
         let expr_ty = expr.ty;
-        let deduplicate_temps =
-            this.fixed_temps_scope.is_some() && this.fixed_temps_scope == temp_lifetime;
+        let deduplicate_temps = this.fixed_temps_scope.is_some()
+            && this.fixed_temps_scope == temp_lifetime.temp_lifetime;
         let temp = if deduplicate_temps && let Some(temp_index) = this.fixed_temps.get(&expr_id) {
             *temp_index
         } else {
@@ -76,7 +75,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     LocalInfo::BlockTailTemp(tail_info)
                 }
 
-                _ if let Some(Scope { data: ScopeData::IfThenRescope, id }) = temp_lifetime => {
+                _ if let Some(Scope { data: ScopeData::IfThenRescope, id }) =
+                    temp_lifetime.temp_lifetime =>
+                {
                     LocalInfo::IfThenRescopeTemp {
                         if_then: HirId { owner: this.hir_id.owner, local_id: id },
                     }
@@ -117,7 +118,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 // Anything with a shorter lifetime (e.g the `&foo()` in
                 // `bar(&foo())` or anything within a block will keep the
                 // regular drops just like runtime code.
-                if let Some(temp_lifetime) = temp_lifetime {
+                if let Some(temp_lifetime) = temp_lifetime.temp_lifetime {
                     this.schedule_drop(expr_span, temp_lifetime, temp, DropKind::Storage);
                 }
             }
@@ -125,10 +126,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
         block = this.expr_into_dest(temp_place, block, expr_id).into_block();
 
-        if let Some(temp_lifetime) = temp_lifetime {
+        if let Some(temp_lifetime) = temp_lifetime.temp_lifetime {
             this.schedule_drop(expr_span, temp_lifetime, temp, DropKind::Value);
         }
 
+        if let Some(backwards_incompatible) = temp_lifetime.backwards_incompatible {
+            this.schedule_backwards_incompatible_drop(expr_span, backwards_incompatible, temp);
+        }
+
         block.and(temp)
     }
 }
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index 0dec56d21ae..bebb44faba6 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -139,7 +139,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 // (#66975) Source could be a const of type `!`, so has to
                 // exist in the generated MIR.
                 unpack!(
-                    block = this.as_temp(block, Some(this.local_scope()), source, Mutability::Mut)
+                    block =
+                        this.as_temp(block, this.local_temp_lifetime(), source, Mutability::Mut)
                 );
 
                 // This is an optimization. If the expression was a call then we already have an
@@ -321,7 +322,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 let is_union = adt_def.is_union();
                 let active_field_index = is_union.then(|| fields[0].name);
 
-                let scope = this.local_scope();
+                let scope = this.local_temp_lifetime();
 
                 // first process the set of fields that were provided
                 // (evaluating them in order given by user)
@@ -333,7 +334,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                             unpack!(
                                 block = this.as_operand(
                                     block,
-                                    Some(scope),
+                                    scope,
                                     f.expr,
                                     LocalInfo::AggregateTemp,
                                     NeedsTemporary::Maybe,
@@ -548,15 +549,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
 
             ExprKind::Yield { value } => {
-                let scope = this.local_scope();
+                let scope = this.local_temp_lifetime();
                 let value = unpack!(
-                    block = this.as_operand(
-                        block,
-                        Some(scope),
-                        value,
-                        LocalInfo::Boring,
-                        NeedsTemporary::No
-                    )
+                    block =
+                        this.as_operand(block, scope, value, LocalInfo::Boring, NeedsTemporary::No)
                 );
                 let resume = this.cfg.start_new_block();
                 this.cfg.terminate(block, source_info, TerminatorKind::Yield {
diff --git a/compiler/rustc_mir_build/src/build/expr/stmt.rs b/compiler/rustc_mir_build/src/build/expr/stmt.rs
index 02ca12028d3..15ee6dd014c 100644
--- a/compiler/rustc_mir_build/src/build/expr/stmt.rs
+++ b/compiler/rustc_mir_build/src/build/expr/stmt.rs
@@ -172,8 +172,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     None
                 };
 
-                let temp =
-                    unpack!(block = this.as_temp(block, statement_scope, expr_id, Mutability::Not));
+                let temp = unpack!(
+                    block = this.as_temp(
+                        block,
+                        TempLifetime {
+                            temp_lifetime: statement_scope,
+                            backwards_incompatible: None
+                        },
+                        expr_id,
+                        Mutability::Not
+                    )
+                );
 
                 if let Some(span) = adjusted_span {
                     this.local_decls[temp].source_info.span = span;