Clean up parsing of trait types
diff --git a/src/ty.rs b/src/ty.rs
index 04339fe..b2d9046 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -245,7 +245,7 @@
pub struct PolyTraitRef {
/// The `for<'a>` in `for<'a> Foo<&'a T>`
pub bound_lifetimes: Option<BoundLifetimes>,
- /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
+ /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`
pub trait_ref: Path,
}
}
@@ -367,14 +367,14 @@
named!(ambig_ty(allow_plus: bool) -> Type, alt!(
syn!(TypeGroup) => { Type::Group }
|
- // must be before mac
+ // must be before TypeTup
syn!(TypeParen) => { Type::Paren }
|
- // must be before path
+ // must be before TypePath
syn!(Macro) => { Type::Macro }
|
- // must be before ty_poly_trait_ref
- call!(ty_path, allow_plus)
+ // must be before TypeTraitObject
+ call!(TypePath::parse, allow_plus) => { Type::Path }
|
syn!(TypeSlice) => { Type::Slice }
|
@@ -390,8 +390,8 @@
|
syn!(TypeTup) => { Type::Tup }
|
- // Don't try parsing poly_trait_ref if we aren't allowing it
- call!(ty_poly_trait_ref, allow_plus)
+ // Don't try parsing more than one trait bound if we aren't allowing it
+ call!(TypeTraitObject::parse, allow_plus) => { Type::TraitObject }
|
syn!(TypeImplTrait) => { Type::ImplTrait }
|
@@ -518,46 +518,24 @@
));
}
- named!(ty_path(allow_plus: bool) -> Type, do_parse!(
- qpath: qpath >>
- parenthesized: cond!(
- qpath.1.segments.get(qpath.1.segments.len() - 1).item().arguments.is_empty(),
- option!(syn!(ParenthesizedGenericArguments))
- ) >>
- // Only allow parsing additional bounds if allow_plus is true.
- bounds: alt!(
- cond_reduce!(
- allow_plus,
- option!(tuple!(punct!(+), call!(Delimited::<TypeParamBound, Token![+]>::parse_terminated)))
- )
- |
- value!(None)
- ) >>
- ({
- let (qself, mut path) = qpath;
- if let Some(Some(parenthesized)) = parenthesized {
- let parenthesized = PathArguments::Parenthesized(parenthesized);
- let len = path.segments.len();
- path.segments.get_mut(len - 1).item_mut().arguments = parenthesized;
- }
- if let Some((plus, rest)) = bounds {
- let path = TypeParamBound::Trait(
- PolyTraitRef {
- bound_lifetimes: None,
- trait_ref: path,
- },
- TraitBoundModifier::None,
- );
-
- let mut new_bounds = Delimited::new();
- new_bounds.push(delimited::Element::Delimited(path, plus));
- new_bounds.extend(rest);
- TypeTraitObject { dyn_token: None, bounds: new_bounds }.into()
- } else {
- TypePath { qself: qself, path: path }.into()
- }
- })
- ));
+ impl TypePath {
+ named!(parse(allow_plus: bool) -> Self, do_parse!(
+ qpath: qpath >>
+ parenthesized: cond!(
+ qpath.1.segments.last().unwrap().item().arguments.is_empty(),
+ option!(syn!(ParenthesizedGenericArguments))
+ ) >>
+ cond!(allow_plus, not!(peek!(punct!(+)))) >>
+ ({
+ let (qself, mut path) = qpath;
+ if let Some(Some(parenthesized)) = parenthesized {
+ let parenthesized = PathArguments::Parenthesized(parenthesized);
+ path.segments.last_mut().unwrap().item_mut().arguments = parenthesized;
+ }
+ TypePath { qself: qself, path: path }
+ })
+ ));
+ }
named!(pub qpath -> (Option<QSelf>, Path), alt!(
map!(syn!(Path), |p| (None, p))
@@ -565,11 +543,7 @@
do_parse!(
lt: punct!(<) >>
this: syn!(Type) >>
- path: option!(do_parse!(
- as_: keyword!(as) >>
- path: syn!(Path) >>
- (as_, path)
- )) >>
+ path: option!(tuple!(keyword!(as), syn!(Path))) >>
gt: punct!(>) >>
colon2: punct!(::) >>
rest: call!(Delimited::parse_separated_nonempty) >>
@@ -629,19 +603,21 @@
));
}
- // Only allow multiple trait references if allow_plus is true.
- named!(ty_poly_trait_ref(allow_plus: bool) -> Type, do_parse!(
- dyn_token: option!(keyword!(dyn)) >>
- bounds: alt!(
- cond_reduce!(allow_plus, call!(Delimited::parse_terminated_nonempty))
- |
- syn!(TypeParamBound) => { |x| vec![x].into() }
- ) >>
- (TypeTraitObject {
- dyn_token: dyn_token,
- bounds: bounds,
- }.into())
- ));
+ impl TypeTraitObject {
+ // Only allow multiple trait references if allow_plus is true.
+ named!(parse(allow_plus: bool) -> Self, do_parse!(
+ dyn_token: option!(keyword!(dyn)) >>
+ bounds: alt!(
+ cond_reduce!(allow_plus, call!(Delimited::parse_terminated_nonempty))
+ |
+ syn!(TypeParamBound) => { |x| vec![x].into() }
+ ) >>
+ (TypeTraitObject {
+ dyn_token: dyn_token,
+ bounds: bounds,
+ })
+ ));
+ }
impl Synom for TypeImplTrait {
named!(parse -> Self, do_parse!(