]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/build/expr/as_temp.rs
Rollup merge of #58873 - GuillaumeGomez:fix-auto-hide-method-doc, r=QuietMisdreavus
[rust.git] / src / librustc_mir / build / expr / as_temp.rs
1 //! See docs in build/expr/mod.rs
2
3 use crate::build::{BlockAnd, BlockAndExtension, Builder};
4 use crate::hair::*;
5 use rustc::middle::region;
6 use rustc::mir::*;
7
8 impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
9     /// Compile `expr` into a fresh temporary. This is used when building
10     /// up rvalues so as to freeze the value that will be consumed.
11     pub fn as_temp<M>(
12         &mut self,
13         block: BasicBlock,
14         temp_lifetime: Option<region::Scope>,
15         expr: M,
16         mutability: Mutability,
17     ) -> BlockAnd<Local>
18     where
19         M: Mirror<'tcx, Output = Expr<'tcx>>,
20     {
21         let expr = self.hir.mirror(expr);
22         self.expr_as_temp(block, temp_lifetime, expr, mutability)
23     }
24
25     fn expr_as_temp(
26         &mut self,
27         mut block: BasicBlock,
28         temp_lifetime: Option<region::Scope>,
29         expr: Expr<'tcx>,
30         mutability: Mutability,
31     ) -> BlockAnd<Local> {
32         debug!(
33             "expr_as_temp(block={:?}, temp_lifetime={:?}, expr={:?}, mutability={:?})",
34             block, temp_lifetime, expr, mutability
35         );
36         let this = self;
37
38         let expr_span = expr.span;
39         let source_info = this.source_info(expr_span);
40         if let ExprKind::Scope {
41             region_scope,
42             lint_level,
43             value,
44         } = expr.kind
45         {
46             return this.in_scope((region_scope, source_info), lint_level, block, |this| {
47                 this.as_temp(block, temp_lifetime, value, mutability)
48             });
49         }
50
51         let expr_ty = expr.ty;
52         let temp = {
53             let mut local_decl = LocalDecl::new_temp(expr_ty, expr_span);
54             if mutability == Mutability::Not {
55                 local_decl = local_decl.immutable();
56             }
57
58             debug!("creating temp {:?} with block_context: {:?}", local_decl, this.block_context);
59             // Find out whether this temp is being created within the
60             // tail expression of a block whose result is ignored.
61             if let Some(tail_info) = this.block_context.currently_in_block_tail() {
62                 local_decl = local_decl.block_tail(tail_info);
63             }
64             this.local_decls.push(local_decl)
65         };
66         if !expr_ty.is_never() {
67             this.cfg.push(
68                 block,
69                 Statement {
70                     source_info,
71                     kind: StatementKind::StorageLive(temp),
72                 },
73             );
74         }
75
76         unpack!(block = this.into(&Place::Base(PlaceBase::Local(temp)), block, expr));
77
78         // In constants, temp_lifetime is None for temporaries that live for the
79         // 'static lifetime. Thus we do not drop these temporaries and simply leak them.
80         // This is equivalent to what `let x = &foo();` does in functions. The temporary
81         // is lifted to their surrounding scope. In a function that means the temporary lives
82         // until just before the function returns. In constants that means it outlives the
83         // constant's initialization value computation. Anything outliving a constant
84         // must have the `'static` lifetime and live forever.
85         // Anything with a shorter lifetime (e.g the `&foo()` in `bar(&foo())` or anything
86         // within a block will keep the regular drops just like runtime code.
87         if let Some(temp_lifetime) = temp_lifetime {
88             this.schedule_drop_storage_and_value(
89                 expr_span,
90                 temp_lifetime,
91                 &Place::Base(PlaceBase::Local(temp)),
92                 expr_ty,
93             );
94         }
95
96         block.and(temp)
97     }
98 }