Skip to content

Commit 69c8f9d

Browse files
committed
move build_mir into build directory
1 parent c2cfdbb commit 69c8f9d

File tree

3 files changed

+217
-224
lines changed

3 files changed

+217
-224
lines changed

src/librustc_mir/build/mod.rs

Lines changed: 213 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,223 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
12+
use build;
1113
use hair::cx::Cx;
1214
use hair::Pattern;
13-
15+
use rustc::hir;
16+
use rustc::hir::def_id::DefId;
1417
use rustc::middle::region::{CodeExtent, CodeExtentData};
15-
use rustc::ty::{self, Ty};
1618
use rustc::mir::*;
19+
use rustc::mir::transform::MirSource;
20+
use rustc::mir::visit::MutVisitor;
21+
use rustc::traits::Reveal;
22+
use rustc::ty::{self, Ty, TyCtxt};
23+
use rustc::ty::steal::Steal;
24+
use rustc::ty::subst::Substs;
1725
use rustc::util::nodemap::NodeMap;
18-
use rustc::hir;
26+
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
27+
use shim;
28+
use std::mem;
29+
use std::u32;
1930
use syntax::abi::Abi;
2031
use syntax::ast;
2132
use syntax::symbol::keywords;
2233
use syntax_pos::Span;
34+
use util as mir_util;
2335

24-
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
36+
pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Steal<Mir<'tcx>> {
37+
let id = tcx.hir.as_local_node_id(def_id).unwrap();
38+
let unsupported = || {
39+
span_bug!(tcx.hir.span(id), "can't build MIR for {:?}", def_id);
40+
};
2541

26-
use std::u32;
42+
// Figure out what primary body this item has.
43+
let body_id = match tcx.hir.get(id) {
44+
hir::map::NodeItem(item) => {
45+
match item.node {
46+
hir::ItemConst(_, body) |
47+
hir::ItemStatic(_, _, body) |
48+
hir::ItemFn(.., body) => body,
49+
_ => unsupported()
50+
}
51+
}
52+
hir::map::NodeTraitItem(item) => {
53+
match item.node {
54+
hir::TraitItemKind::Const(_, Some(body)) |
55+
hir::TraitItemKind::Method(_,
56+
hir::TraitMethod::Provided(body)) => body,
57+
_ => unsupported()
58+
}
59+
}
60+
hir::map::NodeImplItem(item) => {
61+
match item.node {
62+
hir::ImplItemKind::Const(_, body) |
63+
hir::ImplItemKind::Method(_, body) => body,
64+
_ => unsupported()
65+
}
66+
}
67+
hir::map::NodeExpr(expr) => {
68+
// FIXME(eddyb) Closures should have separate
69+
// function definition IDs and expression IDs.
70+
// Type-checking should not let closures get
71+
// this far in a constant position.
72+
// Assume that everything other than closures
73+
// is a constant "initializer" expression.
74+
match expr.node {
75+
hir::ExprClosure(_, _, body, _) => body,
76+
_ => hir::BodyId { node_id: expr.id }
77+
}
78+
}
79+
hir::map::NodeVariant(variant) =>
80+
return create_constructor_shim(tcx, id, &variant.node.data),
81+
hir::map::NodeStructCtor(ctor) =>
82+
return create_constructor_shim(tcx, id, ctor),
83+
_ => unsupported()
84+
};
85+
86+
let src = MirSource::from_node(tcx, id);
87+
tcx.infer_ctxt(body_id, Reveal::UserFacing).enter(|infcx| {
88+
let cx = Cx::new(&infcx, src);
89+
let mut mir = if cx.tables().tainted_by_errors {
90+
build::construct_error(cx, body_id)
91+
} else if let MirSource::Fn(id) = src {
92+
// fetch the fully liberated fn signature (that is, all bound
93+
// types/lifetimes replaced)
94+
let fn_sig = cx.tables().liberated_fn_sigs[&id].clone();
95+
96+
let ty = tcx.type_of(tcx.hir.local_def_id(id));
97+
let mut abi = fn_sig.abi;
98+
let implicit_argument = if let ty::TyClosure(..) = ty.sty {
99+
// HACK(eddyb) Avoid having RustCall on closures,
100+
// as it adds unnecessary (and wrong) auto-tupling.
101+
abi = Abi::Rust;
102+
Some((closure_self_ty(tcx, id, body_id), None))
103+
} else {
104+
None
105+
};
106+
107+
let body = tcx.hir.body(body_id);
108+
let explicit_arguments =
109+
body.arguments
110+
.iter()
111+
.enumerate()
112+
.map(|(index, arg)| {
113+
(fn_sig.inputs()[index], Some(&*arg.pat))
114+
});
115+
116+
let arguments = implicit_argument.into_iter().chain(explicit_arguments);
117+
build::construct_fn(cx, id, arguments, abi, fn_sig.output(), body)
118+
} else {
119+
build::construct_const(cx, body_id)
120+
};
121+
122+
// Convert the Mir to global types.
123+
let mut globalizer = GlobalizeMir {
124+
tcx: tcx,
125+
span: mir.span
126+
};
127+
globalizer.visit_mir(&mut mir);
128+
let mir = unsafe {
129+
mem::transmute::<Mir, Mir<'tcx>>(mir)
130+
};
131+
132+
mir_util::dump_mir(tcx, None, "mir_map", &0, src, &mir);
133+
134+
tcx.alloc_steal_mir(mir)
135+
})
136+
}
137+
138+
/// A pass to lift all the types and substitutions in a Mir
139+
/// to the global tcx. Sadly, we don't have a "folder" that
140+
/// can change 'tcx so we have to transmute afterwards.
141+
struct GlobalizeMir<'a, 'gcx: 'a> {
142+
tcx: TyCtxt<'a, 'gcx, 'gcx>,
143+
span: Span
144+
}
145+
146+
impl<'a, 'gcx: 'tcx, 'tcx> MutVisitor<'tcx> for GlobalizeMir<'a, 'gcx> {
147+
fn visit_ty(&mut self, ty: &mut Ty<'tcx>) {
148+
if let Some(lifted) = self.tcx.lift(ty) {
149+
*ty = lifted;
150+
} else {
151+
span_bug!(self.span,
152+
"found type `{:?}` with inference types/regions in MIR",
153+
ty);
154+
}
155+
}
156+
157+
fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>) {
158+
if let Some(lifted) = self.tcx.lift(substs) {
159+
*substs = lifted;
160+
} else {
161+
span_bug!(self.span,
162+
"found substs `{:?}` with inference types/regions in MIR",
163+
substs);
164+
}
165+
}
166+
}
167+
168+
fn create_constructor_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
169+
ctor_id: ast::NodeId,
170+
v: &'tcx hir::VariantData)
171+
-> &'tcx Steal<Mir<'tcx>>
172+
{
173+
let span = tcx.hir.span(ctor_id);
174+
if let hir::VariantData::Tuple(ref fields, ctor_id) = *v {
175+
let pe = ty::ParameterEnvironment::for_item(tcx, ctor_id);
176+
tcx.infer_ctxt(pe, Reveal::UserFacing).enter(|infcx| {
177+
let (mut mir, src) =
178+
shim::build_adt_ctor(&infcx, ctor_id, fields, span);
179+
180+
// Convert the Mir to global types.
181+
let tcx = infcx.tcx.global_tcx();
182+
let mut globalizer = GlobalizeMir {
183+
tcx: tcx,
184+
span: mir.span
185+
};
186+
globalizer.visit_mir(&mut mir);
187+
let mir = unsafe {
188+
mem::transmute::<Mir, Mir<'tcx>>(mir)
189+
};
190+
191+
mir_util::dump_mir(tcx, None, "mir_map", &0, src, &mir);
192+
193+
tcx.alloc_steal_mir(mir)
194+
})
195+
} else {
196+
span_bug!(span, "attempting to create MIR for non-tuple variant {:?}", v);
197+
}
198+
}
199+
200+
///////////////////////////////////////////////////////////////////////////
201+
// BuildMir -- walks a crate, looking for fn items and methods to build MIR from
202+
203+
fn closure_self_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
204+
closure_expr_id: ast::NodeId,
205+
body_id: hir::BodyId)
206+
-> Ty<'tcx> {
207+
let closure_ty = tcx.body_tables(body_id).node_id_to_type(closure_expr_id);
208+
209+
let region = ty::ReFree(ty::FreeRegion {
210+
scope: Some(tcx.item_extent(body_id.node_id)),
211+
bound_region: ty::BoundRegion::BrEnv,
212+
});
213+
let region = tcx.mk_region(region);
214+
215+
match tcx.closure_kind(tcx.hir.local_def_id(closure_expr_id)) {
216+
ty::ClosureKind::Fn =>
217+
tcx.mk_ref(region,
218+
ty::TypeAndMut { ty: closure_ty,
219+
mutbl: hir::MutImmutable }),
220+
ty::ClosureKind::FnMut =>
221+
tcx.mk_ref(region,
222+
ty::TypeAndMut { ty: closure_ty,
223+
mutbl: hir::MutMutable }),
224+
ty::ClosureKind::FnOnce =>
225+
closure_ty
226+
}
227+
}
27228

