diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-12-01 11:07:49 +0100 |
|---|---|---|
| committer | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-12-12 17:54:48 +0100 |
| commit | 7672bff3780ef0e7ba5313bf23644465644e19e6 (patch) | |
| tree | 9b7530f48523da9cfb6407ca8aed4fba155f5241 | |
| parent | 10270bcd30d1d85a003412e597e367f2e7c89942 (diff) | |
| download | rust-7672bff3780ef0e7ba5313bf23644465644e19e6.tar.gz rust-7672bff3780ef0e7ba5313bf23644465644e19e6.zip | |
Unify associated function parsing.
| -rw-r--r-- | src/librustc_parse/parser/item.rs | 65 | ||||
| -rw-r--r-- | src/libsyntax/ast.rs | 1 |
2 files changed, 24 insertions, 42 deletions
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 3fc4cafc0da..32cc156783c 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -6,7 +6,7 @@ use crate::maybe_whole; use rustc_errors::{PResult, Applicability, DiagnosticBuilder, StashKey}; use rustc_error_codes::*; use syntax::ast::{self, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, AnonConst, Item}; -use syntax::ast::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind}; +use syntax::ast::{ItemKind, ImplItem, TraitItem, TraitItemKind, UseTree, UseTreeKind}; use syntax::ast::{AssocItemKind}; use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness, Extern, StrLit}; use syntax::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind}; @@ -705,7 +705,7 @@ impl<'a> Parser<'a> { // FIXME: code copied from `parse_macro_use_or_failure` -- use abstraction! (Ident::invalid(), ast::ImplItemKind::Macro(mac), Generics::default()) } else { - self.parse_impl_method(at_end, &mut attrs)? + self.parse_assoc_fn(at_end, &mut attrs, |_| true)? }; Ok(ImplItem { @@ -876,7 +876,11 @@ impl<'a> Parser<'a> { // trait item macro. (Ident::invalid(), TraitItemKind::Macro(mac), Generics::default()) } else { - self.parse_trait_item_method(at_end, &mut attrs)? + // This is somewhat dubious; We don't want to allow + // param names to be left off if there is a definition... + // + // We don't allow param names to be left off in edition 2018. + self.parse_assoc_fn(at_end, &mut attrs, |t| t.span.rust_2018())? }; Ok(TraitItem { @@ -1823,48 +1827,40 @@ impl<'a> Parser<'a> { }) } - /// Parses a method or a macro invocation in a trait impl. - fn parse_impl_method( - &mut self, - at_end: &mut bool, - attrs: &mut Vec<Attribute>, - ) -> PResult<'a, (Ident, ImplItemKind, Generics)> { - let (ident, sig, generics) = self.parse_method_sig(|_| true)?; - let body = self.parse_trait_method_body(at_end, attrs)?; - Ok((ident, ast::ImplItemKind::Method(sig, body), generics)) - } - - fn parse_trait_item_method( + fn parse_assoc_fn( &mut self, at_end: &mut bool, attrs: &mut Vec<Attribute>, - ) -> PResult<'a, (Ident, TraitItemKind, 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 (ident, sig, generics) = self.parse_method_sig(|t| t.span.rust_2018())?; - let body = self.parse_trait_method_body(at_end, attrs)?; - Ok((ident, TraitItemKind::Method(sig, body), generics)) + is_name_required: fn(&token::Token) -> bool, + ) -> PResult<'a, (Ident, AssocItemKind, Generics)> { + let header = self.parse_fn_front_matter()?; + let (ident, decl, generics) = self.parse_fn_sig(ParamCfg { + is_self_allowed: true, + allow_c_variadic: false, + is_name_required, + })?; + let sig = FnSig { header, decl }; + let body = self.parse_assoc_fn_body(at_end, attrs)?; + Ok((ident, AssocItemKind::Method(sig, body), generics)) } - /// Parse the "body" of a method in a trait item definition. + /// Parse the "body" of a method in an associated 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( + fn parse_assoc_fn_body( &mut self, at_end: &mut bool, attrs: &mut Vec<Attribute>, ) -> PResult<'a, Option<P<Block>>> { Ok(match self.token.kind { token::Semi => { - debug!("parse_trait_method_body(): parsing required method"); + debug!("parse_assoc_fn_body(): parsing required method"); self.bump(); *at_end = true; None } token::OpenDelim(token::Brace) => { - debug!("parse_trait_method_body(): parsing provided method"); + debug!("parse_assoc_fn_body(): parsing provided method"); *at_end = true; let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; attrs.extend(inner_attrs.iter().cloned()); @@ -1885,21 +1881,6 @@ impl<'a> Parser<'a> { }) } - /// 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: fn(&token::Token) -> bool, - ) -> PResult<'a, (Ident, FnSig, Generics)> { - let header = self.parse_fn_front_matter()?; - let (ident, decl, generics) = self.parse_fn_sig(ParamCfg { - is_self_allowed: true, - allow_c_variadic: false, - is_name_required, - })?; - Ok((ident, FnSig { header, decl }, generics)) - } - /// Parses all the "front matter" for a `fn` declaration, up to /// and including the `fn` keyword: /// diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index dd8a7fa8665..5866f9db078 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1640,6 +1640,7 @@ pub enum AssocItemKind { Const(P<Ty>, Option<P<Expr>>), /// An associated function. + /// FIXME(Centril): Rename to `Fn`. Method(FnSig, Option<P<Block>>), /// An associated type. |
