Skip to content

Commit 908b048

Browse files
committed
generate MIR for statics and constants
This does not generate MIR for associated constants
1 parent 95545e7 commit 908b048

File tree

4 files changed

+126
-8
lines changed

4 files changed

+126
-8
lines changed

src/librustc_mir/build/expr/as_temp.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,11 @@ impl<'a,'tcx> Builder<'a,'tcx> {
3535

3636
let expr_ty = expr.ty.clone();
3737
let temp = this.temp(expr_ty.clone());
38-
let temp_lifetime = match expr.temp_lifetime {
39-
Some(t) => t,
40-
None => {
41-
span_bug!(expr.span, "no temp_lifetime for expr");
42-
}
43-
};
44-
this.schedule_drop(expr.span, temp_lifetime, &temp, expr_ty);
38+
if let Some(temp_lifetime) = expr.temp_lifetime {
39+
this.schedule_drop(expr.span, temp_lifetime, &temp, expr_ty);
40+
}
41+
// if expression is inside a constant then
42+
// there's no temp_lifetime and no need to drop
4543

4644
// Careful here not to cause an infinite cycle. If we always
4745
// called `into`, then for lvalues like `x.f`, it would

src/librustc_mir/build/mod.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,76 @@ pub fn construct<'a,'tcx>(hir: Cx<'a,'tcx>,
264264
)
265265
}
266266

267+
268+
///////////////////////////////////////////////////////////////////////////
269+
/// the main entry point for building MIR for an arbitrary expression
270+
271+
pub fn construct_expr<'a,'tcx>(hir: Cx<'a,'tcx>,
272+
id: ast::NodeId,
273+
span: Span,
274+
expr: &'tcx hir::Expr)
275+
-> (Mir<'tcx>, ScopeAuxiliaryVec) {
276+
let tcx = hir.tcx();
277+
let cfg = CFG { basic_blocks: vec![] };
278+
let ty = tcx.node_id_to_type(id);
279+
280+
let mut builder = Builder {
281+
hir: hir,
282+
cfg: cfg,
283+
fn_span: span,
284+
scopes: vec![],
285+
scope_datas: vec![],
286+
scope_auxiliary: ScopeAuxiliaryVec { vec: vec![] },
287+
loop_scopes: vec![],
288+
temp_decls: vec![],
289+
var_decls: vec![],
290+
var_indices: FnvHashMap(),
291+
unit_temp: None,
292+
cached_resume_block: None,
293+
};
294+
295+
assert_eq!(builder.cfg.start_new_block(), START_BLOCK);
296+
assert_eq!(builder.cfg.start_new_block(), END_BLOCK);
297+
298+
let call_site_extent = tcx.region_maps.item_extent(id);
299+
let _ = builder.in_scope(call_site_extent, START_BLOCK, |builder, call_site_scope_id| {
300+
let mut block = START_BLOCK;
301+
let expr = builder.hir.mirror(expr);
302+
unpack!(block = builder.into(&Lvalue::ReturnPointer, block, expr));
303+
builder.cfg.terminate(block, call_site_scope_id, span,
304+
TerminatorKind::Goto { target: END_BLOCK });
305+
builder.cfg.terminate(END_BLOCK, call_site_scope_id, span,
306+
TerminatorKind::Return);
307+
308+
END_BLOCK.unit()
309+
});
310+
311+
assert!(
312+
builder.cfg.basic_blocks
313+
.iter()
314+
.enumerate()
315+
.all(|(index, block)| {
316+
if block.terminator.is_none() {
317+
bug!("no terminator on block {:?} in fn {:?}",
318+
index, id)
319+
}
320+
true
321+
}));
322+
323+
(
324+
Mir {
325+
basic_blocks: builder.cfg.basic_blocks,
326+
scopes: builder.scope_datas,
327+
var_decls: builder.var_decls,
328+
arg_decls: Vec::new(),
329+
temp_decls: builder.temp_decls,
330+
return_ty: FnOutput::FnConverging(ty),
331+
span: span
332+
},
333+
builder.scope_auxiliary,
334+
)
335+
}
336+
267337
impl<'a,'tcx> Builder<'a,'tcx> {
268338
fn args_and_body(&mut self,
269339
mut block: BasicBlock,

src/librustc_mir/mir_map.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ impl<'a, 'tcx> OuterDump<'a, 'tcx> {
8080

8181
impl<'a, 'tcx> Visitor<'tcx> for OuterDump<'a, 'tcx> {
8282
fn visit_item(&mut self, item: &'tcx hir::Item) {
83-
self.visit_mir(&item.attrs, |c| intravisit::walk_item(c, item));
83+
self.visit_mir(&item.attrs, |c| c.visit_item(item));
8484
intravisit::walk_item(self, item);
8585
}
8686

@@ -150,6 +150,32 @@ impl<'a, 'm, 'tcx> Visitor<'tcx> for InnerDump<'a,'m,'tcx> {
150150

151151
intravisit::walk_fn(self, fk, decl, body, span);
152152
}
153+
154+
fn visit_item(&mut self, i: &'tcx hir::Item) {
155+
match i.node {
156+
hir::ItemConst(_, ref expr) |
157+
hir::ItemStatic(_, _, ref expr) => {
158+
let param_env = ty::ParameterEnvironment::for_item(self.tcx, i.id);
159+
let infcx = infer::new_infer_ctxt(self.tcx,
160+
&self.tcx.tables,
161+
Some(param_env),
162+
ProjectionMode::AnyFinal);
163+
let (mir, scope_auxiliary) = build::construct_expr(Cx::new(&infcx),
164+
i.id,
165+
i.span,
166+
expr);
167+
pretty::dump_mir(self.tcx,
168+
"mir_map",
169+
&0,
170+
i.id,
171+
&mir,
172+
Some(&scope_auxiliary));
173+
assert!(self.map.map.insert(i.id, mir).is_none());
174+
},
175+
_ => {},
176+
}
177+
intravisit::walk_item(self, i);
178+
}
153179
}
154180

155181
fn build_mir<'a,'tcx:'a>(cx: Cx<'a,'tcx>,

src/test/run-pass/mir_constant.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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.
4+
//
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.
10+
11+
// This test does nothing useful yet, it just generates MIR for constants
12+
13+
#![feature(rustc_attrs)]
14+
15+
#[rustc_mir]
16+
const C: i32 = 5 + 6;
17+
18+
#[rustc_mir]
19+
const D: i32 = C - 3;
20+
21+
fn main() {
22+
assert_eq!(D, 8);
23+
assert_eq!(C, 11);
24+
}

0 commit comments

Comments
 (0)