use hair;
use rustc::middle::region::CodeExtent;
-use rustc::middle::ty::Ty;
+use rustc::middle::ty::{FnOutput, Ty};
use rustc_data_structures::fnv::FnvHashMap;
use rustc_front::hir;
use repr::*;
///////////////////////////////////////////////////////////////////////////
// construct() -- the main entry point for building MIR for a function
-pub fn construct<'a, 'tcx>(mut hir: Cx<'a, 'tcx>,
- _span: Span,
- implicit_arguments: Vec<Ty<'tcx>>,
- explicit_arguments: Vec<(Ty<'tcx>, PatNode<'tcx>)>,
- argument_extent: CodeExtent,
- ast_block: &'tcx hir::Block)
- -> Mir<'tcx> {
+pub fn construct<'a,'tcx>(mut hir: Cx<'a,'tcx>,
+ _span: Span,
+ implicit_arguments: Vec<Ty<'tcx>>,
+ explicit_arguments: Vec<(Ty<'tcx>, PatNode<'tcx>)>,
+ argument_extent: CodeExtent,
+ return_ty: FnOutput<'tcx>,
+ ast_block: &'tcx hir::Block)
+ -> Mir<'tcx> {
let cfg = CFG { basic_blocks: vec![] };
// it's handy to have a temporary of type `()` sometimes, so make
var_decls: builder.var_decls,
arg_decls: arg_decls,
temp_decls: builder.temp_decls,
+ return_ty: return_ty,
}
}
}
}
-fn build_mir<'a, 'tcx: 'a>(cx: Cx<'a, 'tcx>,
- implicit_arg_tys: Vec<Ty<'tcx>>,
- fn_id: ast::NodeId,
- span: Span,
- decl: &'tcx hir::FnDecl,
- body: &'tcx hir::Block)
- -> Result<Mir<'tcx>, ErrorReported> {
- let arguments = decl.inputs
- .iter()
- .map(|arg| {
- let ty = cx.tcx().node_id_to_type(arg.id);
- (ty, PatNode::irrefutable(&arg.pat))
- })
- .collect();
-
- let parameter_scope = cx.tcx().region_maps.lookup_code_extent(CodeExtentData::ParameterScope {
- fn_id: fn_id,
- body_id: body.id,
- });
- Ok(build::construct(cx, span, implicit_arg_tys, arguments, parameter_scope, body))
+fn build_mir<'a,'tcx:'a>(cx: Cx<'a,'tcx>,
+ implicit_arg_tys: Vec<Ty<'tcx>>,
+ fn_id: ast::NodeId,
+ span: Span,
+ decl: &'tcx hir::FnDecl,
+ body: &'tcx hir::Block)
+ -> Result<Mir<'tcx>, ErrorReported> {
+ // fetch the fully liberated fn signature (that is, all bound
+ // types/lifetimes replaced)
+ let fn_sig = match cx.tcx().tables.borrow().liberated_fn_sigs.get(&fn_id) {
+ Some(f) => f.clone(),
+ None => {
+ cx.tcx().sess.span_bug(span,
+ &format!("no liberated fn sig for {:?}", fn_id));
+ }
+ };
+
+ let arguments =
+ decl.inputs
+ .iter()
+ .enumerate()
+ .map(|(index, arg)| {
+ (fn_sig.inputs[index], PatNode::irrefutable(&arg.pat))
+ })
+ .collect();
+
+ let parameter_scope =
+ cx.tcx().region_maps.lookup_code_extent(
+ CodeExtentData::ParameterScope { fn_id: fn_id, body_id: body.id });
+ Ok(build::construct(cx,
+ span,
+ implicit_arg_tys,
+ arguments,
+ parameter_scope,
+ fn_sig.output,
+ body))
}
fn closure_self_ty<'a, 'tcx>(tcx: &ty::ctxt<'tcx>,
use rustc::middle::def_id::DefId;
use rustc::middle::region::CodeExtent;
use rustc::middle::subst::Substs;
-use rustc::middle::ty::{AdtDef, ClosureSubsts, Region, Ty};
+use rustc::middle::ty::{AdtDef, ClosureSubsts, FnOutput, Region, Ty};
use rustc_back::slice;
use rustc_data_structures::fnv::FnvHashMap;
use rustc_front::hir::InlineAsm;
pub struct Mir<'tcx> {
pub basic_blocks: Vec<BasicBlockData<'tcx>>,
+ pub return_ty: FnOutput<'tcx>,
+
// for every node id
pub extents: FnvHashMap<CodeExtent, Vec<GraphExtent>>,