]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #35618 - jseyfried:ast_view_path_refactor, r=eddyb
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>
Sun, 28 Aug 2016 10:31:15 +0000 (10:31 +0000)
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>
Sun, 28 Aug 2016 10:31:24 +0000 (10:31 +0000)
Refactor `PathListItem`s

This refactors away variant `Mod` of `ast::PathListItemKind` and refactors the remaining variant `Ident` to a struct `ast::PathListItem_`.

1  2 
src/librustc/hir/fold.rs
src/librustc/hir/lowering.rs
src/librustc/hir/mod.rs
src/librustc/hir/print.rs
src/librustc/middle/dead.rs
src/librustdoc/clean/mod.rs
src/libsyntax/ast.rs
src/libsyntax/fold.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs

diff --combined src/librustc/hir/fold.rs
index 0b362bac8882b01f782b4534f71a3d0b8630ee45,5e4ca82dd0090312fdfcfbdb3eb0dbabc3a4ca1e..e3b9b51ce6c0ea818b0d50865b94d35fc151f6ed
@@@ -271,16 -271,10 +271,10 @@@ pub fn noop_fold_view_path<T: Folder>(v
                      ViewPathList(fld.fold_path(path),
                                   path_list_idents.move_map(|path_list_ident| {
                                       Spanned {
-                                          node: match path_list_ident.node {
-                                              PathListIdent { id, name, rename } => PathListIdent {
-                                                  id: fld.new_id(id),
-                                                  name: name,
-                                                  rename: rename,
-                                              },
-                                              PathListMod { id, rename } => PathListMod {
-                                                  id: fld.new_id(id),
-                                                  rename: rename,
-                                              },
+                                          node: PathListItem_ {
+                                              id: fld.new_id(path_list_ident.node.id),
+                                              name: path_list_ident.node.name,
+                                              rename: path_list_ident.node.rename,
                                           },
                                           span: fld.new_span(path_list_ident.span),
                                       }
@@@ -577,14 -571,13 +571,14 @@@ pub fn noop_fold_opt_lifetime<T: Folder
      o_lt.map(|lt| fld.fold_lifetime(lt))
  }
  
 -pub fn noop_fold_generics<T: Folder>(Generics { ty_params, lifetimes, where_clause }: Generics,
 +pub fn noop_fold_generics<T: Folder>(Generics {ty_params, lifetimes, where_clause, span}: Generics,
                                       fld: &mut T)
                                       -> Generics {
      Generics {
          ty_params: fld.fold_ty_params(ty_params),
          lifetimes: fld.fold_lifetime_defs(lifetimes),
          where_clause: fld.fold_where_clause(where_clause),
 +        span: fld.new_span(span),
      }
  }
  
index 5c52fde875415c6d80522d9311b36d51ea6e1448,691396b9b7751b9a68b1f4509e3f5ac8d026415a..4ac0bde2835ee10994fe883541ed9d76c9bf0c21
@@@ -218,16 -218,10 +218,10 @@@ impl<'a> LoweringContext<'a> 
  
      fn lower_path_list_item(&mut self, path_list_ident: &PathListItem) -> hir::PathListItem {
          Spanned {
-             node: match path_list_ident.node {
-                 PathListItemKind::Ident { id, name, rename } => hir::PathListIdent {
-                     id: id,
-                     name: name.name,
-                     rename: rename.map(|x| x.name),
-                 },
-                 PathListItemKind::Mod { id, rename } => hir::PathListMod {
-                     id: id,
-                     rename: rename.map(|x| x.name),
-                 },
+             node: hir::PathListItem_ {
+                 id: path_list_ident.node.id,
+                 name: path_list_ident.node.name.name,
+                 rename: path_list_ident.node.rename.map(|rename| rename.name),
              },
              span: path_list_ident.span,
          }
              ty_params: self.lower_ty_params(&g.ty_params),
              lifetimes: self.lower_lifetime_defs(&g.lifetimes),
              where_clause: self.lower_where_clause(&g.where_clause),
 +            span: g.span,
          }
      }
  
                      let inplace_finalize = ["ops", "InPlace", "finalize"];
  
                      let make_call = |this: &mut LoweringContext, p, args| {
 -                        let path = this.core_path(e.span, p);
 +                        let path = this.std_path(e.span, p);
                          let path = this.expr_path(path, ThinVec::new());
                          this.expr_call(e.span, path, args)
                      };
                                     ast_expr: &Expr,
                                     path: &[&str],
                                     fields: &[(&str, &P<Expr>)]) -> P<hir::Expr> {
 -                        let strs = this.std_path(&iter::once(&"ops")
 -                                                        .chain(path)
 -                                                        .map(|s| *s)
 -                                                        .collect::<Vec<_>>());
 -
 -                        let structpath = this.path_global(ast_expr.span, strs);
 +                        let struct_path = this.std_path(ast_expr.span,
 +                                                        &iter::once(&"ops").chain(path)
 +                                                                           .map(|s| *s)
 +                                                                           .collect::<Vec<_>>());
  
                          let hir_expr = if fields.len() == 0 {
 -                            this.expr_path(structpath, ast_expr.attrs.clone())
 +                            this.expr_path(struct_path, ast_expr.attrs.clone())
                          } else {
                              let fields = fields.into_iter().map(|&(s, e)| {
                                  let expr = this.lower_expr(&e);
                              }).collect();
                              let attrs = ast_expr.attrs.clone();
  
 -                            this.expr_struct(ast_expr.span, structpath, fields, None, attrs)
 +                            this.expr_struct(ast_expr.span, struct_path, fields, None, attrs)
                          };
  
                          this.signal_block_expr(hir_vec![],
  
                      // `match ::std::iter::Iterator::next(&mut iter) { ... }`
                      let match_expr = {
 -                        let next_path = {
 -                            let strs = self.std_path(&["iter", "Iterator", "next"]);
 -
 -                            self.path_global(e.span, strs)
 -                        };
 +                        let next_path = self.std_path(e.span, &["iter", "Iterator", "next"]);
                          let iter = self.expr_ident(e.span, iter, iter_pat.id);
                          let ref_mut_iter = self.expr_mut_addr_of(e.span, iter);
                          let next_path = self.expr_path(next_path, ThinVec::new());
  
                      // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
                      let into_iter_expr = {
 -                        let into_iter_path = {
 -                            let strs = self.std_path(&["iter", "IntoIterator", "into_iter"]);
 -
 -                            self.path_global(e.span, strs)
 -                        };
 +                        let into_iter_path = self.std_path(e.span,
 +                                                           &["iter", "IntoIterator", "into_iter"]);
  
                          let into_iter = self.expr_path(into_iter_path, ThinVec::new());
                          self.expr_call(e.span, into_iter, hir_vec![head])
                      // to:
                      //
                      // {
 -                    //     match <expr> {
 +                    //     match { Carrier::translate( { <expr> } ) } {
                      //         Ok(val) => val,
 -                    //         Err(err) => {
 -                    //             return Err(From::from(err))
 -                    //         }
 +                    //         Err(err) => { return Carrier::from_error(From::from(err)); }
                      //     }
                      // }
  
 -                    // expand <expr>
 -                    let sub_expr = self.lower_expr(sub_expr);
 +                    // { Carrier::translate( { <expr> } ) }
 +                    let discr = {
 +                        // expand <expr>
 +                        let sub_expr = self.lower_expr(sub_expr);
 +                        let sub_expr = self.signal_block_expr(hir_vec![],
 +                                                              sub_expr,
 +                                                              e.span,
 +                                                              hir::PopUnstableBlock,
 +                                                              ThinVec::new());
 +
 +                        let path = self.std_path(e.span, &["ops", "Carrier", "translate"]);
 +                        let path = self.expr_path(path, ThinVec::new());
 +                        let call = self.expr_call(e.span, path, hir_vec![sub_expr]);
 +
 +                        self.signal_block_expr(hir_vec![],
 +                                               call,
 +                                               e.span,
 +                                               hir::PushUnstableBlock,
 +                                               ThinVec::new())
 +                    };
  
                      // Ok(val) => val
                      let ok_arm = {
                          self.arm(hir_vec![ok_pat], val_expr)
                      };
  
 -                    // Err(err) => return Err(From::from(err))
 +                    // Err(err) => { return Carrier::from_error(From::from(err)); }
                      let err_arm = {
                          let err_ident = self.str_to_ident("err");
                          let err_local = self.pat_ident(e.span, err_ident);
                          let from_expr = {
 -                            let path = self.std_path(&["convert", "From", "from"]);
 -                            let path = self.path_global(e.span, path);
 +                            let path = self.std_path(e.span, &["convert", "From", "from"]);
                              let from = self.expr_path(path, ThinVec::new());
                              let err_expr = self.expr_ident(e.span, err_ident, err_local.id);
  
                              self.expr_call(e.span, from, hir_vec![err_expr])
                          };
 -                        let err_expr = {
 -                            let path = self.std_path(&["result", "Result", "Err"]);
 -                            let path = self.path_global(e.span, path);
 -                            let err_ctor = self.expr_path(path, ThinVec::new());
 -                            self.expr_call(e.span, err_ctor, hir_vec![from_expr])
 +                        let from_err_expr = {
 +                            let path = self.std_path(e.span, &["ops", "Carrier", "from_error"]);
 +                            let from_err = self.expr_path(path, ThinVec::new());
 +                            self.expr_call(e.span, from_err, hir_vec![from_expr])
                          };
 -                        let err_pat = self.pat_err(e.span, err_local);
 +
                          let ret_expr = self.expr(e.span,
 -                                                 hir::Expr_::ExprRet(Some(err_expr)),
 -                                                 ThinVec::new());
 -                        self.arm(hir_vec![err_pat], ret_expr)
 +                                                 hir::Expr_::ExprRet(Some(from_err_expr)),
 +                                                                     ThinVec::new());
 +                        let ret_stmt = self.stmt_expr(ret_expr);
 +                        let block = self.signal_block_stmt(ret_stmt, e.span,
 +                                                           hir::PushUnstableBlock, ThinVec::new());
 +
 +                        let err_pat = self.pat_err(e.span, err_local);
 +                        self.arm(hir_vec![err_pat], block)
                      };
  
 -                    return self.expr_match(e.span, sub_expr, hir_vec![err_arm, ok_arm],
 +                    return self.expr_match(e.span, discr, hir_vec![err_arm, ok_arm],
                                             hir::MatchSource::TryDesugar);
                  }
  
          (respan(sp, hir::StmtDecl(P(decl), self.next_id())), pat_id)
      }
  
 +    // Turns `<expr>` into `<expr>;`, note that this produces a StmtSemi, not a
 +    // StmtExpr.
 +    fn stmt_expr(&self, expr: P<hir::Expr>) -> hir::Stmt {
 +        hir::Stmt {
 +            span: expr.span,
 +            node: hir::StmtSemi(expr, self.next_id()),
 +        }
 +    }
 +
      fn block_expr(&mut self, expr: P<hir::Expr>) -> P<hir::Block> {
          self.block_all(expr.span, hir::HirVec::new(), Some(expr))
      }
      }
  
      fn pat_ok(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
 -        let ok = self.std_path(&["result", "Result", "Ok"]);
 -        let path = self.path_global(span, ok);
 +        let path = self.std_path(span, &["result", "Result", "Ok"]);
          self.pat_enum(span, path, hir_vec![pat])
      }
  
      fn pat_err(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
 -        let err = self.std_path(&["result", "Result", "Err"]);
 -        let path = self.path_global(span, err);
 +        let path = self.std_path(span, &["result", "Result", "Err"]);
          self.pat_enum(span, path, hir_vec![pat])
      }
  
      fn pat_some(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
 -        let some = self.std_path(&["option", "Option", "Some"]);
 -        let path = self.path_global(span, some);
 +        let path = self.std_path(span, &["option", "Option", "Some"]);
          self.pat_enum(span, path, hir_vec![pat])
      }
  
      fn pat_none(&mut self, span: Span) -> P<hir::Pat> {
 -        let none = self.std_path(&["option", "Option", "None"]);
 -        let path = self.path_global(span, none);
 +        let path = self.std_path(span, &["option", "Option", "None"]);
          self.pat_enum(span, path, hir_vec![])
      }
  
          }
      }
  
 -    fn std_path(&mut self, components: &[&str]) -> Vec<Name> {
 +    fn std_path_components(&mut self, components: &[&str]) -> Vec<Name> {
          let mut v = Vec::new();
          if let Some(s) = self.crate_root {
              v.push(token::intern(s));
  
      // Given suffix ["b","c","d"], returns path `::std::b::c::d` when
      // `fld.cx.use_std`, and `::core::b::c::d` otherwise.
 -    fn core_path(&mut self, span: Span, components: &[&str]) -> hir::Path {
 -        let idents = self.std_path(components);
 +    fn std_path(&mut self, span: Span, components: &[&str]) -> hir::Path {
 +        let idents = self.std_path_components(components);
          self.path_global(span, idents)
      }
  
          });
          self.expr_block(block, attrs)
      }
 +
 +    fn signal_block_stmt(&mut self,
 +                         stmt: hir::Stmt,
 +                         span: Span,
 +                         rule: hir::BlockCheckMode,
 +                         attrs: ThinVec<Attribute>)
 +                         -> P<hir::Expr> {
 +        let id = self.next_id();
 +        let block = P(hir::Block {
 +            rules: rule,
 +            span: span,
 +            id: id,
 +            stmts: hir_vec![stmt],
 +            expr: None,
 +        });
 +        self.expr_block(block, attrs)
 +    }
  }
diff --combined src/librustc/hir/mod.rs
index e570d251eeafad8b994776851c60cfecb84c0208,d6b8a84698a87afa852ea147ff034b851c326975..295a49d26d0fed82b8a3046d7bfe276557e3d014
@@@ -20,7 -20,6 +20,6 @@@ pub use self::FunctionRetTy::*
  pub use self::ForeignItem_::*;
  pub use self::Item_::*;
  pub use self::Mutability::*;
- pub use self::PathListItem_::*;
  pub use self::PrimTy::*;
  pub use self::Stmt_::*;
  pub use self::TraitItem_::*;
@@@ -36,7 -35,7 +35,7 @@@ use hir::def::Def
  use hir::def_id::DefId;
  use util::nodemap::{NodeMap, FnvHashSet};
  
 -use syntax_pos::{BytePos, mk_sp, Span, ExpnId};
 +use syntax_pos::{mk_sp, Span, ExpnId, DUMMY_SP};
  use syntax::codemap::{self, respan, Spanned};
  use syntax::abi::Abi;
  use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, AsmDialect};
@@@ -301,7 -300,6 +300,7 @@@ pub struct Generics 
      pub lifetimes: HirVec<LifetimeDef>,
      pub ty_params: HirVec<TyParam>,
      pub where_clause: WhereClause,
 +    pub span: Span,
  }
  
  impl Generics {
                  id: DUMMY_NODE_ID,
                  predicates: HirVec::new(),
              },
 +            span: DUMMY_SP,
          }
      }
  
      pub fn is_parameterized(&self) -> bool {
          self.is_lt_parameterized() || self.is_type_parameterized()
      }
 -
 -    // Does return a span which includes lifetimes and type parameters,
 -    // not where clause.
 -    pub fn span(&self) -> Option<Span> {
 -        if !self.is_parameterized() {
 -            None
 -        } else {
 -            let mut span: Option<Span> = None;
 -            for lifetime in self.lifetimes.iter() {
 -                if let Some(ref mut span) = span {
 -                    let life_span = lifetime.lifetime.span;
 -                    span.hi = if span.hi > life_span.hi { span.hi } else { life_span.hi };
 -                    span.lo = if span.lo < life_span.lo { span.lo } else { life_span.lo };
 -                } else {
 -                    span = Some(lifetime.lifetime.span.clone());
 -                }
 -            }
 -            for ty_param in self.ty_params.iter() {
 -                if let Some(ref mut span) = span {
 -                    span.lo = if span.lo < ty_param.span.lo { span.lo } else { ty_param.span.lo };
 -                    span.hi = if span.hi > ty_param.span.hi { span.hi } else { ty_param.span.hi };
 -                } else {
 -                    span = Some(ty_param.span.clone());
 -                }
 -            }
 -            if let Some(ref mut span) = span {
 -                span.lo = span.lo - BytePos(1);
 -                span.hi = span.hi + BytePos(1);
 -            }
 -            span
 -        }
 -    }
  }
  
  /// A `where` clause in a definition
