]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #34403 - jonathandturner:move_liberror, r=alexcrichton
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>
Sat, 25 Jun 2016 22:27:27 +0000 (22:27 +0000)
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>
Sat, 25 Jun 2016 22:35:09 +0000 (22:35 +0000)
This PR refactors the 'errors' part of libsyntax into its own crate (librustc_errors).  This is the first part of a few refactorings to simplify error reporting and potentially support more output formats (like a standardized JSON output and possibly an --explain mode that can work with the user's code), though this PR stands on its own and doesn't assume further changes.

As part of separating out the errors crate, I have also refactored the code position portion of codemap into its own crate (libsyntax_pos).  While it's helpful to have the common code positions in a separate crate for the new errors crate, this may also enable further simplifications in the future.

15 files changed:
1  2 
src/librustc/hir/lowering.rs
src/librustc_lint/lib.rs
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/lib.rs
src/librustc_save_analysis/dump_visitor.rs
src/librustc_save_analysis/lib.rs
src/libsyntax/ast.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/fold.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/visit.rs

index 374d0c69aaad30ff9e22a3cc0c0346e68ba449ff,cfceb70881e9154bcb20bec7c17902849dea84cb..aea292a76925bd138aaa0773c542e3422c13cb21
@@@ -52,10 -52,11 +52,11 @@@ use std::iter
  use syntax::ast::*;
  use syntax::attr::{ThinAttributes, ThinAttributesExt};
  use syntax::ptr::P;
- use syntax::codemap::{respan, Spanned, Span};
+ use syntax::codemap::{respan, Spanned};
  use syntax::parse::token;
  use syntax::std_inject;
  use syntax::visit::{self, Visitor};
+ use syntax_pos::Span;
  
  pub struct LoweringContext<'a> {
      crate_root: Option<&'static str>,
@@@ -683,7 -684,6 +684,7 @@@ impl<'a> LoweringContext<'a> 
                          hir::TypeTraitItem(this.lower_bounds(bounds),
                                             default.as_ref().map(|x| this.lower_ty(x)))
                      }
 +                    TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"),
                  },
                  span: i.span,
              }
                                                pats.iter().map(|x| self.lower_pat(x)).collect(),
                                                ddpos)
                  }
 -                PatKind::Path(ref pth) => {
 +                PatKind::Path(None, ref pth) => {
                      hir::PatKind::Path(self.lower_path(pth))
                  }
 -                PatKind::QPath(ref qself, ref pth) => {
 +                PatKind::Path(Some(ref qself), ref pth) => {
                      let qself = hir::QSelf {
                          ty: self.lower_ty(&qself.ty),
                          position: qself.position,
diff --combined src/librustc_lint/lib.rs
index 7baadb2b69a5f22df1fc9d380e9342c5396f8250,37523645ceb25b84ae744a4c0b30e01b5b633e94..4ae5b3afdba19f4bf1d119173c00d92d98da66cd
@@@ -45,6 -45,7 +45,7 @@@ extern crate rustc
  extern crate log;
  extern crate rustc_back;
  extern crate rustc_const_eval;
+ extern crate syntax_pos;
  
  pub use rustc::lint as lint;
  pub use rustc::middle as middle;
@@@ -163,7 -164,7 +164,7 @@@ pub fn register_builtins(store: &mut li
          },
          FutureIncompatibleInfo {
              id: LintId::of(INVALID_TYPE_PARAM_DEFAULT),
 -            reference: "PR 30742 <https://github.com/rust-lang/rust/pull/30724>",
 +            reference: "PR 30724 <https://github.com/rust-lang/rust/pull/30724>",
          },
          FutureIncompatibleInfo {
              id: LintId::of(SUPER_OR_SELF_IN_GLOBAL_PATH),
index 71f894813060eb15d021fe1c4885f95ee8c8d7bf,a7c74b93ef5bce7e17ec26d0c8dca6437b60a451..b4cbef183530511daa229f7be7d05335143f38a6
@@@ -29,7 -29,6 +29,6 @@@ use rustc::ty::{self, VariantKind}
  use syntax::ast::Name;
  use syntax::attr;
  use syntax::parse::token;
- use syntax::codemap::{Span, DUMMY_SP};
  
  use syntax::ast::{Block, Crate, DeclKind};
  use syntax::ast::{ForeignItem, ForeignItemKind, Item, ItemKind};
@@@ -38,6 -37,8 +37,8 @@@ use syntax::ast::{Stmt, StmtKind, Trait
  use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
  use syntax::visit::{self, Visitor};
  
+ use syntax_pos::{Span, DUMMY_SP};
  trait ToNameBinding<'a> {
      fn to_name_binding(self) -> NameBinding<'a>;
  }
@@@ -313,7 -314,6 +314,7 @@@ impl<'b> Resolver<'b> 
                              (Def::Method(item_def_id), ValueNS)
                          }
                          TraitItemKind::Type(..) => (Def::AssociatedTy(def_id, item_def_id), TypeNS),
 +                        TraitItemKind::Macro(_) => panic!("unexpanded macro in resolve!"),
                      };
  
                      self.define(module_parent, item.ident.name, ns, (def, item.span, vis));
index 688e46dca3eafea85f8d4a91a81f0d1a62195b00,7b24d8df65c6343bc07a96d17f108bd6f413ed85..444926698d636a07cabe575616533516b1577c7b
@@@ -27,6 -27,8 +27,8 @@@
  extern crate log;
  #[macro_use]
  extern crate syntax;
+ extern crate syntax_pos;
+ extern crate rustc_errors as errors;
  extern crate arena;
  #[macro_use]
  extern crate rustc;
@@@ -54,8 -56,6 +56,6 @@@ use rustc::util::nodemap::{NodeMap, Nod
  use syntax::ext::mtwt;
  use syntax::ast::{self, FloatTy};
  use syntax::ast::{CRATE_NODE_ID, Name, NodeId, CrateNum, IntTy, UintTy};
- use syntax::codemap::{self, Span};
- use syntax::errors::DiagnosticBuilder;
  use syntax::parse::token::{self, keywords};
  use syntax::util::lev_distance::find_best_match_for_name;
  
@@@ -66,6 -66,9 +66,9 @@@ use syntax::ast::{Item, ItemKind, ImplI
  use syntax::ast::{Local, Mutability, Pat, PatKind, Path};
  use syntax::ast::{PathSegment, PathParameters, QSelf, TraitItemKind, TraitRef, Ty, TyKind};
  
+ use syntax_pos::Span;
+ use errors::DiagnosticBuilder;
  use std::collections::{HashMap, HashSet};
  use std::cell::{Cell, RefCell};
  use std::fmt;
@@@ -177,13 -180,13 +180,13 @@@ enum UnresolvedNameContext<'a> 
  }
  
  fn resolve_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
-                                  span: syntax::codemap::Span,
+                                  span: syntax_pos::Span,
                                   resolution_error: ResolutionError<'c>) {
      resolve_struct_error(resolver, span, resolution_error).emit();
  }
  
  fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
-                                         span: syntax::codemap::Span,
+                                         span: syntax_pos::Span,
                                          resolution_error: ResolutionError<'c>)
                                          -> DiagnosticBuilder<'a> {
      if !resolver.emit_errors {
@@@ -1637,7 -1640,6 +1640,7 @@@ impl<'a> Resolver<'a> 
                                          visit::walk_trait_item(this, trait_item)
                                      });
                                  }
 +                                TraitItemKind::Macro(_) => panic!("unexpanded macro in resolve!"),
                              };
                          }
                      });
                              self.resolve_crate_relative_path(trait_path.span, segments, TypeNS)
                          } else {
                              self.resolve_module_relative_path(trait_path.span, segments, TypeNS)
-                         }.map(|binding| binding.span).unwrap_or(codemap::DUMMY_SP)
+                         }.map(|binding| binding.span).unwrap_or(syntax_pos::DUMMY_SP)
                      };
  