28229
struct Builder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
29230
hir: Cx<'a, 'gcx, 'tcx>,
@@ -121,13 +322,13 @@ macro_rules! unpack {
121322
///////////////////////////////////////////////////////////////////////////
122323
/// the main entry point for building MIR for a function
123324
124-
pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
125-
fn_id: ast::NodeId,
126-
arguments: A,
127-
abi: Abi,
128-
return_ty: Ty<'gcx>,
129-
body: &'gcx hir::Body)
130-
-> Mir<'tcx>
325+
fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
326+
fn_id: ast::NodeId,
327+
arguments: A,
328+
abi: Abi,
329+
return_ty: Ty<'gcx>,
330+
body: &'gcx hir::Body)
331+
-> Mir<'tcx>
131332
where A: Iterator<Item=(Ty<'gcx>, Option<&'gcx hir::Pat>)>
132333
{
133334
let arguments: Vec<_> = arguments.collect();

src/librustc_mir/hair/cx/mod.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use rustc::middle::region::RegionMaps;
2626
use rustc::infer::InferCtxt;
2727
use rustc::ty::subst::Subst;
2828
use rustc::ty::{self, Ty, TyCtxt};
29-
use syntax::symbol::{Symbol, InternedString};
29+
use syntax::symbol::Symbol;
3030
use rustc::hir;
3131
use rustc_const_math::{ConstInt, ConstUsize};
3232
use std::rc::Rc;
@@ -103,10 +103,6 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
103103
self.tcx.mk_nil()
104104
}
105105

106-
pub fn str_literal(&mut self, value: InternedString) -> Literal<'tcx> {
107-
Literal::Value { value: ConstVal::Str(value) }
108-
}
109-
110106
pub fn true_literal(&mut self) -> Literal<'tcx> {
111107
Literal::Value { value: ConstVal::Bool(true) }
112108
}

0 commit comments

Comments
 (0)