From b65277496c8848cd6f08b55e8b413096c74b92af Mon Sep 17 00:00:00 2001 From: Scott Olson Date: Tue, 29 Dec 2015 22:55:38 -0600 Subject: [PATCH 1/2] Fix argument indices in MIR for closures. Previously, all references to closure arguments went to the argument before the one they should (e.g. to arg1 when it was supposed to be 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. --- src/librustc_mir/build/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index bd94f4e5bf2..7ea9301664f 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -139,6 +139,7 @@ fn args_and_body(&mut self, { self.in_scope(argument_extent, block, |this| { let arg_decls = { + let num_implicit_args = implicit_arguments.len(); let implicit_arg_decls = implicit_arguments.into_iter() .map(|ty| ArgDecl { ty: ty }); @@ -149,7 +150,7 @@ fn args_and_body(&mut self, .into_iter() .enumerate() .map(|(index, (ty, pattern))| { - let lvalue = Lvalue::Arg(index as u32); + let lvalue = Lvalue::Arg((num_implicit_args + index) as u32); let pattern = this.hir.irrefutable_pat(pattern); unpack!(block = this.lvalue_into_pattern(block, argument_extent, From f8b61340e33bbb24709a862fd834ec10c871413c Mon Sep 17 00:00:00 2001 From: Scott Olson Date: Wed, 30 Dec 2015 06:55:51 -0600 Subject: [PATCH 2/2] Refactor MIR building for arguments. --- src/librustc_mir/build/mod.rs | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 7ea9301664f..8347a03cda6 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -138,29 +138,25 @@ fn args_and_body(&mut self, -> BlockAnd>> { self.in_scope(argument_extent, block, |this| { - let arg_decls = { - let num_implicit_args = implicit_arguments.len(); - 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))| { - let lvalue = Lvalue::Arg((num_implicit_args + index) as u32); + // 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));