]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_mir/shim.rs
Rollup merge of #61750 - tmandry:fix-install, r=Mark-Simulacrum
[rust.git] / src / librustc_mir / shim.rs
index 087f8779b6916fb896a82e47525dba45bf040694..ea11901672a23369bb9fbad7ae73ffa899876b43 100644 (file)
@@ -1,6 +1,5 @@
 use rustc::hir;
 use rustc::hir::def_id::DefId;
-use rustc::infer;
 use rustc::mir::*;
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::layout::VariantIdx;
 };
 use crate::util::elaborate_drops::{self, DropElaborator, DropStyle, DropFlagMode};
 use crate::util::patch::MirPatch;
+use crate::util::expand_aggregate;
 
 pub fn provide(providers: &mut Providers<'_>) {
     providers.mir_shims = make_shim;
 }
 
-fn make_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                       instance: ty::InstanceDef<'tcx>)
-                       -> &'tcx Body<'tcx>
-{
+fn make_shim<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx Body<'tcx> {
     debug!("make_shim({:?})", instance);
 
     let mut result = match instance {
@@ -125,7 +122,7 @@ fn make_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     debug!("make_shim({:?}) = {:?}", instance, result);
 
-    tcx.alloc_mir(result)
+    tcx.arena.alloc(result)
 }
 
 #[derive(Copy, Clone, Debug, PartialEq)]
@@ -166,17 +163,17 @@ fn local_decls_for_sig<'tcx>(sig: &ty::FnSig<'tcx>, span: Span)
         .collect()
 }
 
-fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                             def_id: DefId,
-                             ty: Option<Ty<'tcx>>)
-                             -> Body<'tcx>
-{
+fn build_drop_shim<'tcx>(
+    tcx: TyCtxt<'tcx, 'tcx>,
+    def_id: DefId,
+    ty: Option<Ty<'tcx>>,
+) -> Body<'tcx> {
     debug!("build_drop_shim(def_id={:?}, ty={:?})", def_id, ty);
 
     // Check if this is a generator, if so, return the drop glue for it
     if let Some(&ty::TyS { sty: ty::Generator(gen_def_id, substs, _), .. }) = ty {
-        let mir = &**tcx.optimized_mir(gen_def_id).generator_drop.as_ref().unwrap();
-        return mir.subst(tcx, substs.substs);
+        let body = &**tcx.optimized_mir(gen_def_id).generator_drop.as_ref().unwrap();
+        return body.subst(tcx, substs.substs);
     }
 
     let substs = if let Some(ty) = ty {
@@ -202,7 +199,7 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     block(&mut blocks, TerminatorKind::Goto { target: return_block });
     block(&mut blocks, TerminatorKind::Return);
 
-    let mut mir = Body::new(
+    let mut body = Body::new(
         blocks,
         IndexVec::from_elem_n(
             SourceScopeData { span: span, parent_scope: None }, 1
@@ -223,7 +220,7 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         let dropee_ptr = Place::Base(PlaceBase::Local(Local::new(1+0)));
         if tcx.sess.opts.debugging_opts.mir_emit_retag {
             // Function arguments should be retagged, and we make this one raw.
-            mir.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
+            body.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
                 source_info,
                 kind: StatementKind::Retag(RetagKind::Raw, dropee_ptr.clone()),
             });
@@ -231,8 +228,8 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         let patch = {
             let param_env = tcx.param_env(def_id).with_reveal_all();
             let mut elaborator = DropShimElaborator {
-                mir: &mir,
-                patch: MirPatch::new(&mir),
+                body: &body,
+                patch: MirPatch::new(&body),
                 tcx,
                 param_env
             };
@@ -249,16 +246,16 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             );
             elaborator.patch
         };
-        patch.apply(&mut mir);
+        patch.apply(&mut body);
     }
 
-    mir
+    body
 }
 
 pub struct DropShimElaborator<'a, 'tcx: 'a> {
-    pub mir: &'a Body<'tcx>,
+    pub body: &'a Body<'tcx>,
     pub patch: MirPatch<'tcx>,