@@@ -1307,39 -1336,11 +1306,11 @@@ pub struct Variant_ 
  pub type Variant = Spanned<Variant_>;
  
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
- pub enum PathListItem_ {
-     PathListIdent {
-         name: Name,
-         /// renamed in list, eg `use foo::{bar as baz};`
-         rename: Option<Name>,
-         id: NodeId,
-     },
-     PathListMod {
-         /// renamed in list, eg `use foo::{self as baz};`
-         rename: Option<Name>,
-         id: NodeId,
-     },
- }
- impl PathListItem_ {
-     pub fn id(&self) -> NodeId {
-         match *self {
-             PathListIdent { id, .. } | PathListMod { id, .. } => id,
-         }
-     }
-     pub fn name(&self) -> Option<Name> {
-         match *self {
-             PathListIdent { name, .. } => Some(name),
-             PathListMod { .. } => None,
-         }
-     }
-     pub fn rename(&self) -> Option<Name> {
-         match *self {
-             PathListIdent { rename, .. } | PathListMod { rename, .. } => rename,
-         }
-     }
+ pub struct PathListItem_ {
+     pub name: Name,
+     /// renamed in list, eg `use foo::{bar as baz};`
+     pub rename: Option<Name>,
+     pub id: NodeId,
  }
  
  pub type PathListItem = Spanned<PathListItem_>;
@@@ -1591,7 -1592,7 +1562,7 @@@ pub type FreevarMap = NodeMap<Vec<Freev
  
  pub type CaptureModeMap = NodeMap<CaptureClause>;
  
 -#[derive(Clone)]
 +#[derive(Clone, Debug)]
  pub struct TraitCandidate {
      pub def_id: DefId,
      pub import_id: Option<NodeId>,
index 1cbead123d8715183b366a90e3f1debbb3e48491,cdd8a36fbad6c452ab2d8722ce1cca5a4ee3d420..893d6708ead4b4993582017fb347a3e0150b88c7
@@@ -523,7 -523,6 +523,7 @@@ impl<'a> State<'a> 
                          id: ast::DUMMY_NODE_ID,
                          predicates: hir::HirVec::new(),
                      },
 +                    span: syntax_pos::DUMMY_SP,
                  };
                  self.print_ty_fn(f.abi, f.unsafety, &f.decl, None, &generics)?;
              }
                      self.print_path(path, false, 0)?;
                      word(&mut self.s, "::{")?;
                  }
