Skip to content

Commit 7448f48

Browse files
committed
Rollup merge of rust-lang#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: &[[email protected]: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 rust-lang#30602 to get merged.)
2 parents 1aa4abd + f8b6134 commit 7448f48

File tree

1 file changed

+13
-16
lines changed

1 file changed

+13
-16
lines changed

src/librustc_mir/build/mod.rs

+13-16
Original file line numberDiff line numberDiff line change
@@ -138,28 +138,25 @@ impl<'a,'tcx> Builder<'a,'tcx> {
138138
-> BlockAnd<Vec<ArgDecl<'tcx>>>
139139
{
140140
self.in_scope(argument_extent, block, |this| {
141-
let arg_decls = {
142-
let implicit_arg_decls = implicit_arguments.into_iter()
143-
.map(|ty| ArgDecl { ty: ty });
144-
145-
// to start, translate the argument patterns and collect the
146-
// argument types.
147-
let explicit_arg_decls =
148-
explicit_arguments
149-
.into_iter()
150-
.enumerate()
151-
.map(|(index, (ty, pattern))| {
141+
// to start, translate the argument patterns and collect the argument types.
142+
let implicits = implicit_arguments.into_iter().map(|ty| (ty, None));
143+
let explicits = explicit_arguments.into_iter().map(|(ty, pat)| (ty, Some(pat)));
144+
let arg_decls =
145+
implicits
146+
.chain(explicits)
147+
.enumerate()
148+
.map(|(index, (ty, pattern))| {
149+
if let Some(pattern) = pattern {
152150
let lvalue = Lvalue::Arg(index as u32);
153151
let pattern = this.hir.irrefutable_pat(pattern);
154152
unpack!(block = this.lvalue_into_pattern(block,
155153
argument_extent,
156154
pattern,
157155
&lvalue));
158-
ArgDecl { ty: ty }
159-
});
160-
161-
implicit_arg_decls.chain(explicit_arg_decls).collect()
162-
};
156+
}
157+
ArgDecl { ty: ty }
158+
})
159+
.collect();
163160

164161
// start the first basic block and translate the body
165162
unpack!(block = this.ast_block(&Lvalue::ReturnPointer, block, ast_block));

0 commit comments

Comments
 (0)