1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
14 use rustc::mir::transform::MirSource;
16 use rustc::ty::maps::Providers;
18 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
23 use std::cell::RefCell;
26 pub fn provide(providers: &mut Providers) {
27 providers.mir_shims = make_shim;
30 fn make_shim<'a, 'tcx>(_tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
31 instance: ty::InstanceDef<'tcx>)
32 -> &'tcx RefCell<Mir<'tcx>>
35 ty::InstanceDef::Item(..) =>
36 bug!("item {:?} passed to make_shim", instance),
37 ty::InstanceDef::FnPtrShim(..) => unimplemented!()
41 fn local_decls_for_sig<'tcx>(sig: &ty::FnSig<'tcx>)
42 -> IndexVec<Local, LocalDecl<'tcx>>
44 iter::once(LocalDecl {
45 mutability: Mutability::Mut,
49 }).chain(sig.inputs().iter().map(|ity| LocalDecl {
50 mutability: Mutability::Not,
57 pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
59 fields: &[hir::StructField],
61 -> (Mir<'tcx>, MirSource)
64 let def_id = tcx.hir.local_def_id(ctor_id);
65 let sig = match tcx.item_type(def_id).sty {
66 ty::TyFnDef(_, _, fty) => tcx.no_late_bound_regions(&fty)
67 .expect("LBR in ADT constructor signature"),
68 _ => bug!("unexpected type for ctor {:?}", def_id)
70 let sig = tcx.erase_regions(&sig);
72 let (adt_def, substs) = match sig.output().sty {
73 ty::TyAdt(adt_def, substs) => (adt_def, substs),
74 _ => bug!("unexpected type for ADT ctor {:?}", sig.output())
77 debug!("build_ctor: def_id={:?} sig={:?} fields={:?}", def_id, sig, fields);
79 let local_decls = local_decls_for_sig(&sig);
81 let source_info = SourceInfo {
83 scope: ARGUMENT_VISIBILITY_SCOPE
86 let variant_no = if adt_def.is_enum() {
87 adt_def.variant_index_with_id(def_id)
92 // return = ADT(arg0, arg1, ...); return
93 let start_block = BasicBlockData {
94 statements: vec![Statement {
95 source_info: source_info,
96 kind: StatementKind::Assign(
97 Lvalue::Local(RETURN_POINTER),
99 AggregateKind::Adt(adt_def, variant_no, substs, None),
100 (1..sig.inputs().len()+1).map(|i| {
101 Operand::Consume(Lvalue::Local(Local::new(i)))
106 terminator: Some(Terminator {
107 source_info: source_info,
108 kind: TerminatorKind::Return,
114 IndexVec::from_elem_n(start_block, 1),
115 IndexVec::from_elem_n(
116 VisibilityScopeData { span: span, parent_scope: None }, 1
125 (mir, MirSource::Fn(ctor_id))