@@ -117,7 +117,7 @@ impl<'a> Parser<'a> {
117
117
118
118
impl < ' a > Parser < ' a > {
119
119
pub fn parse_item ( & mut self , force_collect : ForceCollect ) -> PResult < ' a , Option < P < Item > > > {
120
- let fn_parse_mode = FnParseMode { req_name : |_| true , req_body : true } ;
120
+ let fn_parse_mode = FnParseMode { req_name : |_, _ | true , req_body : true } ;
121
121
self . parse_item_ ( fn_parse_mode, force_collect) . map ( |i| i. map ( P ) )
122
122
}
123
123
@@ -935,7 +935,7 @@ impl<'a> Parser<'a> {
935
935
& mut self ,
936
936
force_collect : ForceCollect ,
937
937
) -> PResult < ' a , Option < Option < P < AssocItem > > > > {
938
- let fn_parse_mode = FnParseMode { req_name : |_| true , req_body : true } ;
938
+ let fn_parse_mode = FnParseMode { req_name : |_, _ | true , req_body : true } ;
939
939
self . parse_assoc_item ( fn_parse_mode, force_collect)
940
940
}
941
941
@@ -944,7 +944,7 @@ impl<'a> Parser<'a> {
944
944
force_collect : ForceCollect ,
945
945
) -> PResult < ' a , Option < Option < P < AssocItem > > > > {
946
946
let fn_parse_mode =
947
- FnParseMode { req_name : |edition| edition >= Edition :: Edition2018 , req_body : false } ;
947
+ FnParseMode { req_name : |edition, _ | edition >= Edition :: Edition2018 , req_body : false } ;
948
948
self . parse_assoc_item ( fn_parse_mode, force_collect)
949
949
}
950
950
@@ -1221,7 +1221,10 @@ impl<'a> Parser<'a> {
1221
1221
& mut self ,
1222
1222
force_collect : ForceCollect ,
1223
1223
) -> PResult < ' a , Option < Option < P < ForeignItem > > > > {
1224
- let fn_parse_mode = FnParseMode { req_name : |_| true , req_body : false } ;
1224
+ let fn_parse_mode = FnParseMode {
1225
+ req_name : |_, is_dot_dot_dot| is_dot_dot_dot == IsDotDotDot :: No ,
1226
+ req_body : false ,
1227
+ } ;
1225
1228
Ok ( self . parse_item_ ( fn_parse_mode, force_collect) ?. map (
1226
1229
|Item { attrs, id, span, vis, kind, tokens } | {
1227
1230
let kind = match ForeignItemKind :: try_from ( kind) {
@@ -2093,7 +2096,7 @@ impl<'a> Parser<'a> {
2093
2096
let inherited_vis =
2094
2097
Visibility { span : DUMMY_SP , kind : VisibilityKind :: Inherited , tokens : None } ;
2095
2098
// We use `parse_fn` to get a span for the function
2096
- let fn_parse_mode = FnParseMode { req_name : |_| true , req_body : true } ;
2099
+ let fn_parse_mode = FnParseMode { req_name : |_, _ | true , req_body : true } ;
2097
2100
match self . parse_fn (
2098
2101
& mut AttrVec :: new ( ) ,
2099
2102
fn_parse_mode,
@@ -2326,8 +2329,16 @@ impl<'a> Parser<'a> {
2326
2329
/// The function decides if, per-parameter `p`, `p` must have a pattern or just a type.
2327
2330
///
2328
2331
/// This function pointer accepts an edition, because in edition 2015, trait declarations
2329
- /// were allowed to omit parameter names. In 2018, they became required.
2330
- type ReqName = fn ( Edition ) -> bool ;
2332
+ /// were allowed to omit parameter names. In 2018, they became required. It also accepts an
2333
+ /// `IsDotDotDot` parameter, as `extern` function declarations and function pointer types are
2334
+ /// allowed to omit the name of the `...` but regular function items are not.
2335
+ type ReqName = fn ( Edition , IsDotDotDot ) -> bool ;
2336
+
2337
+ #[ derive( PartialEq ) ]
2338
+ pub ( crate ) enum IsDotDotDot {
2339
+ Yes ,
2340
+ No ,
2341
+ }
2331
2342
2332
2343
/// Parsing configuration for functions.
2333
2344
///
@@ -2360,6 +2371,8 @@ pub(crate) struct FnParseMode {
2360
2371
/// to true.
2361
2372
/// * The span is from Edition 2015. In particular, you can get a
2362
2373
/// 2015 span inside a 2021 crate using macros.
2374
+ ///
2375
+ /// Or if `IsDotDotDot::Yes`, this function will also return `false` with an `extern` block.
2363
2376
pub ( super ) req_name : ReqName ,
2364
2377
/// If this flag is set to `true`, then plain, semicolon-terminated function
2365
2378
/// prototypes are not allowed here.
@@ -2991,10 +3004,15 @@ impl<'a> Parser<'a> {
2991
3004
return Ok ( ( res?, Trailing :: No , UsePreAttrPos :: No ) ) ;
2992
3005
}
2993
3006
2994
- let is_name_required = match this. token . kind {
2995
- token:: DotDotDot => false ,
2996
- _ => req_name ( this. token . span . with_neighbor ( this. prev_token . span ) . edition ( ) ) ,
3007
+ let is_dot_dot_dot = if this. token . kind == token:: DotDotDot {
3008
+ IsDotDotDot :: Yes
3009
+ } else {
3010
+ IsDotDotDot :: No
2997
3011
} ;
3012
+ let is_name_required = req_name (
3013
+ this. token . span . with_neighbor ( this. prev_token . span ) . edition ( ) ,
3014
+ is_dot_dot_dot,
3015
+ ) ;
2998
3016
let ( pat, ty) = if is_name_required || this. is_named_param ( ) {
2999
3017
debug ! ( "parse_param_general parse_pat (is_name_required:{})" , is_name_required) ;
3000
3018
let ( pat, colon) = this. parse_fn_param_pat_colon ( ) ?;
0 commit comments