Rollup merge of #30630 - tsion:mir-closure-args, r=nagisa
Previously, all references to closure arguments went to the argument before the one they should (e.g. to `arg1` when it was supposed to go to `arg2`). This was because the MIR builder did not account for the implicit arguments that come before the explicit arguments, and closures have one implicit argument - the struct containing the captures. This is my test code and a diff of the MIR generated for the closure: ```rust let a = 2i32; let _f = |b: i32| -> i32 { a + b }: ``` ```diff --- old 2015-12-29 23:16:32.027926372 -0600 +++ new 2015-12-29 23:16:42.975400757 -0600 @@ -1,22 +1,22 @@ fn(arg0: &[closure@closure-args.rs:8:14: 8:39 a:&i32], arg1: i32) -> i32 { let var0: i32; // b let tmp0: (); let tmp1: i32; let tmp2: i32; bb0: { - var0 = arg0; + var0 = arg1; tmp1 = (*(*arg0).0); tmp2 = var0; ReturnPointer = Add(tmp1, tmp2); goto -> bb1; } bb1: { return; } bb2: { diverge; } } ``` (If you're wondering where this text MIR output comes from, it's from another branch of mine waiting on https://github.com/rust-lang/rust/pull/30602 to get merged.)
This commit is contained in:
commit
7448f4861a
@ -138,28 +138,25 @@ fn args_and_body(&mut self,
|
||||
-> BlockAnd<Vec<ArgDecl<'tcx>>>
|
||||
{
|
||||
self.in_scope(argument_extent, block, |this| {
|
||||
let arg_decls = {
|
||||
let implicit_arg_decls = implicit_arguments.into_iter()
|
||||
.map(|ty| ArgDecl { ty: ty });
|
||||
|
||||
// to start, translate the argument patterns and collect the
|
||||
// argument types.
|
||||
let explicit_arg_decls =
|
||||
explicit_arguments
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(index, (ty, pattern))| {
|
||||
// to start, translate the argument patterns and collect the argument types.
|
||||
let implicits = implicit_arguments.into_iter().map(|ty| (ty, None));
|
||||
let explicits = explicit_arguments.into_iter().map(|(ty, pat)| (ty, Some(pat)));
|
||||
let arg_decls =
|
||||
implicits
|
||||
.chain(explicits)
|
||||
.enumerate()
|
||||
.map(|(index, (ty, pattern))| {
|
||||
if let Some(pattern) = pattern {
|
||||
let lvalue = Lvalue::Arg(index as u32);
|
||||
let pattern = this.hir.irrefutable_pat(pattern);
|
||||
unpack!(block = this.lvalue_into_pattern(block,
|
||||
argument_extent,
|
||||
pattern,
|
||||
&lvalue));
|
||||
ArgDecl { ty: ty }
|
||||
});
|
||||
|
||||
implicit_arg_decls.chain(explicit_arg_decls).collect()
|
||||
};
|
||||
}
|
||||
ArgDecl { ty: ty }
|
||||
})
|
||||
.collect();
|
||||
|
||||
// start the first basic block and translate the body
|
||||
unpack!(block = this.ast_block(&Lvalue::ReturnPointer, block, ast_block));
|
||||
|
Loading…
Reference in New Issue
Block a user