Parse nested imports
diff --git a/src/gen/fold.rs b/src/gen/fold.rs
index 8912384..a7c5f9e 100644
--- a/src/gen/fold.rs
+++ b/src/gen/fold.rs
@@ -313,16 +313,8 @@
 fn fold_path(&mut self, i: Path) -> Path { fold_path(self, i) }
 
 fn fold_path_arguments(&mut self, i: PathArguments) -> PathArguments { fold_path_arguments(self, i) }
-# [ cfg ( feature = "full" ) ]
-fn fold_path_glob(&mut self, i: PathGlob) -> PathGlob { fold_path_glob(self, i) }
-# [ cfg ( feature = "full" ) ]
-fn fold_path_list(&mut self, i: PathList) -> PathList { fold_path_list(self, i) }
-# [ cfg ( feature = "full" ) ]
-fn fold_path_list_item(&mut self, i: PathListItem) -> PathListItem { fold_path_list_item(self, i) }
 
 fn fold_path_segment(&mut self, i: PathSegment) -> PathSegment { fold_path_segment(self, i) }
-# [ cfg ( feature = "full" ) ]
-fn fold_path_simple(&mut self, i: PathSimple) -> PathSimple { fold_path_simple(self, i) }
 
 fn fold_poly_trait_ref(&mut self, i: PolyTraitRef) -> PolyTraitRef { fold_poly_trait_ref(self, i) }
 
@@ -385,12 +377,18 @@
 fn fold_un_op(&mut self, i: UnOp) -> UnOp { fold_un_op(self, i) }
 
 fn fold_unsafety(&mut self, i: Unsafety) -> Unsafety { fold_unsafety(self, i) }
+# [ cfg ( feature = "full" ) ]
+fn fold_use_glob(&mut self, i: UseGlob) -> UseGlob { fold_use_glob(self, i) }
+# [ cfg ( feature = "full" ) ]
+fn fold_use_list(&mut self, i: UseList) -> UseList { fold_use_list(self, i) }
+# [ cfg ( feature = "full" ) ]
+fn fold_use_path(&mut self, i: UsePath) -> UsePath { fold_use_path(self, i) }
+# [ cfg ( feature = "full" ) ]
+fn fold_use_tree(&mut self, i: UseTree) -> UseTree { fold_use_tree(self, i) }
 
 fn fold_variant(&mut self, i: Variant) -> Variant { fold_variant(self, i) }
 
 fn fold_variant_data(&mut self, i: VariantData) -> VariantData { fold_variant_data(self, i) }
-# [ cfg ( feature = "full" ) ]
-fn fold_view_path(&mut self, i: ViewPath) -> ViewPath { fold_view_path(self, i) }
 
 fn fold_vis_crate(&mut self, i: VisCrate) -> VisCrate { fold_vis_crate(self, i) }
 
@@ -1906,7 +1904,9 @@
         attrs: FoldHelper::lift(_i . attrs, |it| { _visitor.fold_attribute(it) }),
         vis: _visitor.fold_visibility(_i . vis),
         use_token: _i . use_token,
-        path: Box::new(_visitor.fold_view_path(* _i . path)),
+        leading_colon: _i . leading_colon,
+        prefix: FoldHelper::lift(_i . prefix, |it| { _visitor.fold_ident(it) }),
+        tree: _visitor.fold_use_tree(_i . tree),
         semi_token: _i . semi_token,
     }
 }
@@ -2221,31 +2221,6 @@
         }
     }
 }
-# [ cfg ( feature = "full" ) ]
-pub fn fold_path_glob<V: Folder + ?Sized>(_visitor: &mut V, _i: PathGlob) -> PathGlob {
-    PathGlob {
-        path: _visitor.fold_path(_i . path),
-        colon2_token: _i . colon2_token,
-        star_token: _i . star_token,
-    }
-}
-# [ cfg ( feature = "full" ) ]
-pub fn fold_path_list<V: Folder + ?Sized>(_visitor: &mut V, _i: PathList) -> PathList {
-    PathList {
-        path: _visitor.fold_path(_i . path),
-        colon2_token: _i . colon2_token,
-        brace_token: _i . brace_token,
-        items: FoldHelper::lift(_i . items, |it| { _visitor.fold_path_list_item(it) }),
-    }
-}
-# [ cfg ( feature = "full" ) ]
-pub fn fold_path_list_item<V: Folder + ?Sized>(_visitor: &mut V, _i: PathListItem) -> PathListItem {
-    PathListItem {
-        name: _visitor.fold_ident(_i . name),
-        rename: (_i . rename).map(|it| { _visitor.fold_ident(it) }),
-        as_token: _i . as_token,
-    }
-}
 
 pub fn fold_path_segment<V: Folder + ?Sized>(_visitor: &mut V, _i: PathSegment) -> PathSegment {
     PathSegment {
@@ -2253,14 +2228,6 @@
         arguments: _visitor.fold_path_arguments(_i . arguments),
     }
 }
