Dyn trait
diff --git a/src/gen/fold.rs b/src/gen/fold.rs
index 586a8d7..8912384 100644
--- a/src/gen/fold.rs
+++ b/src/gen/fold.rs
@@ -2615,6 +2615,7 @@
pub fn fold_type_trait_object<V: Folder + ?Sized>(_visitor: &mut V, _i: TypeTraitObject) -> TypeTraitObject {
TypeTraitObject {
+ dyn_token: _i . dyn_token,
bounds: FoldHelper::lift(_i . bounds, |it| { _visitor.fold_type_param_bound(it) }),
}
}
diff --git a/src/gen/visit.rs b/src/gen/visit.rs
index 8991a4a..947da8c 100644
--- a/src/gen/visit.rs
+++ b/src/gen/visit.rs
@@ -1999,6 +1999,7 @@
}
pub fn visit_type_trait_object<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeTraitObject) {
+ // Skipped field _i . dyn_token;
for el in (_i . bounds).iter() { let it = el.item(); _visitor.visit_type_param_bound(&it) };
}
diff --git a/src/gen/visit_mut.rs b/src/gen/visit_mut.rs
index f22f656..7ef6332 100644
--- a/src/gen/visit_mut.rs
+++ b/src/gen/visit_mut.rs
@@ -1999,6 +1999,7 @@
}
pub fn visit_type_trait_object_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut TypeTraitObject) {
+ // Skipped field _i . dyn_token;
for mut el in (_i . bounds).iter_mut() { let mut it = el.item_mut(); _visitor.visit_type_param_bound_mut(&mut it) };
}
diff --git a/src/ty.rs b/src/ty.rs
index 722f835..b55f2f0 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -53,6 +53,7 @@
/// A trait object type `Bound1 + Bound2 + Bound3`
/// where `Bound` is a trait or a lifetime.
pub TraitObject(TypeTraitObject {
+ pub dyn_token: Option<Token![dyn]>,
pub bounds: Delimited<TypeParamBound, Token![+]>,
}),
/// An `impl Bound1 + Bound2 + Bound3` type
@@ -551,7 +552,7 @@
let mut new_bounds = Delimited::new();
new_bounds.push(delimited::Element::Delimited(path, plus));
new_bounds.extend(rest);
- TypeTraitObject { bounds: new_bounds }.into()
+ TypeTraitObject { dyn_token: None, bounds: new_bounds }.into()
} else {
TypePath { qself: qself, path: path }.into()
}
@@ -629,14 +630,17 @@
}
// Only allow multiple trait references if allow_plus is true.
- named!(ty_poly_trait_ref(allow_plus: bool) -> Type, alt!(
- cond_reduce!(allow_plus, call!(Delimited::parse_terminated_nonempty)) => {
- |x| TypeTraitObject { bounds: x }.into()
- }
- |
- syn!(TypeParamBound) => {
- |x| TypeTraitObject { bounds: vec![x].into() }.into()
- }
+ 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 Synom for TypeImplTrait {
@@ -683,7 +687,8 @@
impl Synom for Path {
named!(parse -> Self, do_parse!(
colon: option!(punct!(::)) >>
- segments: call!(Delimited::parse_separated_nonempty) >>
+ segments: call!(Delimited::<PathSegment, Token![::]>::parse_separated_nonempty) >>
+ cond_reduce!(segments.first().map_or(true, |seg| seg.item().ident != "dyn"), epsilon!()) >>
(Path {
leading_colon: colon,
segments: segments,
@@ -974,6 +979,7 @@
impl ToTokens for TypeTraitObject {
fn to_tokens(&self, tokens: &mut Tokens) {
+ self.dyn_token.to_tokens(tokens);
self.bounds.to_tokens(tokens);
}
}
diff --git a/synom/src/tokens.rs b/synom/src/tokens.rs
index f2f1a89..0b4c6bb 100644
--- a/synom/src/tokens.rs
+++ b/synom/src/tokens.rs
@@ -175,6 +175,7 @@
(pub struct Crate => "crate"),
(pub struct Default => "default"),
(pub struct Do => "do"),
+ (pub struct Dyn => "dyn"),
(pub struct Else => "else"),
(pub struct Enum => "enum"),
(pub struct Extern => "extern"),
@@ -268,6 +269,7 @@
(crate) => { $crate::tokens::Crate };
(default) => { $crate::tokens::Default };
(do) => { $crate::tokens::Do };
+ (dyn) => { $crate::tokens::Dyn };
(else) => { $crate::tokens::Else };
(enum) => { $crate::tokens::Enum };
(extern) => { $crate::tokens::Extern };
@@ -362,6 +364,7 @@
($i:expr, crate) => { call!($i, <$crate::tokens::Crate as $crate::Synom>::parse) };
($i:expr, default) => { call!($i, <$crate::tokens::Default as $crate::Synom>::parse) };
($i:expr, do) => { call!($i, <$crate::tokens::Do as $crate::Synom>::parse) };
+ ($i:expr, dyn) => { call!($i, <$crate::tokens::Dyn as $crate::Synom>::parse) };
($i:expr, else) => { call!($i, <$crate::tokens::Else as $crate::Synom>::parse) };
($i:expr, enum) => { call!($i, <$crate::tokens::Enum as $crate::Synom>::parse) };
($i:expr, extern) => { call!($i, <$crate::tokens::Extern as $crate::Synom>::parse) };