Move "rust-call" tuple spreading out of ArgDecl

If MIR is for a "rust-call" ABI function, the last arg would always
have `spread` set to `true`. Move this flag into `Mir` instead.
This commit is contained in:
Jonas Schievink 2016-09-21 00:45:30 +02:00
parent 3bf4a7ad45
commit 205dac9355
4 changed files with 14 additions and 12 deletions

View File

@ -93,6 +93,12 @@ pub struct Mir<'tcx> {
/// the first argument is either the closure or a reference to it.
pub upvar_decls: Vec<UpvarDecl>,
/// A boolean indicating whether the last argument (which must be a tuple)
/// is passed as its individual components at the LLVM level.
///
/// This is used for the "rust-call" ABI.
pub spread_last_arg: bool,
/// A span representing this MIR, for error reporting
pub span: Span,
@ -123,6 +129,7 @@ impl<'tcx> Mir<'tcx> {
arg_decls: arg_decls,
temp_decls: temp_decls,
upvar_decls: upvar_decls,
spread_last_arg: false,
span: span,
cache: Cache::new()
}
@ -341,10 +348,6 @@ pub struct TempDecl<'tcx> {
pub struct ArgDecl<'tcx> {
pub ty: Ty<'tcx>,
/// If true, this argument is a tuple after monomorphization,
/// and has to be collected from multiple actual arguments.
pub spread: bool,
/// Either keywords::Invalid or the name of a single-binding
/// pattern associated with this argument. Useful for debuginfo.
pub debug_name: Name

View File

@ -665,7 +665,6 @@ macro_rules! make_mir_visitor {
arg_decl: & $($mutability)* ArgDecl<'tcx>) {
let ArgDecl {
ref $($mutability)* ty,
spread: _,
debug_name: _
} = *arg_decl;

View File

@ -169,7 +169,7 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
tcx.region_maps.lookup_code_extent(
CodeExtentData::ParameterScope { fn_id: fn_id, body_id: body_id });
let mut block = START_BLOCK;
let mut arg_decls = unpack!(block = builder.in_scope(call_site_extent, block, |builder| {
let arg_decls = unpack!(block = builder.in_scope(call_site_extent, block, |builder| {
let arg_decls = unpack!(block = builder.in_scope(arg_extent, block, |builder| {
builder.args_and_body(block, return_ty, arguments, arg_extent, ast_block)
}));
@ -184,12 +184,11 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
}));
assert_eq!(block, builder.return_block());
let mut spread_last_arg = false;
match tcx.node_id_to_type(fn_id).sty {
ty::TyFnDef(_, _, f) if f.abi == Abi::RustCall => {
// RustCall pseudo-ABI untuples the last argument.
if let Some(last_arg) = arg_decls.last() {
arg_decls[last_arg].spread = true;
}
spread_last_arg = true;
}
_ => {}
}
@ -218,7 +217,9 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
}).collect()
});
builder.finish(upvar_decls, arg_decls, return_ty)
let (mut mir, aux) = builder.finish(upvar_decls, arg_decls, return_ty);
mir.spread_last_arg = spread_last_arg;
(mir, aux)
}
pub fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
@ -331,7 +332,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
ArgDecl {
ty: ty,
spread: false,
debug_name: name
}
}).collect();

View File

@ -349,7 +349,7 @@ fn arg_local_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>,
mir.arg_decls.iter().enumerate().map(|(arg_index, arg_decl)| {
let arg_ty = bcx.monomorphize(&arg_decl.ty);
let local = mir.local_index(&mir::Lvalue::Arg(mir::Arg::new(arg_index))).unwrap();
if arg_decl.spread {
if mir.spread_last_arg && arg_index == mir.arg_decls.len() - 1 {
// This argument (e.g. the last argument in the "rust-call" ABI)
// is a tuple that was spread at the ABI level and now we have
// to reconstruct it into a tuple local variable, from multiple