]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_mir/transform/promote_consts.rs
Fix tidy
[rust.git] / src / librustc_mir / transform / promote_consts.rs
index 3090b63a7e9934c3952e5b10d62f3b213be5471c..fd5b6c2a32825328bb4f6d768c61329da830bc3a 100644 (file)
 //! initialization and can otherwise silence errors, if
 //! move analysis runs after promotion on broken MIR.
 
+use rustc::hir::def_id::DefId;
 use rustc::mir::*;
 use rustc::mir::visit::{PlaceContext, MutatingUseContext, MutVisitor, Visitor};
 use rustc::mir::traversal::ReversePostorder;
+use rustc::ty::subst::InternalSubsts;
 use rustc::ty::TyCtxt;
 use syntax_pos::Span;
 
@@ -293,17 +295,23 @@ fn promote_temp(&mut self, temp: Local) -> Local {
         new_temp
     }
 
-    fn promote_candidate(mut self, candidate: Candidate) {
+    fn promote_candidate(
+        mut self,
+        def_id: DefId,
+        candidate: Candidate,
+        next_promoted_id: usize,
+    ) -> Option<Body<'tcx>> {
         let mut operand = {
             let promoted = &mut self.promoted;
-            let promoted_id = Promoted::new(self.source.promoted.len());
-            let mut promoted_place = |ty, span| {
+            let promoted_id = Promoted::new(next_promoted_id);
+            let mut promoted_place = |ty, substs, span| {
                 promoted.span = span;
                 promoted.local_decls[RETURN_PLACE] = LocalDecl::new_return_place(ty, span);
                 Place {
                     base: PlaceBase::Static(box Static {
-                        kind: StaticKind::Promoted(promoted_id),
-                        ty
+                        kind: StaticKind::Promoted(promoted_id, substs),
+                        ty,
+                        def_id,
                     }),
                     projection: None,
                 }
@@ -319,7 +327,14 @@ fn promote_candidate(mut self, candidate: Candidate) {
                             let span = statement.source_info.span;
 
                             Operand::Move(Place {
-                                base: mem::replace(&mut place.base, promoted_place(ty, span).base),
+                                base: mem::replace(
+                                    &mut place.base,
+                                    promoted_place(
+                                        ty,
+                                        InternalSubsts::identity_for_item(self.tcx, def_id),
+                                        span,
+                                    ).base
+                                ),
                                 projection: None,
                             })
                         }
@@ -332,7 +347,16 @@ fn promote_candidate(mut self, candidate: Candidate) {
                         StatementKind::Assign(_, box Rvalue::Repeat(ref mut operand, _)) => {
                             let ty = operand.ty(local_decls, self.tcx);
                             let span = statement.source_info.span;
-                            mem::replace(operand, Operand::Copy(promoted_place(ty, span)))
+                            mem::replace(
+                                operand,
+                                Operand::Copy(
+                                    promoted_place(
+                                        ty,
+                                        InternalSubsts::identity_for_item(self.tcx, def_id),
+                                        span,
+                                    )
+                                )
+                            )
                         }
                         _ => bug!()
                     }
@@ -343,7 +367,12 @@ fn promote_candidate(mut self, candidate: Candidate) {
                         TerminatorKind::Call { ref mut args, .. } => {
                             let ty = args[index].ty(local_decls, self.tcx);
                             let span = terminator.source_info.span;
-                            let operand = Operand::Copy(promoted_place(ty, span));
+                            let operand =
+                                Operand::Copy(
+                                    promoted_place(
+                                        ty,
+                                        InternalSubsts::identity_for_item(self.tcx, def_id),
+                                        span));
                             mem::replace(&mut args[index], operand)
                         }
                         // We expected a `TerminatorKind::Call` for which we'd like to promote an
@@ -353,7 +382,7 @@ fn promote_candidate(mut self, candidate: Candidate) {
                         // a function requiring a constant argument and as that constant value
                         // providing a value whose computation contains another call to a function
                         // requiring a constant argument.
-                        TerminatorKind::Goto { .. } => return,
+                        TerminatorKind::Goto { .. } => return None,
                         _ => bug!()
                     }
                 }
@@ -368,7 +397,7 @@ fn promote_candidate(mut self, candidate: Candidate) {
 
         let span = self.promoted.span;
         self.assign(RETURN_PLACE, Rvalue::Use(operand), span);
-        self.source.promoted.push(self.promoted);
+        Some(self.promoted)
     }
 }
 
@@ -385,14 +414,17 @@ fn visit_local(&mut self,
 }
 
 pub fn promote_candidates<'tcx>(
+    def_id: DefId,
     body: &mut Body<'tcx>,
     tcx: TyCtxt<'tcx>,
     mut temps: IndexVec<Local, TempState>,
     candidates: Vec<Candidate>,
-) {
+) -> IndexVec<Promoted, Body<'tcx>> {
     // Visit candidates in reverse, in case they're nested.
     debug!("promote_candidates({:?})", candidates);
 
+    let mut promotions = IndexVec::new();
+
     for candidate in candidates.into_iter().rev() {
         match candidate {
             Candidate::Repeat(Location { block, statement_index }) |
@@ -426,7 +458,6 @@ pub fn promote_candidates<'tcx>(
                 // memory usage?
                 body.source_scopes.clone(),
                 body.source_scope_local_data.clone(),
-                IndexVec::new(),
                 None,
                 initial_locals,
                 IndexVec::new(),
@@ -440,7 +471,10 @@ pub fn promote_candidates<'tcx>(
             temps: &mut temps,
             keep_original: false
         };
-        promoter.promote_candidate(candidate);
+
+        if let Some(promoted) = promoter.promote_candidate(def_id, candidate, promotions.len()) {
+            promotions.push(promoted);
+        }
     }
 
     // Eliminate assignments to, and drops of promoted temps.
@@ -474,4 +508,6 @@ pub fn promote_candidates<'tcx>(
             _ => {}
         }
     }
+
+    promotions
 }