-# [ cfg ( feature = "full" ) ]
-pub fn fold_path_simple<V: Folder + ?Sized>(_visitor: &mut V, _i: PathSimple) -> PathSimple {
-    PathSimple {
-        path: _visitor.fold_path(_i . path),
-        as_token: _i . as_token,
-        rename: (_i . rename).map(|it| { _visitor.fold_ident(it) }),
-    }
-}
 
 pub fn fold_poly_trait_ref<V: Folder + ?Sized>(_visitor: &mut V, _i: PolyTraitRef) -> PolyTraitRef {
     PolyTraitRef {
@@ -2660,6 +2627,47 @@
         Normal => { Normal }
     }
 }
+# [ cfg ( feature = "full" ) ]
+pub fn fold_use_glob<V: Folder + ?Sized>(_visitor: &mut V, _i: UseGlob) -> UseGlob {
+    UseGlob {
+        star_token: _i . star_token,
+    }
+}
+# [ cfg ( feature = "full" ) ]
+pub fn fold_use_list<V: Folder + ?Sized>(_visitor: &mut V, _i: UseList) -> UseList {
+    UseList {
+        brace_token: _i . brace_token,
+        items: FoldHelper::lift(_i . items, |it| { _visitor.fold_use_tree(it) }),
+    }
+}
+# [ cfg ( feature = "full" ) ]
+pub fn fold_use_path<V: Folder + ?Sized>(_visitor: &mut V, _i: UsePath) -> UsePath {
+    UsePath {
+        ident: _visitor.fold_ident(_i . ident),
+        rename: _i . rename,
+    }
+}
+# [ cfg ( feature = "full" ) ]
+pub fn fold_use_tree<V: Folder + ?Sized>(_visitor: &mut V, _i: UseTree) -> UseTree {
+    use ::UseTree::*;
+    match _i {
+        Path(_binding_0, ) => {
+            Path (
+                _visitor.fold_use_path(_binding_0),
+            )
+        }
+        Glob(_binding_0, ) => {
+            Glob (
+                _visitor.fold_use_glob(_binding_0),
+            )
+        }
+        List(_binding_0, ) => {
+            List (
+                _visitor.fold_use_list(_binding_0),
+            )
+        }
+    }
+}
 
 pub fn fold_variant<V: Folder + ?Sized>(_visitor: &mut V, _i: Variant) -> Variant {
     Variant {
@@ -2689,27 +2697,6 @@
         Unit => { Unit }
     }
 }
