@@ -7,7 +7,7 @@ use crate::ast::{
77 Item , ItemKind , ImplItem , TraitItem , TraitItemKind ,
88 UseTree , UseTreeKind , PathSegment ,
99 IsAuto , Constness , IsAsync , Unsafety , Defaultness ,
10- Visibility , VisibilityKind , Mutability , FnDecl , FnHeader ,
10+ Visibility , VisibilityKind , Mutability , FnDecl , FnHeader , MethodSig , Block ,
1111 ForeignItem , ForeignItemKind ,
1212 Ty , TyKind , Generics , GenericBounds , TraitRef ,
1313 EnumDef , VariantData , StructField , AnonConst ,
@@ -848,29 +848,38 @@ impl<'a> Parser<'a> {
848848 }
849849
850850 /// Parses a method or a macro invocation in a trait impl.
851- fn parse_impl_method ( & mut self , vis : & Visibility , at_end : & mut bool )
852- -> PResult < ' a , ( Ident , Vec < Attribute > , Generics , ast:: ImplItemKind ) > {
851+ fn parse_impl_method (
852+ & mut self ,
853+ vis : & Visibility ,
854+ at_end : & mut bool
855+ ) -> PResult < ' a , ( Ident , Vec < Attribute > , Generics , ast:: ImplItemKind ) > {
853856 // FIXME: code copied from `parse_macro_use_or_failure` -- use abstraction!
854857 if let Some ( mac) = self . parse_assoc_macro_invoc ( "impl" , Some ( vis) , at_end) ? {
855858 // method macro
856- Ok ( ( Ident :: invalid ( ) , vec ! [ ] , Generics :: default ( ) ,
857- ast:: ImplItemKind :: Macro ( mac) ) )
859+ Ok ( ( Ident :: invalid ( ) , vec ! [ ] , Generics :: default ( ) , ast:: ImplItemKind :: Macro ( mac) ) )
858860 } else {
859- let ( constness, unsafety, asyncness, abi) = self . parse_fn_front_matter ( ) ?;
860- let ident = self . parse_ident ( ) ?;
861- let mut generics = self . parse_generics ( ) ?;
862- let decl = self . parse_fn_decl_with_self ( |_| true ) ?;
863- generics. where_clause = self . parse_where_clause ( ) ?;
861+ let ( ident, sig, generics) = self . parse_method_sig ( |_| true ) ?;
864862 * at_end = true ;
865863 let ( inner_attrs, body) = self . parse_inner_attrs_and_block ( ) ?;
866- let header = ast:: FnHeader { abi, unsafety, constness, asyncness } ;
867- Ok ( ( ident, inner_attrs, generics, ast:: ImplItemKind :: Method (
868- ast:: MethodSig { header, decl } ,
869- body
870- ) ) )
864+ Ok ( ( ident, inner_attrs, generics, ast:: ImplItemKind :: Method ( sig, body) ) )
871865 }
872866 }
873867
868+ /// Parse the "signature", including the identifier, parameters, and generics
869+ /// of a method. The body is not parsed as that differs between `trait`s and `impl`s.
870+ fn parse_method_sig (
871+ & mut self ,
872+ is_name_required : impl Copy + Fn ( & token:: Token ) -> bool ,
873+ ) -> PResult < ' a , ( Ident , MethodSig , Generics ) > {
874+ let header = self . parse_fn_front_matter ( ) ?;
875+ let ident = self . parse_ident ( ) ?;
876+ let mut generics = self . parse_generics ( ) ?;
877+ let decl = self . parse_fn_decl_with_self ( is_name_required) ?;
878+ let sig = MethodSig { header, decl } ;
879+ generics. where_clause = self . parse_where_clause ( ) ?;
880+ Ok ( ( ident, sig, generics) )
881+ }
882+
874883 /// Parses all the "front matter" for a `fn` declaration, up to
875884 /// and including the `fn` keyword:
876885 ///
@@ -879,14 +888,7 @@ impl<'a> Parser<'a> {
879888 /// - `const unsafe fn`
880889 /// - `extern fn`
881890 /// - etc.
882- fn parse_fn_front_matter ( & mut self )
883- -> PResult < ' a , (
884- Spanned < Constness > ,
885- Unsafety ,
886- Spanned < IsAsync > ,
887- Abi
888- ) >
889- {
891+ fn parse_fn_front_matter ( & mut self ) -> PResult < ' a , FnHeader > {
890892 let is_const_fn = self . eat_keyword ( kw:: Const ) ;
891893 let const_span = self . prev_span ;
892894 let asyncness = self . parse_asyncness ( ) ;
@@ -911,7 +913,7 @@ impl<'a> Parser<'a> {
911913 // account for this.
912914 if !self . expect_one_of ( & [ ] , & [ ] ) ? { unreachable ! ( ) }
913915 }
914- Ok ( ( constness, unsafety, asyncness, abi) )
916+ Ok ( FnHeader { constness, unsafety, asyncness, abi } )
915917 }
916918
917919 /// Parses `trait Foo { ... }` or `trait Foo = Bar;`.
@@ -1025,59 +1027,12 @@ impl<'a> Parser<'a> {
10251027 // trait item macro.
10261028 ( Ident :: invalid ( ) , ast:: TraitItemKind :: Macro ( mac) , Generics :: default ( ) )
10271029 } else {
1028- let ( constness, unsafety, asyncness, abi) = self . parse_fn_front_matter ( ) ?;
1029-
1030- let ident = self . parse_ident ( ) ?;
1031- let mut generics = self . parse_generics ( ) ?;
1032-
10331030 // This is somewhat dubious; We don't want to allow
10341031 // argument names to be left off if there is a definition...
10351032 //
10361033 // We don't allow argument names to be left off in edition 2018.
1037- let decl = self . parse_fn_decl_with_self ( |t| t. span . rust_2018 ( ) ) ?;
1038- generics. where_clause = self . parse_where_clause ( ) ?;
1039-
1040- let sig = ast:: MethodSig {
1041- header : FnHeader {
1042- unsafety,
1043- constness,
1044- abi,
1045- asyncness,
1046- } ,
1047- decl,
1048- } ;
1049-
1050- let body = match self . token . kind {
1051- token:: Semi => {
1052- self . bump ( ) ;
1053- * at_end = true ;
1054- debug ! ( "parse_trait_methods(): parsing required method" ) ;
1055- None
1056- }
1057- token:: OpenDelim ( token:: Brace ) => {
1058- debug ! ( "parse_trait_methods(): parsing provided method" ) ;
1059- * at_end = true ;
1060- let ( inner_attrs, body) = self . parse_inner_attrs_and_block ( ) ?;
1061- attrs. extend ( inner_attrs. iter ( ) . cloned ( ) ) ;
1062- Some ( body)
1063- }
1064- token:: Interpolated ( ref nt) => {
1065- match * * nt {
1066- token:: NtBlock ( ..) => {
1067- * at_end = true ;
1068- let ( inner_attrs, body) = self . parse_inner_attrs_and_block ( ) ?;
1069- attrs. extend ( inner_attrs. iter ( ) . cloned ( ) ) ;
1070- Some ( body)
1071- }
1072- _ => {
1073- return self . expected_semi_or_open_brace ( ) ;
1074- }
1075- }
1076- }
1077- _ => {
1078- return self . expected_semi_or_open_brace ( ) ;
1079- }
1080- } ;
1034+ let ( ident, sig, generics) = self . parse_method_sig ( |t| t. span . rust_2018 ( ) ) ?;
1035+ let body = self . parse_trait_method_body ( at_end, & mut attrs) ?;
10811036 ( ident, ast:: TraitItemKind :: Method ( sig, body) , generics)
10821037 } ;
10831038
@@ -1092,6 +1047,43 @@ impl<'a> Parser<'a> {
10921047 } )
10931048 }
10941049
1050+ /// Parse the "body" of a method in a trait item definition.
1051+ /// This can either be `;` when there's no body,
1052+ /// or e.g. a block when the method is a provided one.
1053+ fn parse_trait_method_body (
1054+ & mut self ,
1055+ at_end : & mut bool ,
1056+ attrs : & mut Vec < Attribute > ,
1057+ ) -> PResult < ' a , Option < P < Block > > > {
1058+ Ok ( match self . token . kind {
1059+ token:: Semi => {
1060+ debug ! ( "parse_trait_method_body(): parsing required method" ) ;
1061+ self . bump ( ) ;
1062+ * at_end = true ;
1063+ None
1064+ }
1065+ token:: OpenDelim ( token:: Brace ) => {
1066+ debug ! ( "parse_trait_method_body(): parsing provided method" ) ;
1067+ * at_end = true ;
1068+ let ( inner_attrs, body) = self . parse_inner_attrs_and_block ( ) ?;
1069+ attrs. extend ( inner_attrs. iter ( ) . cloned ( ) ) ;
1070+ Some ( body)
1071+ }
1072+ token:: Interpolated ( ref nt) => {
1073+ match * * nt {
1074+ token:: NtBlock ( ..) => {
1075+ * at_end = true ;
1076+ let ( inner_attrs, body) = self . parse_inner_attrs_and_block ( ) ?;
1077+ attrs. extend ( inner_attrs. iter ( ) . cloned ( ) ) ;
1078+ Some ( body)
1079+ }
1080+ _ => return self . expected_semi_or_open_brace ( ) ,
1081+ }
1082+ }
1083+ _ => return self . expected_semi_or_open_brace ( ) ,
1084+ } )
1085+ }
1086+
10951087 /// Parses the following grammar:
10961088 ///
10971089 /// TraitItemAssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty]
0 commit comments