@@ -7,54 +7,59 @@ 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 ( p : & mut Parser ) {
11+ list_ ( p, Flavor :: Function )
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_impl_fn ( p : & mut Parser ) {
17+ list_ ( p, Flavor :: ImplFn )
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+ Function , // Includes trait fn params; omitted param idents are not supported
31+ ImplFn ,
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+ Function | ImplFn | FnPointer => ( T ! [ '(' ] , T ! [ ')' ] )
42+ } ;
43+
4344 let m = p. start ( ) ;
4445 p. bump ( bra) ;
45- if flavor. type_required ( ) {
46+
47+ if let Function = 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+ if let Function | FnPointer = flavor {
60+ if p. at ( T ! [ ...] ) {
61+ break ;
62+ }
5863 }
5964
6065 if !p. at_ts ( VALUE_PARAMETER_FIRST ) {
@@ -68,7 +73,7 @@ fn list_(p: &mut Parser, flavor: Flavor) {
6873 }
6974 // test param_list_vararg
7075 // extern "C" { fn printf(format: *const i8, ...) -> i32; }
71- if flavor. type_required ( ) {
76+ if let Function | FnPointer = flavor {
7277 p. eat ( T ! [ ...] ) ;
7378 }
7479 p. expect ( ket) ;
@@ -80,36 +85,52 @@ const VALUE_PARAMETER_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYP
8085fn value_parameter ( p : & mut Parser , flavor : Flavor ) {
8186 let m = p. start ( ) ;
8287 match flavor {
83- Flavor :: OptionalType | Flavor :: Normal => {
88+ // test trait_fn_placeholder_parameter
89+ // trait Foo {
90+ // fn bar(_: u64, mut x: i32);
91+ // }
92+
93+ // test trait_fn_patterns
94+ // trait T {
95+ // fn f1((a, b): (usize, usize)) {}
96+ // fn f2(S { a, b }: S) {}
97+ // fn f3(NewType(a): NewType) {}
98+ // fn f4(&&a: &&usize) {}
99+ // }
100+
101+ // test fn_patterns
102+ // impl U {
103+ // fn f1((a, b): (usize, usize)) {}
104+ // fn f2(S { a, b }: S) {}
105+ // fn f3(NewType(a): NewType) {}
106+ // fn f4(&&a: &&usize) {}
107+ // }
108+ Flavor :: Function => {
84109 patterns:: pattern ( p) ;
85- if p. at ( T ! [ : ] ) && !p. at ( T ! [ :: ] ) || flavor. type_required ( ) {
86- types:: ascription ( p)
87- }
110+ types:: ascription ( p) ;
88111 }
89112 // 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- {
113+ // type F = Box<Fn(i32, &i32, &i32, ())>;
114+ Flavor :: ImplFn => {
115+ types:: type_ ( p) ;
116+ }
117+ // test fn_pointer_param_ident_path
118+ // type Foo = fn(Bar::Baz);
119+ // type Qux = fn(baz: Bar::Baz);
120+ Flavor :: FnPointer => {
121+ if p. at ( IDENT ) && p. nth ( 1 ) == T ! [ : ] && !p. nth_at ( 1 , T ! [ :: ] ) {
107122 patterns:: pattern ( p) ;
108123 types:: ascription ( p) ;
109124 } else {
110125 types:: type_ ( p) ;
111126 }
112127 }
128+ Flavor :: Closure => {
129+ patterns:: pattern ( p) ;
130+ if p. at ( T ! [ : ] ) && !p. at ( T ! [ :: ] ) {
131+ types:: ascription ( p) ;
132+ }
133+ }
113134 }
114135 m. complete ( p, PARAM ) ;
115136}
0 commit comments