-# [ cfg ( feature = "full" ) ]
-pub fn fold_view_path<V: Folder + ?Sized>(_visitor: &mut V, _i: ViewPath) -> ViewPath {
-    use ::ViewPath::*;
-    match _i {
-        Simple(_binding_0, ) => {
-            Simple (
-                _visitor.fold_path_simple(_binding_0),
-            )
-        }
-        Glob(_binding_0, ) => {
-            Glob (
-                _visitor.fold_path_glob(_binding_0),
-            )
-        }
-        List(_binding_0, ) => {
-            List (
-                _visitor.fold_path_list(_binding_0),
-            )
-        }
-    }
-}
 
 pub fn fold_vis_crate<V: Folder + ?Sized>(_visitor: &mut V, _i: VisCrate) -> VisCrate {
     VisCrate {
diff --git a/src/gen/visit.rs b/src/gen/visit.rs
index 947da8c..237592f 100644
--- a/src/gen/visit.rs
+++ b/src/gen/visit.rs
@@ -286,16 +286,8 @@
 fn visit_path(&mut self, i: &'ast Path) { visit_path(self, i) }
 
 fn visit_path_arguments(&mut self, i: &'ast PathArguments) { visit_path_arguments(self, i) }
-# [ cfg ( feature = "full" ) ]
-fn visit_path_glob(&mut self, i: &'ast PathGlob) { visit_path_glob(self, i) }
-# [ cfg ( feature = "full" ) ]
-fn visit_path_list(&mut self, i: &'ast PathList) { visit_path_list(self, i) }
-# [ cfg ( feature = "full" ) ]
-fn visit_path_list_item(&mut self, i: &'ast PathListItem) { visit_path_list_item(self, i) }
 
 fn visit_path_segment(&mut self, i: &'ast PathSegment) { visit_path_segment(self, i) }
-# [ cfg ( feature = "full" ) ]
-fn visit_path_simple(&mut self, i: &'ast PathSimple) { visit_path_simple(self, i) }
 
 fn visit_poly_trait_ref(&mut self, i: &'ast PolyTraitRef) { visit_poly_trait_ref(self, i) }
 
@@ -358,12 +350,18 @@
 fn visit_un_op(&mut self, i: &'ast UnOp) { visit_un_op(self, i) }
 
 fn visit_unsafety(&mut self, i: &'ast Unsafety) { visit_unsafety(self, i) }
+# [ cfg ( feature = "full" ) ]
+fn visit_use_glob(&mut self, i: &'ast UseGlob) { visit_use_glob(self, i) }
+# [ cfg ( feature = "full" ) ]
+fn visit_use_list(&mut self, i: &'ast UseList) { visit_use_list(self, i) }
+# [ cfg ( feature = "full" ) ]
+fn visit_use_path(&mut self, i: &'ast UsePath) { visit_use_path(self, i) }
+# [ cfg ( feature = "full" ) ]
+fn visit_use_tree(&mut self, i: &'ast UseTree) { visit_use_tree(self, i) }
 
 fn visit_variant(&mut self, i: &'ast Variant) { visit_variant(self, i) }
 
 fn visit_variant_data(&mut self, i: &'ast VariantData) { visit_variant_data(self, i) }
-# [ cfg ( feature = "full" ) ]
-fn visit_view_path(&mut self, i: &'ast ViewPath) { visit_view_path(self, i) }
 
 fn visit_vis_crate(&mut self, i: &'ast VisCrate) { visit_vis_crate(self, i) }
 
@@ -1481,7 +1479,9 @@
     for it in (_i . attrs).iter() { _visitor.visit_attribute(&it) };
     _visitor.visit_visibility(&_i . vis);
     // Skipped field _i . use_token;
-    _visitor.visit_view_path(&_i . path);
+    // Skipped field _i . leading_colon;
+    for el in (_i . prefix).iter() { let it = el.item(); _visitor.visit_ident(&it) };
+    _visitor.visit_use_tree(&_i . tree);
     // Skipped field _i . semi_token;
 }
 
@@ -1713,36 +1713,11 @@
         }
     }
 }
-# [ cfg ( feature = "full" ) ]
-pub fn visit_path_glob<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PathGlob) {
-    _visitor.visit_path(&_i . path);
-    // Skipped field _i . colon2_token;
-    // Skipped field _i . star_token;
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_path_list<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PathList) {
-    _visitor.visit_path(&_i . path);
-    // Skipped field _i . colon2_token;
-    // Skipped field _i . brace_token;
-    for el in (_i . items).iter() { let it = el.item(); _visitor.visit_path_list_item(&it) };
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_path_list_item<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PathListItem) {
-    _visitor.visit_ident(&_i . name);
-    if let Some(ref it) = _i . rename { _visitor.visit_ident(&* it) };
-    // Skipped field _i . as_token;
-}
 
 pub fn visit_path_segment<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PathSegment) {
     _visitor.visit_ident(&_i . ident);
     _visitor.visit_path_arguments(&_i . arguments);
 }
-# [ cfg ( feature = "full" ) ]
-pub fn visit_path_simple<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PathSimple) {
-    _visitor.visit_path(&_i . path);
-    // Skipped field _i . as_token;
-    if let Some(ref it) = _i . rename { _visitor.visit_ident(&* it) };
-}
 
 pub fn visit_poly_trait_ref<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PolyTraitRef) {
     if let Some(ref it) = _i . bound_lifetimes { _visitor.visit_bound_lifetimes(&* it) };
@@ -2033,6 +2008,35 @@
         Normal => { }
     }
 }
+# [ cfg ( feature = "full" ) ]
+pub fn visit_use_glob<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast UseGlob) {
+    // Skipped field _i . star_token;
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_use_list<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast UseList) {
+    // Skipped field _i . brace_token;
+    for el in (_i . items).iter() { let it = el.item(); _visitor.visit_use_tree(&it) };
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_use_path<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast UsePath) {
+    _visitor.visit_ident(&_i . ident);
+    // Skipped field _i . rename;
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_use_tree<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast UseTree) {
+    use ::UseTree::*;
+    match *_i {
+        Path(ref _binding_0, ) => {
+            _visitor.visit_use_path(&* _binding_0);
+        }
+        Glob(ref _binding_0, ) => {
+            _visitor.visit_use_glob(&* _binding_0);
+        }
+        List(ref _binding_0, ) => {
+            _visitor.visit_use_list(&* _binding_0);
+        }
+    }
+}
 
 pub fn visit_variant<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast Variant) {
     _visitor.visit_ident(&_i . ident);
@@ -2056,21 +2060,6 @@
         Unit => { }
     }
 }
-# [ cfg ( feature = "full" ) ]
-pub fn visit_view_path<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast ViewPath) {
-    use ::ViewPath::*;
-    match *_i {
-        Simple(ref _binding_0, ) => {
-            _visitor.visit_path_simple(&* _binding_0);
-        }
-        Glob(ref _binding_0, ) => {
-            _visitor.visit_path_glob(&* _binding_0);
-        }
-        List(ref _binding_0, ) => {
-            _visitor.visit_path_list(&* _binding_0);
-        }
-    }
-}
 
 pub fn visit_vis_crate<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast VisCrate) {
     // Skipped field _i . pub_token;
diff --git a/src/gen/visit_mut.rs b/src/gen/visit_mut.rs
index 7ef6332..2ac4861 100644
--- a/src/gen/visit_mut.rs
+++ b/src/gen/visit_mut.rs
@@ -286,16 +286,8 @@
 fn visit_path_mut(&mut self, i: &mut Path) { visit_path_mut(self, i) }
 
 fn visit_path_arguments_mut(&mut self, i: &mut PathArguments) { visit_path_arguments_mut(self, i) }
-# [ cfg ( feature = "full" ) ]
-fn visit_path_glob_mut(&mut self, i: &mut PathGlob) { visit_path_glob_mut(self, i) }
-# [ cfg ( feature = "full" ) ]
-fn visit_path_list_mut(&mut self, i: &mut PathList) { visit_path_list_mut(self, i) }
-# [ cfg ( feature = "full" ) ]
-fn visit_path_list_item_mut(&mut self, i: &mut PathListItem) { visit_path_list_item_mut(self, i) }
 
 fn visit_path_segment_mut(&mut self, i: &mut PathSegment) { visit_path_segment_mut(self, i) }
-# [ cfg ( feature = "full" ) ]
-fn visit_path_simple_mut(&mut self, i: &mut PathSimple) { visit_path_simple_mut(self, i) }
 
 fn visit_poly_trait_ref_mut(&mut self, i: &mut PolyTraitRef) { visit_poly_trait_ref_mut(self, i) }
 
@@ -358,12 +350,18 @@
 fn visit_un_op_mut(&mut self, i: &mut UnOp) { visit_un_op_mut(self, i) }
 
 fn visit_unsafety_mut(&mut self, i: &mut Unsafety) { visit_unsafety_mut(self, i) }
+# [ cfg ( feature = "full" ) ]
+fn visit_use_glob_mut(&mut self, i: &mut UseGlob) { visit_use_glob_mut(self, i) }
+# [ cfg ( feature = "full" ) ]
+fn visit_use_list_mut(&mut self, i: &mut UseList) { visit_use_list_mut(self, i) }
+# [ cfg ( feature = "full" ) ]
+fn visit_use_path_mut(&mut self, i: &mut UsePath) { visit_use_path_mut(self, i) }
+# [ cfg ( feature = "full" ) ]
+fn visit_use_tree_mut(&mut self, i: &mut UseTree) { visit_use_tree_mut(self, i) }
 
 fn visit_variant_mut(&mut self, i: &mut Variant) { visit_variant_mut(self, i) }
 
 fn visit_variant_data_mut(&mut self, i: &mut VariantData) { visit_variant_data_mut(self, i) }
-# [ cfg ( feature = "full" ) ]
-fn visit_view_path_mut(&mut self, i: &mut ViewPath) { visit_view_path_mut(self, i) }
 
 fn visit_vis_crate_mut(&mut self, i: &mut VisCrate) { visit_vis_crate_mut(self, i) }
 
@@ -1481,7 +1479,9 @@
     for mut it in (_i . attrs).iter_mut() { _visitor.visit_attribute_mut(&mut it) };
     _visitor.visit_visibility_mut(&mut _i . vis);
     // Skipped field _i . use_token;
-    _visitor.visit_view_path_mut(&mut _i . path);
+    // Skipped field _i . leading_colon;
+    for mut el in (_i . prefix).iter_mut() { let mut it = el.item_mut(); _visitor.visit_ident_mut(&mut it) };
+    _visitor.visit_use_tree_mut(&mut _i . tree);
     // Skipped field _i . semi_token;
 }
 
@@ -1713,36 +1713,11 @@
         }
     }
 }
-# [ cfg ( feature = "full" ) ]
-pub fn visit_path_glob_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut PathGlob) {
-    _visitor.visit_path_mut(&mut _i . path);
-    // Skipped field _i . colon2_token;
-    // Skipped field _i . star_token;
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_path_list_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut PathList) {
-    _visitor.visit_path_mut(&mut _i . path);
-    // Skipped field _i . colon2_token;
-    // Skipped field _i . brace_token;
-    for mut el in (_i . items).iter_mut() { let mut it = el.item_mut(); _visitor.visit_path_list_item_mut(&mut it) };
-}
-# [ cfg ( feature = "full" ) ]
-pub fn visit_path_list_item_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut PathListItem) {
-    _visitor.visit_ident_mut(&mut _i . name);
-    if let Some(ref mut it) = _i . rename { _visitor.visit_ident_mut(&mut * it) };
-    // Skipped field _i . as_token;
-}
 
 pub fn visit_path_segment_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut PathSegment) {
     _visitor.visit_ident_mut(&mut _i . ident);
     _visitor.visit_path_arguments_mut(&mut _i . arguments);
 }
