From f2904674e8d0dbb6f7b02ae74aa81d930a0e8617 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Sep 2019 00:20:03 +0200 Subject: syntax: cleanup method parsing. --- src/libsyntax/parse/parser/item.rs | 138 +++++++++++++++++-------------------- 1 file changed, 65 insertions(+), 73 deletions(-) (limited to 'src/libsyntax/parse/parser') diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs index 64c494416ff..69fbb343ff3 100644 --- a/src/libsyntax/parse/parser/item.rs +++ b/src/libsyntax/parse/parser/item.rs @@ -7,7 +7,7 @@ use crate::ast::{ Item, ItemKind, ImplItem, TraitItem, TraitItemKind, UseTree, UseTreeKind, PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness, - Visibility, VisibilityKind, Mutability, FnDecl, FnHeader, + Visibility, VisibilityKind, Mutability, FnDecl, FnHeader, MethodSig, Block, ForeignItem, ForeignItemKind, Ty, TyKind, Generics, GenericBounds, TraitRef, EnumDef, VariantData, StructField, AnonConst, @@ -848,29 +848,38 @@ impl<'a> Parser<'a> { } /// Parses a method or a macro invocation in a trait impl. - fn parse_impl_method(&mut self, vis: &Visibility, at_end: &mut bool) - -> PResult<'a, (Ident, Vec, Generics, ast::ImplItemKind)> { + fn parse_impl_method( + &mut self, + vis: &Visibility, + at_end: &mut bool + ) -> PResult<'a, (Ident, Vec, Generics, ast::ImplItemKind)> { // FIXME: code copied from `parse_macro_use_or_failure` -- use abstraction! if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(vis), at_end)? { // method macro - Ok((Ident::invalid(), vec![], Generics::default(), - ast::ImplItemKind::Macro(mac))) + Ok((Ident::invalid(), vec![], Generics::default(), ast::ImplItemKind::Macro(mac))) } else { - let (constness, unsafety, 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(|_| true)?; - generics.where_clause = self.parse_where_clause()?; + let (ident, sig, generics) = self.parse_method_sig(|_| true)?; *at_end = true; let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; - let header = ast::FnHeader { abi, unsafety, constness, asyncness }; - Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method( - ast::MethodSig { header, decl }, - body - ))) + Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method(sig, body))) } } + /// Parse the "signature", including the identifier, parameters, and generics + /// of a method. The body is not parsed as that differs between `trait`s and `impl`s. + fn parse_method_sig( + &mut self, + is_name_required: impl Copy + Fn(&token::Token) -> bool, + ) -> PResult<'a, (Ident, MethodSig, Generics)> { + let header = self.parse_fn_front_matter()?; + let ident = self.parse_ident()?; + let mut generics = self.parse_generics()?; + let decl = self.parse_fn_decl_with_self(is_name_required)?; + let sig = MethodSig { header, decl }; + generics.where_clause = self.parse_where_clause()?; + Ok((ident, sig, generics)) + } + /// Parses all the "front matter" for a `fn` declaration, up to /// and including the `fn` keyword: /// @@ -879,14 +888,7 @@ impl<'a> Parser<'a> { /// - `const unsafe fn` /// - `extern fn` /// - etc. - fn parse_fn_front_matter(&mut self) - -> PResult<'a, ( - Spanned, - Unsafety, - Spanned, - Abi - )> - { + fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> { let is_const_fn = self.eat_keyword(kw::Const); let const_span = self.prev_span; let asyncness = self.parse_asyncness(); @@ -911,7 +913,7 @@ impl<'a> Parser<'a> { // account for this. if !self.expect_one_of(&[], &[])? { unreachable!() } } - Ok((constness, unsafety, asyncness, abi)) + Ok(FnHeader { constness, unsafety, asyncness, abi }) } /// Parses `trait Foo { ... }` or `trait Foo = Bar;`. @@ -1025,59 +1027,12 @@ impl<'a> Parser<'a> { // trait item macro. (Ident::invalid(), ast::TraitItemKind::Macro(mac), Generics::default()) } else { - let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?; - - let ident = self.parse_ident()?; - let mut generics = self.parse_generics()?; - // This is somewhat dubious; We don't want to allow // argument names to be left off if there is a definition... // // We don't allow argument names to be left off in edition 2018. - let decl = self.parse_fn_decl_with_self(|t| t.span.rust_2018())?; - generics.where_clause = self.parse_where_clause()?; - - let sig = ast::MethodSig { - header: FnHeader { - unsafety, - constness, - abi, - asyncness, - }, - decl, - }; - - let body = match self.token.kind { - token::Semi => { - self.bump(); - *at_end = true; - debug!("parse_trait_methods(): parsing required method"); - None - } - token::OpenDelim(token::Brace) => { - debug!("parse_trait_methods(): parsing provided method"); - *at_end = true; - let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; - attrs.extend(inner_attrs.iter().cloned()); - Some(body) - } - token::Interpolated(ref nt) => { - match **nt { - token::NtBlock(..) => { - *at_end = true; - let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; - attrs.extend(inner_attrs.iter().cloned()); - Some(body) - } - _ => { - return self.expected_semi_or_open_brace(); - } - } - } - _ => { - return self.expected_semi_or_open_brace(); - } - }; + let (ident, sig, generics) = self.parse_method_sig(|t| t.span.rust_2018())?; + let body = self.parse_trait_method_body(at_end, &mut attrs)?; (ident, ast::TraitItemKind::Method(sig, body), generics) }; @@ -1092,6 +1047,43 @@ impl<'a> Parser<'a> { }) } + /// Parse the "body" of a method in a trait item definition. + /// This can either be `;` when there's no body, + /// or e.g. a block when the method is a provided one. + fn parse_trait_method_body( + &mut self, + at_end: &mut bool, + attrs: &mut Vec, + ) -> PResult<'a, Option>> { + Ok(match self.token.kind { + token::Semi => { + debug!("parse_trait_method_body(): parsing required method"); + self.bump(); + *at_end = true; + None + } + token::OpenDelim(token::Brace) => { + debug!("parse_trait_method_body(): parsing provided method"); + *at_end = true; + let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; + attrs.extend(inner_attrs.iter().cloned()); + Some(body) + } + token::Interpolated(ref nt) => { + match **nt { + token::NtBlock(..) => { + *at_end = true; + let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; + attrs.extend(inner_attrs.iter().cloned()); + Some(body) + } + _ => return self.expected_semi_or_open_brace(), + } + } + _ => return self.expected_semi_or_open_brace(), + }) + } + /// Parses the following grammar: /// /// TraitItemAssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty] -- cgit 1.4.1-3-g733a5 From 4306d0037e961825abc08bfa39af0b64d1ed52aa Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Sep 2019 02:36:08 +0200 Subject: syntax refactor `parse_self_param` (4) --- src/libsyntax/parse/parser.rs | 59 ++++++++++++++++++++++++---------------- src/libsyntax/parse/parser/ty.rs | 8 ++---- 2 files changed, 37 insertions(+), 30 deletions(-) (limited to 'src/libsyntax/parse/parser') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ae4f181a119..fd6ffb80073 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1063,6 +1063,17 @@ impl<'a> Parser<'a> { } } + /// Possibly parses mutability (`const` or `mut`). + fn parse_const_or_mut(&mut self) -> Option { + if self.eat_keyword(kw::Mut) { + Some(Mutability::Mutable) + } else if self.eat_keyword(kw::Const) { + Some(Mutability::Immutable) + } else { + None + } + } + fn parse_field_name(&mut self) -> PResult<'a, Ident> { if let token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) = self.token.kind { @@ -1276,6 +1287,17 @@ impl<'a> Parser<'a> { } } + /// Recover for the grammar `*self`, `*const self`, and `*mut self`. + fn recover_self_ptr(&mut self) -> PResult<'a, (ast::SelfKind, Ident, Span)> { + let msg = "cannot pass `self` by raw pointer"; + let span = self.token.span; + self.struct_span_err(span, msg) + .span_label(span, msg) + .emit(); + + Ok((SelfKind::Value(Mutability::Immutable), self.expect_self_ident(), self.prev_span)) + } + /// Parse `self` or `self: TYPE`. We already know the current token is `self`. fn parse_self_possibly_typed(&mut self, m: Mutability) -> PResult<'a, (SelfKind, Ident, Span)> { let eself_ident = self.expect_self_ident(); @@ -1327,30 +1349,19 @@ impl<'a> Parser<'a> { return Ok(None); }, self.expect_self_ident(), self.prev_span) } - token::BinOp(token::Star) => { - // `*self` - // `*const self` - // `*mut self` - // `*not_self` - // Emit special error for `self` cases. - let msg = "cannot pass `self` by raw pointer"; - (if self.is_isolated_self(1) { - self.bump(); - self.struct_span_err(self.token.span, msg) - .span_label(self.token.span, msg) - .emit(); - SelfKind::Value(Mutability::Immutable) - } else if self.look_ahead(1, |t| t.is_mutability()) && - self.is_isolated_self(2) { - self.bump(); - self.bump(); - self.struct_span_err(self.token.span, msg) - .span_label(self.token.span, msg) - .emit(); - SelfKind::Value(Mutability::Immutable) - } else { - return Ok(None); - }, self.expect_self_ident(), self.prev_span) + // `*self` + token::BinOp(token::Star) if self.is_isolated_self(1) => { + self.bump(); + self.recover_self_ptr()? + } + // `*mut self` and `*const self` + token::BinOp(token::Star) if + self.look_ahead(1, |t| t.is_mutability()) + && self.is_isolated_self(2) => + { + self.bump(); + self.bump(); + self.recover_self_ptr()? } // `self` and `self: TYPE` token::Ident(..) if self.is_isolated_self(0) => { diff --git a/src/libsyntax/parse/parser/ty.rs b/src/libsyntax/parse/parser/ty.rs index c52d3733b5e..41ee2a1599d 100644 --- a/src/libsyntax/parse/parser/ty.rs +++ b/src/libsyntax/parse/parser/ty.rs @@ -231,11 +231,7 @@ impl<'a> Parser<'a> { } fn parse_ptr(&mut self) -> PResult<'a, MutTy> { - let mutbl = if self.eat_keyword(kw::Mut) { - Mutability::Mutable - } else if self.eat_keyword(kw::Const) { - Mutability::Immutable - } else { + let mutbl = self.parse_const_or_mut().unwrap_or_else(|| { let span = self.prev_span; let msg = "expected mut or const in raw pointer type"; self.struct_span_err(span, msg) @@ -243,7 +239,7 @@ impl<'a> Parser<'a> { .help("use `*mut T` or `*const T` as appropriate") .emit(); Mutability::Immutable - }; + }); let t = self.parse_ty_no_plus()?; Ok(MutTy { ty: t, mutbl }) } -- cgit 1.4.1-3-g733a5 From d9d0e5d36bb6b3e23b4869196788bd10b5220f31 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Sep 2019 05:46:16 +0200 Subject: syntax: cleanup `parse_fn_decl`. --- src/libsyntax/parse/parser/item.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src/libsyntax/parse/parser') diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs index 69fbb343ff3..2f353b65783 100644 --- a/src/libsyntax/parse/parser/item.rs +++ b/src/libsyntax/parse/parser/item.rs @@ -1274,14 +1274,11 @@ impl<'a> Parser<'a> { Ok((id, generics)) } - /// Parses the argument list and result type of a function declaration. + /// Parses the parameter list and result type of a function declaration. fn parse_fn_decl(&mut self, allow_c_variadic: bool) -> PResult<'a, P> { - let args = self.parse_fn_params(true, allow_c_variadic)?; - let ret_ty = self.parse_ret_ty(true)?; - Ok(P(FnDecl { - inputs: args, - output: ret_ty, + inputs: self.parse_fn_params(true, allow_c_variadic)?, + output: self.parse_ret_ty(true)?, })) } -- cgit 1.4.1-3-g733a5 From 258e86a5833588ffb2443a80b4e3c42300c4b278 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Sep 2019 08:53:59 +0200 Subject: syntax: fuse more code paths together. --- src/libsyntax/parse/parser/item.rs | 99 ++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 48 deletions(-) (limited to 'src/libsyntax/parse/parser') diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs index 2f353b65783..eaa04668b7a 100644 --- a/src/libsyntax/parse/parser/item.rs +++ b/src/libsyntax/parse/parser/item.rs @@ -18,7 +18,7 @@ use crate::parse::token; use crate::parse::parser::maybe_append; use crate::parse::diagnostics::Error; use crate::tokenstream::{TokenTree, TokenStream}; -use crate::source_map::{respan, Span, Spanned}; +use crate::source_map::{respan, Span}; use crate::symbol::{kw, sym}; use std::mem; @@ -122,12 +122,12 @@ impl<'a> Parser<'a> { if self.eat_keyword(kw::Fn) { // EXTERN FUNCTION ITEM let fn_span = self.prev_span; - let abi = opt_abi.unwrap_or(Abi::C); - let (ident, item_, extra_attrs) = - self.parse_item_fn(Unsafety::Normal, - respan(fn_span, IsAsync::NotAsync), - respan(fn_span, Constness::NotConst), - abi)?; + let (ident, item_, extra_attrs) = self.parse_item_fn(FnHeader { + unsafety: Unsafety::Normal, + asyncness: respan(fn_span, IsAsync::NotAsync), + constness: respan(fn_span, Constness::NotConst), + abi: opt_abi.unwrap_or(Abi::C), + })?; let prev_span = self.prev_span; let item = self.mk_item(lo.to(prev_span), ident, @@ -165,11 +165,12 @@ impl<'a> Parser<'a> { // CONST FUNCTION ITEM let unsafety = self.parse_unsafety(); self.bump(); - let (ident, item_, extra_attrs) = - self.parse_item_fn(unsafety, - respan(const_span, IsAsync::NotAsync), - respan(const_span, Constness::Const), - Abi::Rust)?; + let (ident, item_, extra_attrs) = self.parse_item_fn(FnHeader { + unsafety, + asyncness: respan(const_span, IsAsync::NotAsync), + constness: respan(const_span, Constness::Const), + abi: Abi::Rust, + })?; let prev_span = self.prev_span; let item = self.mk_item(lo.to(prev_span), ident, @@ -213,14 +214,16 @@ impl<'a> Parser<'a> { let unsafety = self.parse_unsafety(); // `unsafe`? self.expect_keyword(kw::Fn)?; // `fn` let fn_span = self.prev_span; - let (ident, item_, extra_attrs) = - self.parse_item_fn(unsafety, - respan(async_span, IsAsync::Async { - closure_id: DUMMY_NODE_ID, - return_impl_trait_id: DUMMY_NODE_ID, - }), - respan(fn_span, Constness::NotConst), - Abi::Rust)?; + let asyncness = respan(async_span, IsAsync::Async { + closure_id: DUMMY_NODE_ID, + return_impl_trait_id: DUMMY_NODE_ID, + }); + let (ident, item_, extra_attrs) = self.parse_item_fn(FnHeader { + unsafety, + asyncness, + constness: respan(fn_span, Constness::NotConst), + abi: Abi::Rust, + })?; let prev_span = self.prev_span; let item = self.mk_item(lo.to(prev_span), ident, @@ -271,11 +274,12 @@ impl<'a> Parser<'a> { // FUNCTION ITEM self.bump(); let fn_span = self.prev_span; - let (ident, item_, extra_attrs) = - self.parse_item_fn(Unsafety::Normal, - respan(fn_span, IsAsync::NotAsync), - respan(fn_span, Constness::NotConst), - Abi::Rust)?; + let (ident, item_, extra_attrs) = self.parse_item_fn(FnHeader { + unsafety: Unsafety::Normal, + asyncness: respan(fn_span, IsAsync::NotAsync), + constness: respan(fn_span, Constness::NotConst), + abi: Abi::Rust, + })?; let prev_span = self.prev_span; let item = self.mk_item(lo.to(prev_span), ident, @@ -297,11 +301,12 @@ impl<'a> Parser<'a> { }; self.expect_keyword(kw::Fn)?; let fn_span = self.prev_span; - let (ident, item_, extra_attrs) = - self.parse_item_fn(Unsafety::Unsafe, - respan(fn_span, IsAsync::NotAsync), - respan(fn_span, Constness::NotConst), - abi)?; + let (ident, item_, extra_attrs) = self.parse_item_fn(FnHeader { + unsafety: Unsafety::Unsafe, + asyncness: respan(fn_span, IsAsync::NotAsync), + constness: respan(fn_span, Constness::NotConst), + abi, + })?; let prev_span = self.prev_span; let item = self.mk_item(lo.to(prev_span), ident, @@ -872,8 +877,7 @@ impl<'a> Parser<'a> { is_name_required: impl Copy + Fn(&token::Token) -> bool, ) -> PResult<'a, (Ident, MethodSig, Generics)> { let header = self.parse_fn_front_matter()?; - let ident = self.parse_ident()?; - let mut generics = self.parse_generics()?; + let (ident, mut generics) = self.parse_fn_header()?; let decl = self.parse_fn_decl_with_self(is_name_required)?; let sig = MethodSig { header, decl }; generics.where_clause = self.parse_where_clause()?; @@ -1251,20 +1255,22 @@ impl<'a> Parser<'a> { } /// Parses an item-position function declaration. - fn parse_item_fn( + fn parse_item_fn(&mut self, header: FnHeader) -> PResult<'a, ItemInfo> { + let allow_c_variadic = header.abi == Abi::C && header.unsafety == Unsafety::Unsafe; + let (ident, decl, generics) = self.parse_fn_sig(allow_c_variadic)?; + let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; + Ok((ident, ItemKind::Fn(decl, header, generics, body), Some(inner_attrs))) + } + + /// Parse the "signature", including the identifier, parameters, and generics of a function. + fn parse_fn_sig( &mut self, - unsafety: Unsafety, - asyncness: Spanned, - constness: Spanned, - abi: Abi - ) -> PResult<'a, ItemInfo> { + allow_c_variadic: bool, + ) -> PResult<'a, (Ident, P, Generics)> { 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)?; generics.where_clause = self.parse_where_clause()?; - let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; - let header = FnHeader { unsafety, asyncness, constness, abi }; - Ok((ident, ItemKind::Fn(decl, header, generics, body), Some(inner_attrs))) + Ok((ident, decl, generics)) } /// Parses the name and optional generic types of a function header. @@ -1386,18 +1392,15 @@ impl<'a> Parser<'a> { extern_sp: Span, ) -> PResult<'a, ForeignItem> { self.expect_keyword(kw::Fn)?; - - let (ident, mut generics) = self.parse_fn_header()?; - let decl = self.parse_fn_decl(true)?; - generics.where_clause = self.parse_where_clause()?; - let hi = self.token.span; + let (ident, decl, generics) = self.parse_fn_sig(true)?; + let span = lo.to(self.token.span); self.parse_semi_or_incorrect_foreign_fn_body(&ident, extern_sp)?; Ok(ast::ForeignItem { ident, attrs, kind: ForeignItemKind::Fn(decl, generics), id: DUMMY_NODE_ID, - span: lo.to(hi), + span, vis, }) } -- cgit 1.4.1-3-g733a5 From bea404f292f0ec60a990de28433b9eaa1dfecb4c Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Sep 2019 09:13:42 +0200 Subject: syntax: stylistic cleanup in item parsing. --- src/libsyntax/parse/parser/item.rs | 154 +++++++++++-------------------------- 1 file changed, 47 insertions(+), 107 deletions(-) (limited to 'src/libsyntax/parse/parser') diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs index eaa04668b7a..68f0357abd0 100644 --- a/src/libsyntax/parse/parser/item.rs +++ b/src/libsyntax/parse/parser/item.rs @@ -128,13 +128,9 @@ impl<'a> Parser<'a> { constness: respan(fn_span, Constness::NotConst), abi: opt_abi.unwrap_or(Abi::C), })?; - let prev_span = self.prev_span; - let item = self.mk_item(lo.to(prev_span), - ident, - item_, - visibility, - maybe_append(attrs, extra_attrs)); - return Ok(Some(item)); + let span = lo.to(self.prev_span); + let attrs = maybe_append(attrs, extra_attrs); + return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs))); } else if self.check(&token::OpenDelim(token::Brace)) { return Ok(Some( self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs, extern_sp)?, @@ -149,13 +145,9 @@ impl<'a> Parser<'a> { // STATIC ITEM let m = self.parse_mutability(); let (ident, item_, extra_attrs) = self.parse_item_const(Some(m))?; - let prev_span = self.prev_span; - let item = self.mk_item(lo.to(prev_span), - ident, - item_, - visibility, - maybe_append(attrs, extra_attrs)); - return Ok(Some(item)); + let span = lo.to(self.prev_span); + let attrs = maybe_append(attrs, extra_attrs); + return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs))); } if self.eat_keyword(kw::Const) { let const_span = self.prev_span; @@ -171,13 +163,9 @@ impl<'a> Parser<'a> { constness: respan(const_span, Constness::Const), abi: Abi::Rust, })?; - let prev_span = self.prev_span; - let item = self.mk_item(lo.to(prev_span), - ident, - item_, - visibility, - maybe_append(attrs, extra_attrs)); - return Ok(Some(item)); + let span = lo.to(self.prev_span); + let attrs = maybe_append(attrs, extra_attrs); + return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs))); } // CONST ITEM @@ -194,13 +182,9 @@ impl<'a> Parser<'a> { .emit(); } let (ident, item_, extra_attrs) = self.parse_item_const(None)?; - let prev_span = self.prev_span; - let item = self.mk_item(lo.to(prev_span), - ident, - item_, - visibility, - maybe_append(attrs, extra_attrs)); - return Ok(Some(item)); + let span = lo.to(self.prev_span); + let attrs = maybe_append(attrs, extra_attrs); + return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs))); } // Parses `async unsafe? fn`. @@ -224,14 +208,10 @@ impl<'a> Parser<'a> { constness: respan(fn_span, Constness::NotConst), abi: Abi::Rust, })?; - let prev_span = self.prev_span; - let item = self.mk_item(lo.to(prev_span), - ident, - item_, - visibility, - maybe_append(attrs, extra_attrs)); self.ban_async_in_2015(async_span); - return Ok(Some(item)); + let span = lo.to(self.prev_span); + let attrs = maybe_append(attrs, extra_attrs); + return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs))); } } if self.check_keyword(kw::Unsafe) && @@ -246,15 +226,10 @@ impl<'a> Parser<'a> { self.expect_keyword(kw::Trait)?; IsAuto::Yes }; - let (ident, item_, extra_attrs) = - self.parse_item_trait(is_auto, Unsafety::Unsafe)?; - let prev_span = self.prev_span; - let item = self.mk_item(lo.to(prev_span), - ident, - item_, - visibility, - maybe_append(attrs, extra_attrs)); - return Ok(Some(item)); + let (ident, item_, extra_attrs) = self.parse_item_trait(is_auto, Unsafety::Unsafe)?; + let span = lo.to(self.prev_span); + let attrs = maybe_append(attrs, extra_attrs); + return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs))); } if self.check_keyword(kw::Impl) || self.check_keyword(kw::Unsafe) && @@ -265,10 +240,10 @@ impl<'a> Parser<'a> { let defaultness = self.parse_defaultness(); let unsafety = self.parse_unsafety(); self.expect_keyword(kw::Impl)?; - let (ident, item, extra_attrs) = self.parse_item_impl(unsafety, defaultness)?; + let (ident, item_, extra_attrs) = self.parse_item_impl(unsafety, defaultness)?; let span = lo.to(self.prev_span); - return Ok(Some(self.mk_item(span, ident, item, visibility, - maybe_append(attrs, extra_attrs)))); + let attrs = maybe_append(attrs, extra_attrs); + return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs))); } if self.check_keyword(kw::Fn) { // FUNCTION ITEM @@ -280,13 +255,9 @@ impl<'a> Parser<'a> { constness: respan(fn_span, Constness::NotConst), abi: Abi::Rust, })?; - let prev_span = self.prev_span; - let item = self.mk_item(lo.to(prev_span), - ident, - item_, - visibility, - maybe_append(attrs, extra_attrs)); - return Ok(Some(item)); + let span = lo.to(self.prev_span); + let attrs = maybe_append(attrs, extra_attrs); + return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs))); } if self.check_keyword(kw::Unsafe) && self.look_ahead(1, |t| *t != token::OpenDelim(token::Brace)) { @@ -307,25 +278,16 @@ impl<'a> Parser<'a> { constness: respan(fn_span, Constness::NotConst), abi, })?; - let prev_span = self.prev_span; - let item = self.mk_item(lo.to(prev_span), - ident, - item_, - visibility, - maybe_append(attrs, extra_attrs)); - return Ok(Some(item)); + let span = lo.to(self.prev_span); + let attrs = maybe_append(attrs, extra_attrs); + return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs))); } if self.eat_keyword(kw::Mod) { // MODULE ITEM - let (ident, item_, extra_attrs) = - self.parse_item_mod(&attrs[..])?; - let prev_span = self.prev_span; - let item = self.mk_item(lo.to(prev_span), - ident, - item_, - visibility, - maybe_append(attrs, extra_attrs)); - return Ok(Some(item)); + let (ident, item_, extra_attrs) = self.parse_item_mod(&attrs[..])?; + let span = lo.to(self.prev_span); + let attrs = maybe_append(attrs, extra_attrs); + return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs))); } if let Some(type_) = self.eat_type() { let (ident, alias, generics) = type_?; @@ -334,24 +296,15 @@ impl<'a> Parser<'a> { AliasKind::Weak(ty) => ItemKind::TyAlias(ty, generics), AliasKind::OpaqueTy(bounds) => ItemKind::OpaqueTy(bounds, generics), }; - let prev_span = self.prev_span; - let item = self.mk_item(lo.to(prev_span), - ident, - item_, - visibility, - attrs); - return Ok(Some(item)); + let span = lo.to(self.prev_span); + return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs))); } if self.eat_keyword(kw::Enum) { // ENUM ITEM let (ident, item_, extra_attrs) = self.parse_item_enum()?; - let prev_span = self.prev_span; - let item = self.mk_item(lo.to(prev_span), - ident, - item_, - visibility, - maybe_append(attrs, extra_attrs)); - return Ok(Some(item)); + let span = lo.to(self.prev_span); + let attrs = maybe_append(attrs, extra_attrs); + return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs))); } if self.check_keyword(kw::Trait) || (self.check_keyword(kw::Auto) @@ -365,38 +318,25 @@ impl<'a> Parser<'a> { IsAuto::Yes }; // TRAIT ITEM - let (ident, item_, extra_attrs) = - self.parse_item_trait(is_auto, Unsafety::Normal)?; - let prev_span = self.prev_span; - let item = self.mk_item(lo.to(prev_span), - ident, - item_, - visibility, - maybe_append(attrs, extra_attrs)); - return Ok(Some(item)); + let (ident, item_, extra_attrs) = self.parse_item_trait(is_auto, Unsafety::Normal)?; + let span = lo.to(self.prev_span); + let attrs = maybe_append(attrs, extra_attrs); + return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs))); } if self.eat_keyword(kw::Struct) { // STRUCT ITEM let (ident, item_, extra_attrs) = self.parse_item_struct()?; - let prev_span = self.prev_span; - let item = self.mk_item(lo.to(prev_span), - ident, - item_, - visibility, - maybe_append(attrs, extra_attrs)); - return Ok(Some(item)); + let span = lo.to(self.prev_span); + let attrs = maybe_append(attrs, extra_attrs); + return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs))); } if self.is_union_item() { // UNION ITEM self.bump(); let (ident, item_, extra_attrs) = self.parse_item_union()?; - let prev_span = self.prev_span; - let item = self.mk_item(lo.to(prev_span), - ident, - item_, - visibility, - maybe_append(attrs, extra_attrs)); - return Ok(Some(item)); + let span = lo.to(self.prev_span); + let attrs = maybe_append(attrs, extra_attrs); + return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs))); } if let Some(macro_def) = self.eat_macro_def(&attrs, &visibility, lo)? { return Ok(Some(macro_def)); -- cgit 1.4.1-3-g733a5 From 151ce96e3e6c909ec071a313eaddc5e9f3b8f6bd Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Sep 2019 09:32:51 +0200 Subject: syntax: reduce repetition in fn parsing. --- src/libsyntax/parse/parser/item.rs | 47 +++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 26 deletions(-) (limited to 'src/libsyntax/parse/parser') diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs index 68f0357abd0..e8ca264f1c5 100644 --- a/src/libsyntax/parse/parser/item.rs +++ b/src/libsyntax/parse/parser/item.rs @@ -122,15 +122,12 @@ impl<'a> Parser<'a> { if self.eat_keyword(kw::Fn) { // EXTERN FUNCTION ITEM let fn_span = self.prev_span; - let (ident, item_, extra_attrs) = self.parse_item_fn(FnHeader { + return self.parse_item_fn(lo, visibility, attrs, FnHeader { unsafety: Unsafety::Normal, asyncness: respan(fn_span, IsAsync::NotAsync), constness: respan(fn_span, Constness::NotConst), abi: opt_abi.unwrap_or(Abi::C), - })?; - let span = lo.to(self.prev_span); - let attrs = maybe_append(attrs, extra_attrs); - return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs))); + }); } else if self.check(&token::OpenDelim(token::Brace)) { return Ok(Some( self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs, extern_sp)?, @@ -157,15 +154,12 @@ impl<'a> Parser<'a> { // CONST FUNCTION ITEM let unsafety = self.parse_unsafety(); self.bump(); - let (ident, item_, extra_attrs) = self.parse_item_fn(FnHeader { + return self.parse_item_fn(lo, visibility, attrs, FnHeader { unsafety, asyncness: respan(const_span, IsAsync::NotAsync), constness: respan(const_span, Constness::Const), abi: Abi::Rust, - })?; - let span = lo.to(self.prev_span); - let attrs = maybe_append(attrs, extra_attrs); - return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs))); + }); } // CONST ITEM @@ -202,16 +196,14 @@ impl<'a> Parser<'a> { closure_id: DUMMY_NODE_ID, return_impl_trait_id: DUMMY_NODE_ID, }); - let (ident, item_, extra_attrs) = self.parse_item_fn(FnHeader { + let item = self.parse_item_fn(lo, visibility, attrs, FnHeader { unsafety, asyncness, constness: respan(fn_span, Constness::NotConst), abi: Abi::Rust, })?; self.ban_async_in_2015(async_span); - let span = lo.to(self.prev_span); - let attrs = maybe_append(attrs, extra_attrs); - return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs))); + return Ok(item); } } if self.check_keyword(kw::Unsafe) && @@ -249,15 +241,12 @@ impl<'a> Parser<'a> { // FUNCTION ITEM self.bump(); let fn_span = self.prev_span; - let (ident, item_, extra_attrs) = self.parse_item_fn(FnHeader { + return self.parse_item_fn(lo, visibility, attrs, FnHeader { unsafety: Unsafety::Normal, asyncness: respan(fn_span, IsAsync::NotAsync), constness: respan(fn_span, Constness::NotConst), abi: Abi::Rust, - })?; - let span = lo.to(self.prev_span); - let attrs = maybe_append(attrs, extra_attrs); - return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs))); + }); } if self.check_keyword(kw::Unsafe) && self.look_ahead(1, |t| *t != token::OpenDelim(token::Brace)) { @@ -272,15 +261,12 @@ impl<'a> Parser<'a> { }; self.expect_keyword(kw::Fn)?; let fn_span = self.prev_span; - let (ident, item_, extra_attrs) = self.parse_item_fn(FnHeader { + return self.parse_item_fn(lo, visibility, attrs, FnHeader { unsafety: Unsafety::Unsafe, asyncness: respan(fn_span, IsAsync::NotAsync), constness: respan(fn_span, Constness::NotConst), abi, - })?; - let span = lo.to(self.prev_span); - let attrs = maybe_append(attrs, extra_attrs); - return Ok(Some(self.mk_item(span, ident, item_, visibility, attrs))); + }); } if self.eat_keyword(kw::Mod) { // MODULE ITEM @@ -1195,11 +1181,20 @@ impl<'a> Parser<'a> { } /// Parses an item-position function declaration. - fn parse_item_fn(&mut self, header: FnHeader) -> PResult<'a, ItemInfo> { + fn parse_item_fn( + &mut self, + lo: Span, + vis: Visibility, + attrs: Vec, + header: FnHeader, + ) -> PResult<'a, Option>> { let allow_c_variadic = header.abi == Abi::C && header.unsafety == Unsafety::Unsafe; let (ident, decl, generics) = self.parse_fn_sig(allow_c_variadic)?; let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; - Ok((ident, ItemKind::Fn(decl, header, generics, body), Some(inner_attrs))) + let span = lo.to(self.prev_span); + let kind = ItemKind::Fn(decl, header, generics, body); + let attrs = maybe_append(attrs, Some(inner_attrs)); + Ok(Some(self.mk_item(span, ident, kind, vis, attrs))) } /// Parse the "signature", including the identifier, parameters, and generics of a function. -- cgit 1.4.1-3-g733a5 From 5c5dd8069d0aeeb97ef6b6099767f97aec1edee4 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 1 Oct 2019 06:10:06 +0200 Subject: syntax: reformat passing of `FnHeader` to `parse_item_fn`. --- src/libsyntax/parse/parser/item.rs | 28 ++++++++++++---------- .../async-await/edition-deny-async-fns-2015.stderr | 12 +++++----- 2 files changed, 22 insertions(+), 18 deletions(-) (limited to 'src/libsyntax/parse/parser') diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs index e8ca264f1c5..c00a5807d52 100644 --- a/src/libsyntax/parse/parser/item.rs +++ b/src/libsyntax/parse/parser/item.rs @@ -122,12 +122,13 @@ impl<'a> Parser<'a> { if self.eat_keyword(kw::Fn) { // EXTERN FUNCTION ITEM let fn_span = self.prev_span; - return self.parse_item_fn(lo, visibility, attrs, FnHeader { + let header = FnHeader { unsafety: Unsafety::Normal, asyncness: respan(fn_span, IsAsync::NotAsync), constness: respan(fn_span, Constness::NotConst), abi: opt_abi.unwrap_or(Abi::C), - }); + }; + return self.parse_item_fn(lo, visibility, attrs, header); } else if self.check(&token::OpenDelim(token::Brace)) { return Ok(Some( self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs, extern_sp)?, @@ -154,12 +155,13 @@ impl<'a> Parser<'a> { // CONST FUNCTION ITEM let unsafety = self.parse_unsafety(); self.bump(); - return self.parse_item_fn(lo, visibility, attrs, FnHeader { + let header = FnHeader { unsafety, asyncness: respan(const_span, IsAsync::NotAsync), constness: respan(const_span, Constness::Const), abi: Abi::Rust, - }); + }; + return self.parse_item_fn(lo, visibility, attrs, header); } // CONST ITEM @@ -196,14 +198,14 @@ impl<'a> Parser<'a> { closure_id: DUMMY_NODE_ID, return_impl_trait_id: DUMMY_NODE_ID, }); - let item = self.parse_item_fn(lo, visibility, attrs, FnHeader { + self.ban_async_in_2015(async_span); + let header = FnHeader { unsafety, asyncness, constness: respan(fn_span, Constness::NotConst), abi: Abi::Rust, - })?; - self.ban_async_in_2015(async_span); - return Ok(item); + }; + return self.parse_item_fn(lo, visibility, attrs, header); } } if self.check_keyword(kw::Unsafe) && @@ -241,12 +243,13 @@ impl<'a> Parser<'a> { // FUNCTION ITEM self.bump(); let fn_span = self.prev_span; - return self.parse_item_fn(lo, visibility, attrs, FnHeader { + let header = FnHeader { unsafety: Unsafety::Normal, asyncness: respan(fn_span, IsAsync::NotAsync), constness: respan(fn_span, Constness::NotConst), abi: Abi::Rust, - }); + }; + return self.parse_item_fn(lo, visibility, attrs, header); } if self.check_keyword(kw::Unsafe) && self.look_ahead(1, |t| *t != token::OpenDelim(token::Brace)) { @@ -261,12 +264,13 @@ impl<'a> Parser<'a> { }; self.expect_keyword(kw::Fn)?; let fn_span = self.prev_span; - return self.parse_item_fn(lo, visibility, attrs, FnHeader { + let header = FnHeader { unsafety: Unsafety::Unsafe, asyncness: respan(fn_span, IsAsync::NotAsync), constness: respan(fn_span, Constness::NotConst), abi, - }); + }; + return self.parse_item_fn(lo, visibility, attrs, header); } if self.eat_keyword(kw::Mod) { // MODULE ITEM diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr index d3f88af09d1..7633825eb32 100644 --- a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr +++ b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr @@ -10,18 +10,18 @@ error[E0670]: `async fn` is not permitted in the 2015 edition LL | fn baz() { async fn foo() {} } | ^^^^^ -error[E0670]: `async fn` is not permitted in the 2015 edition - --> $DIR/edition-deny-async-fns-2015.rs:8:5 - | -LL | async fn bar() {} - | ^^^^^ - error[E0670]: `async fn` is not permitted in the 2015 edition --> $DIR/edition-deny-async-fns-2015.rs:7:1 | LL | async fn async_baz() { | ^^^^^ +error[E0670]: `async fn` is not permitted in the 2015 edition + --> $DIR/edition-deny-async-fns-2015.rs:8:5 + | +LL | async fn bar() {} + | ^^^^^ + error[E0670]: `async fn` is not permitted in the 2015 edition --> $DIR/edition-deny-async-fns-2015.rs:14:5 | -- cgit 1.4.1-3-g733a5