-                     if definition_site != codemap::DUMMY_SP {
+                     if definition_site != syntax_pos::DUMMY_SP {
                          err.span_label(definition_site,
                                         &format!("type aliases cannot be used for traits"));
                      }
                      }, "variant or struct");
                  }
  
 -                PatKind::Path(ref path) => {
 -                    self.resolve_pattern_path(pat.id, None, path, ValueNS, |def| {
 +                PatKind::Path(ref qself, ref path) => {
 +                    self.resolve_pattern_path(pat.id, qself.as_ref(), path, ValueNS, |def| {
                          match def {
                              Def::Struct(..) | Def::Variant(..) |
                              Def::Const(..) | Def::AssociatedConst(..) | Def::Err => true,
                      }, "variant, struct or constant");
                  }
  
 -                PatKind::QPath(ref qself, ref path) => {
 -                    self.resolve_pattern_path(pat.id, Some(qself), path, ValueNS, |def| {
 -                        match def {
 -                            Def::AssociatedConst(..) | Def::Err => true,
 -                            _ => false,
 -                        }
 -                    }, "associated constant");
 -                }
 -
                  PatKind::Struct(ref path, _, _) => {
                      self.resolve_pattern_path(pat.id, None, path, TypeNS, |def| {
                          match def {
              },
          };
  
-         if old_binding.span != codemap::DUMMY_SP {
+         if old_binding.span != syntax_pos::DUMMY_SP {
              err.span_label(old_binding.span, &format!("previous {} of `{}` here", noun, name));
          }
          err.emit();
index 02319f8e67338734d28befd634d84d73f747caf3,0ac6584f59ae8bf33f0f31fefc77f8954eeb915a..ddd5bf8a3b96b4e346601f96bf3aab3225b0555d
@@@ -36,11 -36,12 +36,12 @@@ use std::collections::HashSet
  use std::hash::*;
  
  use syntax::ast::{self, NodeId, PatKind};
- use syntax::codemap::*;
  use syntax::parse::token::{self, keywords};
  use syntax::visit::{self, Visitor};
  use syntax::print::pprust::{path_to_string, ty_to_string, bounds_to_string, generics_to_string};
  use syntax::ptr::P;
+ use syntax::codemap::Spanned;
+ use syntax_pos::*;
  
  use super::{escape, generated_code, SaveContext, PathCollector};
  use super::data::*;
@@@ -1215,8 -1216,7 +1216,8 @@@ impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'l
                                      trait_item.span);
              }
              ast::TraitItemKind::Const(_, None) |
 -            ast::TraitItemKind::Type(..) => {}
 +            ast::TraitItemKind::Type(..) |
 +            ast::TraitItemKind::Macro(_) => {}
          }
      }
  
index c45aecd07e11e3e57109cb0492520a479002c63d,ca32a82d763e6848035246fa54da6f29347ade81..236d26c0c90aa961286be8d4d629ffd4eb375b43
@@@ -27,6 -27,7 +27,7 @@@
  #[macro_use] extern crate log;
  #[macro_use] extern crate syntax;
  extern crate serialize as rustc_serialize;
+ extern crate syntax_pos;
  
  mod csv_dumper;
  mod json_dumper;
@@@ -49,10 -50,11 +50,11 @@@ use std::fs::{self, File}
  use std::path::{Path, PathBuf};
  
  use syntax::ast::{self, NodeId, PatKind};
- use syntax::codemap::*;
  use syntax::parse::token::{self, keywords};
  use syntax::visit::{self, Visitor};
  use syntax::print::pprust::{ty_to_string, arg_to_string};
+ use syntax::codemap::MacroAttribute;
+ use syntax_pos::*;
  
  pub use self::csv_dumper::CsvDumper;
  pub use self::json_dumper::JsonDumper;
@@@ -699,7 -701,8 +701,7 @@@ impl<'v> Visitor<'v> for PathCollector 
                                             ast::Mutability::Mutable, recorder::TypeRef));
              }
              PatKind::TupleStruct(ref path, _, _) |
 -            PatKind::Path(ref path) |
 -            PatKind::QPath(_, ref path) => {
 +            PatKind::Path(_, ref path) => {
                  self.collected_paths.push((p.id, path.clone(),
                                             ast::Mutability::Mutable, recorder::VarRef));
              }
diff --combined src/libsyntax/ast.rs
index b2aafca40a3db1dbeea2af8118924a7d99d2182d,fdbc4477edb1380c4a51e7d9299a80cda9a32d2c..ca5e9231a30686b1779f2bd5dd68b4f4ec078287
@@@ -16,7 -16,8 +16,8 @@@ pub use self::ViewPath_::*
  pub use self::PathParameters::*;
  
  use attr::{ThinAttributes, HasAttrs};
- use codemap::{mk_sp, respan, Span, Spanned, DUMMY_SP, ExpnId};
+ use syntax_pos::{mk_sp, Span, DUMMY_SP, ExpnId};
+ use codemap::{respan, Spanned};
  use abi::Abi;
  use errors;
  use ext::base;
@@@ -171,19 -172,16 +172,19 @@@ impl fmt::Debug for Lifetime 
      }
  }
  
 -/// A lifetime definition, eg `'a: 'b+'c+'d`
 +/// A lifetime definition, e.g. `'a: 'b+'c+'d`
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub struct LifetimeDef {
      pub lifetime: Lifetime,
      pub bounds: Vec<Lifetime>
  }
  
 -/// A "Path" is essentially Rust's notion of a name; for instance:
 -/// std::cmp::PartialEq  .  It's represented as a sequence of identifiers,
 +/// A "Path" is essentially Rust's notion of a name.
 +///
 +/// It's represented as a sequence of identifiers,
  /// along with a bunch of supporting information.
 +///
 +/// E.g. `std::cmp::PartialEq`
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
  pub struct Path {
      pub span: Span,
@@@ -223,9 -221,8 +224,9 @@@ impl Path 
      }
  }
  
 -/// A segment of a path: an identifier, an optional lifetime, and a set of
 -/// types.
 +/// A segment of a path: an identifier, an optional lifetime, and a set of types.
 +///
 +/// E.g. `std`, `String` or `Box<T>`
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub struct PathSegment {
      /// The identifier portion of this path segment.
      pub parameters: PathParameters,
  }
  
 +/// Parameters of a path segment.
 +///
 +/// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub enum PathParameters {
      /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>`
@@@ -329,8 -323,7 +330,8 @@@ pub struct AngleBracketedParameterData 
      /// The type parameters for this path segment, if present.
      pub types: P<[P<Ty>]>,
      /// Bindings (equality constraints) on associated types, if present.
 -    /// e.g., `Foo<A=Bar>`.
 +    ///
 +    /// E.g., `Foo<A=Bar>`.
      pub bindings: P<[TypeBinding]>,
  }
  
@@@ -455,9 -448,7 +456,9 @@@ pub enum WherePredicate 
      EqPredicate(WhereEqPredicate),
  }
  
 -/// A type bound, e.g. `for<'c> Foo: Send+Clone+'c`
 +/// A type bound.
 +///
 +/// E.g. `for<'c> Foo: Send+Clone+'c`
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub struct WhereBoundPredicate {
      pub span: Span,
      pub bounds: TyParamBounds,
  }
  
 -/// A lifetime predicate, e.g. `'a: 'b+'c`
 +/// A lifetime predicate.
 +///
 +/// E.g. `'a: 'b+'c`
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub struct WhereRegionPredicate {
      pub span: Span,
      pub bounds: Vec<Lifetime>,
  }
  
 -/// An equality predicate (unsupported), e.g. `T=int`
 +/// An equality predicate (unsupported).
 +///
 +/// E.g. `T=int`
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub struct WhereEqPredicate {
      pub id: NodeId,
@@@ -503,27 -490,12 +504,27 @@@ pub struct Crate 
      pub exported_macros: Vec<MacroDef>,
  }
  
 +/// A spanned compile-time attribute item.
 +///
 +/// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
  pub type MetaItem = Spanned<MetaItemKind>;
  
 +/// A compile-time attribute item.
 +///
 +/// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
  #[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub enum MetaItemKind {
 +    /// Word meta item.
 +    ///
 +    /// E.g. `test` as in `#[test]`
      Word(InternedString),
 +    /// List meta item.
 +    ///
 +    /// E.g. `derive(..)` as in `#[derive(..)]`
      List(InternedString, Vec<P<MetaItem>>),
 +    /// Name value meta item.
 +    ///
 +    /// E.g. `feature = "foo"` as in `#[feature = "foo"]`
      NameValue(InternedString, Lit),
  }
  
