@@ -7,54 +7,60 @@ use super::*;
77// fn b(x: i32) {}
88// fn c(x: i32, ) {}
99// fn d(x: i32, y: ()) {}
10- pub ( super ) fn param_list ( p : & mut Parser ) {
11- list_ ( p, Flavor :: Normal )
10+ pub ( super ) fn param_list_fn_def ( p : & mut Parser ) {
11+ list_ ( p, Flavor :: FnDef )
1212}
1313
1414// test param_list_opt_patterns
1515// fn foo<F: FnMut(&mut Foo<'a>)>(){}
16- pub ( super ) fn param_list_opt_patterns ( p : & mut Parser ) {
17- list_ ( p, Flavor :: OptionalPattern )
16+ pub ( super ) fn param_list_fn_trait ( p : & mut Parser ) {
17+ list_ ( p, Flavor :: FnTrait )
1818}
1919
20- pub ( super ) fn param_list_opt_types ( p : & mut Parser ) {
21- list_ ( p, Flavor :: OptionalType )
20+ pub ( super ) fn param_list_fn_ptr ( p : & mut Parser ) {
21+ list_ ( p, Flavor :: FnPointer )
2222}
2323
24- #[ derive( Clone , Copy , Eq , PartialEq ) ]
25- enum Flavor {
26- OptionalType ,
27- OptionalPattern ,
28- Normal ,
24+ pub ( super ) fn param_list_closure ( p : & mut Parser ) {
25+ list_ ( p, Flavor :: Closure )
2926}
3027
31- impl Flavor {
32- fn type_required ( self ) -> bool {
33- match self {
34- Flavor :: OptionalType => false ,
35- _ => true ,
36- }
37- }
28+ #[ derive( Debug , Clone , Copy ) ]
29+ enum Flavor {
30+ FnDef , // Includes trait fn params; omitted param idents are not supported
31+ FnTrait , // Params for `Fn(...)`/`FnMut(...)`/`FnOnce(...)` annotations
32+ FnPointer ,
33+ Closure ,
3834}
3935
4036fn list_ ( p : & mut Parser , flavor : Flavor ) {
41- let ( bra, ket) = if flavor. type_required ( ) { ( T ! [ '(' ] , T ! [ ')' ] ) } else { ( T ! [ |] , T ! [ |] ) } ;
42- assert ! ( p. at( bra) ) ;
37+ use Flavor :: * ;
38+
39+ let ( bra, ket) = match flavor {
40+ Closure => ( T ! [ |] , T ! [ |] ) ,
41+ FnDef | FnTrait | FnPointer => ( T ! [ '(' ] , T ! [ ')' ] ) ,
42+ } ;
43+
4344 let m = p. start ( ) ;
4445 p. bump ( bra) ;
45- if flavor. type_required ( ) {
46+
47+ if let FnDef = flavor {
4648 // test self_param_outer_attr
4749 // fn f(#[must_use] self) {}
4850 attributes:: outer_attributes ( p) ;
4951 opt_self_param ( p) ;
5052 }
53+
5154 while !p. at ( EOF ) && !p. at ( ket) {
5255 // test param_outer_arg
5356 // fn f(#[attr1] pat: Type) {}
5457 attributes:: outer_attributes ( p) ;
5558
56- if flavor. type_required ( ) && p. at ( T ! [ ...] ) {
57- break ;
59+ // test param_list_vararg
60+ // extern "C" { fn printf(format: *const i8, ...) -> i32; }
61+ match flavor {
62+ FnDef | FnPointer if p. eat ( T ! [ ...] ) => break ,
63+ _ => ( ) ,
5864 }
5965
6066 if !p. at_ts ( VALUE_PARAMETER_FIRST ) {
@@ -66,11 +72,7 @@ fn list_(p: &mut Parser, flavor: Flavor) {
6672 p. expect ( T ! [ , ] ) ;
6773 }
6874 }
69- // test param_list_vararg
70- // extern "C" { fn printf(format: *const i8, ...) -> i32; }
71- if flavor. type_required ( ) {
72- p. eat ( T ! [ ...] ) ;
73- }
75+
7476 p. expect ( ket) ;
7577 m. complete ( p, PARAM_LIST ) ;
7678}
@@ -80,36 +82,56 @@ const VALUE_PARAMETER_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYP
8082fn value_parameter ( p : & mut Parser , flavor : Flavor ) {
8183 let m = p. start ( ) ;
8284 match flavor {
83- Flavor :: OptionalType | Flavor :: Normal => {
85+ // test trait_fn_placeholder_parameter
86+ // trait Foo {
87+ // fn bar(_: u64, mut x: i32);
88+ // }
89+
90+ // test trait_fn_patterns
91+ // trait T {
92+ // fn f1((a, b): (usize, usize)) {}
93+ // fn f2(S { a, b }: S) {}
94+ // fn f3(NewType(a): NewType) {}
95+ // fn f4(&&a: &&usize) {}
96+ // }
97+
98+ // test fn_patterns
99+ // impl U {
100+ // fn f1((a, b): (usize, usize)) {}
101+ // fn f2(S { a, b }: S) {}
102+ // fn f3(NewType(a): NewType) {}
103+ // fn f4(&&a: &&usize) {}
104+ // }
105+ Flavor :: FnDef => {
84106 patterns:: pattern ( p) ;
85- if p. at ( T ! [ : ] ) && !p. at ( T ! [ :: ] ) || flavor. type_required ( ) {
86- types:: ascription ( p)
87- }
107+ types:: ascription ( p) ;
88108 }
89109 // test value_parameters_no_patterns
90- // type F = Box<Fn(a: i32, &b: &i32, &mut c: &i32, ())>;
91- Flavor :: OptionalPattern => {
92- let la0 = p. current ( ) ;
93- let la1 = p. nth ( 1 ) ;
94- let la2 = p. nth ( 2 ) ;
95- let la3 = p. nth ( 3 ) ;
96-
97- // test trait_fn_placeholder_parameter
98- // trait Foo {
99- // fn bar(_: u64, mut x: i32);
100- // }
101- if ( la0 == IDENT || la0 == T ! [ _] ) && la1 == T ! [ : ] && !p. nth_at ( 1 , T ! [ :: ] )
102- || la0 == T ! [ mut ] && la1 == IDENT && la2 == T ! [ : ]
103- || la0 == T ! [ & ]
104- && ( la1 == IDENT && la2 == T ! [ : ] && !p. nth_at ( 2 , T ! [ :: ] )
105- || la1 == T ! [ mut ] && la2 == IDENT && la3 == T ! [ : ] && !p. nth_at ( 3 , T ! [ :: ] ) )
106- {
110+ // type F = Box<Fn(i32, &i32, &i32, ())>;
111+ Flavor :: FnTrait => {
112+ types:: type_ ( p) ;
113+ }
114+ // test fn_pointer_param_ident_path
115+ // type Foo = fn(Bar::Baz);
116+ // type Qux = fn(baz: Bar::Baz);
117+ Flavor :: FnPointer => {
118+ if p. at ( IDENT ) && p. nth ( 1 ) == T ! [ : ] && !p. nth_at ( 1 , T ! [ :: ] ) {
107119 patterns:: pattern ( p) ;
108120 types:: ascription ( p) ;
109121 } else {
110122 types:: type_ ( p) ;
111123 }
112124 }
125+ // test closure_params
126+ // fn main() {
127+ // let foo = |bar, baz: Baz, qux: Qux::Quux| ();
128+ // }
129+ Flavor :: Closure => {
130+ patterns:: pattern ( p) ;
131+ if p. at ( T ! [ : ] ) && !p. at ( T ! [ :: ] ) {
132+ types:: ascription ( p) ;
133+ }
134+ }
113135 }
114136 m. complete ( p, PARAM ) ;
115137}
0 commit comments