-# [ cfg ( feature = "full" ) ]
-pub fn visit_path_simple_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut PathSimple) {
-    _visitor.visit_path_mut(&mut _i . path);
-    // Skipped field _i . as_token;
-    if let Some(ref mut it) = _i . rename { _visitor.visit_ident_mut(&mut * it) };
-}
 
 pub fn visit_poly_trait_ref_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut PolyTraitRef) {
     if let Some(ref mut it) = _i . bound_lifetimes { _visitor.visit_bound_lifetimes_mut(&mut * it) };
@@ -2033,6 +2008,35 @@
         Normal => { }
     }
 }
+# [ cfg ( feature = "full" ) ]
+pub fn visit_use_glob_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut UseGlob) {
+    // Skipped field _i . star_token;
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_use_list_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut UseList) {
+    // Skipped field _i . brace_token;
+    for mut el in (_i . items).iter_mut() { let mut it = el.item_mut(); _visitor.visit_use_tree_mut(&mut it) };
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_use_path_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut UsePath) {
+    _visitor.visit_ident_mut(&mut _i . ident);
+    // Skipped field _i . rename;
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_use_tree_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut UseTree) {
+    use ::UseTree::*;
+    match *_i {
+        Path(ref mut _binding_0, ) => {
+            _visitor.visit_use_path_mut(&mut * _binding_0);
+        }
+        Glob(ref mut _binding_0, ) => {
+            _visitor.visit_use_glob_mut(&mut * _binding_0);
+        }
+        List(ref mut _binding_0, ) => {
+            _visitor.visit_use_list_mut(&mut * _binding_0);
+        }
+    }
+}
 
 pub fn visit_variant_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut Variant) {
     _visitor.visit_ident_mut(&mut _i . ident);
@@ -2056,21 +2060,6 @@
         Unit => { }
     }
 }
