diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-05-07 19:30:06 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-05-07 19:30:06 +0200 |
| commit | 535db2f357eaae4b42be783859df6233ab4beff1 (patch) | |
| tree | 5d19a8576bcab732d0d7ef38c9cf942be799a342 /src/libsyntax/parse | |
| parent | 4e233583d0616dc208bbc9acfc78c367ae0d38f6 (diff) | |
| parent | 57ec63c76c97028b6627289caec3c6a83cea92a7 (diff) | |
| download | rust-535db2f357eaae4b42be783859df6233ab4beff1.tar.gz rust-535db2f357eaae4b42be783859df6233ab4beff1.zip | |
Rollup merge of #60535 - taiki-e:async-fn-arguments, r=cramertj
Correct handling of arguments in async fn Fixes #60509 Fixes #60566 r? @cramertj or @davidtwco
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 084091f4c2a..60f685859ee 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1576,7 +1576,7 @@ impl<'a> Parser<'a> { let ident = self.parse_ident()?; let mut generics = self.parse_generics()?; - let d = self.parse_fn_decl_with_self(|p: &mut Parser<'a>| { + let mut decl = self.parse_fn_decl_with_self(|p: &mut Parser<'a>| { // This is somewhat dubious; We don't want to allow // argument names to be left off if there is a // definition... @@ -1585,7 +1585,7 @@ impl<'a> Parser<'a> { p.parse_arg_general(p.span.rust_2018(), true, false) })?; generics.where_clause = self.parse_where_clause()?; - self.construct_async_arguments(&mut asyncness, &d); + self.construct_async_arguments(&mut asyncness, &mut decl); let sig = ast::MethodSig { header: FnHeader { @@ -1594,7 +1594,7 @@ impl<'a> Parser<'a> { abi, asyncness, }, - decl: d, + decl, }; let body = match self.token { @@ -6475,10 +6475,10 @@ impl<'a> Parser<'a> { -> PResult<'a, ItemInfo> { let (ident, mut generics) = self.parse_fn_header()?; let allow_c_variadic = abi == Abi::C && unsafety == Unsafety::Unsafe; - let decl = self.parse_fn_decl(allow_c_variadic)?; + let mut decl = self.parse_fn_decl(allow_c_variadic)?; generics.where_clause = self.parse_where_clause()?; let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; - self.construct_async_arguments(&mut asyncness, &decl); + self.construct_async_arguments(&mut asyncness, &mut decl); let header = FnHeader { unsafety, asyncness, constness, abi }; Ok((ident, ItemKind::Fn(decl, header, generics, body), Some(inner_attrs))) } @@ -6662,9 +6662,9 @@ impl<'a> Parser<'a> { let (constness, unsafety, mut asyncness, abi) = self.parse_fn_front_matter()?; let ident = self.parse_ident()?; let mut generics = self.parse_generics()?; - let decl = self.parse_fn_decl_with_self(|p| p.parse_arg())?; + let mut decl = self.parse_fn_decl_with_self(|p| p.parse_arg())?; generics.where_clause = self.parse_where_clause()?; - self.construct_async_arguments(&mut asyncness, &decl); + self.construct_async_arguments(&mut asyncness, &mut decl); *at_end = true; let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; let header = ast::FnHeader { abi, unsafety, constness, asyncness }; @@ -8710,9 +8710,9 @@ impl<'a> Parser<'a> { /// /// The arguments of the function are replaced in HIR lowering with the arguments created by /// this function and the statements created here are inserted at the top of the closure body. - fn construct_async_arguments(&mut self, asyncness: &mut Spanned<IsAsync>, decl: &FnDecl) { + fn construct_async_arguments(&mut self, asyncness: &mut Spanned<IsAsync>, decl: &mut FnDecl) { if let IsAsync::Async { ref mut arguments, .. } = asyncness.node { - for (index, input) in decl.inputs.iter().enumerate() { + for (index, input) in decl.inputs.iter_mut().enumerate() { let id = ast::DUMMY_NODE_ID; let span = input.pat.span; @@ -8724,8 +8724,10 @@ impl<'a> Parser<'a> { // `let <pat> = __argN;` statement, instead just adding a `let <pat> = <pat>;` // statement. let (binding_mode, ident, is_simple_pattern) = match input.pat.node { - PatKind::Ident(binding_mode, ident, _) => (binding_mode, ident, true), - _ => (BindingMode::ByValue(Mutability::Immutable), ident, false), + PatKind::Ident(binding_mode @ BindingMode::ByValue(_), ident, _) => { + (binding_mode, ident, true) + } + _ => (BindingMode::ByValue(Mutability::Mutable), ident, false), }; // Construct an argument representing `__argN: <ty>` to replace the argument of the @@ -8792,6 +8794,15 @@ impl<'a> Parser<'a> { }) }; + // Remove mutability from arguments. If this is not a simple pattern, + // those arguments are replaced by `__argN`, so there is no need to do this. + if let PatKind::Ident(BindingMode::ByValue(mutability @ Mutability::Mutable), ..) = + &mut input.pat.node + { + assert!(is_simple_pattern); + *mutability = Mutability::Immutable; + } + let move_stmt = Stmt { id, node: StmtKind::Local(P(move_local)), span }; arguments.push(AsyncArgument { ident, arg, pat_stmt, move_stmt }); } |
