1 //! FIXME: write short doc here
5 pub(super) fn opt_generic_param_list(p: &mut Parser) {
12 fn generic_param_list(p: &mut Parser) {
17 while !p.at(EOF) && !p.at(T![>]) {
20 // test generic_lifetime_type_attribute
21 // fn foo<#[derive(Lifetime)] 'a, #[derive(Type)] T>(_: &'a T) {
23 attributes::outer_attrs(p);
26 LIFETIME_IDENT => lifetime_param(p, m),
27 IDENT => type_param(p, m),
28 CONST_KW => const_param(p, m),
31 p.err_and_bump("expected type parameter")
34 if !p.at(T![>]) && !p.expect(T![,]) {
39 m.complete(p, GENERIC_PARAM_LIST);
42 fn lifetime_param(p: &mut Parser, m: Marker) {
43 assert!(p.at(LIFETIME_IDENT));
48 m.complete(p, LIFETIME_PARAM);
51 fn type_param(p: &mut Parser, m: Marker) {
57 // test type_param_default
63 m.complete(p, TYPE_PARAM);
67 // struct S<const N: u32>;
68 fn const_param(p: &mut Parser, m: Marker) {
69 assert!(p.at(CONST_KW));
73 m.complete(p, CONST_PARAM);
76 // test type_param_bounds
77 // struct S<T: 'a + ?Sized + (Copy)>;
78 pub(super) fn bounds(p: &mut Parser) {
81 bounds_without_colon(p);
84 fn lifetime_bounds(p: &mut Parser) {
87 while p.at(LIFETIME_IDENT) {
95 pub(super) fn bounds_without_colon_m(p: &mut Parser, marker: Marker) -> CompletedMarker {
102 marker.complete(p, TYPE_BOUND_LIST)
105 pub(super) fn bounds_without_colon(p: &mut Parser) {
107 bounds_without_colon_m(p, m);
110 fn type_bound(p: &mut Parser) -> bool {
112 let has_paren = p.eat(T!['(']);
115 LIFETIME_IDENT => lifetime(p),
116 T![for] => types::for_type(p, false),
117 _ if paths::is_use_path_start(p) => types::path_type_(p, false),
126 m.complete(p, TYPE_BOUND);
135 // T: Clone + Copy + 'static,
136 // Iterator::Item: 'a,
137 // <T as Iterator>::Item: 'a
139 pub(super) fn opt_where_clause(p: &mut Parser) {
140 if !p.at(T![where]) {
146 while is_where_predicate(p) {
149 let comma = p.eat(T![,]);
151 if is_where_clause_end(p) {
156 p.error("expected comma");
160 m.complete(p, WHERE_CLAUSE);
163 fn is_where_predicate(p: &mut Parser) -> bool {
165 LIFETIME_IDENT => true,
167 token => types::TYPE_FIRST.contains(token),
171 fn is_where_clause_end(p: &mut Parser) -> bool {
172 matches!(p.current(), T!['{'] | T![;] | T![=])
175 fn where_predicate(p: &mut Parser) {
183 p.error("expected colon");
187 p.error("expected lifetime or type");
190 // test where_pred_for
193 // for<'a> F: Fn(&'a str)
196 types::for_binder(p);
204 p.error("expected colon");
208 m.complete(p, WHERE_PRED);