-    pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    pub tcx: TyCtxt<'tcx, 'tcx>,
     pub param_env: ty::ParamEnv<'tcx>,
 }
 
@@ -272,8 +269,10 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> {
     type Path = ();
 
     fn patch(&mut self) -> &mut MirPatch<'tcx> { &mut self.patch }
-    fn mir(&self) -> &'a Body<'tcx> { self.mir }
-    fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> { self.tcx }
+    fn body(&self) -> &'a Body<'tcx> { self.body }
+    fn tcx(&self) -> TyCtxt<'tcx, 'tcx> {
+        self.tcx
+        }
     fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env }
 
     fn drop_style(&self, _path: Self::Path, mode: DropFlagMode) -> DropStyle {
@@ -306,11 +305,7 @@ fn array_subpath(&self, _path: Self::Path, _index: u32, _size: u32) -> Option<Se
 }
 
 /// Builds a `Clone::clone` shim for `self_ty`. Here, `def_id` is `Clone::clone`.
-fn build_clone_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                              def_id: DefId,
-                              self_ty: Ty<'tcx>)
-                              -> Body<'tcx>
-{
+fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Body<'tcx> {
     debug!("build_clone_shim(def_id={:?})", def_id);
 
     let mut builder = CloneShimBuilder::new(tcx, def_id, self_ty);
@@ -340,8 +335,8 @@ fn build_clone_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     builder.into_mir()
 }
 
-struct CloneShimBuilder<'a, 'tcx: 'a> {
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+struct CloneShimBuilder<'tcx> {
+    tcx: TyCtxt<'tcx, 'tcx>,
     def_id: DefId,
     local_decls: IndexVec<Local, LocalDecl<'tcx>>,
     blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
@@ -349,10 +344,8 @@ struct CloneShimBuilder<'a, 'tcx: 'a> {
     sig: ty::FnSig<'tcx>,
 }
 
-impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
-    fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-           def_id: DefId,
-           self_ty: Ty<'tcx>) -> Self {
+impl CloneShimBuilder<'tcx> {
+    fn new(tcx: TyCtxt<'tcx, 'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Self {
         // we must subst the self_ty because it's
         // otherwise going to be TySelf and we can't index
         // or access fields of a Place of type TySelf.
@@ -691,13 +684,13 @@ fn tuple_like_shim<I>(&mut self, dest: Place<'tcx>,
 ///
 /// If `untuple_args` is a vec of types, the second argument of the
 /// function will be untupled as these types.
-fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                             def_id: DefId,
-                             rcvr_adjustment: Adjustment,
-                             call_kind: CallKind,
-                             untuple_args: Option<&[Ty<'tcx>]>)
-                             -> Body<'tcx>
-{
+fn build_call_shim<'tcx>(
+    tcx: TyCtxt<'tcx, 'tcx>,
+    def_id: DefId,
+    rcvr_adjustment: Adjustment,
+    call_kind: CallKind,
+    untuple_args: Option<&[Ty<'tcx>]>,
+) -> Body<'tcx> {
     debug!("build_call_shim(def_id={:?}, rcvr_adjustment={:?}, \
             call_kind={:?}, untuple_args={:?})",
            def_id, rcvr_adjustment, call_kind, untuple_args);
@@ -821,7 +814,7 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         block(&mut blocks, vec![], TerminatorKind::Resume, true);
     }
 
-    let mut mir = Body::new(
+    let mut body = Body::new(
         blocks,
         IndexVec::from_elem_n(
             SourceScopeData { span: span, parent_scope: None }, 1
@@ -837,34 +830,31 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         vec![],
     );
     if let Abi::RustCall = sig.abi {
-        mir.spread_arg = Some(Local::new(sig.inputs().len()));
+        body.spread_arg = Some(Local::new(sig.inputs().len()));
     }
-    mir
+    body
 }
 
-pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
-                                      ctor_id: hir::HirId,
-                                      fields: &[hir::StructField],
-                                      span: Span)
-                                      -> Body<'tcx>
-{
-    let tcx = infcx.tcx;
-    let gcx = tcx.global_tcx();
-    let def_id = tcx.hir().local_def_id_from_hir_id(ctor_id);
-    let param_env = gcx.param_env(def_id);
+pub fn build_adt_ctor<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, ctor_id: DefId) -> &'tcx Body<'tcx> {
+    debug_assert!(tcx.is_constructor(ctor_id));
+
+    let span = tcx.hir().span_if_local(ctor_id)
+        .unwrap_or_else(|| bug!("no span for ctor {:?}", ctor_id));
+
+    let param_env = tcx.param_env(ctor_id);
 
     // Normalize the sig.
-    let sig = gcx.fn_sig(def_id)
+    let sig = tcx.fn_sig(ctor_id)
         .no_bound_vars()
         .expect("LBR in ADT constructor signature");
-    let sig = gcx.normalize_erasing_regions(param_env, sig);
+    let sig = tcx.normalize_erasing_regions(param_env, sig);
 
     let (adt_def, substs) = match sig.output().sty {
         ty::Adt(adt_def, substs) => (adt_def, substs),
         _ => bug!("unexpected type for ADT ctor {:?}", sig.output())
     };
 
-    debug!("build_ctor: def_id={:?} sig={:?} fields={:?}", def_id, sig, fields);
+    debug!("build_ctor: ctor_id={:?} sig={:?}", ctor_id, sig);
 
     let local_decls = local_decls_for_sig(&sig, span);
 
@@ -873,26 +863,37 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
         scope: OUTERMOST_SOURCE_SCOPE
     };
 
-    let variant_no = if adt_def.is_enum() {
-        adt_def.variant_index_with_ctor_id(def_id)
+    let variant_index = if adt_def.is_enum() {
+        adt_def.variant_index_with_ctor_id(ctor_id)
     } else {
         VariantIdx::new(0)
     };
 
-    // return = ADT(arg0, arg1, ...); return
+    // Generate the following MIR:
+    //
+    // (return as Variant).field0 = arg0;
+    // (return as Variant).field1 = arg1;
+    //
+    // return;
+    debug!("build_ctor: variant_index={:?}", variant_index);
+
+    let statements = expand_aggregate(
+        Place::RETURN_PLACE,
+        adt_def
+            .variants[variant_index]
+            .fields
+            .iter()
+            .enumerate()
+            .map(|(idx, field_def)| (
+                Operand::Move(Place::Base(PlaceBase::Local(Local::new(idx + 1)))),
+                field_def.ty(tcx, substs),
+            )),
+        AggregateKind::Adt(adt_def, variant_index, substs, None, None),
+        source_info,
+    ).collect();
+
     let start_block = BasicBlockData {
-        statements: vec![Statement {
-            source_info,
-            kind: StatementKind::Assign(
-                Place::RETURN_PLACE,
-                box Rvalue::Aggregate(
-                    box AggregateKind::Adt(adt_def, variant_no, substs, None, None),
-                    (1..sig.inputs().len()+1).map(|i| {
-                        Operand::Move(Place::Base(PlaceBase::Local(Local::new(i))))
-                    }).collect()
-                )
-            )
-        }],
+        statements,
         terminator: Some(Terminator {
             source_info,
             kind: TerminatorKind::Return,
@@ -900,7 +901,7 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
         is_cleanup: false
     };
 
-    Body::new(
+    let body = Body::new(
         IndexVec::from_elem_n(start_block, 1),
         IndexVec::from_elem_n(
             SourceScopeData { span: span, parent_scope: None }, 1
@@ -914,5 +915,17 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
         vec![],
         span,
         vec![],
-    )
+    );
+
+    crate::util::dump_mir(
+        tcx,
+        None,
+        "mir_map",
+        &0,
+        crate::transform::MirSource::item(ctor_id),
+        &body,
+        |_, _| Ok(()),
+    );
+
+    tcx.arena.alloc(body)
 }