@@@ -553,9 -525,6 +554,9 @@@ impl PartialEq for MetaItemKind 
      }
  }
  
 +/// A Block (`{ .. }`).
 +///
 +/// E.g. `{ .. }` as in `fn foo() { .. }`
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub struct Block {
      /// Statements in a block
@@@ -611,6 -580,7 +612,6 @@@ impl Pat 
              PatKind::Range(_, _) |
              PatKind::Ident(_, _, _) |
              PatKind::Path(..) |
 -            PatKind::QPath(_, _) |
              PatKind::Mac(_) => {
                  true
              }
@@@ -658,11 -628,15 +659,11 @@@ pub enum PatKind 
      /// 0 <= position <= subpats.len()
      TupleStruct(Path, Vec<P<Pat>>, Option<usize>),
  
 -    /// A path pattern.
 -    /// Such pattern can be resolved to a unit struct/variant or a constant.
 -    Path(Path),
 -
 -    /// An associated const named using the qualified path `<T>::CONST` or
 -    /// `<T as Trait>::CONST`. Associated consts from inherent impls can be
 -    /// referred to as simply `T::CONST`, in which case they will end up as
 -    /// PatKind::Path, and the resolver will have to sort that out.
 -    QPath(QSelf, Path),
 +    /// A possibly qualified path pattern.
 +    /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
 +    /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
 +    /// only legally refer to associated constants.
 +    Path(Option<QSelf>, Path),
  
      /// A tuple pattern `(a, b)`.
      /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
@@@ -903,16 -877,7 +904,16 @@@ impl Decl 
      }
  }
  
 -/// represents one arm of a 'match'
 +/// An arm of a 'match'.
 +///
 +/// E.g. `0...10 => { println!("match!") }` as in
 +///
 +/// ```rust,ignore
 +/// match n {
 +///     0...10 => { println!("match!") },
 +///     // ..
 +/// }
 +/// ```
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub struct Arm {
      pub attrs: Vec<Attribute>,
@@@ -1069,7 -1034,7 +1070,7 @@@ pub enum ExprKind 
      /// parameters, e.g. foo::bar::<baz>.
      ///
      /// Optionally "qualified",
 -    /// e.g. `<Vec<T> as SomeTrait>::SomeType`.
 +    /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
      Path(Option<QSelf>, Path),
  
      /// A referencing operation (`&a` or `&mut a`)
  /// separately. `position` represents the index of the associated
  /// item qualified with this Self type.
  ///
 -/// ```ignore
 +/// ```rust,ignore
  /// <Vec<T> as a::b::Trait>::AssociatedItem
  ///  ^~~~~     ~~~~~~~~~~~~~~^
  ///  ty        position = 3
@@@ -1355,9 -1320,6 +1356,9 @@@ pub enum LitIntType 
      Unsuffixed,
  }
  
 +/// Literal kind.
 +///
 +/// E.g. `"foo"`, `42`, `12.34` or `bool`
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub enum LitKind {
      /// A string literal (`"foo"`)
@@@ -1425,7 -1387,6 +1426,7 @@@ pub enum TraitItemKind 
      Const(P<Ty>, Option<P<Expr>>),
      Method(MethodSig, Option<P<Block>>),
      Type(TyParamBounds, Option<P<Ty>>),
 +    Macro(Mac),
  }
  
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
@@@ -1626,8 -1587,8 +1627,8 @@@ pub struct BareFnTy 
      pub decl: P<FnDecl>
  }
  
 -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  /// The different kinds of types recognized by the compiler
 +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub enum TyKind {
      Vec(P<Ty>),
      /// A fixed length array (`[T; n]`)
      Mac(Mac),
  }
  
 +/// Inline assembly dialect.
 +///
 +/// E.g. `"intel"` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")``
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
  pub enum AsmDialect {
      Att,
      Intel,
  }
  
 +/// Inline assembly.
 +///
 +/// E.g. `"={eax}"(result)` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")``
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub struct InlineAsmOutput {
      pub constraint: InternedString,
      pub is_indirect: bool,
  }
  
 +/// Inline assembly.
 +///
 +/// E.g. `asm!("NOP");`
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub struct InlineAsm {
      pub asm: InternedString,
      pub expn_id: ExpnId,
  }
  
 -/// represents an argument in a function header
 +/// An argument in a function header.
 +///
 +/// E.g. `bar: usize` as in `fn foo(bar: usize)`
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub struct Arg {
      pub ty: P<Ty>,
  }
  
  /// Alternative representation for `Arg`s describing `self` parameter of methods.
 +///
 +/// E.g. `&mut self` as in `fn foo(&mut self)`
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub enum SelfKind {
      /// `self`, `mut self`
@@@ -1777,9 -1725,7 +1778,9 @@@ impl Arg 
      }
  }
  
 -/// Represents the header (not the body) of a function declaration
 +/// Header (not the body) of a function declaration.
 +///
 +/// E.g. `fn foo(bar: baz)`
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub struct FnDecl {
      pub inputs: Vec<Arg>,
@@@ -1866,9 -1812,6 +1867,9 @@@ impl FunctionRetTy 
      }
  }
  
 +/// Module declaration.
 +///
 +/// E.g. `mod foo;` or `mod foo { .. }`
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub struct Mod {
      /// A span from the first token past `{` to the last token until `}`.
      pub items: Vec<P<Item>>,
  }
  
 +/// Foreign module declaration.
 +///
 +/// E.g. `extern { .. }` or `extern C { .. }`
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub struct ForeignMod {
      pub abi: Abi,
@@@ -1897,7 -1837,7 +1898,7 @@@ pub struct Variant_ 
      pub name: Ident,
      pub attrs: Vec<Attribute>,
      pub data: VariantData,
 -    /// Explicit discriminant, eg `Foo = 1`
 +    /// Explicit discriminant, e.g. `Foo = 1`
      pub disr_expr: Option<P<Expr>>,
  }
  
