/// Construct the MIR for a given def-id.
Construct the MIR for a given def-id.
Construct the MIR for a given def - id .
pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'tcx> {
    let id = tcx.hir.as_local_node_id(def_id).unwrap();
    let unsupported = || {
        span_bug!(tcx.hir.span(id), "can't build MIR for {:?}", def_id);
    };
    // Figure out what primary body this item has.
    let body_id = match tcx.hir.get(id) {
        hir::map::NodeVariant(variant) =>
            return create_constructor_shim(tcx, id, &variant.node.data),
        hir::map::NodeStructCtor(ctor) =>
            return create_constructor_shim(tcx, id, ctor),
        _ => match tcx.hir.maybe_body_owned_by(id) {
            Some(body) => body,
            None => unsupported(),
        },
    };
    tcx.infer_ctxt().enter(|infcx| {
        let cx = Cx::new(&infcx, id);
        let mut mir = if cx.tables().tainted_by_errors {
            build::construct_error(cx, body_id)
        } else if let hir::BodyOwnerKind::Fn = cx.body_owner_kind {
            // fetch the fully liberated fn signature (that is, all bound
            // types/lifetimes replaced)
            let fn_hir_id = tcx.hir.node_to_hir_id(id);
            let fn_sig = cx.tables().liberated_fn_sigs()[fn_hir_id].clone();
            let ty = tcx.type_of(tcx.hir.local_def_id(id));
            let mut abi = fn_sig.abi;
            let implicit_argument = match ty.sty {
                ty::TyClosure(..) => {
                    // HACK(eddyb) Avoid having RustCall on closures,
                    // as it adds unnecessary (and wrong) auto-tupling.
                    abi = Abi::Rust;
                    Some(ArgInfo(liberated_closure_env_ty(tcx, id, body_id), None, None, None))
                }
                ty::TyGenerator(..) => {
                    let gen_ty = tcx.body_tables(body_id).node_id_to_type(fn_hir_id);
                    Some(ArgInfo(gen_ty, None, None, None))
                }
                _ => None,
            };
            // FIXME: safety in closures
            let safety = match fn_sig.unsafety {
                hir::Unsafety::Normal => Safety::Safe,
                hir::Unsafety::Unsafe => Safety::FnUnsafe,
            };
            let body = tcx.hir.body(body_id);
            let explicit_arguments =
                body.arguments
                    .iter()
                    .enumerate()
                    .map(|(index, arg)| {
                        let owner_id = tcx.hir.body_owner(body_id);
                        let opt_ty_info;
                        let self_arg;
                        if let Some(ref fn_decl) = tcx.hir.fn_decl(owner_id) {
                            let ty_hir_id = fn_decl.inputs[index].hir_id;
                            let ty_span = tcx.hir.span(tcx.hir.hir_to_node_id(ty_hir_id));
                            opt_ty_info = Some(ty_span);
                            self_arg = if index == 0 && fn_decl.has_implicit_self {
                                Some(ImplicitSelfBinding)
                            } else {
                                None
                            };
                        } else {
                            opt_ty_info = None;
                            self_arg = None;
                        }
                        ArgInfo(fn_sig.inputs()[index], opt_ty_info, Some(&*arg.pat), self_arg)
                    });
            let arguments = implicit_argument.into_iter().chain(explicit_arguments);
            let (yield_ty, return_ty) = if body.is_generator {
                let gen_sig = match ty.sty {
                    ty::TyGenerator(gen_def_id, gen_substs, ..) =>
                        gen_substs.sig(gen_def_id, tcx),
                    _ =>
                        span_bug!(tcx.hir.span(id), "generator w/o generator type: {:?}", ty),
                };
                (Some(gen_sig.yield_ty), gen_sig.return_ty)
            } else {
                (None, fn_sig.output())
            };
            build::construct_fn(cx, id, arguments, safety, abi,
                                return_ty, yield_ty, body)
        } else {
            build::construct_const(cx, body_id)
        };
        // Convert the Mir to global types.
        let mut globalizer = GlobalizeMir {
            tcx,
            span: mir.span
        };
        globalizer.visit_mir(&mut mir);
        let mir = unsafe {
            mem::transmute::<Mir, Mir<'tcx>>(mir)
        };
        mir_util::dump_mir(tcx, None, "mir_map", &0,
                           MirSource::item(def_id), &mir, |_, _| Ok(()) );
        mir
    })
}
pub fn mir_build < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , def_id : DefId ) -> Mir < ' tcx > { let id = tcx . hir . as_local_node_id ( def_id ) . unwrap ( ) ; let unsupported = | | { span_bug ! ( tcx hir span ( id ) " " def_id ) ; } ; // Figure out what primary body this item has. let body_id = match tcx . hir . get ( id ) { hir :: map :: NodeVariant ( variant ) => return create_constructor_shim ( tcx , id , & variant . node . data ) , hir :: map :: NodeStructCtor ( ctor ) => return create_constructor_shim ( tcx , id , ctor ) , _ => match tcx . hir . maybe_body_owned_by ( id ) { Some ( body ) => body , None => unsupported ( ) , } , } ; tcx . infer_ctxt ( ) . enter ( | infcx | { let cx = Cx :: new ( & infcx , id ) ; let mut mir = if cx . tables ( ) . tainted_by_errors { build :: construct_error ( cx , body_id ) } else if let hir :: BodyOwnerKind :: Fn = cx . body_owner_kind { // fetch the fully liberated fn signature (that is, all bound // types/lifetimes replaced) let fn_hir_id = tcx . hir . node_to_hir_id ( id ) ; let fn_sig = cx . tables ( ) . liberated_fn_sigs ( ) [ fn_hir_id ] . clone ( ) ; let ty = tcx . type_of ( tcx . hir . local_def_id ( id ) ) ; let mut abi = fn_sig . abi ; let implicit_argument = match ty . sty { ty :: TyClosure ( .. ) => { // HACK(eddyb) Avoid having RustCall on closures, // as it adds unnecessary (and wrong) auto-tupling. abi = Abi :: Rust ; Some ( ArgInfo ( liberated_closure_env_ty ( tcx , id , body_id ) , None , None , None ) ) } ty :: TyGenerator ( .. ) => { let gen_ty = tcx . body_tables ( body_id ) . node_id_to_type ( fn_hir_id ) ; Some ( ArgInfo ( gen_ty , None , None , None ) ) } _ => None , } ; // FIXME: safety in closures let safety = match fn_sig . unsafety { hir :: Unsafety :: Normal => Safety :: Safe , hir :: Unsafety :: Unsafe => Safety :: FnUnsafe , } ; let body = tcx . hir . body ( body_id ) ; let explicit_arguments = body . arguments . iter ( ) . enumerate ( ) . map ( | ( index , arg ) | { let owner_id = tcx . hir . body_owner ( body_id ) ; let opt_ty_info ; let self_arg ; if let Some ( ref fn_decl ) = tcx . hir . fn_decl ( owner_id ) { let ty_hir_id = fn_decl . inputs [ index ] . hir_id ; let ty_span = tcx . hir . span ( tcx . hir . hir_to_node_id ( ty_hir_id ) ) ; opt_ty_info = Some ( ty_span ) ; self_arg = if index == 0 && fn_decl . has_implicit_self { Some ( ImplicitSelfBinding ) } else { None } ; } else { opt_ty_info = None ; self_arg = None ; } ArgInfo ( fn_sig . inputs ( ) [ index ] , opt_ty_info , Some ( & * arg . pat ) , self_arg ) } ) ; let arguments = implicit_argument . into_iter ( ) . chain ( explicit_arguments ) ; let ( yield_ty , return_ty ) = if body . is_generator { let gen_sig = match ty . sty { ty :: TyGenerator ( gen_def_id , gen_substs , .. ) => gen_substs . sig ( gen_def_id , tcx ) , _ => span_bug ! ( tcx hir span ( id ) " " ty ) , } ; ( Some ( gen_sig . yield_ty ) , gen_sig . return_ty ) } else { ( None , fn_sig . output ( ) ) } ; build :: construct_fn ( cx , id , arguments , safety , abi , return_ty , yield_ty , body ) } else { build :: construct_const ( cx , body_id ) } ; // Convert the Mir to global types. let mut globalizer = GlobalizeMir { tcx , span : mir . span } ; globalizer . visit_mir ( & mut mir ) ; let mir = unsafe { mem :: transmute :: < Mir , Mir < ' tcx > > ( mir ) } ; mir_util :: dump_mir ( tcx , None , " " , & 0 , MirSource :: item ( def_id ) , & mir , | _ , _ | Ok ( ( ) ) ) ; mir } ) }
Construct the MIR for a given def-id.
Construct the MIR for a given def - id .
tcx
TyCtxt<'a, 'tcx, 'tcx>
def_id
DefId