@@ -7,7 +7,7 @@ use crate::ast::{
7
7
Item , ItemKind , ImplItem , TraitItem , TraitItemKind ,
8
8
UseTree , UseTreeKind , PathSegment ,
9
9
IsAuto , Constness , IsAsync , Unsafety , Defaultness ,
10
- Visibility , VisibilityKind , Mutability , FnDecl , FnHeader ,
10
+ Visibility , VisibilityKind , Mutability , FnDecl , FnHeader , MethodSig , Block ,
11
11
ForeignItem , ForeignItemKind ,
12
12
Ty , TyKind , Generics , GenericBounds , TraitRef ,
13
13
EnumDef , VariantData , StructField , AnonConst ,
@@ -848,29 +848,38 @@ impl<'a> Parser<'a> {
848
848
}
849
849
850
850
/// 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 ) > {
853
856
// FIXME: code copied from `parse_macro_use_or_failure` -- use abstraction!
854
857
if let Some ( mac) = self . parse_assoc_macro_invoc ( "impl" , Some ( vis) , at_end) ? {
855
858
// 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) ) )
858
860
} 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 ) ?;
864
862
* at_end = true ;
865
863
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) ) )
871
865
}
872
866
}
873
867
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
+
874
883
/// Parses all the "front matter" for a `fn` declaration, up to
875
884
/// and including the `fn` keyword:
876
885
///
@@ -879,14 +888,7 @@ impl<'a> Parser<'a> {
879
888
/// - `const unsafe fn`
880
889
/// - `extern fn`
881
890
/// - 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 > {
890
892
let is_const_fn = self . eat_keyword ( kw:: Const ) ;
891
893
let const_span = self . prev_span ;
892
894
let asyncness = self . parse_asyncness ( ) ;
@@ -911,7 +913,7 @@ impl<'a> Parser<'a> {
911
913
// account for this.
912
914
if !self . expect_one_of ( & [ ] , & [ ] ) ? { unreachable ! ( ) }
913
915
}
914
- Ok ( ( constness, unsafety, asyncness, abi) )
916
+ Ok ( FnHeader { constness, unsafety, asyncness, abi } )
915
917
}
916
918
917
919
/// Parses `trait Foo { ... }` or `trait Foo = Bar;`.
@@ -1025,59 +1027,12 @@ impl<'a> Parser<'a> {
1025
1027
// trait item macro.
1026
1028
( Ident :: invalid ( ) , ast:: TraitItemKind :: Macro ( mac) , Generics :: default ( ) )
1027
1029
} 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
-
1033
1030
// This is somewhat dubious; We don't want to allow
1034
1031
// argument names to be left off if there is a definition...
1035
1032
//
1036
1033
// 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) ?;
1081
1036
( ident, ast:: TraitItemKind :: Method ( sig, body) , generics)
1082
1037
} ;
1083
1038
@@ -1092,6 +1047,43 @@ impl<'a> Parser<'a> {
1092
1047
} )
1093
1048
}
1094
1049
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
+
1095
1087
/// Parses the following grammar:
1096
1088
///
1097
1089
/// TraitItemAssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty]
0 commit comments