@@@ -1907,12 -1847,12 +1908,12 @@@ pub type Variant = Spanned<Variant_>
  pub enum PathListItemKind {
      Ident {
          name: Ident,
 -        /// renamed in list, eg `use foo::{bar as baz};`
 +        /// renamed in list, e.g. `use foo::{bar as baz};`
          rename: Option<Ident>,
          id: NodeId
      },
      Mod {
 -        /// renamed in list, eg `use foo::{self as baz};`
 +        /// renamed in list, e.g. `use foo::{self as baz};`
          rename: Option<Ident>,
          id: NodeId
      }
@@@ -2025,9 -1965,6 +2026,9 @@@ pub enum Visibility 
      Inherited,
  }
  
 +/// Field of a struct.
 +///
 +/// E.g. `bar: usize` as in `struct Foo { bar: usize }`
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub struct StructField {
      pub span: Span,
  /// Id of the whole struct lives in `Item`.
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub enum VariantData {
 +    /// Struct variant.
 +    ///
 +    /// E.g. `Bar { .. }` as in `enum Foo { Bar { .. } }`
      Struct(Vec<StructField>, NodeId),
 +    /// Tuple variant.
 +    ///
 +    /// E.g. `Bar(..)` as in `enum Foo { Bar(..) }`
      Tuple(Vec<StructField>, NodeId),
 +    /// Unit variant.
 +    ///
 +    /// E.g. `Bar = ..` as in `enum Foo { Bar = .. }`
      Unit(NodeId),
  }
  
@@@ -2113,66 -2041,44 +2114,66 @@@ impl Item 
  
  #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
  pub enum ItemKind {
 -    /// An`extern crate` item, with optional original crate name,
 +    /// An`extern crate` item, with optional original crate name.
      ///
 -    /// e.g. `extern crate foo` or `extern crate foo_bar as foo`
 +    /// E.g. `extern crate foo` or `extern crate foo_bar as foo`
      ExternCrate(Option<Name>),
 -    /// A `use` or `pub use` item
 +    /// A use declaration (`use` or `pub use`) item.
 +    ///
 +    /// E.g. `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`
      Use(P<ViewPath>),
 -
 -    /// A `static` item
 +    /// A static item (`static` or `pub static`).
 +    ///
 +    /// E.g. `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`
      Static(P<Ty>, Mutability, P<Expr>),
 -    /// A `const` item
 +    /// A constant item (`const` or `pub const`).
 +    ///
 +    /// E.g. `const FOO: i32 = 42;`
      Const(P<Ty>, P<Expr>),
 -    /// A function declaration
 +    /// A function declaration (`fn` or `pub fn`).
 +    ///
 +    /// E.g. `fn foo(bar: usize) -> usize { .. }`
      Fn(P<FnDecl>, Unsafety, Constness, Abi, Generics, P<Block>),
 -    /// A module
 +    /// A module declaration (`mod` or `pub mod`).
 +    ///
 +    /// E.g. `mod foo;` or `mod foo { .. }`
      Mod(Mod),
 -    /// An external module
 +    /// An external module (`extern` or `pub extern`).
 +    ///
 +    /// E.g. `extern {}` or `extern "C" {}`
      ForeignMod(ForeignMod),
 -    /// A type alias, e.g. `type Foo = Bar<u8>`
 +    /// A type alias (`type` or `pub type`).
 +    ///
 +    /// E.g. `type Foo = Bar<u8>;`
      Ty(P<Ty>, Generics),
 -    /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
 +    /// An enum definition (`enum` or `pub enum`).
 +    ///
 +    /// E.g. `enum Foo<A, B> { C<A>, D<B> }`
      Enum(EnumDef, Generics),
 -    /// A struct definition, e.g. `struct Foo<A> {x: A}`
 +    /// A struct definition (`struct` or `pub struct`).
 +    ///
 +    /// E.g. `struct Foo<A> { x: A }`
      Struct(VariantData, Generics),
 -    /// Represents a Trait Declaration
 +    /// A Trait declaration (`trait` or `pub trait`).
 +    ///
 +    /// E.g. `trait Foo { .. }` or `trait Foo<T> { .. }`
      Trait(Unsafety, Generics, TyParamBounds, Vec<TraitItem>),
 -
 -    // Default trait implementations
 +    // Default trait implementation.
      ///
 -    // `impl Trait for .. {}`
 +    /// E.g. `impl Trait for .. {}` or `impl<T> Trait<T> for .. {}`
      DefaultImpl(Unsafety, TraitRef),
 -    /// An implementation, eg `impl<A> Trait for Foo { .. }`
 +    /// An implementation.
 +    ///
 +    /// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
      Impl(Unsafety,
               ImplPolarity,
               Generics,
               Option<TraitRef>, // (optional) trait this impl implements
               P<Ty>, // self
               Vec<ImplItem>),
 -    /// A macro invocation (which includes macro definition)
 +    /// A macro invocation (which includes macro definition).
 +    ///
 +    /// E.g. `macro_rules! foo { .. }` or `foo!(..)`
      Mac(Mac),
  }
  
index 9d467b4095a8f3ba87c04952bda343fa90c9b603,d760980b96f6142f9775a9aedea29f08a2364324..3ee256342078603a2d3fe382eb66f4725534dab1
@@@ -13,8 -13,8 +13,8 @@@ pub use self::SyntaxExtension::*
  use ast;
  use ast::{Name, PatKind};
  use attr::HasAttrs;
- use codemap;
- use codemap::{CodeMap, Span, ExpnId, ExpnInfo, NO_EXPANSION};
+ use codemap::{self, CodeMap, ExpnInfo};
+ use syntax_pos::{Span, ExpnId, NO_EXPANSION};
  use errors::DiagnosticBuilder;
  use ext;
  use ext::expand;
@@@ -241,11 -241,6 +241,11 @@@ pub trait MacResult 
          None
      }
  
 +    /// Create zero or more trait items.
 +    fn make_trait_items(self: Box<Self>) -> Option<SmallVector<ast::TraitItem>> {
 +        None
 +    }
 +
      /// Create a pattern.
      fn make_pat(self: Box<Self>) -> Option<P<ast::Pat>> {
          None
@@@ -293,7 -288,6 +293,7 @@@ make_MacEager! 
      pat: P<ast::Pat>,
      items: SmallVector<P<ast::Item>>,
      impl_items: SmallVector<ast::ImplItem>,
 +    trait_items: SmallVector<ast::TraitItem>,
      stmts: SmallVector<ast::Stmt>,
      ty: P<ast::Ty>,
  }
