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:
parent
3bf4a7ad45
commit
205dac9355
@ -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
|
||||
|
@ -665,7 +665,6 @@ macro_rules! make_mir_visitor {
|
||||
arg_decl: & $($mutability)* ArgDecl<'tcx>) {
|
||||
let ArgDecl {
|
||||
ref $($mutability)* ty,
|
||||
spread: _,
|
||||
debug_name: _
|
||||
} = *arg_decl;
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user