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) };