-                 self.commasep(Inconsistent, &segments[..], |s, w| {
-                     match w.node {
-                         hir::PathListIdent { name, .. } => {
-                             s.print_name(name)
-                         }
-                         hir::PathListMod { .. } => {
-                             word(&mut s.s, "self")
-                         }
-                     }
-                 })?;
+                 self.commasep(Inconsistent, &segments[..], |s, w| s.print_name(w.node.name))?;
                  word(&mut self.s, "}")
              }
          }
                  id: ast::DUMMY_NODE_ID,
                  predicates: hir::HirVec::new(),
              },
 +            span: syntax_pos::DUMMY_SP,
          };
          self.print_fn(decl,
                        unsafety,
index 37366f38974a4bbc8c77a2e7bf93bacadd09468b,cdd774e11d3282ec5e9e586420a6e28b733e42b4..17bdac982d21aa6e00c871cf845713cb53cf6b5d
@@@ -95,7 -95,7 +95,7 @@@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 't
              Def::AssociatedTy(..) | Def::Method(_) | Def::AssociatedConst(_)
              if self.tcx.trait_of_item(def.def_id()).is_some() => {
                  if let Some(substs) = self.tcx.tables.borrow().item_substs.get(&id) {
 -                    match substs.substs.types[0].sty {
 +                    match substs.substs.type_at(0).sty {
                          TyEnum(tyid, _) | TyStruct(tyid, _) => {
                              self.check_def_id(tyid.did)
                          }
@@@ -294,7 -294,7 +294,7 @@@ impl<'a, 'tcx, 'v> Visitor<'v> for Mark
      }
  
      fn visit_path_list_item(&mut self, path: &hir::Path, item: &hir::PathListItem) {
-         self.lookup_and_handle_definition(item.node.id());
+         self.lookup_and_handle_definition(item.node.id);
          intravisit::walk_path_list_item(self, path, item);
      }
  }
index c8620254b6f42c6696c0adb0568957bf53dccf27,ad2452de33cfe8462b2a7875a1fa1bfdd346e04c..61f7a9db3dd86e03a3d71b20a85f3981b5249865
@@@ -12,6 -12,7 +12,6 @@@
  //! that clean them.
  
  pub use self::Type::*;
 -pub use self::PrimitiveType::*;
  pub use self::TypeKind::*;
  pub use self::VariantKind::*;
  pub use self::Mutability::*;
@@@ -286,34 -287,34 +286,34 @@@ impl Item 
          }
      }
      pub fn is_mod(&self) -> bool {
 -        ItemType::from_item(self) == ItemType::Module
 +        ItemType::from(self) == ItemType::Module
      }
      pub fn is_trait(&self) -> bool {
 -        ItemType::from_item(self) == ItemType::Trait
 +        ItemType::from(self) == ItemType::Trait
      }
      pub fn is_struct(&self) -> bool {
 -        ItemType::from_item(self) == ItemType::Struct
 +        ItemType::from(self) == ItemType::Struct
      }
      pub fn is_enum(&self) -> bool {
 -        ItemType::from_item(self) == ItemType::Module
 +        ItemType::from(self) == ItemType::Module
      }
      pub fn is_fn(&self) -> bool {
 -        ItemType::from_item(self) == ItemType::Function
 +        ItemType::from(self) == ItemType::Function
      }
      pub fn is_associated_type(&self) -> bool {
 -        ItemType::from_item(self) == ItemType::AssociatedType
 +        ItemType::from(self) == ItemType::AssociatedType
      }
      pub fn is_associated_const(&self) -> bool {
 -        ItemType::from_item(self) == ItemType::AssociatedConst
 +        ItemType::from(self) == ItemType::AssociatedConst
      }
      pub fn is_method(&self) -> bool {
 -        ItemType::from_item(self) == ItemType::Method
 +        ItemType::from(self) == ItemType::Method
      }
      pub fn is_ty_method(&self) -> bool {
 -        ItemType::from_item(self) == ItemType::TyMethod
 +        ItemType::from(self) == ItemType::TyMethod
      }
      pub fn is_primitive(&self) -> bool {
 -        ItemType::from_item(self) == ItemType::Primitive
 +        ItemType::from(self) == ItemType::Primitive
      }
      pub fn is_stripped(&self) -> bool {
          match self.inner { StrippedItem(..) => true, _ => false }
@@@ -379,23 -380,6 +379,23 @@@ pub enum ItemEnum 
      StrippedItem(Box<ItemEnum>),
  }
  
 +impl ItemEnum {
 +    pub fn generics(&self) -> Option<&Generics> {
 +        Some(match *self {
 +            ItemEnum::StructItem(ref s) => &s.generics,
 +            ItemEnum::EnumItem(ref e) => &e.generics,
 +            ItemEnum::FunctionItem(ref f) => &f.generics,
 +            ItemEnum::TypedefItem(ref t, _) => &t.generics,
 +            ItemEnum::TraitItem(ref t) => &t.generics,
 +            ItemEnum::ImplItem(ref i) => &i.generics,
 +            ItemEnum::TyMethodItem(ref i) => &i.generics,
 +            ItemEnum::MethodItem(ref i) => &i.generics,
 +            ItemEnum::ForeignFunctionItem(ref f) => &f.generics,
 +            _ => return None,
 +        })
 +    }
 +}
 +
  #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
  pub struct Module {
      pub items: Vec<Item>,
@@@ -642,8 -626,8 +642,8 @@@ impl Clean<TyParamBound> for hir::TyPar
  
  fn external_path_params(cx: &DocContext, trait_did: Option<DefId>, has_self: bool,
                          bindings: Vec<TypeBinding>, substs: &Substs) -> PathParameters {
 -    let lifetimes = substs.regions.iter().filter_map(|v| v.clean(cx)).collect();
 -    let types = substs.types[has_self as usize..].to_vec();
 +    let lifetimes = substs.regions().filter_map(|v| v.clean(cx)).collect();
 +    let types = substs.types().skip(has_self as usize).collect::<Vec<_>>();
  
      match (trait_did, cx.tcx_opt()) {
          // Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C
@@@ -737,11 -721,12 +737,11 @@@ impl<'tcx> Clean<TyParamBound> for ty::
          let path = external_path(cx, &tcx.item_name(self.def_id).as_str(),
                                   Some(self.def_id), true, vec![], self.substs);
  
 -        debug!("ty::TraitRef\n  substs.types: {:?}\n",
 -               &self.input_types()[1..]);
 +        debug!("ty::TraitRef\n  subst: {:?}\n", self.substs);
  
          // collect any late bound regions
          let mut late_bounds = vec![];
 -        for &ty_s in &self.input_types()[1..] {
 +        for ty_s in self.input_types().skip(1) {
              if let ty::TyTuple(ts) = ty_s.sty {
                  for &ty_s in ts {
                      if let ty::TyRef(ref reg, _) = ty_s.sty {
  impl<'tcx> Clean<Option<Vec<TyParamBound>>> for Substs<'tcx> {
      fn clean(&self, cx: &DocContext) -> Option<Vec<TyParamBound>> {
          let mut v = Vec::new();
 -        v.extend(self.regions.iter().filter_map(|r| r.clean(cx))
 +        v.extend(self.regions().filter_map(|r| r.clean(cx))
                       .map(RegionBound));
 -        v.extend(self.types.iter().map(|t| TraitBound(PolyTrait {
 +        v.extend(self.types().map(|t| TraitBound(PolyTrait {
              trait_: t.clean(cx),
              lifetimes: vec![]
          }, hir::TraitBoundModifier::None)));
@@@ -821,7 -806,7 +821,7 @@@ impl Clean<Lifetime> for hir::LifetimeD
      }
  }
  
 -impl Clean<Lifetime> for ty::RegionParameterDef {
 +impl<'tcx> Clean<Lifetime> for ty::RegionParameterDef<'tcx> {
      fn clean(&self, _: &DocContext) -> Lifetime {
          Lifetime(self.name.to_string())
      }
@@@ -913,7 -898,7 +913,7 @@@ impl<'tcx> Clean<WherePredicate> for ty
      }
  }
  
 -impl Clean<WherePredicate> for ty::OutlivesPredicate<ty::Region, ty::Region> {
 +impl<'tcx> Clean<WherePredicate> for ty::OutlivesPredicate<&'tcx ty::Region, &'tcx ty::Region> {
      fn clean(&self, cx: &DocContext) -> WherePredicate {
          let ty::OutlivesPredicate(ref a, ref b) = *self;
          WherePredicate::RegionPredicate {
      }
  }
  
 -impl<'tcx> Clean<WherePredicate> for ty::OutlivesPredicate<ty::Ty<'tcx>, ty::Region> {
 +impl<'tcx> Clean<WherePredicate> for ty::OutlivesPredicate<ty::Ty<'tcx>, &'tcx ty::Region> {
      fn clean(&self, cx: &DocContext) -> WherePredicate {
          let ty::OutlivesPredicate(ref ty, ref lt) = *self;
  
@@@ -1484,8 -1469,8 +1484,8 @@@ pub enum PrimitiveType 
      Str,
      Slice,
      Array,
 -    PrimitiveTuple,
 -    PrimitiveRawPointer,
 +    Tuple,
 +    RawPointer,
  }
  
  #[derive(Clone, RustcEncodable, RustcDecodable, Copy, Debug)]
@@@ -1515,12 -1500,12 +1515,12 @@@ impl Type 
      pub fn primitive_type(&self) -> Option<PrimitiveType> {
          match *self {
              Primitive(p) | BorrowedRef { type_: box Primitive(p), ..} => Some(p),
 -            Vector(..) | BorrowedRef{ type_: box Vector(..), ..  } => Some(Slice),
 +            Vector(..) | BorrowedRef{ type_: box Vector(..), ..  } => Some(PrimitiveType::Slice),
              FixedVector(..) | BorrowedRef { type_: box FixedVector(..), .. } => {
 -                Some(Array)
 +                Some(PrimitiveType::Array)
              }
 -            Tuple(..) => Some(PrimitiveTuple),
 -            RawPointer(..) => Some(PrimitiveRawPointer),
 +            Tuple(..) => Some(PrimitiveType::Tuple),
 +            RawPointer(..) => Some(PrimitiveType::RawPointer),
              _ => None,
          }
      }
@@@ -1545,25 -1530,25 +1545,25 @@@ impl GetDefId for Type 
  impl PrimitiveType {
      fn from_str(s: &str) -> Option<PrimitiveType> {
          match s {
 -            "isize" => Some(Isize),
 -            "i8" => Some(I8),
 -            "i16" => Some(I16),
 -            "i32" => Some(I32),
 -            "i64" => Some(I64),
 -            "usize" => Some(Usize),
 -            "u8" => Some(U8),
 -            "u16" => Some(U16),
 -            "u32" => Some(U32),
 -            "u64" => Some(U64),
 -            "bool" => Some(Bool),
 -            "char" => Some(Char),
 -            "str" => Some(Str),
 -            "f32" => Some(F32),
 -            "f64" => Some(F64),
 -            "array" => Some(Array),
 -            "slice" => Some(Slice),
 -            "tuple" => Some(PrimitiveTuple),
 -            "pointer" => Some(PrimitiveRawPointer),
 +            "isize" => Some(PrimitiveType::Isize),
 +            "i8" => Some(PrimitiveType::I8),
 +            "i16" => Some(PrimitiveType::I16),
 +            "i32" => Some(PrimitiveType::I32),
 +            "i64" => Some(PrimitiveType::I64),
 +            "usize" => Some(PrimitiveType::Usize),
 +            "u8" => Some(PrimitiveType::U8),
 +            "u16" => Some(PrimitiveType::U16),
 +            "u32" => Some(PrimitiveType::U32),
 +            "u64" => Some(PrimitiveType::U64),
 +            "bool" => Some(PrimitiveType::Bool),
 +            "char" => Some(PrimitiveType::Char),
 +            "str" => Some(PrimitiveType::Str),
 +            "f32" => Some(PrimitiveType::F32),
 +            "f64" => Some(PrimitiveType::F64),
 +            "array" => Some(PrimitiveType::Array),
 +            "slice" => Some(PrimitiveType::Slice),
 +            "tuple" => Some(PrimitiveType::Tuple),
 +            "pointer" => Some(PrimitiveType::RawPointer),
              _ => None,
          }
      }
  
      pub fn to_string(&self) -> &'static str {
          match *self {
 -            Isize => "isize",
 -            I8 => "i8",
 -            I16 => "i16",
 -            I32 => "i32",
 -            I64 => "i64",
 -            Usize => "usize",
 -            U8 => "u8",
 -            U16 => "u16",
 -            U32 => "u32",
 -            U64 => "u64",
 -            F32 => "f32",
 -            F64 => "f64",
 -            Str => "str",
 -            Bool => "bool",
 -            Char => "char",
 -            Array => "array",
 -            Slice => "slice",
 -            PrimitiveTuple => "tuple",
 -            PrimitiveRawPointer => "pointer",
 +            PrimitiveType::Isize => "isize",
 +            PrimitiveType::I8 => "i8",
 +            PrimitiveType::I16 => "i16",
 +            PrimitiveType::I32 => "i32",
 +            PrimitiveType::I64 => "i64",
 +            PrimitiveType::Usize => "usize",
 +            PrimitiveType::U8 => "u8",
 +            PrimitiveType::U16 => "u16",
 +            PrimitiveType::U32 => "u32",
 +            PrimitiveType::U64 => "u64",
 +            PrimitiveType::F32 => "f32",
 +            PrimitiveType::F64 => "f64",
 +            PrimitiveType::Str => "str",
 +            PrimitiveType::Bool => "bool",
 +            PrimitiveType::Char => "char",
 +            PrimitiveType::Array => "array",
 +            PrimitiveType::Slice => "slice",
 +            PrimitiveType::Tuple => "tuple",
 +            PrimitiveType::RawPointer => "pointer",
          }
      }
  
      }
  }
  
 +impl From<ast::IntTy> for PrimitiveType {
 +    fn from(int_ty: ast::IntTy) -> PrimitiveType {
 +        match int_ty {
 +            ast::IntTy::Is => PrimitiveType::Isize,
 +            ast::IntTy::I8 => PrimitiveType::I8,
 +            ast::IntTy::I16 => PrimitiveType::I16,
 +            ast::IntTy::I32 => PrimitiveType::I32,
 +            ast::IntTy::I64 => PrimitiveType::I64,
 +        }
 +    }
 +}
 +
 +impl From<ast::UintTy> for PrimitiveType {
 +    fn from(uint_ty: ast::UintTy) -> PrimitiveType {
 +        match uint_ty {
 +            ast::UintTy::Us => PrimitiveType::Usize,
 +            ast::UintTy::U8 => PrimitiveType::U8,
 +            ast::UintTy::U16 => PrimitiveType::U16,
 +            ast::UintTy::U32 => PrimitiveType::U32,
 +            ast::UintTy::U64 => PrimitiveType::U64,
 +        }
 +    }
 +}
 +
 +impl From<ast::FloatTy> for PrimitiveType {
 +    fn from(float_ty: ast::FloatTy) -> PrimitiveType {
 +        match float_ty {
 +            ast::FloatTy::F32 => PrimitiveType::F32,
 +            ast::FloatTy::F64 => PrimitiveType::F64,
 +        }
 +    }
 +}
  
  // Poor man's type parameter substitution at HIR level.
  // Used to replace private type aliases in public signatures with their aliased types.
@@@ -1801,12 -1754,21 +1801,12 @@@ impl<'tcx> Clean<Type> for ty::Ty<'tcx
      fn clean(&self, cx: &DocContext) -> Type {
          match self.sty {
              ty::TyNever => Never,
 -            ty::TyBool => Primitive(Bool),
 -            ty::TyChar => Primitive(Char),
 -            ty::TyInt(ast::IntTy::Is) => Primitive(Isize),
 -            ty::TyInt(ast::IntTy::I8) => Primitive(I8),
 -            ty::TyInt(ast::IntTy::I16) => Primitive(I16),
 -            ty::TyInt(ast::IntTy::I32) => Primitive(I32),
 -            ty::TyInt(ast::IntTy::I64) => Primitive(I64),
 -            ty::TyUint(ast::UintTy::Us) => Primitive(Usize),
 -            ty::TyUint(ast::UintTy::U8) => Primitive(U8),
 -            ty::TyUint(ast::UintTy::U16) => Primitive(U16),
 -            ty::TyUint(ast::UintTy::U32) => Primitive(U32),
 -            ty::TyUint(ast::UintTy::U64) => Primitive(U64),
 -            ty::TyFloat(ast::FloatTy::F32) => Primitive(F32),
 -            ty::TyFloat(ast::FloatTy::F64) => Primitive(F64),
 -            ty::TyStr => Primitive(Str),
 +            ty::TyBool => Primitive(PrimitiveType::Bool),
 +            ty::TyChar => Primitive(PrimitiveType::Char),
 +            ty::TyInt(int_ty) => Primitive(int_ty.into()),
 +            ty::TyUint(uint_ty) => Primitive(uint_ty.into()),
 +            ty::TyFloat(float_ty) => Primitive(float_ty.into()),
 +            ty::TyStr => Primitive(PrimitiveType::Str),
              ty::TyBox(t) => {
                  let box_did = cx.tcx_opt().and_then(|tcx| {
                      tcx.lang_items.owned_box()
@@@ -2459,25 -2421,25 +2459,25 @@@ fn build_deref_target_impls(cx: &DocCon
              }
          };
          let did = match primitive {
 -            Isize => tcx.lang_items.isize_impl(),
 -            I8 => tcx.lang_items.i8_impl(),
 -            I16 => tcx.lang_items.i16_impl(),
 -            I32 => tcx.lang_items.i32_impl(),
 -            I64 => tcx.lang_items.i64_impl(),
 -            Usize => tcx.lang_items.usize_impl(),
 -            U8 => tcx.lang_items.u8_impl(),
 -            U16 => tcx.lang_items.u16_impl(),
 -            U32 => tcx.lang_items.u32_impl(),
 -            U64 => tcx.lang_items.u64_impl(),
 -            F32 => tcx.lang_items.f32_impl(),
 -            F64 => tcx.lang_items.f64_impl(),
 -            Char => tcx.lang_items.char_impl(),
 -            Bool => None,
 -            Str => tcx.lang_items.str_impl(),
 -            Slice => tcx.lang_items.slice_impl(),
 -            Array => tcx.lang_items.slice_impl(),
 -            PrimitiveTuple => None,
 -            PrimitiveRawPointer => tcx.lang_items.const_ptr_impl(),
 +            PrimitiveType::Isize => tcx.lang_items.isize_impl(),
 +            PrimitiveType::I8 => tcx.lang_items.i8_impl(),
 +            PrimitiveType::I16 => tcx.lang_items.i16_impl(),
 +            PrimitiveType::I32 => tcx.lang_items.i32_impl(),
 +            PrimitiveType::I64 => tcx.lang_items.i64_impl(),
 +            PrimitiveType::Usize => tcx.lang_items.usize_impl(),
 +            PrimitiveType::U8 => tcx.lang_items.u8_impl(),
 +            PrimitiveType::U16 => tcx.lang_items.u16_impl(),
 +            PrimitiveType::U32 => tcx.lang_items.u32_impl(),
 +            PrimitiveType::U64 => tcx.lang_items.u64_impl(),
 +            PrimitiveType::F32 => tcx.lang_items.f32_impl(),
 +            PrimitiveType::F64 => tcx.lang_items.f64_impl(),
 +            PrimitiveType::Char => tcx.lang_items.char_impl(),
 +            PrimitiveType::Bool => None,
 +            PrimitiveType::Str => tcx.lang_items.str_impl(),
 +            PrimitiveType::Slice => tcx.lang_items.slice_impl(),
 +            PrimitiveType::Array => tcx.lang_items.slice_impl(),
 +            PrimitiveType::Tuple => None,
 +            PrimitiveType::RawPointer => tcx.lang_items.const_ptr_impl(),
          };
          if let Some(did) = did {
              if !did.is_local() {
@@@ -2551,7 -2513,7 +2551,7 @@@ impl Clean<Vec<Item>> for doctree::Impo
                  let remaining = if !denied {
                      let mut remaining = vec![];
                      for path in list {
-                         match inline::try_inline(cx, path.node.id(), path.node.rename()) {
+                         match inline::try_inline(cx, path.node.id, path.node.rename) {
                              Some(items) => {
                                  ret.extend(items);
                              }
@@@ -2619,17 -2581,10 +2619,10 @@@ pub struct ViewListIdent 
  
  impl Clean<ViewListIdent> for hir::PathListItem {
      fn clean(&self, cx: &DocContext) -> ViewListIdent {
-         match self.node {
-             hir::PathListIdent { id, name, rename } => ViewListIdent {
-                 name: name.clean(cx),
-                 rename: rename.map(|r| r.clean(cx)),
-                 source: resolve_def(cx, id)
-             },
-             hir::PathListMod { id, rename } => ViewListIdent {
-                 name: "self".to_string(),
-                 rename: rename.map(|r| r.clean(cx)),
-                 source: resolve_def(cx, id)
-             }
+         ViewListIdent {
+             name: self.node.name.clean(cx),
+             rename: self.node.rename.map(|r| r.clean(cx)),
+             source: resolve_def(cx, self.node.id)
          }
      }
  }
@@@ -2760,12 -2715,21 +2753,12 @@@ fn resolve_type(cx: &DocContext
  
      let is_generic = match def {
          Def::PrimTy(p) => match p {
 -            hir::TyStr => return Primitive(Str),
 -            hir::TyBool => return Primitive(Bool),
 -            hir::TyChar => return Primitive(Char),
 -            hir::TyInt(ast::IntTy::Is) => return Primitive(Isize),
 -            hir::TyInt(ast::IntTy::I8) => return Primitive(I8),
 -            hir::TyInt(ast::IntTy::I16) => return Primitive(I16),
 -            hir::TyInt(ast::IntTy::I32) => return Primitive(I32),
 -            hir::TyInt(ast::IntTy::I64) => return Primitive(I64),
 -            hir::TyUint(ast::UintTy::Us) => return Primitive(Usize),
 -            hir::TyUint(ast::UintTy::U8) => return Primitive(U8),
 -            hir::TyUint(ast::UintTy::U16) => return Primitive(U16),
 -            hir::TyUint(ast::UintTy::U32) => return Primitive(U32),
 -            hir::TyUint(ast::UintTy::U64) => return Primitive(U64),
 -            hir::TyFloat(ast::FloatTy::F32) => return Primitive(F32),
 -            hir::TyFloat(ast::FloatTy::F64) => return Primitive(F64),
 +            hir::TyStr => return Primitive(PrimitiveType::Str),
 +            hir::TyBool => return Primitive(PrimitiveType::Bool),
 +            hir::TyChar => return Primitive(PrimitiveType::Char),
 +            hir::TyInt(int_ty) => return Primitive(int_ty.into()),
 +            hir::TyUint(uint_ty) => return Primitive(uint_ty.into()),
 +            hir::TyFloat(float_ty) => return Primitive(float_ty.into()),
          },
          Def::SelfTy(..) if path.segments.len() == 1 => {
              return Generic(keywords::SelfType.name().to_string());
diff --combined src/libsyntax/ast.rs
index 968956d3391a07e091b021e5dcb89b3372344366,8265798e796f3194ac67536adb7d03f65ca26ccf..b7cbb1e17c045a74ceac92eb6284072473b267ae
@@@ -336,7 -336,7 +336,7 @@@ pub struct TyParam 
      pub id: NodeId,
      pub bounds: TyParamBounds,
      pub default: Option<P<Ty>>,
 -    pub span: Span
 +    pub span: Span,
  }
  
  /// Represents lifetimes and type parameters attached to a declaration
@@@ -346,7 -346,6 +346,7 @@@ pub struct Generics 
      pub lifetimes: Vec<LifetimeDef>,
      pub ty_params: P<[TyParam]>,
      pub where_clause: WhereClause,
 +    pub span: Span,
  }
  
  impl Generics {
@@@ -369,8 -368,7 +369,8 @@@ impl Default for Generics 
              where_clause: WhereClause {
                  id: DUMMY_NODE_ID,
                  predicates: Vec::new(),
 -            }
 +            },
 +            span: DUMMY_SP,
          }
      }
  }
@@@ -1626,42 -1624,14 +1626,14 @@@ pub struct Variant_ 
  pub type Variant = Spanned<Variant_>;
  
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
- pub enum PathListItemKind {
-     Ident {
-         name: Ident,
-         /// renamed in list, e.g. `use foo::{bar as baz};`
-         rename: Option<Ident>,
-         id: NodeId
-     },
-     Mod {
-         /// renamed in list, e.g. `use foo::{self as baz};`
-         rename: Option<Ident>,
-         id: NodeId
-     }
- }
- impl PathListItemKind {
-     pub fn id(&self) -> NodeId {
-         match *self {
-             PathListItemKind::Ident { id, .. } | PathListItemKind::Mod { id, .. } => id
-         }
-     }
-     pub fn name(&self) -> Option<Ident> {
-         match *self {
-             PathListItemKind::Ident { name, .. } => Some(name),
-             PathListItemKind::Mod { .. } => None,
-         }
-     }
-     pub fn rename(&self) -> Option<Ident> {
-         match *self {
-             PathListItemKind::Ident { rename, .. } | PathListItemKind::Mod { rename, .. } => rename
-         }
-     }
+ pub struct PathListItem_ {
+     pub name: Ident,
+     /// renamed in list, e.g. `use foo::{bar as baz};`
+     pub rename: Option<Ident>,
+     pub id: NodeId,
  }
  
- pub type PathListItem = Spanned<PathListItemKind>;
+ pub type PathListItem = Spanned<PathListItem_>;
  
  pub type ViewPath = Spanned<ViewPath_>;
  
diff --combined src/libsyntax/fold.rs
index c566aa5661be0a89a5323890c81b4dca349c9c3a,9eb6217e5099509f4238060493d48b3747512d5d..504883811e266ebd1bc7bd56633a3bf86f73d1b9
@@@ -307,18 -307,10 +307,10 @@@ pub fn noop_fold_view_path<T: Folder>(v
                  ViewPathList(fld.fold_path(path),
                               path_list_idents.move_map(|path_list_ident| {
                                  Spanned {
-                                     node: match path_list_ident.node {
-                                         PathListItemKind::Ident { id, name, rename } =>
-                                             PathListItemKind::Ident {
-                                                 id: fld.new_id(id),
-                                                 rename: rename,
-                                                 name: name
-                                             },
-                                         PathListItemKind::Mod { id, rename } =>
-                                             PathListItemKind::Mod {
-                                                 id: fld.new_id(id),
-                                                 rename: rename
-                                             }
+                                     node: PathListItem_ {
+                                         id: fld.new_id(path_list_ident.node.id),
+                                         rename: path_list_ident.node.rename,
+                                         name: path_list_ident.node.name,
                                      },
                                      span: fld.new_span(path_list_ident.span)
                                  }
@@@ -698,13 -690,12 +690,13 @@@ pub fn noop_fold_opt_lifetime<T: Folder
      o_lt.map(|lt| fld.fold_lifetime(lt))
  }
  
 -pub fn noop_fold_generics<T: Folder>(Generics {ty_params, lifetimes, where_clause}: Generics,
 +pub fn noop_fold_generics<T: Folder>(Generics {ty_params, lifetimes, where_clause, span}: Generics,
                                       fld: &mut T) -> Generics {
      Generics {
          ty_params: fld.fold_ty_params(ty_params),
          lifetimes: fld.fold_lifetime_defs(lifetimes),
          where_clause: fld.fold_where_clause(where_clause),
 +        span: fld.new_span(span),
      }
  }
  
index 5b710882219c249d716354d7a05425770ab1c8f2,63dbd325075c1b829fbc2bd9c340ad61a184aa09..d5d108084d6f937121de1a756068c1a4f29253da
@@@ -725,8 -725,8 +725,8 @@@ impl<'a> Parser<'a> 
                  let gt_str = Parser::token_to_string(&token::Gt);
                  let this_token_str = self.this_token_to_string();
                  Err(self.fatal(&format!("expected `{}`, found `{}`",
 -                                   gt_str,
 -                                   this_token_str)))
 +                                        gt_str,
 +                                        this_token_str)))
              }
          }
      }
          if !self.eat(&token::OpenDelim(token::Brace)) {
              let sp = self.span;
              let tok = self.this_token_to_string();
 -            return Err(self.span_fatal_help(sp,
 -                                 &format!("expected `{{`, found `{}`", tok),
 -                                 "place this code inside a block"));
 +            let mut e = self.span_fatal(sp, &format!("expected `{{`, found `{}`", tok));
 +
 +            // Check to see if the user has written something like
 +            //
 +            //    if (cond)
 +            //      bar;
 +            //
 +            // Which is valid in other languages, but not Rust.
 +            match self.parse_stmt_without_recovery(false) {
 +                Ok(Some(stmt)) => {
 +                    let mut stmt_span = stmt.span;
 +                    // expand the span to include the semicolon, if it exists
 +                    if self.eat(&token::Semi) {
 +                        stmt_span.hi = self.last_span.hi;
 +                    }
 +                    e.span_help(stmt_span, "try placing this code inside a block");
 +                }
 +                Err(mut e) => {
 +                    self.recover_stmt_(SemiColonMode::Break);
 +                    e.cancel();
 +                }
 +                _ => ()
 +            }
 +            return Err(e);
          }
  
          self.parse_block_tail(lo, BlockCheckMode::Default)
      /// where   typaramseq = ( typaram ) | ( typaram , typaramseq )
      pub fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
          maybe_whole!(self, NtGenerics);
 +        let span_lo = self.span.lo;
  
          if self.eat(&token::Lt) {
              let lifetime_defs = self.parse_lifetime_defs()?;
                  where_clause: WhereClause {
                      id: ast::DUMMY_NODE_ID,
                      predicates: Vec::new(),
 -                }
 +                },
 +                span: mk_sp(span_lo, self.last_span.hi),
              })
          } else {
              Ok(ast::Generics::default())
                                   &token::CloseDelim(token::Brace),
                                   SeqSep::trailing_allowed(token::Comma), |this| {
              let lo = this.span.lo;
-             let node = if this.eat_keyword(keywords::SelfValue) {
-                 let rename = this.parse_rename()?;
-                 ast::PathListItemKind::Mod { id: ast::DUMMY_NODE_ID, rename: rename }
+             let ident = if this.eat_keyword(keywords::SelfValue) {
+                 keywords::SelfValue.ident()
              } else {
-                 let ident = this.parse_ident()?;
-                 let rename = this.parse_rename()?;
-                 ast::PathListItemKind::Ident { name: ident, rename: rename, id: ast::DUMMY_NODE_ID }
+                 this.parse_ident()?
+             };
+             let rename = this.parse_rename()?;
+             let node = ast::PathListItem_ {
+                 name: ident,
+                 rename: rename,
+                 id: ast::DUMMY_NODE_ID
              };
              let hi = this.last_span.hi;
              Ok(spanned(lo, hi, node))
index 22b0bb2c07ad09452fa4947431a7b199bffa6b7d,65a5e06028fea692d602e661ceb376ef45fa77f9..668bf89d3c6a175530dd8b42310ad287a7229d82
@@@ -1001,7 -1001,6 +1001,7 @@@ impl<'a> State<'a> 
                          id: ast::DUMMY_NODE_ID,
                          predicates: Vec::new(),
                      },
 +                    span: syntax_pos::DUMMY_SP,
                  };
                  try!(self.print_ty_fn(f.abi,
                                   f.unsafety,
                      try!(word(&mut self.s, "::{"));
                  }
                  try!(self.commasep(Inconsistent, &idents[..], |s, w| {
-                     match w.node {
-                         ast::PathListItemKind::Ident { name, rename, .. } => {
-                             try!(s.print_ident(name));
-                             if let Some(ident) = rename {
-                                 try!(space(&mut s.s));
-                                 try!(s.word_space("as"));
-                                 try!(s.print_ident(ident));
-                             }
-                             Ok(())
-                         },
-                         ast::PathListItemKind::Mod { rename, .. } => {
-                             try!(word(&mut s.s, "self"));
-                             if let Some(ident) = rename {
-                                 try!(space(&mut s.s));
-                                 try!(s.word_space("as"));
-                                 try!(s.print_ident(ident));
-                             }
-                             Ok(())
-                         }
+                     try!(s.print_ident(w.node.name));
+                     if let Some(ident) = w.node.rename {
+                         try!(space(&mut s.s));
+                         try!(s.word_space("as"));
+                         try!(s.print_ident(ident));
                      }
+                     Ok(())
                  }));
                  word(&mut self.s, "}")
              }
                  id: ast::DUMMY_NODE_ID,
                  predicates: Vec::new(),
              },
 +            span: syntax_pos::DUMMY_SP,
          };
          try!(self.print_fn(decl,
                        unsafety,