-# [ cfg ( feature = "full" ) ]
-pub fn visit_view_path_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut ViewPath) {
-    use ::ViewPath::*;
-    match *_i {
-        Simple(ref mut _binding_0, ) => {
-            _visitor.visit_path_simple_mut(&mut * _binding_0);
-        }
-        Glob(ref mut _binding_0, ) => {
-            _visitor.visit_path_glob_mut(&mut * _binding_0);
-        }
-        List(ref mut _binding_0, ) => {
-            _visitor.visit_path_list_mut(&mut * _binding_0);
-        }
-    }
-}
 
 pub fn visit_vis_crate_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut VisCrate) {
     // Skipped field _i . pub_token;
diff --git a/src/item.rs b/src/item.rs
index f7e3e91..16444e4 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -23,7 +23,9 @@
             pub attrs: Vec<Attribute>,
             pub vis: Visibility,
             pub use_token: Token![use],
-            pub path: Box<ViewPath>,
+            pub leading_colon: Option<Token![::]>,
+            pub prefix: Delimited<Ident, Token![::]>,
+            pub tree: UseTree,
             pub semi_token: Token![;],
         }),
         /// A static item (`static` or `pub static`).
@@ -231,44 +233,25 @@
 }
 
 ast_enum_of_structs! {
-    pub enum ViewPath {
-        /// `foo::bar::baz as quux`
-        ///
-        /// or just
-        ///
-        /// `foo::bar::baz` (with `as baz` implicitly on the right)
-        pub Simple(PathSimple {
-            pub path: Path,
-            pub as_token: Option<Token![as]>,
-            pub rename: Option<Ident>,
+    /// Things that can appear directly inside of a module.
+    pub enum UseTree {
+        /// `use prefix::Ty` or `use prefix::Ty as Renamed`
+        pub Path(UsePath {
+            pub ident: Ident,
+            pub rename: Option<(Token![as], Ident)>,
         }),
-
-        /// `foo::bar::*`
-        pub Glob(PathGlob {
-            pub path: Path,
-            pub colon2_token: Option<Token![::]>,
+        /// `use prefix::*`
+        pub Glob(UseGlob {
             pub star_token: Token![*],
         }),
-
-        /// `foo::bar::{a, b, c}`
-        pub List(PathList {
-            pub path: Path,
-            pub colon2_token: Token![::],
+        /// `use prefix::{a, b, c}`
+        pub List(UseList {
             pub brace_token: tokens::Brace,
-            pub items: Delimited<PathListItem, Token![,]>,
+            pub items: Delimited<UseTree, Token![,]>,
         }),
     }
 }
 
-ast_struct! {
-    pub struct PathListItem {
-        pub name: Ident,
-        /// renamed in list, e.g. `use foo::{bar as baz};`
-        pub rename: Option<Ident>,
-        pub as_token: Option<Token![as]>,
-    }
-}
-
 ast_enum! {
     #[cfg_attr(feature = "clone-impls", derive(Copy))]
     pub enum Constness {
@@ -555,116 +538,88 @@
         attrs: many0!(call!(Attribute::parse_outer)) >>
         vis: syn!(Visibility) >>
         use_: keyword!(use) >>
-        what: syn!(ViewPath) >>
+        leading_colon: option!(punct!(::)) >>
+        mut prefix: call!(Delimited::parse_terminated_with, use_prefix) >>
+        tree: switch!(value!(leading_colon.is_none() && prefix.is_empty()),
+            true => syn!(UseTree)
+            |
+            false => switch!(value!(prefix.empty_or_trailing()),
+                true => syn!(UseTree)
+                |
+                false => alt!(
+                    tuple!(keyword!(as), syn!(Ident)) => {
+                        |rename| UseTree::Path(UsePath {
+                            ident: prefix.pop().unwrap().into_item(),
+                            rename: Some(rename),
+                        })
+                    }
+                    |
+                    epsilon!() => {
+                        |_| UseTree::Path(UsePath {
+                            ident: prefix.pop().unwrap().into_item(),
+                            rename: None,
+                        })
+                    }
+                )
+            )
+        ) >>
         semi: punct!(;) >>
         (ItemUse {
             attrs: attrs,
             vis: vis,
             use_token: use_,
-            path: Box::new(what),
+            leading_colon: leading_colon,
+            prefix: prefix,
+            tree: tree,
             semi_token: semi,
         })
     ));
 
-    impl Synom for ViewPath {
-        named!(parse -> Self, alt!(
-            syn!(PathGlob) => { ViewPath::Glob }
+    named!(use_prefix -> Ident, alt!(
+        syn!(Ident)
+        |
+        keyword!(self) => { Into::into }
+        |
+        keyword!(super) => { Into::into }
+        |
+        keyword!(crate) => { Into::into }
+    ));
+
+    impl_synom!(UseTree "use tree" alt!(
+        syn!(UsePath) => { UseTree::Path }
+        |
+        syn!(UseGlob) => { UseTree::Glob }
+        |
+        syn!(UseList) => { UseTree::List }
+    ));
+
+    impl_synom!(UsePath "use path" do_parse!(
+        ident: alt!(
+            syn!(Ident)
             |
-            syn!(PathList) => { ViewPath::List }
-            |
-            syn!(PathSimple) => { ViewPath::Simple } // must be last
-        ));
-    }
+            keyword!(self) => { Into::into }
+        ) >>
+        rename: option!(tuple!(keyword!(as), syn!(Ident))) >>
+        (UsePath {
+            ident: ident,
+            rename: rename,
+        })
+    ));
 
-    impl Synom for PathSimple {
-        named!(parse -> Self, do_parse!(
-            path: syn!(Path) >>
-            rename: option!(tuple!(keyword!(as), syn!(Ident))) >>
-            (PathSimple {
-                path: path,
-                as_token: rename.as_ref().map(|p| Token![as]((p.0).0)),
-                rename: rename.map(|p| p.1),
-            })
-        ));
-    }
+    impl_synom!(UseGlob "use glob" do_parse!(
+        star: punct!(*) >>
+        (UseGlob {
+            star_token: star,
+        })
+    ));
 
-    impl Synom for PathGlob {
-        named!(parse -> Self, do_parse!(
-            path: option!(do_parse!(
-                path: syn!(Path) >>
-                colon2: punct!(::) >>
-                (path, colon2)
-            )) >>
-            star: punct!(*) >>
-            ({
-                match path {
-                    Some((path, colon2)) => {
-                        PathGlob {
-                            path: path,
-                            colon2_token: Some(colon2),
-                            star_token: star,
-                        }
-                    }
-                    None => {
-                        PathGlob {
-                            path: Path {
-                                leading_colon: None,
-                                segments: Default::default(),
-                            },
-                            colon2_token: None,
-                            star_token: star,
-                        }
-                    }
-                }
-            })
-        ));
-    }
-
-    impl Synom for PathList {
-        named!(parse -> Self, alt!(
-            do_parse!(
-                path: syn!(Path) >>
-                colon2: punct!(::) >>
-                items: braces!(call!(Delimited::parse_terminated)) >>
-                (PathList {
-                    path: path,
-                    items: items.0,
-                    brace_token: items.1,
-                    colon2_token: colon2,
-                })
-            )
-            |
-            do_parse!(
-                colon: option!(punct!(::)) >>
-                items: braces!(call!(Delimited::parse_terminated)) >>
-                (PathList {
-                    path: Path {
-                        leading_colon: None,
-                        segments: Delimited::new(),
-                    },
-                    colon2_token: colon.unwrap_or_default(),
-                    brace_token: items.1,
-                    items: items.0,
-                })
-            )
-        ));
-    }
-
-    impl Synom for PathListItem {
-        named!(parse -> Self, do_parse!(
-            name: alt!(
-                syn!(Ident)
-                |
-                map!(keyword!(self), Into::into)
-            ) >>
-            rename: option!(tuple!(keyword!(as), syn!(Ident))) >>
-            (PathListItem {
-                name: name,
-                as_token: rename.as_ref().map(|p| Token![as]((p.0).0)),
-                rename: rename.map(|p| p.1),
-            })
-        ));
-    }
+    impl_synom!(UseList "use list" do_parse!(
+        list: braces!(Delimited::parse_terminated) >>
+        (UseList {
+            brace_token: list.1,
+            items: list.0,
+        })
+    ));
 
     impl_synom!(ItemStatic "static item" do_parse!(
         attrs: many0!(call!(Attribute::parse_outer)) >>
@@ -1372,7 +1327,9 @@
             tokens.append_all(self.attrs.outer());
             self.vis.to_tokens(tokens);
             self.use_token.to_tokens(tokens);
-            self.path.to_tokens(tokens);
+            self.leading_colon.to_tokens(tokens);
+            self.prefix.to_tokens(tokens);
+            self.tree.to_tokens(tokens);
             self.semi_token.to_tokens(tokens);
         }
     }
@@ -1591,46 +1548,30 @@
         }
     }
 
-    impl ToTokens for PathSimple {
+    impl ToTokens for UsePath {
         fn to_tokens(&self, tokens: &mut Tokens) {
-            self.path.to_tokens(tokens);
-            if self.rename.is_some() {
-                TokensOrDefault(&self.as_token).to_tokens(tokens);
-                self.rename.to_tokens(tokens);
+            self.ident.to_tokens(tokens);
+            if let Some((ref as_token, ref rename)) = self.rename {
+                as_token.to_tokens(tokens);
+                rename.to_tokens(tokens);
             }
         }
     }
 
-    impl ToTokens for PathGlob {
+    impl ToTokens for UseGlob {
         fn to_tokens(&self, tokens: &mut Tokens) {
-            if self.path.segments.len() > 0 {
-                self.path.to_tokens(tokens);
-                TokensOrDefault(&self.colon2_token).to_tokens(tokens);
-            }
             self.star_token.to_tokens(tokens);
         }
     }
 
-    impl ToTokens for PathList {
+    impl ToTokens for UseList {
         fn to_tokens(&self, tokens: &mut Tokens) {
-            self.path.to_tokens(tokens);
-            self.colon2_token.to_tokens(tokens);
             self.brace_token.surround(tokens, |tokens| {
                 self.items.to_tokens(tokens);
             });
         }
     }
 
-    impl ToTokens for PathListItem {
-        fn to_tokens(&self, tokens: &mut Tokens) {
-            self.name.to_tokens(tokens);
-            if self.rename.is_some() {
-                TokensOrDefault(&self.as_token).to_tokens(tokens);
-                self.rename.to_tokens(tokens);
-            }
-        }
-    }
-
     impl ToTokens for TraitItemConst {
         fn to_tokens(&self, tokens: &mut Tokens) {
             tokens.append_all(self.attrs.outer());
diff --git a/src/lib.rs b/src/lib.rs
index bcad33a..71534e9 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -53,14 +53,14 @@
 mod item;
 #[cfg(feature = "full")]
 pub use item::{Constness, Defaultness, FnArg, FnDecl, ForeignItem, ItemForeignMod,
-               ImplItem, ImplPolarity, Item, MethodSig, PathListItem,
-               TraitItem, ViewPath, ItemExternCrate, ItemUse,
+               ImplItem, ImplPolarity, Item, MethodSig,
+               TraitItem, ItemExternCrate, ItemUse,
                ItemStatic, ItemConst, ItemFn, ItemMacro, ItemMacro2, ItemMod, ItemType, ItemEnum,
                ItemStruct, ItemUnion, ItemTrait, ItemDefaultImpl, ItemImpl,
-               PathSimple, PathGlob, PathList, ForeignItemFn, ForeignItemStatic, ForeignItemType,
+               UsePath, UseGlob, UseList, ForeignItemFn, ForeignItemStatic, ForeignItemType,
                TraitItemConst, TraitItemMacro, TraitItemMethod, TraitItemType,
                ImplItemConst, ImplItemMacro, ImplItemMethod, ImplItemType, ArgSelfRef,
-               ArgSelf, ArgCaptured};
+               ArgSelf, ArgCaptured, UseTree};
 
 #[cfg(feature = "full")]
 mod file;
diff --git a/src/ty.rs b/src/ty.rs
index fee6326..8dd0a96 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -747,17 +747,15 @@
     }
 
     named!(mod_style_path_segment -> PathSegment, alt!(
-        map!(syn!(Ident), Into::into)
+        syn!(Ident) => { Into::into }
         |
-        alt!(
-            keyword!(super) => { Into::into }
-            |
-            keyword!(self) => { Into::into }
-            |
-            keyword!(Self) => { Into::into }
-            |
-            keyword!(crate) => { Into::into }
-        )
+        keyword!(super) => { Into::into }
+        |
+        keyword!(self) => { Into::into }
+        |
+        keyword!(Self) => { Into::into }
+        |
+        keyword!(crate) => { Into::into }
     ));
 
     impl Synom for TypeBinding {