Derive hash for AST types
diff --git a/src/attr.rs b/src/attr.rs
index 8f70319..146427a 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -3,7 +3,7 @@
 use std::iter;
 
 /// Doc-comments are promoted to attributes that have `is_sugared_doc` = true
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct Attribute {
     pub style: AttrStyle,
     pub value: MetaItem,
@@ -19,7 +19,7 @@
 /// Distinguishes between Attributes that decorate items and Attributes that
 /// are contained as statements within items. These two cases need to be
 /// distinguished for pretty-printing.
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
 pub enum AttrStyle {
     Outer,
     Inner,
@@ -28,7 +28,7 @@
 /// A compile-time attribute item.
 ///
 /// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum MetaItem {
     /// Word meta item.
     ///
@@ -57,7 +57,7 @@
 /// Possible values inside of compile-time attribute lists.
 ///
 /// E.g. the '..' in `#[name(..)]`.
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum NestedMetaItem {
     /// A full MetaItem, for recursive meta items.
     MetaItem(MetaItem),
diff --git a/src/constant.rs b/src/constant.rs
index b2420c0..c7d0e32 100644
--- a/src/constant.rs
+++ b/src/constant.rs
@@ -1,6 +1,6 @@
 use super::*;
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum ConstExpr {
     /// A function call
     ///
@@ -28,7 +28,7 @@
 }
 
 #[cfg(not(feature = "full"))]
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct Other {
     _private: (),
 }
diff --git a/src/data.rs b/src/data.rs
index 738d4a7..7ccfd7a 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -1,6 +1,6 @@
 use super::*;
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct Variant {
     pub ident: Ident,
     pub attrs: Vec<Attribute>,
@@ -9,7 +9,7 @@
     pub discriminant: Option<ConstExpr>,
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum VariantData {
     Struct(Vec<Field>),
     Tuple(Vec<Field>),
@@ -34,7 +34,7 @@
     }
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct Field {
     pub ident: Option<Ident>,
     pub vis: Visibility,
@@ -42,7 +42,7 @@
     pub ty: Ty,
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum Visibility {
     Public,
     Crate,
diff --git a/src/expr.rs b/src/expr.rs
index 72922ca..c8b574d 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -1,6 +1,6 @@
 use super::*;
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct Expr {
     pub node: ExprKind,
     pub attrs: Vec<Attribute>,
@@ -15,7 +15,7 @@
     }
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum ExprKind {
     /// A `box x` expression.
     Box(Box<Expr>),
@@ -145,7 +145,7 @@
     Try(Box<Expr>),
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct FieldValue {
     pub ident: Ident,
     pub expr: Expr,
@@ -155,19 +155,19 @@
 /// A Block (`{ .. }`).
 ///
 /// E.g. `{ .. }` as in `fn foo() { .. }`
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct Block {
     /// Statements in a block
     pub stmts: Vec<Stmt>,
 }
 
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
 pub enum BlockCheckMode {
     Default,
     Unsafe,
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum Stmt {
     /// A local (let) binding.
     Local(Box<Local>),
@@ -183,7 +183,7 @@
     Mac(Box<(Mac, MacStmtStyle, Vec<Attribute>)>),
 }
 
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
 pub enum MacStmtStyle {
     /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
     /// `foo!(...);`, `foo![...];`
@@ -197,7 +197,7 @@
 }
 
 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct Local {
     pub pat: Box<Pat>,
     pub ty: Option<Box<Ty>>,
@@ -206,7 +206,7 @@
     pub attrs: Vec<Attribute>,
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 // Clippy false positive
 // https://github.com/Manishearth/rust-clippy/issues/1241
 #[cfg_attr(feature = "clippy", allow(enum_variant_names))]
@@ -264,7 +264,7 @@
 ///     // ..
 /// }
 /// ```
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct Arm {
     pub attrs: Vec<Attribute>,
     pub pats: Vec<Pat>,
@@ -273,14 +273,14 @@
 }
 
 /// A capture clause
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
 pub enum CaptureBy {
     Value,
     Ref,
 }
 
 /// Limit types of a range (inclusive or exclusive)
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
 pub enum RangeLimits {
     /// Inclusive at the beginning, exclusive at the end
     HalfOpen,
@@ -293,7 +293,7 @@
 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
 /// are treated the same as `x: x, y: ref y, z: ref mut z`,
 /// except `is_shorthand` is true
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct FieldPat {
     /// The identifier for the field
     pub ident: Ident,
@@ -302,7 +302,7 @@
     pub is_shorthand: bool,
 }
 
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
 pub enum BindingMode {
     ByRef(Mutability),
     ByValue(Mutability),
diff --git a/src/generics.rs b/src/generics.rs
index 99165c4..d76051f 100644
--- a/src/generics.rs
+++ b/src/generics.rs
@@ -2,7 +2,7 @@
 
 /// Represents lifetimes and type parameters attached to a declaration
 /// of a function, enum, trait, etc.
-#[derive(Debug, Clone, Eq, PartialEq, Default)]
+#[derive(Debug, Clone, Eq, PartialEq, Default, Hash)]
 pub struct Generics {
     pub lifetimes: Vec<LifetimeDef>,
     pub ty_params: Vec<TyParam>,
@@ -45,7 +45,7 @@
     }
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct Lifetime {
     pub ident: Ident,
 }
@@ -63,7 +63,7 @@
 }
 
 /// A lifetime definition, e.g. `'a: 'b+'c+'d`
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct LifetimeDef {
     pub attrs: Vec<Attribute>,
     pub lifetime: Lifetime,
@@ -80,7 +80,7 @@
     }
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct TyParam {
     pub attrs: Vec<Attribute>,
     pub ident: Ident,
@@ -92,7 +92,7 @@
 /// `typeck::collect::compute_bounds` matches these against
 /// the "special" built-in traits (see `middle::lang_items`) and
 /// detects Copy, Send and Sync.
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum TyParamBound {
     Trait(PolyTraitRef, TraitBoundModifier),
     Region(Lifetime),
@@ -100,14 +100,14 @@
 
 /// A modifier on a bound, currently this is only used for `?Sized`, where the
 /// modifier is `Maybe`. Negative bounds should also be handled here.
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
 pub enum TraitBoundModifier {
     None,
     Maybe,
 }
 
 /// A `where` clause in a definition
-#[derive(Debug, Clone, Eq, PartialEq, Default)]
+#[derive(Debug, Clone, Eq, PartialEq, Default, Hash)]
 pub struct WhereClause {
     pub predicates: Vec<WherePredicate>,
 }
@@ -119,7 +119,7 @@
 }
 
 /// A single predicate in a `where` clause
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum WherePredicate {
     /// A type binding, e.g. `for<'c> Foo: Send+Clone+'c`
     BoundPredicate(WhereBoundPredicate),
@@ -130,7 +130,7 @@
 /// A type bound.
 ///
 /// E.g. `for<'c> Foo: Send+Clone+'c`
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct WhereBoundPredicate {
     /// Any lifetimes from a `for` binding
     pub bound_lifetimes: Vec<LifetimeDef>,
@@ -143,7 +143,7 @@
 /// A lifetime predicate.
 ///
 /// E.g. `'a: 'b+'c`
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct WhereRegionPredicate {
     pub lifetime: Lifetime,
     pub bounds: Vec<Lifetime>,
diff --git a/src/item.rs b/src/item.rs
index a8eb737..00d537a 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -3,7 +3,7 @@
 /// An item
 ///
 /// The name might be a dummy name in case of anonymous items
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct Item {
     pub ident: Ident,
     pub vis: Visibility,
@@ -11,7 +11,7 @@
     pub node: ItemKind,
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum ItemKind {
     /// An`extern crate` item, with optional original crate name.
     ///
@@ -94,7 +94,7 @@
     }
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum ViewPath {
     /// `foo::bar::baz as quux`
     ///
@@ -110,20 +110,20 @@
     List(Path, Vec<PathListItem>),
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct PathListItem {
     pub name: Ident,
     /// renamed in list, e.g. `use foo::{bar as baz};`
     pub rename: Option<Ident>,
 }
 
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
 pub enum Constness {
     Const,
     NotConst,
 }
 
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
 pub enum Defaultness {
     Default,
     Final,
@@ -132,13 +132,13 @@
 /// Foreign module declaration.
 ///
 /// E.g. `extern { .. }` or `extern "C" { .. }`
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct ForeignMod {
     pub abi: Abi,
     pub items: Vec<ForeignItem>,
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct ForeignItem {
     pub ident: Ident,
     pub attrs: Vec<Attribute>,
@@ -147,7 +147,7 @@
 }
 
 /// An item within an `extern` block
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum ForeignItemKind {
     /// A foreign function
     Fn(Box<FnDecl>, Generics),
@@ -159,14 +159,14 @@
 /// possibly including a default implementation. A trait item is
 /// either required (meaning it doesn't have an implementation, just a
 /// signature) or provided (meaning it has a default implementation).
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct TraitItem {
     pub ident: Ident,
     pub attrs: Vec<Attribute>,
     pub node: TraitItemKind,
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum TraitItemKind {
     Const(Ty, Option<Expr>),
     Method(MethodSig, Option<Block>),
@@ -174,7 +174,7 @@
     Macro(Mac),
 }
 
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
 pub enum ImplPolarity {
     /// `impl Trait for Type`
     Positive,
@@ -182,7 +182,7 @@
     Negative,
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct ImplItem {
     pub ident: Ident,
     pub vis: Visibility,
@@ -191,7 +191,7 @@
     pub node: ImplItemKind,
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum ImplItemKind {
     Const(Ty, Expr),
     Method(MethodSig, Block),
@@ -201,7 +201,7 @@
 
 /// Represents a method's signature in a trait declaration,
 /// or in an implementation.
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct MethodSig {
     pub unsafety: Unsafety,
     pub constness: Constness,
@@ -213,7 +213,7 @@
 /// Header (not the body) of a function declaration.
 ///
 /// E.g. `fn foo(bar: baz)`
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct FnDecl {
     pub inputs: Vec<FnArg>,
     pub output: FunctionRetTy,
@@ -223,7 +223,7 @@
 /// An argument in a function header.
 ///
 /// E.g. `bar: usize` as in `fn foo(bar: usize)`
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum FnArg {
     SelfRef(Option<Lifetime>, Mutability),
     SelfValue(Mutability),
diff --git a/src/krate.rs b/src/krate.rs
index 06368f0..7ed16b5 100644
--- a/src/krate.rs
+++ b/src/krate.rs
@@ -1,6 +1,6 @@
 use super::*;
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct Crate {
     pub shebang: Option<String>,
     pub attrs: Vec<Attribute>,
diff --git a/src/lit.rs b/src/lit.rs
index 5b94ceb..6617410 100644
--- a/src/lit.rs
+++ b/src/lit.rs
@@ -1,7 +1,7 @@
 /// Literal kind.
 ///
 /// E.g. `"foo"`, `42`, `12.34` or `bool`
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum Lit {
     /// A string literal (`"foo"`)
     Str(String, StrStyle),
@@ -19,7 +19,7 @@
     Bool(bool),
 }
 
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
 pub enum StrStyle {
     /// A regular string, like `"foo"`
     Cooked,
@@ -65,7 +65,7 @@
     }
 }
 
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
 pub enum IntTy {
     Isize,
     I8,
@@ -80,7 +80,7 @@
     Unsuffixed,
 }
 
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
 pub enum FloatTy {
     F32,
     F64,
diff --git a/src/mac.rs b/src/mac.rs
index e9c942e..642f7bc 100644
--- a/src/mac.rs
+++ b/src/mac.rs
@@ -6,7 +6,7 @@
 ///
 /// NB: the additional ident for a `macro_rules`-style macro is actually
 /// stored in the enclosing item. Oog.
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct Mac {
     pub path: Path,
     pub tts: Vec<TokenTree>,
@@ -24,7 +24,7 @@
 ///
 /// The RHS of an MBE macro is the only place `SubstNt`s are substituted.
 /// Nothing special happens to misnamed or misplaced `SubstNt`s.
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum TokenTree {
     /// A single token
     Token(Token),
@@ -32,7 +32,7 @@
     Delimited(Delimited),
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct Delimited {
     /// The type of delimiter
     pub delim: DelimToken,
@@ -40,7 +40,7 @@
     pub tts: Vec<TokenTree>,
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum Token {
     // Expression-operator symbols.
     Eq,
@@ -84,7 +84,7 @@
     DocComment(String),
 }
 
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
 pub enum BinOpToken {
     Plus,
     Minus,
@@ -99,7 +99,7 @@
 }
 
 /// A delimiter token
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
 pub enum DelimToken {
     /// A round parenthesis: `(` or `)`
     Paren,
diff --git a/src/macro_input.rs b/src/macro_input.rs
index 3abdc3d..de99f27 100644
--- a/src/macro_input.rs
+++ b/src/macro_input.rs
@@ -1,6 +1,6 @@
 use super::*;
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct MacroInput {
     pub ident: Ident,
     pub vis: Visibility,
@@ -9,7 +9,7 @@
     pub body: Body,
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum Body {
     Enum(Vec<Variant>),
     Struct(VariantData),
diff --git a/src/op.rs b/src/op.rs
index ffe181f..d4b0bc7 100644
--- a/src/op.rs
+++ b/src/op.rs
@@ -1,4 +1,4 @@
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
 pub enum BinOp {
     /// The `+` operator (addition)
     Add,
@@ -38,7 +38,7 @@
     Gt,
 }
 
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
 pub enum UnOp {
     /// The `*` operator for dereferencing
     Deref,
diff --git a/src/ty.rs b/src/ty.rs
index 48cf0f9..e10901c 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -1,7 +1,7 @@
 use super::*;
 
 /// The different kinds of types recognized by the compiler
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum Ty {
     /// A variable-length array (`[T]`)
     Slice(Box<Ty>),
@@ -35,13 +35,13 @@
     Infer,
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct MutTy {
     pub ty: Ty,
     pub mutability: Mutability,
 }
 
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
 pub enum Mutability {
     Mutable,
     Immutable,
@@ -53,7 +53,7 @@
 /// along with a bunch of supporting information.
 ///
 /// E.g. `std::cmp::PartialEq`
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct Path {
     pub global: bool,
     pub segments: Vec<PathSegment>,
@@ -73,7 +73,7 @@
 /// A segment of a path: an identifier, an optional lifetime, and a set of types.
 ///
 /// E.g. `std`, `String` or `Box<T>`
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct PathSegment {
     pub ident: Ident,
     pub parameters: PathParameters,
@@ -93,7 +93,7 @@
 /// Parameters of a path segment.
 ///
 /// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum PathParameters {
     /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>`
     AngleBracketed(AngleBracketedParameterData),
@@ -118,7 +118,7 @@
 }
 
 /// A path like `Foo<'a, T>`
-#[derive(Debug, Clone, Eq, PartialEq, Default)]
+#[derive(Debug, Clone, Eq, PartialEq, Default, Hash)]
 pub struct AngleBracketedParameterData {
     /// The lifetime parameters for this path segment.
     pub lifetimes: Vec<Lifetime>,
@@ -131,14 +131,14 @@
 }
 
 /// Bind a type to an associated type: `A=Foo`.
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct TypeBinding {
     pub ident: Ident,
     pub ty: Ty,
 }
 
 /// A path like `Foo(A,B) -> C`
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct ParenthesizedParameterData {
     /// `(A, B)`
     pub inputs: Vec<Ty>,
@@ -146,7 +146,7 @@
     pub output: Option<Ty>,
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct PolyTraitRef {
     /// The `'a` in `<'a> Foo<&'a T>`
     pub bound_lifetimes: Vec<LifetimeDef>,
@@ -168,13 +168,13 @@
 ///  ^~~~~    ^
 ///  ty       position = 0
 /// ```
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct QSelf {
     pub ty: Box<Ty>,
     pub position: usize,
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct BareFnTy {
     pub unsafety: Unsafety,
     pub abi: Option<Abi>,
@@ -184,13 +184,13 @@
     pub variadic: bool,
 }
 
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
 pub enum Unsafety {
     Unsafe,
     Normal,
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum Abi {
     Named(String),
     Rust,
@@ -199,13 +199,13 @@
 /// An argument in a function type.
 ///
 /// E.g. `bar: usize` as in `fn foo(bar: usize)`
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct BareFnArg {
     pub name: Option<Ident>,
     pub ty: Ty,
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub enum FunctionRetTy {
     /// Return type is not specified.
     ///