]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_mir/transform/const_prop.rs
Move def_id out add substsref
[rust.git] / src / librustc_mir / transform / const_prop.rs
index c3c432d606644ed77a4a3bf53ce98c0b749313fa..b6146b6b7227df927f66e5b06b1437b33d612fa3 100644 (file)
@@ -8,7 +8,7 @@
     AggregateKind, Constant, Location, Place, PlaceBase, Body, Operand, Rvalue,
     Local, NullOp, UnOp, StatementKind, Statement, LocalKind, Static, StaticKind,
     TerminatorKind, Terminator,  ClearCrossCrate, SourceInfo, BinOp, ProjectionElem,
-    SourceScope, SourceScopeLocalData, LocalDecl, Promoted,
+    SourceScope, SourceScopeLocalData, LocalDecl,
 };
 use rustc::mir::visit::{
     Visitor, PlaceContext, MutatingUseContext, MutVisitor, NonMutatingUseContext,
@@ -19,7 +19,7 @@
 use rustc::ty::subst::InternalSubsts;
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc::ty::layout::{
-    LayoutOf, TyLayout, LayoutError, HasTyCtxt, TargetDataLayout, HasDataLayout, Size,
+    LayoutOf, TyLayout, LayoutError, HasTyCtxt, TargetDataLayout, HasDataLayout,
 };
 
 use crate::interpret::{
     ImmTy, MemoryKind, StackPopCleanup, LocalValue, LocalState,
 };
 use crate::const_eval::{
-    CompileTimeInterpreter, error_to_const_error, eval_promoted, mk_eval_cx,
+    CompileTimeInterpreter, error_to_const_error, mk_eval_cx,
 };
 use crate::transform::{MirPass, MirSource};
 
 pub struct ConstProp;
 
-impl MirPass for ConstProp {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for ConstProp {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) {
         // will be evaluated by miri and produce its errors there
         if source.promoted.is_some() {
             return;
@@ -64,17 +64,12 @@ fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut
             &mut body.source_scope_local_data,
             ClearCrossCrate::Clear
         );
-        let promoted = std::mem::replace(
-            &mut body.promoted,
-            IndexVec::new()
-        );
 
         let dummy_body =
             &Body::new(
                 body.basic_blocks().clone(),
                 Default::default(),
                 ClearCrossCrate::Clear,
-                Default::default(),
                 None,
                 body.local_decls.clone(),
                 Default::default(),
@@ -92,22 +87,17 @@ fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut
             body,
             dummy_body,
             source_scope_local_data,
-            promoted,
             tcx,
             source
         );
         optimization_finder.visit_body(body);
 
         // put back the data we stole from `mir`
-        let (source_scope_local_data, promoted) = optimization_finder.release_stolen_data();
+        let source_scope_local_data = optimization_finder.release_stolen_data();
         std::mem::replace(
             &mut body.source_scope_local_data,
             source_scope_local_data
         );
-        std::mem::replace(
-            &mut body.promoted,
-            promoted
-        );
 
         trace!("ConstProp done for {:?}", source.def_id());
     }
@@ -124,7 +114,6 @@ struct ConstPropagator<'mir, 'tcx> {
     param_env: ParamEnv<'tcx>,
     source_scope_local_data: ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>>,
     local_decls: IndexVec<Local, LocalDecl<'tcx>>,
-    promoted: IndexVec<Promoted, Body<'tcx>>,
 }
 
 impl<'mir, 'tcx> LayoutOf for ConstPropagator<'mir, 'tcx> {
@@ -155,7 +144,6 @@ fn new(
         body: &Body<'tcx>,
         dummy_body: &'mir Body<'tcx>,
         source_scope_local_data: ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>>,
-        promoted: IndexVec<Promoted, Body<'tcx>>,
         tcx: TyCtxt<'tcx>,
         source: MirSource<'tcx>,
     ) -> ConstPropagator<'mir, 'tcx> {
@@ -184,17 +172,11 @@ fn new(
             source_scope_local_data,
             //FIXME(wesleywiser) we can't steal this because `Visitor::super_visit_body()` needs it
             local_decls: body.local_decls.clone(),
-            promoted,
         }
     }
 
-    fn release_stolen_data(
-        self,
-    ) -> (
-        ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>>,
-        IndexVec<Promoted, Body<'tcx>>,
-    ) {
-        (self.source_scope_local_data, self.promoted)
+    fn release_stolen_data(self) -> ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>> {
+        self.source_scope_local_data
     }
 
     fn get_const(&self, local: Local) -> Option<Const<'tcx>> {
@@ -303,7 +285,7 @@ fn eval_place(&mut self, place: &Place<'tcx>, source_info: SourceInfo) -> Option
         place.iterate(|place_base, place_projection| {
             let mut eval = match place_base {
                 PlaceBase::Local(loc) => self.get_const(*loc).clone()?,
-                PlaceBase::Static(box Static {kind: StaticKind::Promoted(promoted), ..}) => {
+                PlaceBase::Static(box Static {kind: StaticKind::Promoted(promoted, _), ..}) => {
                     let generics = self.tcx.generics_of(self.source.def_id());
                     if generics.requires_monomorphization(self.tcx) {
                         // FIXME: can't handle code with generics
@@ -315,11 +297,8 @@ fn eval_place(&mut self, place: &Place<'tcx>, source_info: SourceInfo) -> Option
                         instance,
                         promoted: Some(*promoted),
                     };
-                    // cannot use `const_eval` here, because that would require having the MIR
-                    // for the current function available, but we're producing said MIR right now
                     let res = self.use_ecx(source_info, |this| {
-                        let body = &this.promoted[*promoted];
-                        eval_promoted(this.tcx, cid, body, this.param_env)
+                        this.ecx.const_eval_raw(cid)
                     })?;
                     trace!("evaluated promoted {:?} to {:?}", promoted, res);
                     res.into()
@@ -396,17 +375,10 @@ fn const_prop(
                 if let ty::Slice(_) = mplace.layout.ty.sty {
                     let len = mplace.meta.unwrap().to_usize(&self.ecx).unwrap();
 
-                    Some(ImmTy {
-                        imm: Immediate::Scalar(
-                            Scalar::from_uint(
-                                len,
-                                Size::from_bits(
-                                    self.tcx.sess.target.usize_ty.bit_width().unwrap() as u64
-                                )
-                            ).into(),
-                        ),
-                        layout: self.tcx.layout_of(self.param_env.and(self.tcx.types.usize)).ok()?,
-                    }.into())
+                    Some(ImmTy::from_uint(
+                        len,
+                        self.tcx.layout_of(self.param_env.and(self.tcx.types.usize)).ok()?,
+                    ).into())
                 } else {
                     trace!("not slice: {:?}", mplace.layout.ty.sty);
                     None
@@ -414,12 +386,10 @@ fn const_prop(
             },
             Rvalue::NullaryOp(NullOp::SizeOf, ty) => {
                 type_size_of(self.tcx, self.param_env, ty).and_then(|n| Some(
-                    ImmTy {
-                        imm: Immediate::Scalar(
-                            Scalar::from_uint(n, self.tcx.data_layout.pointer_size).into()
-                        ),
-                        layout: self.tcx.layout_of(self.param_env.and(self.tcx.types.usize)).ok()?,
-                    }.into()
+                    ImmTy::from_uint(
+                        n,
+                        self.tcx.layout_of(self.param_env.and(self.tcx.types.usize)).ok()?,
+                    ).into()
                 ))
             }
             Rvalue::UnaryOp(op, ref arg) => {
@@ -452,11 +422,7 @@ fn const_prop(
                     // Now run the actual operation.
                     this.ecx.unary_op(op, prim)
                 })?;
-                let res = ImmTy {
-                    imm: Immediate::Scalar(val.into()),
-                    layout: place_layout,
-                };
-                Some(res.into())
+                Some(val.into())
             }
             Rvalue::CheckedBinaryOp(op, ref left, ref right) |
             Rvalue::BinaryOp(op, ref left, ref right) => {
@@ -510,8 +476,8 @@ fn const_prop(
                     this.ecx.read_immediate(left)
                 })?;
                 trace!("const evaluating {:?} for {:?} and {:?}", op, left, right);
-                let (val, overflow) = self.use_ecx(source_info, |this| {
-                    this.ecx.binary_op(op, l, r)
+                let (val, overflow, _ty) = self.use_ecx(source_info, |this| {
+                    this.ecx.overflowing_binary_op(op, l, r)
                 })?;
                 let val = if let Rvalue::CheckedBinaryOp(..) = *rvalue {
                     Immediate::ScalarPair(