@@@ -311,10 -305,6 +311,10 @@@ impl MacResult for MacEager 
          self.impl_items
      }
  
 +    fn make_trait_items(self: Box<Self>) -> Option<SmallVector<ast::TraitItem>> {
 +        self.trait_items
 +    }
 +
      fn make_stmts(self: Box<Self>) -> Option<SmallVector<ast::Stmt>> {
          match self.stmts.as_ref().map_or(0, |s| s.len()) {
              0 => make_stmts_default!(self),
@@@ -423,14 -413,6 +423,14 @@@ impl MacResult for DummyResult 
          }
      }
  
 +    fn make_trait_items(self: Box<DummyResult>) -> Option<SmallVector<ast::TraitItem>> {
 +        if self.expr_only {
 +            None
 +        } else {
 +            Some(SmallVector::zero())
 +        }
 +    }
 +
      fn make_stmts(self: Box<DummyResult>) -> Option<SmallVector<ast::Stmt>> {
          Some(SmallVector::one(
              codemap::respan(self.span,
index 1d27cf5b0a19e07ca5a0be26e22597e221b0fe3d,abcfadf5630ef264cf3c810af3d3b51c48fb2a64..fdf2626333012cbe55cc7a029c4f574b18901117
@@@ -11,7 -11,8 +11,8 @@@
  use abi::Abi;
  use ast::{self, Ident, Generics, Expr, BlockCheckMode, UnOp, PatKind};
  use attr;
- use codemap::{Span, respan, Spanned, DUMMY_SP, Pos};
+ use syntax_pos::{Span, DUMMY_SP, Pos};
+ use codemap::{respan, Spanned};
  use ext::base::ExtCtxt;
  use parse::token::{self, keywords, InternedString};
  use ptr::P;
@@@ -830,7 -831,7 +831,7 @@@ impl<'a> AstBuilder for ExtCtxt<'a> 
      }
      fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec<P<ast::Pat>>) -> P<ast::Pat> {
          let pat = if subpats.is_empty() {
 -            PatKind::Path(path)
 +            PatKind::Path(None, path)
          } else {
              PatKind::TupleStruct(path, subpats, None)
          };
index 126f39bcb0edc8373b9c209669d8011b7fbfce82,aa5fe4fe2fa18fbf23904387131c0af5e2bd61f2..123d38c0006362de724f47db89a801fb45af9af5
@@@ -18,8 -18,8 +18,8 @@@ use ext::mtwt
  use ext::build::AstBuilder;
  use attr;
  use attr::{AttrMetaMethods, WithAttrs, ThinAttributesExt};
- use codemap;
- use codemap::{Span, Spanned, ExpnInfo, ExpnId, NameAndSpan, MacroBang, MacroAttribute};
+ use codemap::{Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
+ use syntax_pos::{self, Span, ExpnId};
  use config::StripUnconfigured;
  use ext::base::*;
  use feature_gate::{self, Features};
@@@ -81,11 -81,8 +81,11 @@@ impl_macro_generable! 
          "statement",  .make_stmts, lift .fold_stmt, lift .visit_stmt, |_span| SmallVector::zero();
      SmallVector<P<ast::Item>>:
          "item",       .make_items, lift .fold_item, lift .visit_item, |_span| SmallVector::zero();
 +    SmallVector<ast::TraitItem>:
 +        "trait item", .make_trait_items, lift .fold_trait_item, lift .visit_trait_item,
 +        |_span| SmallVector::zero();
      SmallVector<ast::ImplItem>:
 -        "impl item",  .make_impl_items, lift .fold_impl_item, lift .visit_impl_item,
 +        "impl item",  .make_impl_items,  lift .fold_impl_item,  lift .visit_impl_item,
          |_span| SmallVector::zero();
  }
  
@@@ -757,10 -754,25 +757,10 @@@ fn expand_multi_modified(a: Annotatable
              _ => noop_fold_item(it, fld),
          }.into_iter().map(|i| Annotatable::Item(i)).collect(),
  
 -        Annotatable::TraitItem(it) => match it.node {
 -            ast::TraitItemKind::Method(_, Some(_)) => {
 -                let ti = it.unwrap();
 -                SmallVector::one(ast::TraitItem {
 -                    id: ti.id,
 -                    ident: ti.ident,
 -                    attrs: ti.attrs,
 -                    node: match ti.node  {
 -                        ast::TraitItemKind::Method(sig, Some(body)) => {
 -                            let (sig, body) = expand_and_rename_method(sig, body, fld);
 -                            ast::TraitItemKind::Method(sig, Some(body))
 -                        }
 -                        _ => unreachable!()
 -                    },
 -                    span: ti.span,
 -                })
 -            }
 -            _ => fold::noop_fold_trait_item(it.unwrap(), fld)
 -        }.into_iter().map(|ti| Annotatable::TraitItem(P(ti))).collect(),
 +        Annotatable::TraitItem(it) => {
 +            expand_trait_item(it.unwrap(), fld).into_iter().
 +                map(|it| Annotatable::TraitItem(P(it))).collect()
 +        }
  
          Annotatable::ImplItem(ii) => {
              expand_impl_item(ii.unwrap(), fld).into_iter().
@@@ -888,31 -900,6 +888,31 @@@ fn expand_impl_item(ii: ast::ImplItem, 
      }
  }
  
 +fn expand_trait_item(ti: ast::TraitItem, fld: &mut MacroExpander)
 +                     -> SmallVector<ast::TraitItem> {
 +    match ti.node {
 +        ast::TraitItemKind::Method(_, Some(_)) => {
 +            SmallVector::one(ast::TraitItem {
 +                id: ti.id,
 +                ident: ti.ident,
 +                attrs: ti.attrs,
 +                node: match ti.node  {
 +                    ast::TraitItemKind::Method(sig, Some(body)) => {
 +                        let (sig, body) = expand_and_rename_method(sig, body, fld);
 +                        ast::TraitItemKind::Method(sig, Some(body))
 +                    }
 +                    _ => unreachable!()
 +                },
 +                span: ti.span,
 +            })
 +        }
 +        ast::TraitItemKind::Macro(mac) => {
 +            expand_mac_invoc(mac, None, ti.attrs, ti.span, fld)
 +        }
 +        _ => fold::noop_fold_trait_item(ti, fld)
 +    }
 +}
 +
  /// Given a fn_decl and a block and a MacroExpander, expand the fn_decl, then use the
  /// PatIdents in its arguments to perform renaming in the FnDecl and
  /// the block, returning both the new FnDecl and the new Block.
@@@ -1053,7 -1040,7 +1053,7 @@@ impl<'a, 'b> Folder for MacroExpander<'
                  result = expand_item(item, self);
                  self.pop_mod_path();
              } else {
-                 let filename = if inner != codemap::DUMMY_SP {
+                 let filename = if inner != syntax_pos::DUMMY_SP {
                      Some(self.cx.parse_sess.codemap().span_to_filename(inner))
                  } else { None };
                  let orig_filename = replace(&mut self.cx.filename, filename);
@@@ -1242,7 -1229,7 +1242,7 @@@ mod tests 
      use super::{PatIdentFinder, IdentRenamer, PatIdentRenamer, ExpansionConfig};
      use ast;
      use ast::Name;
-     use codemap;
+     use syntax_pos;
      use ext::base::{ExtCtxt, DummyMacroLoader};
      use ext::mtwt;
      use fold::Folder;
      }
  
      impl<'v> Visitor<'v> for IdentFinder {
-         fn visit_ident(&mut self, _: codemap::Span, id: ast::Ident){
+         fn visit_ident(&mut self, _: syntax_pos::Span, id: ast::Ident){
              self.ident_accumulator.push(id);
          }
      }
index fe98394c3e4519c90f443a996bad7799aa26d4b0,a21c9eb76545ff24ffc59c2b9515639dafc05d74..850fbb5addf6ed962d13c4f13d997ed33d264adb
@@@ -9,7 -9,7 +9,7 @@@
  // except according to those terms.
  
  use ast::{self, TokenTree};
- use codemap::{Span, DUMMY_SP};
+ use syntax_pos::{Span, DUMMY_SP};
  use ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension};
  use ext::base::{NormalTT, TTMacroExpander};
  use ext::tt::macro_parser::{Success, Error, Failure};
@@@ -100,21 -100,6 +100,21 @@@ impl<'a> MacResult for ParserAnyMacro<'
          Some(ret)
      }
  
 +    fn make_trait_items(self: Box<ParserAnyMacro<'a>>)
 +                       -> Option<SmallVector<ast::TraitItem>> {
 +        let mut ret = SmallVector::zero();
 +        loop {
 +            let mut parser = self.parser.borrow_mut();
 +            match parser.token {
 +                token::Eof => break,
 +                _ => ret.push(panictry!(parser.parse_trait_item()))
 +            }
 +        }
 +        self.ensure_complete_parse(false, "item");
 +        Some(ret)
 +    }
 +
 +
      fn make_stmts(self: Box<ParserAnyMacro<'a>>)
                   -> Option<SmallVector<ast::Stmt>> {
          let mut ret = SmallVector::zero();
diff --combined src/libsyntax/fold.rs
index 18661f3dc01edd1ffc387e0fa694f0f8a7cecac3,69c3cd5c59268c0933f787635caebac43379a774..e8f9ddb243154ba33210ccd29ee4ebcc0f14a15d
@@@ -21,7 -21,8 +21,8 @@@
  use ast::*;
  use ast;
  use attr::{ThinAttributes, ThinAttributesExt};
- use codemap::{respan, Span, Spanned};
+ use syntax_pos::Span;
+ use codemap::{Spanned, respan};
  use parse::token::{self, keywords};
  use ptr::P;
  use util::small_vector::SmallVector;
@@@ -945,9 -946,6 +946,9 @@@ pub fn noop_fold_trait_item<T: Folder>(
                  TraitItemKind::Type(folder.fold_bounds(bounds),
                                default.map(|x| folder.fold_ty(x)))
              }
 +            ast::TraitItemKind::Macro(mac) => {
 +                TraitItemKind::Macro(folder.fold_mac(mac))
 +            }
          },
          span: folder.new_span(i.span)
      })
@@@ -1091,11 -1089,12 +1092,11 @@@ pub fn noop_fold_pat<T: Folder>(p: P<Pa
                  PatKind::TupleStruct(folder.fold_path(pth),
                          pats.move_map(|x| folder.fold_pat(x)), ddpos)
              }
 -            PatKind::Path(pth) => {
 -                PatKind::Path(folder.fold_path(pth))
 -            }
 -            PatKind::QPath(qself, pth) => {
 -                let qself = QSelf {ty: folder.fold_ty(qself.ty), .. qself};
 -                PatKind::QPath(qself, folder.fold_path(pth))
 +            PatKind::Path(opt_qself, pth) => {
 +                let opt_qself = opt_qself.map(|qself| {
 +                    QSelf { ty: folder.fold_ty(qself.ty), position: qself.position }
 +                });
 +                PatKind::Path(opt_qself, folder.fold_path(pth))
              }
              PatKind::Struct(pth, fields, etc) => {
                  let pth = folder.fold_path(pth);
index de41ab5e1893ed56a0498a5acaf1330aa489d5cf,a8597c99a569c1dd3446229939bcf8013753b64d..99eddce36451885175700c0fee64f430f438cef2
@@@ -40,7 -40,8 +40,8 @@@ use ast::{Visibility, WhereClause}
  use attr::{ThinAttributes, ThinAttributesExt, AttributesExt};
  use ast::{BinOpKind, UnOp};
  use ast;
- use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp, CodeMap};
+ use codemap::{self, CodeMap, Spanned, spanned};
+ use syntax_pos::{self, Span, BytePos, mk_sp};
  use errors::{self, DiagnosticBuilder};
  use ext::tt::macro_parser;
  use parse;
@@@ -344,7 -345,7 +345,7 @@@ impl<'a> Parser<'a> 
      {
          let tok0 = rdr.real_token();
          let span = tok0.sp;
-         let filename = if span != codemap::DUMMY_SP {
+         let filename = if span != syntax_pos::DUMMY_SP {
              Some(sess.codemap().span_to_filename(span))
          } else { None };
          let placeholder = TokenAndSpan {
      }
  
      /// Parse the items in a trait declaration
 -    pub fn parse_trait_items(&mut self) -> PResult<'a,  Vec<TraitItem>> {
 -        self.parse_unspanned_seq(
 -            &token::OpenDelim(token::Brace),
 -            &token::CloseDelim(token::Brace),
 -            SeqSep::none(),
 -            |p| -> PResult<'a, TraitItem> {
 -            maybe_whole!(no_clone_from_p p, NtTraitItem);
 -            let mut attrs = p.parse_outer_attributes()?;
 -            let lo = p.span.lo;
 -
 -            let (name, node) = if p.eat_keyword(keywords::Type) {
 -                let TyParam {ident, bounds, default, ..} = p.parse_ty_param()?;
 -                p.expect(&token::Semi)?;
 -                (ident, TraitItemKind::Type(bounds, default))
 -            } else if p.is_const_item() {
 -                p.expect_keyword(keywords::Const)?;
 -                let ident = p.parse_ident()?;
 -                p.expect(&token::Colon)?;
 -                let ty = p.parse_ty_sum()?;
 -                let default = if p.check(&token::Eq) {
 -                    p.bump();
 -                    let expr = p.parse_expr()?;
 -                    p.commit_expr_expecting(&expr, token::Semi)?;
 -                    Some(expr)
 -                } else {
 -                    p.expect(&token::Semi)?;
 -                    None
 -                };
 -                (ident, TraitItemKind::Const(ty, default))
 +    pub fn parse_trait_item(&mut self) -> PResult<'a, TraitItem> {
 +        maybe_whole!(no_clone_from_p self, NtTraitItem);
 +        let mut attrs = self.parse_outer_attributes()?;
 +        let lo = self.span.lo;
 +
 +        let (name, node) = if self.eat_keyword(keywords::Type) {
 +            let TyParam {ident, bounds, default, ..} = self.parse_ty_param()?;
 +            self.expect(&token::Semi)?;
 +            (ident, TraitItemKind::Type(bounds, default))
 +        } else if self.is_const_item() {
 +                self.expect_keyword(keywords::Const)?;
 +            let ident = self.parse_ident()?;
 +            self.expect(&token::Colon)?;
 +            let ty = self.parse_ty_sum()?;
 +            let default = if self.check(&token::Eq) {
 +                self.bump();
 +                let expr = self.parse_expr()?;
 +                self.commit_expr_expecting(&expr, token::Semi)?;
 +                Some(expr)
 +            } else {
 +                self.expect(&token::Semi)?;
 +                None
 +            };
 +            (ident, TraitItemKind::Const(ty, default))
 +        } else if !self.token.is_any_keyword()
 +            && self.look_ahead(1, |t| *t == token::Not)
 +            && (self.look_ahead(2, |t| *t == token::OpenDelim(token::Paren))
 +                || self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace))) {
 +                // trait item macro.
 +                // code copied from parse_macro_use_or_failure... abstraction!
 +                let lo = self.span.lo;
 +                let pth = self.parse_ident_into_path()?;
 +                self.expect(&token::Not)?;
 +
 +                // eat a matched-delimiter token tree:
 +                let delim = self.expect_open_delim()?;
 +                let tts = self.parse_seq_to_end(&token::CloseDelim(delim),
 +                                             SeqSep::none(),
 +                                             |pp| pp.parse_token_tree())?;
 +                let m_ = Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT };
 +                let m: ast::Mac = codemap::Spanned { node: m_,
 +                                                     span: mk_sp(lo,
 +                                                                 self.last_span.hi) };
 +                if delim != token::Brace {
 +                    self.expect(&token::Semi)?
 +                }
 +                (keywords::Invalid.ident(), ast::TraitItemKind::Macro(m))
              } else {
 -                let (constness, unsafety, abi) = match p.parse_fn_front_matter() {
 +                let (constness, unsafety, abi) = match self.parse_fn_front_matter() {
                      Ok(cua) => cua,
                      Err(e) => {
                          loop {
 -                            match p.token {
 +                            match self.token {
                                  token::Eof => break,
 -
                                  token::CloseDelim(token::Brace) |
                                  token::Semi => {
 -                                    p.bump();
 +                                    self.bump();
                                      break;
                                  }
 -
                                  token::OpenDelim(token::Brace) => {
 -                                    p.parse_token_tree()?;
 +                                    self.parse_token_tree()?;
                                      break;
                                  }
 -
 -                                _ => p.bump()
 +                                _ => self.bump()
                              }
                          }
  
                      }
                  };
  
 -                let ident = p.parse_ident()?;
 -                let mut generics = p.parse_generics()?;
 +                let ident = self.parse_ident()?;
 +                let mut generics = self.parse_generics()?;
  
 -                let d = p.parse_fn_decl_with_self(|p: &mut Parser<'a>|{
 +                let d = self.parse_fn_decl_with_self(|p: &mut Parser<'a>|{
                      // This is somewhat dubious; We don't want to allow
                      // argument names to be left off if there is a
                      // definition...
                      p.parse_arg_general(false)
                  })?;
  
 -                generics.where_clause = p.parse_where_clause()?;
 +                generics.where_clause = self.parse_where_clause()?;
                  let sig = ast::MethodSig {
                      unsafety: unsafety,
                      constness: constness,
                      abi: abi,
                  };
  
 -                let body = match p.token {
 -                  token::Semi => {
 -                    p.bump();
 -                    debug!("parse_trait_methods(): parsing required method");
 -                    None
 -                  }
 -                  token::OpenDelim(token::Brace) => {
 -                    debug!("parse_trait_methods(): parsing provided method");
 -                    let (inner_attrs, body) =
 -                        p.parse_inner_attrs_and_block()?;
 -                    attrs.extend(inner_attrs.iter().cloned());
 -                    Some(body)
 -                  }
 +                let body = match self.token {
 +                    token::Semi => {
 +                        self.bump();
 +                        debug!("parse_trait_methods(): parsing required method");
 +                        None
 +                    }
 +                    token::OpenDelim(token::Brace) => {
 +                        debug!("parse_trait_methods(): parsing provided method");
 +                        let (inner_attrs, body) =
 +                            self.parse_inner_attrs_and_block()?;
 +                        attrs.extend(inner_attrs.iter().cloned());
 +                        Some(body)
 +                    }
  
 -                  _ => {
 -                      let token_str = p.this_token_to_string();
 -                      return Err(p.fatal(&format!("expected `;` or `{{`, found `{}`",
 -                                       token_str)[..]))
 -                  }
 +                    _ => {
 +                        let token_str = self.this_token_to_string();
 +                        return Err(self.fatal(&format!("expected `;` or `{{`, found `{}`",
 +                                                    token_str)[..]))
 +                    }
                  };
                  (ident, ast::TraitItemKind::Method(sig, body))
              };
 +        Ok(TraitItem {
 +            id: ast::DUMMY_NODE_ID,
 +            ident: name,
 +            attrs: attrs,
 +            node: node,
 +            span: mk_sp(lo, self.last_span.hi),
 +        })
 +    }
  
 -            Ok(TraitItem {
 -                id: ast::DUMMY_NODE_ID,
 -                ident: name,
 -                attrs: attrs,
 -                node: node,
 -                span: mk_sp(lo, p.last_span.hi),
 +
 +    /// Parse the items in a trait declaration
 +    pub fn parse_trait_items(&mut self) -> PResult<'a,  Vec<TraitItem>> {
 +        self.parse_unspanned_seq(
 +            &token::OpenDelim(token::Brace),
 +            &token::CloseDelim(token::Brace),
 +            SeqSep::none(),
 +            |p| -> PResult<'a, TraitItem> {
 +                p.parse_trait_item()
              })
 -        })
      }
  
      /// Parse a possibly mutable type
      }
  
      /// Parse the fields of a struct-like pattern
-     fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<codemap::Spanned<ast::FieldPat>> , bool)> {
+     fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<codemap::Spanned<ast::FieldPat>>, bool)> {
          let mut fields = Vec::new();
          let mut etc = false;
          let mut first = true;
              };
  
              fields.push(codemap::Spanned { span: mk_sp(lo, hi),
-                                            node: ast::FieldPat { ident: fieldname,
-                                                                  pat: subpat,
-                                                                  is_shorthand: is_shorthand }});
+                                               node: ast::FieldPat { ident: fieldname,
+                                                                     pat: subpat,
+                                                                     is_shorthand: is_shorthand }});
          }
          return Ok((fields, etc));
      }
                              SeqSep::none(), |p| p.parse_token_tree())?;
                          let mac = Mac_ { path: path, tts: tts, ctxt: EMPTY_CTXT };
                          pat = PatKind::Mac(codemap::Spanned {node: mac,
-                                                        span: mk_sp(lo, self.last_span.hi)});
+                                                                span: mk_sp(lo, self.last_span.hi)});
                      } else {
                          // Parse ident @ pat
                          // This can give false positives and parse nullary enums,
                          pat = PatKind::TupleStruct(path, fields, ddpos)
                        }
                        _ => {
 -                        pat = match qself {
 -                            // Parse qualified path
 -                            Some(qself) => PatKind::QPath(qself, path),
 -                            // Parse nullary enum
 -                            None => PatKind::Path(path)
 -                        };
 +                        pat = PatKind::Path(qself, path);
                        }
                      }
                  }
                                              |p| p.parse_token_tree())?;
              let m_ = Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT };
              let m: ast::Mac = codemap::Spanned { node: m_,
-                                                 span: mk_sp(lo,
-                                                             self.last_span.hi) };
+                                                     span: mk_sp(lo,
+                                                                 self.last_span.hi) };
              if delim != token::Brace {
                  self.expect(&token::Semi)?
              }
  
      /// Parse trait Foo { ... }
      fn parse_item_trait(&mut self, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
 -
          let ident = self.parse_ident()?;
          let mut tps = self.parse_generics()?;
  
              return Err(self.fatal(&format!("expected item, found `{}`", token_str)));
          }
  
