blob: d1e889c3d83a9247ebde8bf50b28f95bcea373bf [file] [log] [blame]
David Tolnayb79ee962016-09-04 09:39:20 -07001use super::*;
2
David Tolnay86eca752016-09-04 11:26:41 -07003#[cfg(feature = "parsing")]
David Tolnayb79ee962016-09-04 09:39:20 -07004use common::word;
David Tolnay86eca752016-09-04 11:26:41 -07005#[cfg(feature = "parsing")]
David Tolnayb79ee962016-09-04 09:39:20 -07006use ty::{ty, poly_trait_ref};
David Tolnay86eca752016-09-04 11:26:41 -07007#[cfg(feature = "parsing")]
David Tolnay65e7f302016-09-04 10:19:25 -07008use nom::multispace;
David Tolnayb79ee962016-09-04 09:39:20 -07009
10#[derive(Debug, Clone, Eq, PartialEq, Default)]
11pub struct Generics {
12 pub lifetimes: Vec<LifetimeDef>,
13 pub ty_params: Vec<TyParam>,
14 pub where_clause: Vec<WherePredicate>,
15}
16
17#[derive(Debug, Clone, Eq, PartialEq)]
18pub struct Lifetime {
19 pub ident: Ident,
20}
21
22#[derive(Debug, Clone, Eq, PartialEq)]
23pub struct LifetimeDef {
24 pub lifetime: Lifetime,
25 pub bounds: Vec<Lifetime>,
26}
27
28#[derive(Debug, Clone, Eq, PartialEq)]
29pub struct TyParam {
30 pub ident: Ident,
31 pub bounds: Vec<TyParamBound>,
32 pub default: Option<Ty>,
33}
34
35#[derive(Debug, Clone, Eq, PartialEq)]
36pub enum TyParamBound {
37 MaybeSized,
38 Region(Lifetime),
39 Trait(PolyTraitRef),
40}
41
42/// A single predicate in a `where` clause
43#[derive(Debug, Clone, Eq, PartialEq)]
44pub enum WherePredicate {
45 /// A type binding, e.g. `for<'c> Foo: Send+Clone+'c`
46 BoundPredicate(WhereBoundPredicate),
47 /// A lifetime predicate, e.g. `'a: 'b+'c`
48 RegionPredicate(WhereRegionPredicate),
49}
50
51/// A type bound.
52///
53/// E.g. `for<'c> Foo: Send+Clone+'c`
54#[derive(Debug, Clone, Eq, PartialEq)]
55pub struct WhereBoundPredicate {
56 /// Any lifetimes from a `for` binding
57 pub bound_lifetimes: Vec<LifetimeDef>,
58 /// The type being bounded
59 pub bounded_ty: Ty,
60 /// Trait and lifetime bounds (`Clone+Send+'static`)
61 pub bounds: Vec<TyParamBound>,
62}
63
64/// A lifetime predicate.
65///
66/// E.g. `'a: 'b+'c`
67#[derive(Debug, Clone, Eq, PartialEq)]
68pub struct WhereRegionPredicate {
69 pub lifetime: Lifetime,
70 pub bounds: Vec<Lifetime>,
71}
72
David Tolnay86eca752016-09-04 11:26:41 -070073#[cfg(feature = "parsing")]
David Tolnay6b7aaf02016-09-04 10:39:25 -070074named!(pub generics<&str, Generics>, do_parse!(
David Tolnayb79ee962016-09-04 09:39:20 -070075 bracketed: alt!(
David Tolnay6b7aaf02016-09-04 10:39:25 -070076 do_parse!(
77 punct!("<") >>
78 lifetimes: separated_list!(punct!(","), lifetime_def) >>
David Tolnayb79ee962016-09-04 09:39:20 -070079 ty_params: opt_vec!(preceded!(
80 cond!(!lifetimes.is_empty(), punct!(",")),
81 separated_nonempty_list!(punct!(","), ty_param)
David Tolnay6b7aaf02016-09-04 10:39:25 -070082 )) >>
83 punct!(">") >>
84 (lifetimes, ty_params)
David Tolnayb79ee962016-09-04 09:39:20 -070085 )
86 |
87 epsilon!() => { |_| (Vec::new(), Vec::new()) }
David Tolnay6b7aaf02016-09-04 10:39:25 -070088 ) >>
89 where_clause: opt_vec!(do_parse!(
90 punct!("where") >>
91 multispace >>
92 predicates: separated_nonempty_list!(punct!(","), where_predicate) >>
93 opt!(punct!(",")) >>
94 (predicates)
95 )) >>
96 (Generics {
David Tolnayb79ee962016-09-04 09:39:20 -070097 lifetimes: bracketed.0,
98 ty_params: bracketed.1,
99 where_clause: where_clause,
David Tolnay6b7aaf02016-09-04 10:39:25 -0700100 })
David Tolnayb79ee962016-09-04 09:39:20 -0700101));
102
David Tolnay86eca752016-09-04 11:26:41 -0700103#[cfg(feature = "parsing")]
David Tolnayb79ee962016-09-04 09:39:20 -0700104named!(pub lifetime<&str, Lifetime>, preceded!(
105 punct!("'"),
106 map!(word, |ident| Lifetime { ident: ident })
107));
108
David Tolnay86eca752016-09-04 11:26:41 -0700109#[cfg(feature = "parsing")]
David Tolnay6b7aaf02016-09-04 10:39:25 -0700110named!(pub lifetime_def<&str, LifetimeDef>, do_parse!(
111 life: lifetime >>
David Tolnayb79ee962016-09-04 09:39:20 -0700112 bounds: opt_vec!(preceded!(
113 punct!(":"),
114 separated_nonempty_list!(punct!(","), lifetime)
David Tolnay6b7aaf02016-09-04 10:39:25 -0700115 )) >>
116 (LifetimeDef {
David Tolnayb79ee962016-09-04 09:39:20 -0700117 lifetime: life,
118 bounds: bounds,
David Tolnay6b7aaf02016-09-04 10:39:25 -0700119 })
David Tolnayb79ee962016-09-04 09:39:20 -0700120));
121
David Tolnay86eca752016-09-04 11:26:41 -0700122#[cfg(feature = "parsing")]
David Tolnay6b7aaf02016-09-04 10:39:25 -0700123named!(pub bound_lifetimes<&str, Vec<LifetimeDef> >, opt_vec!(do_parse!(
124 punct!("for") >>
125 punct!("<") >>
126 lifetimes: separated_list!(punct!(","), lifetime_def) >>
127 punct!(">") >>
128 (lifetimes)
David Tolnayb79ee962016-09-04 09:39:20 -0700129)));
130
David Tolnay86eca752016-09-04 11:26:41 -0700131#[cfg(feature = "parsing")]
David Tolnay6b7aaf02016-09-04 10:39:25 -0700132named!(ty_param<&str, TyParam>, do_parse!(
133 ident: word >>
David Tolnayb79ee962016-09-04 09:39:20 -0700134 bounds: opt_vec!(preceded!(
135 punct!(":"),
136 separated_nonempty_list!(punct!("+"), ty_param_bound)
David Tolnay6b7aaf02016-09-04 10:39:25 -0700137 )) >>
David Tolnayb79ee962016-09-04 09:39:20 -0700138 default: opt!(preceded!(
139 punct!("="),
140 ty
David Tolnay6b7aaf02016-09-04 10:39:25 -0700141 )) >>
142 (TyParam {
David Tolnayb79ee962016-09-04 09:39:20 -0700143 ident: ident,
144 bounds: bounds,
145 default: default,
David Tolnay6b7aaf02016-09-04 10:39:25 -0700146 })
David Tolnayb79ee962016-09-04 09:39:20 -0700147));
148
David Tolnay86eca752016-09-04 11:26:41 -0700149#[cfg(feature = "parsing")]
David Tolnayb79ee962016-09-04 09:39:20 -0700150named!(pub ty_param_bound<&str, TyParamBound>, alt!(
151 tuple!(punct!("?"), punct!("Sized")) => { |_| TyParamBound::MaybeSized }
152 |
153 lifetime => { TyParamBound::Region }
154 |
155 poly_trait_ref => { TyParamBound::Trait }
156));
157
David Tolnay86eca752016-09-04 11:26:41 -0700158#[cfg(feature = "parsing")]
David Tolnayb79ee962016-09-04 09:39:20 -0700159named!(where_predicate<&str, WherePredicate>, alt!(
David Tolnay6b7aaf02016-09-04 10:39:25 -0700160 do_parse!(
161 ident: lifetime >>
162 punct!(":") >>
163 bounds: separated_nonempty_list!(punct!("+"), lifetime) >>
164 (WherePredicate::RegionPredicate(WhereRegionPredicate {
David Tolnayb79ee962016-09-04 09:39:20 -0700165 lifetime: ident,
166 bounds: bounds,
David Tolnay6b7aaf02016-09-04 10:39:25 -0700167 }))
David Tolnayb79ee962016-09-04 09:39:20 -0700168 )
169 |
David Tolnay6b7aaf02016-09-04 10:39:25 -0700170 do_parse!(
171 bound_lifetimes: bound_lifetimes >>
172 bounded_ty: ty >>
173 punct!(":") >>
174 bounds: separated_nonempty_list!(punct!("+"), ty_param_bound) >>
175 (WherePredicate::BoundPredicate(WhereBoundPredicate {
David Tolnayb79ee962016-09-04 09:39:20 -0700176 bound_lifetimes: bound_lifetimes,
177 bounded_ty: bounded_ty,
178 bounds: bounds,
David Tolnay6b7aaf02016-09-04 10:39:25 -0700179 }))
David Tolnayb79ee962016-09-04 09:39:20 -0700180 )
181));