/// 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,
arg_decls: arg_decls,
temp_decls: temp_decls,
upvar_decls: upvar_decls,
+ spread_last_arg: false,
span: span,
cache: Cache::new()
}
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
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)
}));
}));
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;
}
_ => {}
}
}).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>,
ArgDecl {
ty: ty,
- spread: false,
debug_name: name
}
}).collect();
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