-         let hi = if self.span == codemap::DUMMY_SP {
+         let hi = if self.span == syntax_pos::DUMMY_SP {
              inner_lo
          } else {
              self.last_span.hi
              // single-variant-enum... :
              let m = Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT };
              let m: ast::Mac = codemap::Spanned { node: m,
-                                              span: mk_sp(mac_lo,
-                                                          self.last_span.hi) };
+                                                  span: mk_sp(mac_lo,
+                                                              self.last_span.hi) };
  
              if delim != token::Brace {
                  if !self.eat(&token::Semi) {
index 1fefc53af6320c354beb384d11d73e46826a7bd4,d254d3a71cf7915efb151dfdc00cb8334f0ae4a0..9fc5e1089c0ada40702eb9f5854047a810f8c757
@@@ -18,7 -18,8 +18,8 @@@ use attr::ThinAttributesExt
  use util::parser::AssocOp;
  use attr;
  use attr::{AttrMetaMethods, AttributeMethods};
- use codemap::{self, CodeMap, BytePos};
+ use codemap::{self, CodeMap};
+ use syntax_pos::{self, BytePos};
  use errors;
  use parse::token::{self, keywords, BinOpToken, Token, InternedString};
  use parse::lexer::comments;
@@@ -842,11 -843,11 +843,11 @@@ impl<'a> State<'a> 
          self.end() // close the head-box
      }
  
-     pub fn bclose_(&mut self, span: codemap::Span,
+     pub fn bclose_(&mut self, span: syntax_pos::Span,
                     indented: usize) -> io::Result<()> {
          self.bclose_maybe_open(span, indented, true)
      }
-     pub fn bclose_maybe_open(&mut self, span: codemap::Span,
+     pub fn bclose_maybe_open(&mut self, span: syntax_pos::Span,
                               indented: usize, close_box: bool) -> io::Result<()> {
          try!(self.maybe_print_comment(span.hi));
          try!(self.break_offset_if_not_bol(1, -(indented as isize)));
          }
          Ok(())
      }
-     pub fn bclose(&mut self, span: codemap::Span) -> io::Result<()> {
+     pub fn bclose(&mut self, span: syntax_pos::Span) -> io::Result<()> {
          self.bclose_(span, INDENT_UNIT)
      }
  
                                    mut op: F,
                                    mut get_span: G) -> io::Result<()> where
          F: FnMut(&mut State, &T) -> io::Result<()>,
-         G: FnMut(&T) -> codemap::Span,
+         G: FnMut(&T) -> syntax_pos::Span,
      {
          try!(self.rbox(0, b));
          let len = elts.len();
  
      pub fn print_enum_def(&mut self, enum_definition: &ast::EnumDef,
                            generics: &ast::Generics, ident: ast::Ident,
-                           span: codemap::Span,
+                           span: syntax_pos::Span,
                            visibility: &ast::Visibility) -> io::Result<()> {
          try!(self.head(&visibility_qualified(visibility, "enum")));
          try!(self.print_ident(ident));
  
      pub fn print_variants(&mut self,
                            variants: &[ast::Variant],
-                           span: codemap::Span) -> io::Result<()> {
+                           span: syntax_pos::Span) -> io::Result<()> {
          try!(self.bopen());
          for v in variants {
              try!(self.space_if_not_bol());
                          struct_def: &ast::VariantData,
                          generics: &ast::Generics,
                          ident: ast::Ident,
-                         span: codemap::Span,
+                         span: syntax_pos::Span,
                          print_finalizer: bool) -> io::Result<()> {
          try!(self.print_ident(ident));
          try!(self.print_generics(generics));
                  try!(self.print_associated_type(ti.ident, Some(bounds),
                                             default.as_ref().map(|ty| &**ty)));
              }
 +            ast::TraitItemKind::Macro(codemap::Spanned { ref node, .. }) => {
 +                // code copied from ItemKind::Mac:
 +                self.print_path(&node.path, false, 0)?;
 +                word(&mut self.s, "! ")?;
 +                self.cbox(INDENT_UNIT)?;
 +                self.popen()?;
 +                self.print_tts(&node.tts[..])?;
 +                self.pclose()?;
 +                word(&mut self.s, ";")?;
 +                self.end()?
 +            }
          }
          self.ann.post(self, NodeSubItem(ti.id))
      }
                  }
                  try!(self.pclose());
              }
 -            PatKind::Path(ref path) => {
 +            PatKind::Path(None, ref path) => {
                  try!(self.print_path(path, true, 0));
              }
 -            PatKind::QPath(ref qself, ref path) => {
 +            PatKind::Path(Some(ref qself), ref path) => {
                  try!(self.print_qpath(path, qself, false));
              }
              PatKind::Struct(ref path, ref fields, etc) => {
          self.end()
      }
  
-     pub fn maybe_print_trailing_comment(&mut self, span: codemap::Span,
+     pub fn maybe_print_trailing_comment(&mut self, span: syntax_pos::Span,
                                          next_pos: Option<BytePos>)
          -> io::Result<()> {
          let cm = match self.cm {
@@@ -3115,6 -3105,7 +3116,7 @@@ mod tests 
      use ast;
      use codemap;
      use parse::token;
+     use syntax_pos;
  
      #[test]
      fn test_fun_to_string() {
  
          let decl = ast::FnDecl {
              inputs: Vec::new(),
-             output: ast::FunctionRetTy::Default(codemap::DUMMY_SP),
+             output: ast::FunctionRetTy::Default(syntax_pos::DUMMY_SP),
              variadic: false
          };
          let generics = ast::Generics::default();
      fn test_variant_to_string() {
          let ident = token::str_to_ident("principal_skinner");
  
-         let var = codemap::respan(codemap::DUMMY_SP, ast::Variant_ {
+         let var = codemap::respan(syntax_pos::DUMMY_SP, ast::Variant_ {
              name: ident,
              attrs: Vec::new(),
              // making this up as I go.... ?
diff --combined src/libsyntax/visit.rs
index 5ec4c3eef31890f3a4bda9395de8f8020ba55bc8,b98f88d632ba8fb947dd5a611bfd69b2e7f0b94e..113c0d0293b994d7adb5734afb9794272f02d322
@@@ -26,7 -26,8 +26,8 @@@
  use abi::Abi;
  use ast::*;
  use attr::ThinAttributesExt;
- use codemap::{Span, Spanned};
+ use syntax_pos::Span;
+ use codemap::Spanned;
  
  #[derive(Copy, Clone, PartialEq, Eq)]
  pub enum FnKind<'a> {
@@@ -409,10 -410,11 +410,10 @@@ pub fn walk_pat<'v, V: Visitor<'v>>(vis
              visitor.visit_path(path, pattern.id);
              walk_list!(visitor, visit_pat, children);
          }
 -        PatKind::Path(ref path) => {
 -            visitor.visit_path(path, pattern.id);
 -        }
 -        PatKind::QPath(ref qself, ref path) => {
 -            visitor.visit_ty(&qself.ty);
 +        PatKind::Path(ref opt_qself, ref path) => {
 +            if let Some(ref qself) = *opt_qself {
 +                visitor.visit_ty(&qself.ty);
 +            }
              visitor.visit_path(path, pattern.id)
          }
          PatKind::Struct(ref path, ref fields, _) => {
@@@ -567,9 -569,6 +568,9 @@@ pub fn walk_trait_item<'v, V: Visitor<'
              walk_list!(visitor, visit_ty_param_bound, bounds);
              walk_list!(visitor, visit_ty, default);
          }
 +        TraitItemKind::Macro(ref mac) => {
 +            visitor.visit_mac(mac);
 +        }
      }
  }