about summary refs log tree commit diff
path: root/tests/incremental/hashes
diff options
context:
space:
mode:
Diffstat (limited to 'tests/incremental/hashes')
-rw-r--r--tests/incremental/hashes/call_expressions.rs197
-rw-r--r--tests/incremental/hashes/closure_expressions.rs124
-rw-r--r--tests/incremental/hashes/consts.rs109
-rw-r--r--tests/incremental/hashes/enum_constructors.rs387
-rw-r--r--tests/incremental/hashes/enum_defs.rs715
-rw-r--r--tests/incremental/hashes/exported_vs_not.rs72
-rw-r--r--tests/incremental/hashes/extern_mods.rs221
-rw-r--r--tests/incremental/hashes/for_loops.rs299
-rw-r--r--tests/incremental/hashes/function_interfaces.rs411
-rw-r--r--tests/incremental/hashes/if_expressions.rs225
-rw-r--r--tests/incremental/hashes/indexing_expressions.rs134
-rw-r--r--tests/incremental/hashes/inherent_impls.rs787
-rw-r--r--tests/incremental/hashes/inline_asm.rs219
-rw-r--r--tests/incremental/hashes/let_expressions.rs219
-rw-r--r--tests/incremental/hashes/loop_expressions.rs224
-rw-r--r--tests/incremental/hashes/match_expressions.rs334
-rw-r--r--tests/incremental/hashes/panic_exprs.rs151
-rw-r--r--tests/incremental/hashes/statics.rs183
-rw-r--r--tests/incremental/hashes/struct_constructors.rs267
-rw-r--r--tests/incremental/hashes/struct_defs.rs332
-rw-r--r--tests/incremental/hashes/trait_defs.rs1409
-rw-r--r--tests/incremental/hashes/trait_impls.rs617
-rw-r--r--tests/incremental/hashes/type_defs.rs220
-rw-r--r--tests/incremental/hashes/unary_and_binary_exprs.rs506
-rw-r--r--tests/incremental/hashes/while_let_loops.rs247
-rw-r--r--tests/incremental/hashes/while_loops.rs249
26 files changed, 8858 insertions, 0 deletions
diff --git a/tests/incremental/hashes/call_expressions.rs b/tests/incremental/hashes/call_expressions.rs
new file mode 100644
index 00000000000..65df2e8292a
--- /dev/null
+++ b/tests/incremental/hashes/call_expressions.rs
@@ -0,0 +1,197 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for function and method call expressions.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+fn callee1(_x: u32, _y: i64) {}
+fn callee2(_x: u32, _y: i64) {}
+
+
+// Change Callee (Function)
+#[cfg(any(cfail1,cfail4))]
+pub fn change_callee_function() {
+    callee1(1, 2)
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_callee_function() {
+    callee2(1, 2)
+}
+
+
+
+// Change Argument (Function)
+#[cfg(any(cfail1,cfail4))]
+pub fn change_argument_function() {
+    callee1(1, 2)
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_argument_function() {
+    callee1(1, 3)
+}
+
+
+
+// Change Callee Indirectly (Function)
+mod change_callee_indirectly_function {
+    #[cfg(any(cfail1,cfail4))]
+    use super::callee1 as callee;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::callee2 as callee;
+
+    #[rustc_clean(except="hir_owner_nodes,typeck", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner_nodes,typeck", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn change_callee_indirectly_function() {
+        callee(1, 2)
+    }
+}
+
+
+struct Struct;
+impl Struct {
+    fn method1(&self, _x: char, _y: bool) {}
+    fn method2(&self, _x: char, _y: bool) {}
+}
+
+// Change Callee (Method)
+#[cfg(any(cfail1,cfail4))]
+pub fn change_callee_method() {
+    let s = Struct;
+    s.method1('x', true);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_callee_method() {
+    let s = Struct;
+    s.method2('x', true);
+}
+
+
+
+// Change Argument (Method)
+#[cfg(any(cfail1,cfail4))]
+pub fn change_argument_method() {
+    let s = Struct;
+    s.method1('x', true);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_argument_method() {
+    let s = Struct;
+    s.method1('y', true);
+}
+
+
+
+// Change Callee (Method, UFCS)
+#[cfg(any(cfail1,cfail4))]
+pub fn change_ufcs_callee_method() {
+    let s = Struct;
+    Struct::method1(&s, 'x', true);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_ufcs_callee_method() {
+    let s = Struct;
+    Struct::method2(&s, 'x', true);
+}
+
+
+
+// Change Argument (Method, UFCS)
+#[cfg(any(cfail1,cfail4))]
+pub fn change_argument_method_ufcs() {
+    let s = Struct;
+    Struct::method1(&s, 'x', true);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_argument_method_ufcs() {
+    let s = Struct;
+    Struct::method1(&s, 'x',false);
+}
+
+
+
+// Change To UFCS
+#[cfg(any(cfail1,cfail4))]
+pub fn change_to_ufcs() {
+    let s = Struct;
+    s.method1('x', true); // ------
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
+// One might think this would be expanded in the hir_owner_nodes/Mir, but it actually
+// results in slightly different hir_owner/Mir.
+pub fn change_to_ufcs() {
+    let s = Struct;
+    Struct::method1(&s, 'x', true);
+}
+
+
+struct Struct2;
+impl Struct2 {
+    fn method1(&self, _x: char, _y: bool) {}
+}
+
+// Change UFCS Callee Indirectly
+pub mod change_ufcs_callee_indirectly {
+    #[cfg(any(cfail1,cfail4))]
+    use super::Struct as Struct;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::Struct2 as Struct;
+
+    #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn change_ufcs_callee_indirectly() {
+        let s = Struct;
+        Struct::method1(&s, 'q', false)
+    }
+}
diff --git a/tests/incremental/hashes/closure_expressions.rs b/tests/incremental/hashes/closure_expressions.rs
new file mode 100644
index 00000000000..927bcd96e6f
--- /dev/null
+++ b/tests/incremental/hashes/closure_expressions.rs
@@ -0,0 +1,124 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for closure expression.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+
+// Change closure body
+#[cfg(any(cfail1,cfail4))]
+pub fn change_closure_body() {
+    let _ = || 1u32;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_closure_body() {
+    let _ = || 3u32;
+}
+
+
+
+// Add parameter
+#[cfg(any(cfail1,cfail4))]
+pub fn add_parameter() {
+    let x = 0u32;
+    let _ = |      | x + 1;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_parameter() {
+    let x = 0u32;
+    let _ = |x: u32| x + 1;
+}
+
+
+
+// Change parameter pattern
+#[cfg(any(cfail1,cfail4))]
+pub fn change_parameter_pattern() {
+    let _ = | x  : (u32,)| x;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_parameter_pattern() {
+    let _ = |(x,): (u32,)| x;
+}
+
+
+
+// Add `move` to closure
+#[cfg(any(cfail1,cfail4))]
+pub fn add_move() {
+    let _ =      || 1;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_move() {
+    let _ = move || 1;
+}
+
+
+
+// Add type ascription to parameter
+#[cfg(any(cfail1,cfail4))]
+pub fn add_type_ascription_to_parameter() {
+    let closure = |x     | x + 1u32;
+    let _: u32 = closure(1);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2", except = "hir_owner_nodes, typeck")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner_nodes, typeck")]
+#[rustc_clean(cfg = "cfail6")]
+pub fn add_type_ascription_to_parameter() {
+    let closure = |x: u32| x + 1u32;
+    let _: u32 = closure(1);
+}
+
+
+
+// Change parameter type
+#[cfg(any(cfail1,cfail4))]
+pub fn change_parameter_type() {
+    let closure = |x: u32| (x as u64) + 1;
+    let _ = closure(1);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir, typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_parameter_type() {
+    let closure = |x: u16| (x as u64) + 1;
+    let _ = closure(1);
+}
diff --git a/tests/incremental/hashes/consts.rs b/tests/incremental/hashes/consts.rs
new file mode 100644
index 00000000000..eaef63386ff
--- /dev/null
+++ b/tests/incremental/hashes/consts.rs
@@ -0,0 +1,109 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for consts.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3
+// compile-flags: -Z query-dep-graph -O
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+
+// Change const visibility
+#[cfg(cfail1)]
+const CONST_VISIBILITY: u8 = 0;
+
+#[cfg(not(cfail1))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+pub const CONST_VISIBILITY: u8 = 0;
+
+
+// Change type from i32 to u32
+#[cfg(cfail1)]
+const CONST_CHANGE_TYPE_1: i32 = 0;
+
+#[cfg(not(cfail1))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail3")]
+const CONST_CHANGE_TYPE_1: u32 = 0;
+
+
+// Change type from Option<u32> to Option<u64>
+#[cfg(cfail1)]
+const CONST_CHANGE_TYPE_2: Option<u32> = None;
+
+#[cfg(not(cfail1))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail3")]
+const CONST_CHANGE_TYPE_2: Option<u64> = None;
+
+
+// Change value between simple literals
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+const CONST_CHANGE_VALUE_1: i16 = {
+    #[cfg(cfail1)]
+    { 1 }
+
+    #[cfg(not(cfail1))]
+    { 2 }
+};
+
+
+// Change value between expressions
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+const CONST_CHANGE_VALUE_2: i16 = {
+    #[cfg(cfail1)]
+    { 1 + 1 }
+
+    #[cfg(not(cfail1))]
+    { 1 + 2 }
+};
+
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+const CONST_CHANGE_VALUE_3: i16 = {
+    #[cfg(cfail1)]
+    { 2 + 3 }
+
+    #[cfg(not(cfail1))]
+    { 2 * 3 }
+};
+
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+const CONST_CHANGE_VALUE_4: i16 = {
+    #[cfg(cfail1)]
+    { 1 + 2 * 3 }
+
+    #[cfg(not(cfail1))]
+    { 1 + 2 * 4 }
+};
+
+
+// Change type indirectly
+struct ReferencedType1;
+struct ReferencedType2;
+
+mod const_change_type_indirectly {
+    #[cfg(cfail1)]
+    use super::ReferencedType1 as Type;
+
+    #[cfg(not(cfail1))]
+    use super::ReferencedType2 as Type;
+
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+    #[rustc_clean(cfg="cfail3")]
+    const CONST_CHANGE_TYPE_INDIRECTLY_1: Type = Type;
+
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+    #[rustc_clean(cfg="cfail3")]
+    const CONST_CHANGE_TYPE_INDIRECTLY_2: Option<Type> = None;
+}
diff --git a/tests/incremental/hashes/enum_constructors.rs b/tests/incremental/hashes/enum_constructors.rs
new file mode 100644
index 00000000000..db367d07094
--- /dev/null
+++ b/tests/incremental/hashes/enum_constructors.rs
@@ -0,0 +1,387 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for struct constructor expressions.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+
+pub enum Enum {
+    Struct {
+        x: i32,
+        y: i64,
+        z: i16,
+    },
+    Tuple(i32, i64, i16)
+}
+
+// Change field value (struct-like) -----------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_field_value_struct_like() -> Enum {
+    Enum::Struct {
+        x: 0,
+        y: 1,
+        z: 2,
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_field_value_struct_like() -> Enum {
+    Enum::Struct {
+        x: 0,
+        y: 2,
+        z: 2,
+    }
+}
+
+
+
+// Change field order (struct-like) -----------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_field_order_struct_like() -> Enum {
+    Enum::Struct {
+        x: 3,
+        y: 4,
+        z: 5,
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+// FIXME(michaelwoerister):Interesting. I would have thought that that changes the MIR. And it
+// would if it were not all constants
+pub fn change_field_order_struct_like() -> Enum {
+    Enum::Struct {
+        y: 4,
+        x: 3,
+        z: 5,
+    }
+}
+
+
+pub enum Enum2 {
+    Struct {
+        x: i8,
+        y: i8,
+        z: i8,
+    },
+    Struct2 {
+        x: i8,
+        y: i8,
+        z: i8,
+    },
+    Tuple(u16, u16, u16),
+    Tuple2(u64, u64, u64),
+}
+
+// Change constructor path (struct-like) ------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_constructor_path_struct_like() {
+    let _ = Enum ::Struct {
+        x: 0,
+        y: 1,
+        z: 2,
+    };
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_constructor_path_struct_like() {
+    let _ = Enum2::Struct {
+        x: 0,
+        y: 1,
+        z: 2,
+    };
+}
+
+
+
+// Change variant (regular struct) ------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_constructor_variant_struct_like() {
+    let _ = Enum2::Struct  {
+        x: 0,
+        y: 1,
+        z: 2,
+    };
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_constructor_variant_struct_like() {
+    let _ = Enum2::Struct2 {
+        x: 0,
+        y: 1,
+        z: 2,
+    };
+}
+
+
+// Change constructor path indirectly (struct-like) -------------------------
+pub mod change_constructor_path_indirectly_struct_like {
+    #[cfg(any(cfail1,cfail4))]
+    use super::Enum as TheEnum;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::Enum2 as TheEnum;
+
+    #[rustc_clean(
+        cfg="cfail2",
+        except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,\
+                typeck"
+    )]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        cfg="cfail5",
+        except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,\
+                typeck"
+    )]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn function() -> TheEnum {
+        TheEnum::Struct {
+            x: 0,
+            y: 1,
+            z: 2,
+        }
+    }
+}
+
+
+// Change constructor variant indirectly (struct-like) ---------------------------
+pub mod change_constructor_variant_indirectly_struct_like {
+    use super::Enum2;
+    #[cfg(any(cfail1,cfail4))]
+    use super::Enum2::Struct as Variant;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::Enum2::Struct2 as Variant;
+
+    #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn function() -> Enum2 {
+        Variant {
+            x: 0,
+            y: 1,
+            z: 2,
+        }
+    }
+}
+
+
+// Change field value (tuple-like) -------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_field_value_tuple_like() -> Enum {
+    Enum::Tuple(0, 1, 2)
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_field_value_tuple_like() -> Enum {
+    Enum::Tuple(0, 1, 3)
+}
+
+
+
+// Change constructor path (tuple-like) --------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_constructor_path_tuple_like() {
+    let _ = Enum ::Tuple(0, 1, 2);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(
+    cfg="cfail2",
+    except="hir_owner_nodes,typeck"
+)]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(
+    cfg="cfail5",
+    except="hir_owner_nodes,typeck"
+)]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_constructor_path_tuple_like() {
+    let _ = Enum2::Tuple(0, 1, 2);
+}
+
+
+
+// Change constructor variant (tuple-like) --------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_constructor_variant_tuple_like() {
+    let _ = Enum2::Tuple (0, 1, 2);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(
+    cfg="cfail2",
+    except="hir_owner_nodes,typeck"
+)]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(
+    cfg="cfail5",
+    except="hir_owner_nodes,typeck"
+)]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_constructor_variant_tuple_like() {
+    let _ = Enum2::Tuple2(0, 1, 2);
+}
+
+
+// Change constructor path indirectly (tuple-like) ---------------------------
+pub mod change_constructor_path_indirectly_tuple_like {
+    #[cfg(any(cfail1,cfail4))]
+    use super::Enum as TheEnum;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::Enum2 as TheEnum;
+
+    #[rustc_clean(
+        cfg="cfail2",
+        except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,\
+                typeck"
+    )]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        cfg="cfail5",
+        except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,\
+                typeck"
+    )]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn function() -> TheEnum {
+        TheEnum::Tuple(0, 1, 2)
+    }
+}
+
+
+
+// Change constructor variant indirectly (tuple-like) ---------------------------
+pub mod change_constructor_variant_indirectly_tuple_like {
+    use super::Enum2;
+    #[cfg(any(cfail1,cfail4))]
+    use super::Enum2::Tuple as Variant;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::Enum2::Tuple2 as Variant;
+
+    #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn function() -> Enum2 {
+        Variant(0, 1, 2)
+    }
+}
+
+
+pub enum Clike {
+    A,
+    B,
+    C
+}
+
+pub enum Clike2 {
+    B,
+    C,
+    D
+}
+
+// Change constructor path (C-like) --------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_constructor_path_c_like() {
+    let _x = Clike ::B;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_constructor_path_c_like() {
+    let _x = Clike2::B;
+}
+
+
+
+// Change constructor variant (C-like) --------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_constructor_variant_c_like() {
+    let _x = Clike::A;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_constructor_variant_c_like() {
+    let _x = Clike::C;
+}
+
+
+// Change constructor path indirectly (C-like) ---------------------------
+pub mod change_constructor_path_indirectly_c_like {
+    #[cfg(any(cfail1,cfail4))]
+    use super::Clike as TheEnum;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::Clike2 as TheEnum;
+
+    #[rustc_clean(
+        cfg="cfail2",
+        except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,\
+                typeck"
+    )]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        cfg="cfail5",
+        except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,\
+                typeck"
+    )]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn function() -> TheEnum {
+        TheEnum::B
+    }
+}
+
+
+
+// Change constructor variant indirectly (C-like) ---------------------------
+pub mod change_constructor_variant_indirectly_c_like {
+    use super::Clike;
+    #[cfg(any(cfail1,cfail4))]
+    use super::Clike::A as Variant;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::Clike::B as Variant;
+
+    #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn function() -> Clike {
+        Variant
+    }
+}
diff --git a/tests/incremental/hashes/enum_defs.rs b/tests/incremental/hashes/enum_defs.rs
new file mode 100644
index 00000000000..bc83723a908
--- /dev/null
+++ b/tests/incremental/hashes/enum_defs.rs
@@ -0,0 +1,715 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for enum definitions.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// We also test the ICH for enum definitions exported in metadata. Same as
+// above, we want to make sure that the change between rev1 and rev2 also
+// results in a change of the ICH for the enum's metadata, and that it stays
+// the same between rev2 and rev3.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![feature(stmt_expr_attributes)]
+#![crate_type="rlib"]
+
+
+
+// Change enum visibility -----------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum     EnumVisibility { A }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub enum EnumVisibility { A }
+
+
+
+// Change name of a c-style variant -------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumChangeNameCStyleVariant {
+    Variant1,
+    Variant2,
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumChangeNameCStyleVariant {
+    Variant1,
+    Variant2Changed,
+}
+
+
+
+// Change name of a tuple-style variant ---------------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumChangeNameTupleStyleVariant {
+    Variant1,
+    Variant2(u32, f32),
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumChangeNameTupleStyleVariant {
+    Variant1,
+    Variant2Changed(u32, f32),
+}
+
+
+
+// Change name of a struct-style variant --------------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumChangeNameStructStyleVariant {
+    Variant1,
+    Variant2 { a: u32, b: f32 },
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumChangeNameStructStyleVariant {
+    Variant1,
+    Variant2Changed { a: u32, b: f32 },
+}
+
+
+
+// Change the value of a c-style variant --------------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumChangeValueCStyleVariant0 {
+    Variant1,
+    Variant2 = 11,
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumChangeValueCStyleVariant0 {
+    Variant1,
+    Variant2 = 22,
+}
+
+#[cfg(any(cfail1,cfail4))]
+enum EnumChangeValueCStyleVariant1 {
+    Variant1,
+    Variant2,
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumChangeValueCStyleVariant1 {
+    Variant1,
+    Variant2 = 11,
+}
+
+
+
+// Add a c-style variant ------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumAddCStyleVariant {
+    Variant1,
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumAddCStyleVariant {
+    Variant1,
+    Variant2,
+}
+
+
+
+// Remove a c-style variant ---------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumRemoveCStyleVariant {
+    Variant1,
+    Variant2,
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumRemoveCStyleVariant {
+    Variant1,
+}
+
+
+
+// Add a tuple-style variant --------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumAddTupleStyleVariant {
+    Variant1,
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumAddTupleStyleVariant {
+    Variant1,
+    Variant2(u32, f32),
+}
+
+
+
+// Remove a tuple-style variant -----------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumRemoveTupleStyleVariant {
+    Variant1,
+    Variant2(u32, f32),
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumRemoveTupleStyleVariant {
+    Variant1,
+}
+
+
+
+// Add a struct-style variant -------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumAddStructStyleVariant {
+    Variant1,
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumAddStructStyleVariant {
+    Variant1,
+    Variant2 { a: u32, b: f32 },
+}
+
+
+
+// Remove a struct-style variant ----------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumRemoveStructStyleVariant {
+    Variant1,
+    Variant2 { a: u32, b: f32 },
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumRemoveStructStyleVariant {
+    Variant1,
+}
+
+
+
+// Change the type of a field in a tuple-style variant ------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumChangeFieldTypeTupleStyleVariant {
+    Variant1(u32, u32),
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumChangeFieldTypeTupleStyleVariant {
+    Variant1(u32,
+        u64),
+}
+
+
+
+// Change the type of a field in a struct-style variant -----------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumChangeFieldTypeStructStyleVariant {
+    Variant1,
+    Variant2 { a: u32, b: u32 },
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumChangeFieldTypeStructStyleVariant {
+    Variant1,
+    Variant2 {
+        a: u32,
+        b: u64
+    },
+}
+
+
+
+// Change the name of a field in a struct-style variant -----------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumChangeFieldNameStructStyleVariant {
+    Variant1 { a: u32, b: u32 },
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumChangeFieldNameStructStyleVariant {
+    Variant1 { a: u32, c: u32 },
+}
+
+
+
+// Change order of fields in a tuple-style variant ----------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumChangeOrderTupleStyleVariant {
+    Variant1(u32, u64),
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumChangeOrderTupleStyleVariant {
+    Variant1(
+        u64,
+        u32),
+}
+
+
+
+// Change order of fields in a struct-style variant ---------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumChangeFieldOrderStructStyleVariant {
+    Variant1 { a: u32, b: f32 },
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumChangeFieldOrderStructStyleVariant {
+    Variant1 { b: f32, a: u32 },
+}
+
+
+
+// Add a field to a tuple-style variant ---------------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumAddFieldTupleStyleVariant {
+    Variant1(u32, u32),
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumAddFieldTupleStyleVariant {
+    Variant1(u32, u32, u32),
+}
+
+
+
+// Add a field to a struct-style variant --------------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumAddFieldStructStyleVariant {
+    Variant1 { a: u32, b: u32 },
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumAddFieldStructStyleVariant {
+    Variant1 { a: u32, b: u32, c: u32 },
+}
+
+
+
+// Add #[must_use] to the enum ------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumAddMustUse {
+    Variant1,
+    Variant2,
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+#[must_use]
+enum EnumAddMustUse {
+    Variant1,
+    Variant2,
+}
+
+
+
+// Add #[repr(C)] to the enum -------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumAddReprC {
+    Variant1,
+    Variant2,
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="type_of")]
+#[rustc_clean(cfg="cfail6")]
+#[repr(C)]
+enum EnumAddReprC {
+    Variant1,
+    Variant2,
+}
+
+
+
+// Change the name of a type parameter ----------------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumChangeNameOfTypeParameter<S> {
+    Variant1(S),
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumChangeNameOfTypeParameter<T> {
+    Variant1(T),
+}
+
+
+
+// Add a type parameter ------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumAddTypeParameter<S> {
+    Variant1(S),
+    Variant2(S),
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumAddTypeParameter<S, T> {
+    Variant1(S),
+    Variant2(T),
+}
+
+
+
+// Change the name of a lifetime parameter ------------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumChangeNameOfLifetimeParameter<'a> {
+    Variant1(&'a u32),
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,generics_of,type_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumChangeNameOfLifetimeParameter<'b> {
+    Variant1(&'b u32),
+}
+
+
+
+// Add a lifetime parameter ---------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumAddLifetimeParameter<'a> {
+    Variant1(&'a u32),
+    Variant2(&'a u32),
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,generics_of,type_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumAddLifetimeParameter<'a, 'b> {
+    Variant1(&'a u32),
+    Variant2(&'b u32),
+}
+
+
+
+// Add a lifetime bound to a lifetime parameter -------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumAddLifetimeParameterBound<'a, 'b> {
+    Variant1(&'a u32),
+    Variant2(&'b u32),
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,predicates_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,predicates_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumAddLifetimeParameterBound<'a, 'b: 'a> {
+    Variant1(&'a u32),
+    Variant2(&'b u32),
+}
+
+// Add a lifetime bound to a type parameter -----------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumAddLifetimeBoundToParameter<'a, T> {
+    Variant1(T),
+    Variant2(&'a u32),
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,predicates_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,predicates_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumAddLifetimeBoundToParameter<'a, T: 'a> {
+    Variant1(T),
+    Variant2(&'a u32),
+}
+
+
+
+// Add a trait bound to a type parameter --------------------------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumAddTraitBound<S> {
+    Variant1(S),
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumAddTraitBound<T: Sync> {
+    Variant1(T),
+}
+
+
+
+// Add a lifetime bound to a lifetime parameter in where clause ---------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumAddLifetimeParameterBoundWhere<'a, 'b> {
+    Variant1(&'a u32),
+    Variant2(&'b u32),
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,predicates_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,predicates_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumAddLifetimeParameterBoundWhere<'a, 'b> where 'b: 'a {
+    Variant1(&'a u32),
+    Variant2(&'b u32),
+}
+
+
+
+// Add a lifetime bound to a type parameter in where clause -------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumAddLifetimeBoundToParameterWhere<'a, T> {
+    Variant1(T),
+    Variant2(&'a u32),
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,predicates_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,predicates_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumAddLifetimeBoundToParameterWhere<'a, T> where T: 'a {
+    Variant1(T),
+    Variant2(&'a u32),
+}
+
+
+
+// Add a trait bound to a type parameter in where clause ----------------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumAddTraitBoundWhere<S> {
+    Variant1(S),
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumAddTraitBoundWhere<T> where T: Sync {
+    Variant1(T),
+}
+
+
+
+// In an enum with two variants, swap usage of type parameters ----------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumSwapUsageTypeParameters<A, B> {
+    Variant1 { a: A },
+    Variant2 { a: B },
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumSwapUsageTypeParameters<A, B> {
+    Variant1 {
+        a: B
+    },
+    Variant2 {
+        a: A
+    },
+}
+
+
+
+// In an enum with two variants, swap usage of lifetime parameters ------------
+#[cfg(any(cfail1,cfail4))]
+enum EnumSwapUsageLifetimeParameters<'a, 'b> {
+    Variant1 { a: &'a u32 },
+    Variant2 { b: &'b u32 },
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+enum EnumSwapUsageLifetimeParameters<'a, 'b> {
+    Variant1 {
+        a: &'b u32
+    },
+    Variant2 {
+        b: &'a u32
+    },
+}
+
+
+
+struct ReferencedType1;
+struct ReferencedType2;
+
+
+
+// Change field type in tuple-style variant indirectly by modifying a use statement
+mod change_field_type_indirectly_tuple_style {
+    #[cfg(any(cfail1,cfail4))]
+    use super::ReferencedType1 as FieldType;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::ReferencedType2 as FieldType;
+
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+    #[rustc_clean(cfg="cfail6")]
+    enum TupleStyle {
+        Variant1(
+            FieldType
+        )
+    }
+}
+
+
+
+// Change field type in record-style variant indirectly by modifying a use statement
+mod change_field_type_indirectly_struct_style {
+    #[cfg(any(cfail1,cfail4))]
+    use super::ReferencedType1 as FieldType;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::ReferencedType2 as FieldType;
+
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+    #[rustc_clean(cfg="cfail6")]
+    enum StructStyle {
+        Variant1 {
+            a: FieldType
+        }
+    }
+}
+
+
+
+trait ReferencedTrait1 {}
+trait ReferencedTrait2 {}
+
+
+
+// Change trait bound of type parameter indirectly by modifying a use statement
+mod change_trait_bound_indirectly {
+    #[cfg(any(cfail1,cfail4))]
+    use super::ReferencedTrait1 as Trait;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::ReferencedTrait2 as Trait;
+
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,predicates_of")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,predicates_of")]
+    #[rustc_clean(cfg="cfail6")]
+    enum Enum<T: Trait> {
+        Variant1(T)
+    }
+}
+
+
+
+// Change trait bound of type parameter in where clause indirectly by modifying a use statement
+mod change_trait_bound_indirectly_where {
+    #[cfg(any(cfail1,cfail4))]
+    use super::ReferencedTrait1 as Trait;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::ReferencedTrait2 as Trait;
+
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,predicates_of")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,predicates_of")]
+    #[rustc_clean(cfg="cfail6")]
+    enum Enum<T> where T: Trait {
+        Variant1(T)
+    }
+}
diff --git a/tests/incremental/hashes/exported_vs_not.rs b/tests/incremental/hashes/exported_vs_not.rs
new file mode 100644
index 00000000000..9ac9ae24f81
--- /dev/null
+++ b/tests/incremental/hashes/exported_vs_not.rs
@@ -0,0 +1,72 @@
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+// Case 1: The function body is not exported to metadata. If the body changes,
+//         the hash of the hir_owner_nodes node should change, but not the hash of
+//         either the hir_owner or the Metadata node.
+
+#[cfg(any(cfail1,cfail4))]
+pub fn body_not_exported_to_metadata() -> u32 {
+    1
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn body_not_exported_to_metadata() -> u32 {
+    2
+}
+
+
+
+// Case 2: The function body *is* exported to metadata because the function is
+//         marked as #[inline]. Only the hash of the hir_owner depnode should be
+//         unaffected by a change to the body.
+
+#[cfg(any(cfail1,cfail4))]
+#[inline]
+pub fn body_exported_to_metadata_because_of_inline() -> u32 {
+    1
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+#[inline]
+pub fn body_exported_to_metadata_because_of_inline() -> u32 {
+    2
+}
+
+
+
+// Case 2: The function body *is* exported to metadata because the function is
+//         generic. Only the hash of the hir_owner depnode should be
+//         unaffected by a change to the body.
+
+#[cfg(any(cfail1,cfail4))]
+#[inline]
+pub fn body_exported_to_metadata_because_of_generic() -> u32 {
+    1
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+#[inline]
+pub fn body_exported_to_metadata_because_of_generic() -> u32 {
+    2
+}
diff --git a/tests/incremental/hashes/extern_mods.rs b/tests/incremental/hashes/extern_mods.rs
new file mode 100644
index 00000000000..1906843c7a2
--- /dev/null
+++ b/tests/incremental/hashes/extern_mods.rs
@@ -0,0 +1,221 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for `extern` modules.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![feature(unboxed_closures)]
+#![crate_type = "rlib"]
+
+// Change function name --------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+extern "C" {
+    pub fn change_function_name1(c: i64) -> i32;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2", except = "hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg = "cfail6")]
+extern "C" {
+    pub fn change_function_name2(c: i64) -> i32;
+}
+
+// Change parameter name -------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+extern "C" {
+    pub fn change_parameter_name(c: i64) -> i32;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
+extern "C" {
+    pub fn change_parameter_name(d: i64) -> i32;
+}
+
+// Change parameter type -------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+extern "C" {
+    pub fn change_parameter_type(c: i64) -> i32;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
+extern "C" {
+    pub fn change_parameter_type(c: i32) -> i32;
+}
+
+// Change return type ----------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+extern "C" {
+    pub fn change_return_type(c: i32) -> i32;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
+extern "C" {
+    pub fn change_return_type(c: i32) -> i8 ;
+}
+
+// Add parameter ---------------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+extern "C" {
+    pub fn add_parameter(c: i32        ) -> i32;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
+extern "C" {
+    pub fn add_parameter(c: i32, d: i32) -> i32;
+}
+
+// Add return type -------------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+extern "C" {
+    pub fn add_return_type(c: i32)       ;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
+extern "C" {
+    pub fn add_return_type(c: i32) -> i32;
+}
+
+// Make function variadic ------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+extern "C" {
+    pub fn make_function_variadic(c: i32     );
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
+extern "C" {
+    pub fn make_function_variadic(c: i32, ...);
+}
+
+// Change calling convention ---------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+extern "C" {
+    pub fn change_calling_convention(c: (i32,));
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2", except = "hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg = "cfail6")]
+extern "rust-call" {
+    pub fn change_calling_convention(c: (i32,));
+}
+
+// Make function public --------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+extern "C" {
+    fn     make_function_public(c: i32);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
+extern "C" {
+    pub fn make_function_public(c: i32);
+}
+
+// Add function ----------------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+extern "C" {
+    pub fn add_function1(c: i32);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2", except = "hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg = "cfail6")]
+extern "C" {
+    pub fn add_function1(c: i32);
+    pub fn add_function2();
+}
+
+// Change link-name ------------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+#[link(name = "foo")]
+extern "C" {
+    pub fn change_link_name(c: i32);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
+#[link(name = "bar")]
+extern "C" {
+    pub fn change_link_name(c: i32);
+}
+
+type c_i32 = i32;
+type c_i64 = i64;
+
+// Indirectly change parameter type --------------------------------------------
+mod indirectly_change_parameter_type {
+    #[cfg(any(cfail1,cfail4))]
+    use super::c_i32 as c_int;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::c_i64 as c_int;
+
+    #[rustc_clean(cfg = "cfail2")]
+    #[rustc_clean(cfg = "cfail3")]
+    #[rustc_clean(cfg = "cfail5")]
+    #[rustc_clean(cfg = "cfail6")]
+    extern "C" {
+        pub fn indirectly_change_parameter_type(c: c_int);
+    }
+}
+
+// Indirectly change return type --------------------------------------------
+mod indirectly_change_return_type {
+    #[cfg(any(cfail1,cfail4))]
+    use super::c_i32 as c_int;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::c_i64 as c_int;
+
+    #[rustc_clean(cfg = "cfail2")]
+    #[rustc_clean(cfg = "cfail3")]
+    #[rustc_clean(cfg = "cfail5")]
+    #[rustc_clean(cfg = "cfail6")]
+    extern "C" {
+        pub fn indirectly_change_return_type() -> c_int;
+    }
+}
diff --git a/tests/incremental/hashes/for_loops.rs b/tests/incremental/hashes/for_loops.rs
new file mode 100644
index 00000000000..193e792c843
--- /dev/null
+++ b/tests/incremental/hashes/for_loops.rs
@@ -0,0 +1,299 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for `for` loops.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+
+// Change loop body ------------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_loop_body() {
+    let mut _x = 0;
+    for _ in 0..1 {
+        _x = 1;
+        break;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_loop_body() {
+    let mut _x = 0;
+    for _ in 0..1 {
+        _x = 2;
+        break;
+    }
+}
+
+
+
+// Change iteration variable name ----------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_iteration_variable_name() {
+    let mut _x = 0;
+    for _i in 0..1 {
+        _x = 1;
+        break;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_iteration_variable_name() {
+    let mut _x = 0;
+    for _a in 0..1 {
+        _x = 1;
+        break;
+    }
+}
+
+
+
+// Change iteration variable pattern -------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_iteration_variable_pattern() {
+    let mut _x = 0;
+    for  _i in &[0, 1, 2] {
+        _x = 1;
+        break;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir, typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_iteration_variable_pattern() {
+    let mut _x = 0;
+    for &_i in &[0, 1, 2] {
+        _x = 1;
+        break;
+    }
+}
+
+
+
+// Change iterable -------------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_iterable() {
+    let mut _x = 0;
+    for _ in &[0, 1, 2] {
+        _x = 1;
+        break;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, promoted_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, promoted_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_iterable() {
+    let mut _x = 0;
+    for _ in &[0, 1, 3] {
+        _x = 1;
+        break;
+    }
+}
+
+
+
+// Add break -------------------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn add_break() {
+    let mut _x = 0;
+    for _ in 0..1 {
+        _x = 1;
+        // ---
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir, typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_break() {
+    let mut _x = 0;
+    for _ in 0..1 {
+        _x = 1;
+        break;
+    }
+}
+
+
+
+// Add loop label --------------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn add_loop_label() {
+    let mut _x = 0;
+            for _ in 0..1 {
+        _x = 1;
+        break;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_loop_label() {
+    let mut _x = 0;
+    'label: for _ in 0..1 {
+        _x = 1;
+        break;
+    }
+}
+
+
+
+// Add loop label to break -----------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn add_loop_label_to_break() {
+    let mut _x = 0;
+    'label: for _ in 0..1 {
+        _x = 1;
+        break       ;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_loop_label_to_break() {
+    let mut _x = 0;
+    'label: for _ in 0..1 {
+        _x = 1;
+        break 'label;
+    }
+}
+
+
+
+// Change break label ----------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_break_label() {
+    let mut _x = 0;
+    'outer: for _ in 0..1 {
+        'inner: for _ in 0..1 {
+            _x = 1;
+            break 'inner;
+        }
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_break_label() {
+    let mut _x = 0;
+    'outer: for _ in 0..1 {
+        'inner: for _ in 0..1 {
+            _x = 1;
+            break 'outer;
+        }
+    }
+}
+
+
+
+// Add loop label to continue --------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn add_loop_label_to_continue() {
+    let mut _x = 0;
+    'label: for _ in 0..1 {
+        _x = 1;
+        continue       ;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_loop_label_to_continue() {
+    let mut _x = 0;
+    'label: for _ in 0..1 {
+        _x = 1;
+        continue 'label;
+    }
+}
+
+
+
+// Change continue label ----------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_continue_label() {
+    let mut _x = 0;
+    'outer: for _ in 0..1 {
+        'inner: for _ in 0..1 {
+            _x = 1;
+            continue 'inner;
+        }
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_continue_label() {
+    let mut _x = 0;
+    'outer: for _ in 0..1 {
+        'inner: for _ in 0..1 {
+            _x = 1;
+            continue 'outer;
+        }
+    }
+}
+
+
+
+// Change continue to break ----------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_continue_to_break() {
+    let mut _x = 0;
+    for _ in 0..1 {
+        _x = 1;
+        continue;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_continue_to_break() {
+    let mut _x = 0;
+    for _ in 0..1 {
+        _x = 1;
+        break   ;
+    }
+}
diff --git a/tests/incremental/hashes/function_interfaces.rs b/tests/incremental/hashes/function_interfaces.rs
new file mode 100644
index 00000000000..182ca7d926c
--- /dev/null
+++ b/tests/incremental/hashes/function_interfaces.rs
@@ -0,0 +1,411 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for function interfaces.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(linkage)]
+#![feature(rustc_attrs)]
+#![crate_type = "rlib"]
+
+// Add Parameter ---------------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub fn add_parameter() {}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(
+    cfg = "cfail2",
+    except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+)]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(
+    cfg = "cfail5",
+    except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+)]
+#[rustc_clean(cfg = "cfail6")]
+pub fn add_parameter(p: i32) {}
+
+// Add Return Type -------------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub fn add_return_type()       {}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg = "cfail6")]
+pub fn add_return_type() -> () {}
+
+// Change Parameter Type -------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub fn type_of_parameter(p: i32) {}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(
+    cfg = "cfail2",
+    except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+)]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(
+    cfg = "cfail5",
+    except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+)]
+#[rustc_clean(cfg = "cfail6")]
+pub fn type_of_parameter(p: i64) {}
+
+// Change Parameter Type Reference ---------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub fn type_of_parameter_ref(p: &i32) {}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(
+    cfg = "cfail2",
+    except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+)]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(
+    cfg = "cfail5",
+    except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+)]
+#[rustc_clean(cfg = "cfail6")]
+pub fn type_of_parameter_ref(p: &mut i32) {}
+
+// Change Parameter Order ------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub fn order_of_parameters(p1: i32, p2: i64) {}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(
+    cfg = "cfail2",
+    except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+)]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(
+    cfg = "cfail5",
+    except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+)]
+#[rustc_clean(cfg = "cfail6")]
+pub fn order_of_parameters(p2: i64, p1: i32) {}
+
+// Unsafe ----------------------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub fn make_unsafe() {}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(
+    cfg = "cfail2",
+    except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+)]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(
+    cfg = "cfail5",
+    except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+)]
+#[rustc_clean(cfg = "cfail6")]
+pub unsafe fn make_unsafe() {}
+
+// Extern ----------------------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub            fn make_extern() {}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, typeck, fn_sig")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, typeck, fn_sig")]
+#[rustc_clean(cfg = "cfail6")]
+pub extern "C" fn make_extern() {}
+
+// Type Parameter --------------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub fn type_parameter   () {}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(
+    cfg = "cfail2",
+    except = "hir_owner, hir_owner_nodes, generics_of, type_of, predicates_of"
+)]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(
+    cfg = "cfail5",
+    except = "hir_owner, hir_owner_nodes, generics_of, type_of, predicates_of"
+)]
+#[rustc_clean(cfg = "cfail6")]
+pub fn type_parameter<T>() {}
+
+// Lifetime Parameter ----------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub fn lifetime_parameter    () {}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, generics_of,fn_sig")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, generics_of,fn_sig")]
+#[rustc_clean(cfg = "cfail6")]
+pub fn lifetime_parameter<'a>() {}
+
+// Trait Bound -----------------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub fn trait_bound<T    >() {}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, predicates_of")]
+#[rustc_clean(cfg = "cfail3")]
+pub fn trait_bound<T: Eq>() {}
+
+// Builtin Bound ---------------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub fn builtin_bound<T      >() {}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, predicates_of")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, predicates_of")]
+#[rustc_clean(cfg = "cfail6")]
+pub fn builtin_bound<T: Send>() {}
+
+// Lifetime Bound --------------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub fn lifetime_bound<'a, T>() {}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(
+    cfg = "cfail2",
+    except = "hir_owner, hir_owner_nodes, generics_of, type_of, predicates_of,fn_sig"
+)]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(
+    cfg = "cfail5",
+    except = "hir_owner, hir_owner_nodes, generics_of, type_of, predicates_of,fn_sig,optimized_mir"
+)]
+#[rustc_clean(cfg = "cfail6")]
+pub fn lifetime_bound<'a, T: 'a>() {}
+
+// Second Trait Bound ----------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub fn second_trait_bound<T: Eq        >() {}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, predicates_of")]
+#[rustc_clean(cfg = "cfail3")]
+pub fn second_trait_bound<T: Eq + Clone>() {}
+
+// Second Builtin Bound --------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub fn second_builtin_bound<T: Send        >() {}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, predicates_of")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, predicates_of")]
+#[rustc_clean(cfg = "cfail6")]
+pub fn second_builtin_bound<T: Send + Sized>() {}
+
+// Second Lifetime Bound -------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub fn second_lifetime_bound<'a, 'b, T: 'a     >() {}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(
+    cfg = "cfail2",
+    except = "hir_owner, hir_owner_nodes, generics_of, type_of, predicates_of,fn_sig"
+)]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(
+    cfg = "cfail5",
+    except = "hir_owner, hir_owner_nodes, generics_of, type_of, predicates_of,fn_sig"
+)]
+#[rustc_clean(cfg = "cfail6")]
+pub fn second_lifetime_bound<'a, 'b, T: 'a + 'b>() {}
+
+// Inline ----------------------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub fn inline() {}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
+#[inline]
+pub fn inline() {}
+
+// Inline Never ----------------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+#[inline(always)]
+pub fn inline_never() {}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
+#[inline(never)]
+pub fn inline_never() {}
+
+// No Mangle -------------------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub fn no_mangle() {}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
+#[no_mangle]
+pub fn no_mangle() {}
+
+// Linkage ---------------------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub fn linkage() {}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5")]
+#[rustc_clean(cfg = "cfail6")]
+#[linkage = "weak_odr"]
+pub fn linkage() {}
+
+// Return Impl Trait -----------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub fn return_impl_trait() -> i32        {
+    0
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, typeck, fn_sig, optimized_mir")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, typeck, fn_sig, optimized_mir")]
+#[rustc_clean(cfg = "cfail6")]
+pub fn return_impl_trait() -> impl Clone {
+    0
+}
+
+// Change Return Impl Trait ----------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub fn change_return_impl_trait() -> impl Clone {
+    0u32
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg = "cfail2")]
+#[rustc_clean(cfg = "cfail3")]
+#[rustc_clean(cfg = "cfail5", except = "typeck")]
+#[rustc_clean(cfg = "cfail6")]
+pub fn change_return_impl_trait() -> impl  Copy {
+    0u32
+}
+
+// Change Return Type Indirectly -----------------------------------------------
+
+pub struct ReferencedType1;
+pub struct ReferencedType2;
+
+pub mod change_return_type_indirectly {
+    #[cfg(any(cfail1,cfail4))]
+    use super::ReferencedType1 as ReturnType;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::ReferencedType2 as ReturnType;
+
+    #[rustc_clean(
+        cfg = "cfail2",
+        except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+    )]
+    #[rustc_clean(cfg = "cfail3")]
+    #[rustc_clean(
+        cfg = "cfail5",
+        except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+    )]
+    #[rustc_clean(cfg = "cfail6")]
+    pub fn indirect_return_type() -> ReturnType {
+        ReturnType {}
+    }
+}
+
+// Change Parameter Type Indirectly --------------------------------------------
+
+pub mod change_parameter_type_indirectly {
+    #[cfg(any(cfail1,cfail4))]
+    use super::ReferencedType1 as ParameterType;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::ReferencedType2 as ParameterType;
+
+    #[rustc_clean(
+        cfg = "cfail2",
+        except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+    )]
+    #[rustc_clean(cfg = "cfail3")]
+    #[rustc_clean(
+        cfg = "cfail5",
+        except = "hir_owner, hir_owner_nodes, optimized_mir, typeck, fn_sig"
+    )]
+    #[rustc_clean(cfg = "cfail6")]
+    pub fn indirect_parameter_type(p: ParameterType) {}
+}
+
+// Change Trait Bound Indirectly -----------------------------------------------
+
+pub trait ReferencedTrait1 {}
+pub trait ReferencedTrait2 {}
+
+pub mod change_trait_bound_indirectly {
+    #[cfg(any(cfail1,cfail4))]
+    use super::ReferencedTrait1 as Trait;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::ReferencedTrait2 as Trait;
+
+    #[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, predicates_of")]
+    #[rustc_clean(cfg = "cfail3")]
+    #[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, predicates_of")]
+    #[rustc_clean(cfg = "cfail6")]
+    pub fn indirect_trait_bound<T: Trait>(p: T) {}
+}
+
+// Change Trait Bound Indirectly In Where Clause -------------------------------
+
+pub mod change_trait_bound_indirectly_in_where_clause {
+    #[cfg(any(cfail1,cfail4))]
+    use super::ReferencedTrait1 as Trait;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::ReferencedTrait2 as Trait;
+
+    #[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, predicates_of")]
+    #[rustc_clean(cfg = "cfail3")]
+    #[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, predicates_of")]
+    #[rustc_clean(cfg = "cfail6")]
+    pub fn indirect_trait_bound_where<T>(p: T)
+    where
+        T: Trait,
+    {
+    }
+}
diff --git a/tests/incremental/hashes/if_expressions.rs b/tests/incremental/hashes/if_expressions.rs
new file mode 100644
index 00000000000..937fd3ac879
--- /dev/null
+++ b/tests/incremental/hashes/if_expressions.rs
@@ -0,0 +1,225 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for if expressions.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+// Change condition (if)
+#[cfg(any(cfail1,cfail4))]
+pub fn change_condition(x: bool) -> u32 {
+    if  x {
+        return 1
+    }
+
+    return 0
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_condition(x: bool) -> u32 {
+    if !x {
+        return 1
+    }
+
+    return 0
+}
+
+// Change then branch (if)
+#[cfg(any(cfail1,cfail4))]
+pub fn change_then_branch(x: bool) -> u32 {
+    if x {
+        return 1
+    }
+
+    return 0
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_then_branch(x: bool) -> u32 {
+    if x {
+        return 2
+    }
+
+    return 0
+}
+
+
+
+// Change else branch (if)
+#[cfg(any(cfail1,cfail4))]
+pub fn change_else_branch(x: bool) -> u32 {
+    if x {
+        1
+    } else {
+        2
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_else_branch(x: bool) -> u32 {
+    if x {
+        1
+    } else {
+        3
+    }
+}
+
+
+
+// Add else branch (if)
+#[cfg(any(cfail1,cfail4))]
+pub fn add_else_branch(x: bool) -> u32 {
+    let mut ret = 1;
+
+    if x {
+        ret = 2;
+    /*----*/
+    }
+
+    ret
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_else_branch(x: bool) -> u32 {
+    let mut ret = 1;
+
+    if x {
+        ret = 2;
+    } else {
+    }
+
+    ret
+}
+
+
+
+// Change condition (if let)
+#[cfg(any(cfail1,cfail4))]
+pub fn change_condition_if_let(x: Option<u32>) -> u32 {
+    if let Some(_x) = x {
+        return 1
+    }
+
+    0
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_condition_if_let(x: Option<u32>) -> u32 {
+    if let Some(_ ) = x {
+        return 1
+    }
+
+    0
+}
+
+
+
+// Change then branch (if let)
+#[cfg(any(cfail1,cfail4))]
+pub fn change_then_branch_if_let(x: Option<u32>) -> u32 {
+    if let Some(x) = x {
+        return x //-
+    }
+
+    0
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_then_branch_if_let(x: Option<u32>) -> u32 {
+    if let Some(x) = x {
+        return x + 1
+    }
+
+    0
+}
+
+
+
+// Change else branch (if let)
+#[cfg(any(cfail1,cfail4))]
+pub fn change_else_branch_if_let(x: Option<u32>) -> u32 {
+    if let Some(x) = x {
+        x
+    } else {
+        1
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_else_branch_if_let(x: Option<u32>) -> u32 {
+    if let Some(x) = x {
+        x
+    } else {
+        2
+    }
+}
+
+
+
+// Add else branch (if let)
+#[cfg(any(cfail1,cfail4))]
+pub fn add_else_branch_if_let(x: Option<u32>) -> u32 {
+    let mut ret = 1;
+
+    if let Some(x) = x {
+        ret = x;
+    /*----*/
+    }
+
+    ret
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_else_branch_if_let(x: Option<u32>) -> u32 {
+    let mut ret = 1;
+
+    if let Some(x) = x {
+        ret = x;
+    } else {
+    }
+
+    ret
+}
diff --git a/tests/incremental/hashes/indexing_expressions.rs b/tests/incremental/hashes/indexing_expressions.rs
new file mode 100644
index 00000000000..b1ac6f6fa6c
--- /dev/null
+++ b/tests/incremental/hashes/indexing_expressions.rs
@@ -0,0 +1,134 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for indexing expression.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+// Change simple index
+#[cfg(any(cfail1,cfail4))]
+fn change_simple_index(slice: &[u32]) -> u32 {
+    slice[3]
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+fn change_simple_index(slice: &[u32]) -> u32 {
+    slice[4]
+}
+
+
+
+// Change lower bound
+#[cfg(any(cfail1,cfail4))]
+fn change_lower_bound(slice: &[u32]) -> &[u32] {
+    &slice[3..5]
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+fn change_lower_bound(slice: &[u32]) -> &[u32] {
+    &slice[2..5]
+}
+
+
+
+// Change upper bound
+#[cfg(any(cfail1,cfail4))]
+fn change_upper_bound(slice: &[u32]) -> &[u32] {
+    &slice[3..5]
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+fn change_upper_bound(slice: &[u32]) -> &[u32] {
+    &slice[3..7]
+}
+
+
+
+// Add lower bound
+#[cfg(any(cfail1,cfail4))]
+fn add_lower_bound(slice: &[u32]) -> &[u32] {
+    &slice[ ..4]
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,typeck", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,typeck", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+fn add_lower_bound(slice: &[u32]) -> &[u32] {
+    &slice[3..4]
+}
+
+
+
+// Add upper bound
+#[cfg(any(cfail1,cfail4))]
+fn add_upper_bound(slice: &[u32]) -> &[u32] {
+    &slice[3.. ]
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,typeck", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,typeck", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+fn add_upper_bound(slice: &[u32]) -> &[u32] {
+    &slice[3..7]
+}
+
+
+
+// Change mutability
+#[cfg(any(cfail1,cfail4))]
+fn change_mutability(slice: &mut [u32]) -> u32 {
+    (&mut slice[3..5])[0]
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,typeck", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,typeck", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+fn change_mutability(slice: &mut [u32]) -> u32 {
+    (&    slice[3..5])[0]
+}
+
+
+
+// Exclusive to inclusive range
+#[cfg(any(cfail1,cfail4))]
+fn exclusive_to_inclusive_range(slice: &[u32]) -> &[u32] {
+    &slice[3.. 7]
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,typeck", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,typeck", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+fn exclusive_to_inclusive_range(slice: &[u32]) -> &[u32] {
+    &slice[3..=7]
+}
diff --git a/tests/incremental/hashes/inherent_impls.rs b/tests/incremental/hashes/inherent_impls.rs
new file mode 100644
index 00000000000..285f857c9cb
--- /dev/null
+++ b/tests/incremental/hashes/inherent_impls.rs
@@ -0,0 +1,787 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for let expressions.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+pub struct Foo;
+
+// Change Method Name -----------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    pub fn method_name() { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,associated_item_def_ids")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,associated_item_def_ids")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn method_name2() { }
+}
+
+// Change Method Body -----------------------------------------------------------
+//
+// This should affect the method itself, but not the impl.
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    //--------------------------------------------------------------------------------------
+    //--------------------------
+    //--------------------------------------------------------------------------------------
+    //--------------------------
+    pub fn method_body() {
+        // -----------------------
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,promoted_mir,typeck")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,promoted_mir,typeck")]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn method_body() {
+        println!("Hello, world!");
+    }
+}
+
+
+// Change Method Body (inlined) ------------------------------------------------
+//
+// This should affect the method itself, but not the impl.
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    //------------
+    //---------------
+    //------------------------------------------------------------
+    //
+    //--------------------------
+    //------------
+    //---------------
+    //------------------------------------------------------------
+    //
+    //--------------------------
+    #[inline]
+    pub fn method_body_inlined() {
+        // -----------------------
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    #[rustc_clean(
+        cfg="cfail2",
+        except="hir_owner_nodes,optimized_mir,promoted_mir,typeck"
+    )]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        cfg="cfail5",
+        except="hir_owner_nodes,optimized_mir,promoted_mir,typeck"
+    )]
+    #[rustc_clean(cfg="cfail6")]
+    #[inline]
+    pub fn method_body_inlined() {
+        println!("Hello, world!");
+    }
+}
+
+
+// Change Method Privacy -------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    //--------------------------
+    //--------------------------
+    //--------------------------------------------------------------
+    //--------------------------
+    pub fn method_privacy() { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    #[rustc_clean(cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+    #[rustc_clean(cfg="cfail6")]
+    fn     method_privacy() { }
+}
+
+// Change Method Selfness -----------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    //------------
+    //---------------
+    //---------------------------------------------------------------------------------------------
+    //
+    //--------------------------
+    //------------
+    //---------------
+    //---------------------------------------------------------------------------------------------
+    //
+    //--------------------------
+    pub fn method_selfness() { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    #[rustc_clean(
+        cfg="cfail2",
+        except="hir_owner,hir_owner_nodes,fn_sig,generics_of,typeck,associated_item,optimized_mir",
+    )]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        cfg="cfail5",
+        except="hir_owner,hir_owner_nodes,fn_sig,generics_of,typeck,associated_item,optimized_mir",
+    )]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn method_selfness(&self) { }
+}
+
+// Change Method Selfmutness ---------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    //------------------------------------------------------------------------------------------
+    //--------------------------
+    //------------------------------------------------------------------------------------------
+    //--------------------------
+    pub fn method_selfmutness(&    self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir")]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn method_selfmutness(&mut self) { }
+}
+
+
+
+// Add Method To Impl ----------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    pub fn add_method_to_impl1(&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,associated_item_def_ids")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,associated_item_def_ids")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    #[rustc_clean(cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn add_method_to_impl1(&self) { }
+
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn add_method_to_impl2(&self) { }
+}
+
+
+
+// Add Method Parameter --------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    //------------------------------------------------------------------------------------------
+    //--------------------------
+    //------------------------------------------------------------------------------------------
+    //--------------------------
+    pub fn add_method_parameter(&self        ) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir")]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn add_method_parameter(&self, _: i32) { }
+}
+
+
+
+// Change Method Parameter Name ------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    //------------------------------------------------------------------
+    //--------------------------
+    //------------------------------------------------------------------
+    //--------------------------
+    pub fn change_method_parameter_name(&self, a: i64) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn change_method_parameter_name(&self, b: i64) { }
+}
+
+
+
+// Change Method Return Type ---------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    //------------------------------------------------------------------------------------------
+    //--------------------------
+    //------------------------------------------------------------------------------------------
+    //--------------------------
+    pub fn change_method_return_type(&self) -> u16 { 0 }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,fn_sig,optimized_mir,typeck")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,fn_sig,optimized_mir,typeck")]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn change_method_return_type(&self) -> u32 { 0 }
+}
+
+
+
+// Make Method #[inline] -------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    //--------------------------
+    //--------------------------
+    //--------------------------
+    //--------------------------
+    //-------
+    pub fn make_method_inline(&self) -> u8 { 0 }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    #[rustc_clean(cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    #[inline]
+    pub fn make_method_inline(&self) -> u8 { 0 }
+}
+
+
+
+//  Change order of parameters -------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    //------------------------------------------------------------------
+    //--------------------------
+    //------------------------------------------------------------------
+    //--------------------------
+    pub fn change_method_parameter_order(&self, a: i64, b: i64) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    #[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn change_method_parameter_order(&self, b: i64, a: i64) { }
+}
+
+
+
+// Make method unsafe ----------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    //------------------------------------------------------------------------------------------
+    //--------------------------
+    //------------------------------------------------------------------------------------------
+    //--------------------------
+    pub        fn make_method_unsafe(&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir")]
+    #[rustc_clean(cfg="cfail6")]
+    pub unsafe fn make_method_unsafe(&self) { }
+}
+
+
+
+// Make method extern ----------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    //----------------------------------------------------------------------------
+    //--------------------------
+    //----------------------------------------------------------------------------
+    //--------------------------
+    pub            fn make_method_extern(&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,fn_sig,typeck")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,fn_sig,typeck")]
+    #[rustc_clean(cfg="cfail6")]
+    pub extern "C" fn make_method_extern(&self) { }
+}
+
+
+
+// Change method calling convention --------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    //----------------------------------------------------------------------------
+    //--------------------------
+    //----------------------------------------------------------------------------
+    //--------------------------
+    pub extern "C"      fn change_method_calling_convention(&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,fn_sig,typeck")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,fn_sig,typeck")]
+    #[rustc_clean(cfg="cfail6")]
+    pub extern "system" fn change_method_calling_convention(&self) { }
+}
+
+
+
+// Add Lifetime Parameter to Method --------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    // -----------------------------------------------------
+    // ---------------------------------------------------------
+    // ----------------------------------------------------------
+    // -------------------------------------------------------
+    // -------------------------------------------------------
+    // --------------------------------------------------------
+    // ----------------------------------------------------------
+    // -----------------------------------------------------------
+    // ----------------------------------------------------------
+    // --------------------------------------------------------------------
+    // -------------------------
+    // --------------------------------------------------------------------------------
+    // -------------------------
+    pub fn add_lifetime_parameter_to_method    (&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    // Warning: Note that `typeck` are coming up clean here.
+    // The addition or removal of lifetime parameters that don't
+    // appear in the arguments or fn body in any way does not, in
+    // fact, affect the `typeck` in any semantic way (at least
+    // as of this writing). **However,** altering the order of
+    // lowering **can** cause it appear to affect the `typeck`:
+    // if we lower generics before the body, then the `HirId` for
+    // things in the body will be affected. So if you start to see
+    // `typeck` appear dirty, that might be the cause. -nmatsakis
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,fn_sig")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,fn_sig,generics_of")]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn add_lifetime_parameter_to_method<'a>(&self) { }
+}
+
+
+
+// Add Type Parameter To Method ------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    // -----------------------------------------------------
+    // ---------------------------------------------------------------
+    // -------------------------------------------------------------
+    // -----------------------------------------------------
+    // -------------------------------------------------------------
+    // ---------------------------------------------------
+    // ------------------------------------------------------------
+    // ------------------------------------------------------
+    // -------------------------------------------------
+    // -----------
+    // --------------
+    // ----------------------------------------------------------------------
+    //
+    // -------------------------
+    // -----------
+    // --------------
+    // ----------------------------------------------------------------------
+    //
+    // -------------------------
+    pub fn add_type_parameter_to_method   (&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    // Warning: Note that `typeck` are coming up clean here.
+    // The addition or removal of type parameters that don't appear in
+    // the arguments or fn body in any way does not, in fact, affect
+    // the `typeck` in any semantic way (at least as of this
+    // writing). **However,** altering the order of lowering **can**
+    // cause it appear to affect the `typeck`: if we lower
+    // generics before the body, then the `HirId` for things in the
+    // body will be affected. So if you start to see `typeck`
+    // appear dirty, that might be the cause. -nmatsakis
+    #[rustc_clean(
+        cfg="cfail2",
+        except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of",
+    )]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        cfg="cfail5",
+        except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of",
+    )]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn add_type_parameter_to_method<T>(&self) { }
+}
+
+
+
+// Add Lifetime Bound to Lifetime Parameter of Method --------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    //------------
+    //---------------
+    //-----------------------------------------------------------------------------
+    //
+    //--------------------------
+    //------------
+    //---------------
+    //-----------------------------------------------------------------------------
+    //
+    //--------------------------
+    pub fn add_lifetime_bound_to_lifetime_param_of_method<'a, 'b    >(&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    #[rustc_clean(
+        cfg="cfail2",
+        except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of,fn_sig"
+    )]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        cfg="cfail5",
+        except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of,fn_sig"
+    )]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn add_lifetime_bound_to_lifetime_param_of_method<'a, 'b: 'a>(&self) { }
+}
+
+
+
+// Add Lifetime Bound to Type Parameter of Method ------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    // -----------------------------------------------------
+    // ----------------------------------------------------------
+    // -------------------------------------------------------------
+    // -------------------------------------------------
+    // -------------------------------------------------------------
+    // ---------------------------------------------------
+    // ------------------------------------------------------------
+    // ------------------------------------------------------
+    // -------------------------------------------------
+    // -----------
+    // --------------
+    // ----------------------------------------------------------------------------
+    //
+    // -------------------------
+    // -----------
+    // --------------
+    // ----------------------------------------------------------------------------
+    //
+    // -------------------------
+    pub fn add_lifetime_bound_to_type_param_of_method<'a, T    >(&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    // Warning: Note that `typeck` are coming up clean here.
+    // The addition or removal of bounds that don't appear in the
+    // arguments or fn body in any way does not, in fact, affect the
+    // `typeck` in any semantic way (at least as of this
+    // writing). **However,** altering the order of lowering **can**
+    // cause it appear to affect the `typeck`: if we lower
+    // generics before the body, then the `HirId` for things in the
+    // body will be affected. So if you start to see `typeck`
+    // appear dirty, that might be the cause. -nmatsakis
+    #[rustc_clean(
+        cfg="cfail2",
+        except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of,fn_sig"
+    )]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        cfg="cfail5",
+        except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of,fn_sig"
+    )]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn add_lifetime_bound_to_type_param_of_method<'a, T: 'a>(&self) { }
+}
+
+
+
+// Add Trait Bound to Type Parameter of Method ------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    // -----------------------------------------------------
+    // ----------------------------------------------------------
+    // -------------------------------------------------------------
+    // -------------------------------------------------
+    // -------------------------------------------------------------
+    // ---------------------------------------------------
+    // ------------------------------------------------------------
+    // ------------------------------------------------------
+    // -------------------------------------------------
+    // ---------------------------------------------------------------------------
+    // -------------------------
+    // ---------------------------------------------------------------------------
+    // -------------------------
+    pub fn add_trait_bound_to_type_param_of_method<T       >(&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    // Warning: Note that `typeck` are coming up clean here.
+    // The addition or removal of bounds that don't appear in the
+    // arguments or fn body in any way does not, in fact, affect the
+    // `typeck` in any semantic way (at least as of this
+    // writing). **However,** altering the order of lowering **can**
+    // cause it appear to affect the `typeck`: if we lower
+    // generics before the body, then the `HirId` for things in the
+    // body will be affected. So if you start to see `typeck`
+    // appear dirty, that might be the cause. -nmatsakis
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,predicates_of")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,predicates_of")]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn add_trait_bound_to_type_param_of_method<T: Clone>(&self) { }
+}
+
+
+
+// Add #[no_mangle] to Method --------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Foo {
+    //--------------------------
+    //--------------------------
+    //--------------------------
+    //--------------------------
+    //----------
+    pub fn add_no_mangle_to_method(&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl Foo {
+    #[rustc_clean(cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    #[no_mangle]
+    pub fn add_no_mangle_to_method(&self) { }
+}
+
+
+
+struct Bar<T>(T);
+
+// Add Type Parameter To Impl --------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Bar<u32> {
+    pub fn add_type_parameter_to_impl(&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,generics_of")]
+#[rustc_clean(cfg="cfail6")]
+impl<T> Bar<T> {
+    #[rustc_clean(
+        cfg="cfail2",
+        except="generics_of,fn_sig,typeck,type_of,optimized_mir"
+    )]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        cfg="cfail5",
+        except="generics_of,fn_sig,typeck,type_of,optimized_mir"
+    )]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn add_type_parameter_to_impl(&self) { }
+}
+
+
+
+// Change Self Type of Impl ----------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl Bar<u32> {
+    pub fn change_impl_self_type(&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+impl Bar<u64> {
+    #[rustc_clean(cfg="cfail2", except="fn_sig,optimized_mir,typeck")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="fn_sig,optimized_mir,typeck")]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn change_impl_self_type(&self) { }
+}
+
+
+
+// Add Lifetime Bound to Impl --------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl<T> Bar<T> {
+    pub fn add_lifetime_bound_to_impl_parameter(&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+impl<T: 'static> Bar<T> {
+    #[rustc_clean(cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn add_lifetime_bound_to_impl_parameter(&self) { }
+}
+
+
+
+// Add Trait Bound to Impl Parameter -------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+impl<T> Bar<T> {
+    pub fn add_trait_bound_to_impl_parameter(&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+impl<T: Clone> Bar<T> {
+    #[rustc_clean(cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn add_trait_bound_to_impl_parameter(&self) { }
+}
+
+
+// Force instantiation of some fns so we can check their hash.
+pub fn instantiation_root() {
+    Foo::method_privacy();
+
+    #[cfg(any(cfail1,cfail4))]
+    {
+        Bar(0u32).change_impl_self_type();
+    }
+
+    #[cfg(not(any(cfail1,cfail4)))]
+    {
+        Bar(0u64).change_impl_self_type();
+    }
+}
diff --git a/tests/incremental/hashes/inline_asm.rs b/tests/incremental/hashes/inline_asm.rs
new file mode 100644
index 00000000000..3118aa13564
--- /dev/null
+++ b/tests/incremental/hashes/inline_asm.rs
@@ -0,0 +1,219 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for inline asm.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// needs-asm-support
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+use std::arch::asm;
+
+// Change template
+#[cfg(any(cfail1,cfail4))]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+pub fn change_template(_a: i32) -> i32 {
+    let c: i32;
+    unsafe {
+        asm!("mov {0}, 1",
+             out(reg) c
+             );
+    }
+    c
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+pub fn change_template(_a: i32) -> i32 {
+    let c: i32;
+    unsafe {
+        asm!("mov {0}, 2",
+             out(reg) c
+             );
+    }
+    c
+}
+
+
+
+// Change output
+#[cfg(any(cfail1,cfail4))]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+pub fn change_output(a: i32) -> i32 {
+    let mut _out1: i32 = 0;
+    let mut _out2: i32 = 0;
+    unsafe {
+        asm!("mov {0}, {1}",
+             out(reg) _out1,
+             in(reg) a
+             );
+    }
+    _out1
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+pub fn change_output(a: i32) -> i32 {
+    let mut _out1: i32 = 0;
+    let mut _out2: i32 = 0;
+    unsafe {
+        asm!("mov {0}, {1}",
+             out(reg) _out2,
+             in(reg) a
+             );
+    }
+    _out1
+}
+
+
+
+// Change input
+#[cfg(any(cfail1,cfail4))]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+pub fn change_input(_a: i32, _b: i32) -> i32 {
+    let _out;
+    unsafe {
+        asm!("mov {0}, {1}",
+             out(reg) _out,
+             in(reg) _a
+             );
+    }
+    _out
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+pub fn change_input(_a: i32, _b: i32) -> i32 {
+    let _out;
+    unsafe {
+        asm!("mov {0}, {1}",
+             out(reg) _out,
+             in(reg) _b
+             );
+    }
+    _out
+}
+
+
+
+// Change input constraint
+#[cfg(any(cfail1,cfail4))]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+pub fn change_input_constraint(_a: i32, _b: i32) -> i32 {
+    let _out;
+    unsafe {
+        asm!("mov {0}, {1}",
+             out(reg) _out,
+             in(reg) _a,
+             in("eax") _b);
+    }
+    _out
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+pub fn change_input_constraint(_a: i32, _b: i32) -> i32 {
+    let _out;
+    unsafe {
+        asm!("mov {0}, {1}",
+             out(reg) _out,
+             in(reg) _a,
+             in("ecx") _b);
+    }
+    _out
+}
+
+
+// Change clobber
+#[cfg(any(cfail1,cfail4))]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+pub fn change_clobber(_a: i32) -> i32 {
+    let _out;
+    unsafe {
+        asm!("mov {0}, {1}",
+             out(reg) _out,
+             in(reg) _a,
+             lateout("ecx") _
+             );
+    }
+    _out
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+pub fn change_clobber(_a: i32) -> i32 {
+    let _out;
+    unsafe {
+        asm!("mov {0}, {1}",
+             out(reg) _out,
+             in(reg) _a,
+             lateout("edx") _
+             );
+    }
+    _out
+}
+
+
+
+// Change options
+#[cfg(any(cfail1,cfail4))]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+pub fn change_options(_a: i32) -> i32 {
+    let _out;
+    unsafe {
+        asm!("mov {0}, {1}",
+             out(reg) _out,
+             in(reg) _a,
+             options(readonly),
+             );
+    }
+    _out
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+pub fn change_options(_a: i32) -> i32 {
+    let _out;
+    unsafe {
+        asm!("mov {0}, {1}",
+             out(reg) _out,
+             in(reg) _a,
+             options(nomem   ),
+             );
+    }
+    _out
+}
diff --git a/tests/incremental/hashes/let_expressions.rs b/tests/incremental/hashes/let_expressions.rs
new file mode 100644
index 00000000000..180bf6fec87
--- /dev/null
+++ b/tests/incremental/hashes/let_expressions.rs
@@ -0,0 +1,219 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for let expressions.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+// Change Name -----------------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_name() {
+    let _x = 2u64;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_name() {
+    let _y = 2u64;
+}
+
+
+
+// Add Type --------------------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn add_type() {
+    let _x      = 2u32;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_type() {
+    let _x: u32 = 2u32;
+}
+
+
+
+// Change Type -----------------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_type() {
+    let _x: u64 = 2;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_type() {
+    let _x: u8  = 2;
+}
+
+
+
+// Change Mutability of Reference Type -----------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_mutability_of_reference_type() {
+    let _x: &    u64;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_mutability_of_reference_type() {
+    let _x: &mut u64;
+}
+
+
+
+// Change Mutability of Slot ---------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_mutability_of_slot() {
+    let mut _x: u64 = 0;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_mutability_of_slot() {
+    let     _x: u64 = 0;
+}
+
+
+
+// Change Simple Binding to Pattern --------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_simple_binding_to_pattern() {
+    let  _x      = (0u8, 'x');
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_simple_binding_to_pattern() {
+    let (_a, _b) = (0u8, 'x');
+}
+
+
+
+// Change Name in Pattern ------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_name_in_pattern() {
+    let (_a, _b) = (1u8, 'y');
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_name_in_pattern() {
+    let (_a, _c) = (1u8, 'y');
+}
+
+
+
+// Add `ref` in Pattern --------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn add_ref_in_pattern() {
+    let (    _a, _b) = (1u8, 'y');
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_ref_in_pattern() {
+    let (ref _a, _b) = (1u8, 'y');
+}
+
+
+
+// Add `&` in Pattern ----------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn add_amp_in_pattern() {
+    let ( _a, _b) = (&1u8, 'y');
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_amp_in_pattern() {
+    let (&_a, _b) = (&1u8, 'y');
+}
+
+
+
+// Change Mutability of Binding in Pattern -------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_mutability_of_binding_in_pattern() {
+    let (    _a, _b) = (99u8, 'q');
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_mutability_of_binding_in_pattern() {
+    let (mut _a, _b) = (99u8, 'q');
+}
+
+
+
+// Add Initializer -------------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn add_initializer() {
+    let _x: i16       ;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_initializer() {
+    let _x: i16 = 3i16;
+}
+
+
+
+// Change Initializer ----------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_initializer() {
+    let _x = 4u16;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_initializer() {
+    let _x = 5u16;
+}
diff --git a/tests/incremental/hashes/loop_expressions.rs b/tests/incremental/hashes/loop_expressions.rs
new file mode 100644
index 00000000000..87b86479d07
--- /dev/null
+++ b/tests/incremental/hashes/loop_expressions.rs
@@ -0,0 +1,224 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for `loop` loops.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+
+// Change loop body
+#[cfg(any(cfail1,cfail4))]
+pub fn change_loop_body() {
+    let mut _x = 0;
+    loop {
+        _x = 1;
+        break;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_loop_body() {
+    let mut _x = 0;
+    loop {
+        _x = 2;
+        break;
+    }
+}
+
+
+
+// Add break
+#[cfg(any(cfail1,cfail4))]
+pub fn add_break() {
+    let mut _x = 0;
+    loop {
+        _x = 1;
+        //----
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir, typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_break() {
+    let mut _x = 0;
+    loop {
+        _x = 1;
+        break;
+    }
+}
+
+
+
+// Add loop label
+#[cfg(any(cfail1,cfail4))]
+pub fn add_loop_label() {
+    let mut _x = 0;
+    /*---*/ loop {
+        _x = 1;
+        break;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_loop_label() {
+    let mut _x = 0;
+    'label: loop {
+        _x = 1;
+        break;
+    }
+}
+
+
+
+// Add loop label to break
+#[cfg(any(cfail1,cfail4))]
+pub fn add_loop_label_to_break() {
+    let mut _x = 0;
+    'label: loop {
+        _x = 1;
+        break       ;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_loop_label_to_break() {
+    let mut _x = 0;
+    'label: loop {
+        _x = 1;
+        break 'label;
+    }
+}
+
+
+
+// Change break label
+#[cfg(any(cfail1,cfail4))]
+pub fn change_break_label() {
+    let mut _x = 0;
+    'outer: loop {
+        'inner: loop {
+            _x = 1;
+            break 'inner;
+        }
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir, typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_break_label() {
+    let mut _x = 0;
+    'outer: loop {
+        'inner: loop {
+            _x = 1;
+            break 'outer;
+        }
+    }
+}
+
+
+
+// Add loop label to continue
+#[cfg(any(cfail1,cfail4))]
+pub fn add_loop_label_to_continue() {
+    let mut _x = 0;
+    'label: loop {
+        _x = 1;
+        continue       ;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_loop_label_to_continue() {
+    let mut _x = 0;
+    'label: loop {
+        _x = 1;
+        continue 'label;
+    }
+}
+
+
+
+// Change continue label
+#[cfg(any(cfail1,cfail4))]
+pub fn change_continue_label() {
+    let mut _x = 0;
+    'outer: loop {
+        'inner: loop {
+            _x = 1;
+            continue 'inner;
+        }
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_continue_label() {
+    let mut _x = 0;
+    'outer: loop {
+        'inner: loop {
+            _x = 1;
+            continue 'outer;
+        }
+    }
+}
+
+
+
+// Change continue to break
+#[cfg(any(cfail1,cfail4))]
+pub fn change_continue_to_break() {
+    let mut _x = 0;
+    loop {
+        _x = 1;
+        continue;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, typeck, optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, typeck, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_continue_to_break() {
+    let mut _x = 0;
+    loop {
+        _x = 1;
+        break   ;
+    }
+}
diff --git a/tests/incremental/hashes/match_expressions.rs b/tests/incremental/hashes/match_expressions.rs
new file mode 100644
index 00000000000..4429df6833e
--- /dev/null
+++ b/tests/incremental/hashes/match_expressions.rs
@@ -0,0 +1,334 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for match expressions.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+// Add Arm ---------------------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn add_arm(x: u32) -> u32 {
+    match x {
+        0 => 0,
+        1 => 1,
+        /*---*/
+        _ => 100,
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_arm(x: u32) -> u32 {
+    match x {
+        0 => 0,
+        1 => 1,
+        2 => 2,
+        _ => 100,
+    }
+}
+
+
+
+// Change Order Of Arms --------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_order_of_arms(x: u32) -> u32 {
+    match x {
+        0 => 0,
+        1 => 1,
+        _ => 100,
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_order_of_arms(x: u32) -> u32 {
+    match x {
+        1 => 1,
+        0 => 0,
+        _ => 100,
+    }
+}
+
+
+
+// Add Guard Clause ------------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn add_guard_clause(x: u32, y: bool) -> u32 {
+    match x {
+        0 => 0,
+        1      => 1,
+        _ => 100,
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_guard_clause(x: u32, y: bool) -> u32 {
+    match x {
+        0 => 0,
+        1 if y => 1,
+        _ => 100,
+    }
+}
+
+
+
+// Change Guard Clause ------------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_guard_clause(x: u32, y: bool) -> u32 {
+    match x {
+        0 => 0,
+        1 if  y => 1,
+        _ => 100,
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_guard_clause(x: u32, y: bool) -> u32 {
+    match x {
+        0 => 0,
+        1 if !y => 1,
+        _ => 100,
+    }
+}
+
+
+
+// Add @-Binding ---------------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn add_at_binding(x: u32) -> u32 {
+    match x {
+        0 => 0,
+        1 => 1,
+            _ => x,
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_at_binding(x: u32) -> u32 {
+    match x {
+        0 => 0,
+        1 => 1,
+        x @ _ => x,
+    }
+}
+
+
+
+// Change Name of @-Binding ----------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_name_of_at_binding(x: u32) -> u32 {
+    match x {
+        0 => 0,
+        1 => 1,
+        x @ _ => 7,
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_name_of_at_binding(x: u32) -> u32 {
+    match x {
+        0 => 0,
+        1 => 1,
+        y @ _ => 7,
+    }
+}
+
+
+
+// Change Simple Binding To Pattern --------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_simple_name_to_pattern(x: u32) -> u32 {
+    match (x, x & 1) {
+        (0, 0) => 0,
+         a     => 1,
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_simple_name_to_pattern(x: u32) -> u32 {
+    match (x, x & 1) {
+        (0, 0) => 0,
+        (x, y) => 1,
+    }
+}
+
+
+
+// Change Name In Pattern ------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_name_in_pattern(x: u32) -> u32 {
+    match (x, x & 1) {
+        (a, 0) => 0,
+        (a, 1) => a,
+        _ => 100,
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_name_in_pattern(x: u32) -> u32 {
+    match (x, x & 1) {
+        (b, 0) => 0,
+        (a, 1) => a,
+        _ => 100,
+    }
+}
+
+
+
+// Change Mutability Of Binding In Pattern -------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 {
+    match (x, x & 1) {
+        (    a, 0) => 0,
+        _ => 1,
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 {
+    match (x, x & 1) {
+        (mut a, 0) => 0,
+        _ => 1,
+    }
+}
+
+
+
+// Add `ref` To Binding In Pattern -------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 {
+    match (x, x & 1) {
+        (    a, 0) => 0,
+        _ => 1,
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 {
+    match (x, x & 1) {
+        (ref a, 0) => 0,
+        _ => 1,
+    }
+}
+
+
+
+// Add `&` To Binding In Pattern -------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 {
+    match (&x, x & 1) {
+        ( a, 0) => 0,
+        _ => 1,
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 {
+    match (&x, x & 1) {
+        (&a, 0) => 0,
+        _ => 1,
+    }
+}
+
+
+
+// Change RHS Of Arm -----------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn change_rhs_of_arm(x: u32) -> u32 {
+    match x {
+        0 => 0,
+        1 => 1,
+        _ => 2,
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_rhs_of_arm(x: u32) -> u32 {
+    match x {
+        0 => 0,
+        1 => 3,
+        _ => 2,
+    }
+}
+
+
+
+// Add Alternative To Arm ------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn add_alternative_to_arm(x: u32) -> u32 {
+    match x {
+        0     => 0,
+        1 => 1,
+        _ => 2,
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_alternative_to_arm(x: u32) -> u32 {
+    match x {
+        0 | 7 => 0,
+        1 => 3,
+        _ => 2,
+    }
+}
diff --git a/tests/incremental/hashes/panic_exprs.rs b/tests/incremental/hashes/panic_exprs.rs
new file mode 100644
index 00000000000..37d10d922c1
--- /dev/null
+++ b/tests/incremental/hashes/panic_exprs.rs
@@ -0,0 +1,151 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for exprs that can panic at runtime (e.g., because of bounds checking). For
+// these expressions an error message containing their source location is
+// generated, so their hash must always depend on their location in the source
+// code, not just when debuginfo is enabled.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3
+// compile-flags: -Z query-dep-graph -C debug-assertions -O
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+
+// Indexing expression
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+pub fn indexing(slice: &[u8]) -> u8 {
+    #[cfg(cfail1)]
+    {
+        slice[100]
+    }
+    #[cfg(not(cfail1))]
+    {
+        slice[100]
+    }
+}
+
+
+// Arithmetic overflow plus
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+pub fn arithmetic_overflow_plus(val: i32) -> i32 {
+    #[cfg(cfail1)]
+    {
+        val + 1
+    }
+    #[cfg(not(cfail1))]
+    {
+        val + 1
+    }
+}
+
+
+// Arithmetic overflow minus
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+pub fn arithmetic_overflow_minus(val: i32) -> i32 {
+    #[cfg(cfail1)]
+    {
+        val - 1
+    }
+    #[cfg(not(cfail1))]
+    {
+        val - 1
+    }
+}
+
+
+// Arithmetic overflow mult
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+pub fn arithmetic_overflow_mult(val: i32) -> i32 {
+    #[cfg(cfail1)]
+    {
+        val * 2
+    }
+    #[cfg(not(cfail1))]
+    {
+        val * 2
+    }
+}
+
+
+// Arithmetic overflow negation
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+pub fn arithmetic_overflow_negation(val: i32) -> i32 {
+    #[cfg(cfail1)]
+    {
+        -val
+    }
+    #[cfg(not(cfail1))]
+    {
+        -val
+    }
+}
+
+
+// Division by zero
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+pub fn division_by_zero(val: i32) -> i32 {
+    #[cfg(cfail1)]
+    {
+        2 / val
+    }
+    #[cfg(not(cfail1))]
+    {
+        2 / val
+    }
+}
+
+// Division by zero
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+pub fn mod_by_zero(val: i32) -> i32 {
+    #[cfg(cfail1)]
+    {
+        2 % val
+    }
+    #[cfg(not(cfail1))]
+    {
+        2 % val
+    }
+}
+
+
+// shift left
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+pub fn shift_left(val: i32, shift: usize) -> i32 {
+    #[cfg(cfail1)]
+    {
+        val << shift
+    }
+    #[cfg(not(cfail1))]
+    {
+        val << shift
+    }
+}
+
+
+// shift right
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+pub fn shift_right(val: i32, shift: usize) -> i32 {
+    #[cfg(cfail1)]
+    {
+        val >> shift
+    }
+    #[cfg(not(cfail1))]
+    {
+        val >> shift
+    }
+}
diff --git a/tests/incremental/hashes/statics.rs b/tests/incremental/hashes/statics.rs
new file mode 100644
index 00000000000..bb83f8300d0
--- /dev/null
+++ b/tests/incremental/hashes/statics.rs
@@ -0,0 +1,183 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for statics.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![feature(linkage)]
+#![feature(thread_local)]
+#![crate_type="rlib"]
+
+
+// Change static visibility
+#[cfg(any(cfail1,cfail4))]
+static     STATIC_VISIBILITY: u8 = 0;
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub static STATIC_VISIBILITY: u8 = 0;
+
+
+// Change static mutability
+#[cfg(any(cfail1,cfail4))]
+static STATIC_MUTABILITY: u8 = 0;
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+static mut STATIC_MUTABILITY: u8 = 0;
+
+
+// Add linkage attribute
+#[cfg(any(cfail1,cfail4))]
+static STATIC_LINKAGE: u8 = 0;
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+#[linkage="weak_odr"]
+static STATIC_LINKAGE: u8 = 0;
+
+
+// Add no_mangle attribute
+#[cfg(any(cfail1,cfail4))]
+static STATIC_NO_MANGLE: u8 = 0;
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+#[no_mangle]
+static STATIC_NO_MANGLE: u8 = 0;
+
+
+// Add thread_local attribute
+#[cfg(any(cfail1,cfail4))]
+static STATIC_THREAD_LOCAL: u8 = 0;
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+#[thread_local]
+static STATIC_THREAD_LOCAL: u8 = 0;
+
+
+// Change type from i16 to u64
+#[cfg(any(cfail1,cfail4))]
+static STATIC_CHANGE_TYPE_1: i16 = 0;
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
+static STATIC_CHANGE_TYPE_1: u64 = 0;
+
+
+// Change type from Option<i8> to Option<u16>
+#[cfg(any(cfail1,cfail4))]
+static STATIC_CHANGE_TYPE_2: Option<i8> = None;
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
+static STATIC_CHANGE_TYPE_2: Option<u16> = None;
+
+
+// Change value between simple literals
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+static STATIC_CHANGE_VALUE_1: i16 = {
+    #[cfg(any(cfail1,cfail4))]
+    { 1 }
+
+    #[cfg(not(any(cfail1,cfail4)))]
+    { 2 }
+};
+
+
+// Change value between expressions
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+static STATIC_CHANGE_VALUE_2: i16 = {
+    #[cfg(any(cfail1,cfail4))]
+    { 1 + 1 }
+
+    #[cfg(not(any(cfail1,cfail4)))]
+    { 1 + 2 }
+};
+
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+static STATIC_CHANGE_VALUE_3: i16 = {
+    #[cfg(any(cfail1,cfail4))]
+    { 2 + 3 }
+
+    #[cfg(not(any(cfail1,cfail4)))]
+    { 2 * 3 }
+};
+
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+static STATIC_CHANGE_VALUE_4: i16 = {
+    #[cfg(any(cfail1,cfail4))]
+    { 1 + 2 * 3 }
+
+    #[cfg(not(any(cfail1,cfail4)))]
+    { 1 + 2 * 4 }
+};
+
+
+// Change type indirectly
+struct ReferencedType1;
+struct ReferencedType2;
+
+mod static_change_type_indirectly {
+    #[cfg(any(cfail1,cfail4))]
+    use super::ReferencedType1 as Type;
+
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::ReferencedType2 as Type;
+
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+    #[rustc_clean(cfg="cfail6")]
+    static STATIC_CHANGE_TYPE_INDIRECTLY_1: Type = Type;
+
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,type_of")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+    #[rustc_clean(cfg="cfail6")]
+    static STATIC_CHANGE_TYPE_INDIRECTLY_2: Option<Type> = None;
+}
diff --git a/tests/incremental/hashes/struct_constructors.rs b/tests/incremental/hashes/struct_constructors.rs
new file mode 100644
index 00000000000..e50e5674c66
--- /dev/null
+++ b/tests/incremental/hashes/struct_constructors.rs
@@ -0,0 +1,267 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for struct constructor expressions.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+
+pub struct RegularStruct {
+    x: i32,
+    y: i64,
+    z: i16,
+}
+
+// Change field value (regular struct)
+#[cfg(any(cfail1,cfail4))]
+pub fn change_field_value_regular_struct() -> RegularStruct {
+    RegularStruct {
+        x: 0,
+        y: 1,
+        z: 2,
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_field_value_regular_struct() -> RegularStruct {
+    RegularStruct {
+        x: 0,
+        y: 2,
+        z: 2,
+    }
+}
+
+
+
+// Change field order (regular struct)
+#[cfg(any(cfail1,cfail4))]
+pub fn change_field_order_regular_struct() -> RegularStruct {
+    RegularStruct {
+        x: 3,
+        y: 4,
+        z: 5,
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_field_order_regular_struct() -> RegularStruct {
+    RegularStruct {
+        y: 4,
+        x: 3,
+        z: 5,
+    }
+}
+
+
+
+// Add field (regular struct)
+#[cfg(any(cfail1,cfail4))]
+pub fn add_field_regular_struct() -> RegularStruct {
+    let struct1 = RegularStruct {
+        x: 3,
+        y: 4,
+        z: 5,
+    };
+
+    RegularStruct {
+        x: 7,
+        // --
+        .. struct1
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_field_regular_struct() -> RegularStruct {
+    let struct1 = RegularStruct {
+        x: 3,
+        y: 4,
+        z: 5,
+    };
+
+    RegularStruct {
+        x: 7,
+        y: 8,
+        .. struct1
+    }
+}
+
+
+
+// Change field label (regular struct)
+#[cfg(any(cfail1,cfail4))]
+pub fn change_field_label_regular_struct() -> RegularStruct {
+    let struct1 = RegularStruct {
+        x: 3,
+        y: 4,
+        z: 5,
+    };
+
+    RegularStruct {
+        x: 7,
+        y: 9,
+        .. struct1
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_field_label_regular_struct() -> RegularStruct {
+    let struct1 = RegularStruct {
+        x: 3,
+        y: 4,
+        z: 5,
+    };
+
+    RegularStruct {
+        x: 7,
+        z: 9,
+        .. struct1
+    }
+}
+
+
+
+pub struct RegularStruct2 {
+    x: i8,
+    y: i8,
+    z: i8,
+}
+
+// Change constructor path (regular struct)
+#[cfg(any(cfail1,cfail4))]
+pub fn change_constructor_path_regular_struct() {
+    let _ = RegularStruct  {
+        x: 0,
+        y: 1,
+        z: 2,
+    };
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_constructor_path_regular_struct() {
+    let _ = RegularStruct2 {
+        x: 0,
+        y: 1,
+        z: 2,
+    };
+}
+
+
+
+// Change constructor path indirectly (regular struct)
+pub mod change_constructor_path_indirectly_regular_struct {
+    #[cfg(any(cfail1,cfail4))]
+    use super::RegularStruct as Struct;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::RegularStruct2 as Struct;
+
+    #[rustc_clean(
+        cfg="cfail2",
+        except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,typeck"
+    )]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        cfg="cfail5",
+        except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,typeck"
+    )]
+    #[rustc_clean(cfg="cfail6")]
+    pub fn function() -> Struct {
+        Struct {
+            x: 0,
+            y: 1,
+            z: 2,
+        }
+    }
+}
+
+
+
+pub struct TupleStruct(i32, i64, i16);
+
+// Change field value (tuple struct)
+#[cfg(any(cfail1,cfail4))]
+pub fn change_field_value_tuple_struct() -> TupleStruct {
+    TupleStruct(0, 1, 2)
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_field_value_tuple_struct() -> TupleStruct {
+    TupleStruct(0, 1, 3)
+}
+
+
+
+pub struct TupleStruct2(u16, u16, u16);
+
+// Change constructor path (tuple struct)
+#[cfg(any(cfail1,cfail4))]
+pub fn change_constructor_path_tuple_struct() {
+    let _ = TupleStruct (0, 1, 2);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_constructor_path_tuple_struct() {
+    let _ = TupleStruct2(0, 1, 2);
+}
+
+
+
+// Change constructor path indirectly (tuple struct)
+pub mod change_constructor_path_indirectly_tuple_struct {
+    #[cfg(any(cfail1,cfail4))]
+    use super::TupleStruct as Struct;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::TupleStruct2 as Struct;
+
+    #[rustc_clean(
+        cfg="cfail5",
+        except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,typeck"
+    )]
+    #[rustc_clean(cfg="cfail6")]
+    #[rustc_clean(
+        cfg="cfail2",
+        except="fn_sig,hir_owner,hir_owner_nodes,optimized_mir,typeck"
+    )]
+    #[rustc_clean(cfg="cfail3")]
+    pub fn function() -> Struct {
+        Struct(0, 1, 2)
+    }
+}
diff --git a/tests/incremental/hashes/struct_defs.rs b/tests/incremental/hashes/struct_defs.rs
new file mode 100644
index 00000000000..4a2706b4f01
--- /dev/null
+++ b/tests/incremental/hashes/struct_defs.rs
@@ -0,0 +1,332 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for struct definitions.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// We also test the ICH for struct definitions exported in metadata. Same as
+// above, we want to make sure that the change between rev1 and rev2 also
+// results in a change of the ICH for the struct's metadata, and that it stays
+// the same between rev2 and rev3.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+// Layout ----------------------------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub struct LayoutPacked;
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="type_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="type_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+#[repr(packed)]
+pub struct LayoutPacked;
+
+#[cfg(any(cfail1,cfail4))]
+struct LayoutC;
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="type_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="type_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+#[repr(C)]
+struct LayoutC;
+
+
+// Tuple Struct Change Field Type ----------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+struct TupleStructFieldType(i32);
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+// Note that changing the type of a field does not change the type of the struct or enum, but
+// adding/removing fields or changing a fields name or visibility does.
+struct TupleStructFieldType(
+    u32
+);
+
+
+// Tuple Struct Add Field ------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+struct TupleStructAddField(i32);
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+struct TupleStructAddField(
+    i32,
+    u32
+);
+
+
+// Tuple Struct Field Visibility -----------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+struct TupleStructFieldVisibility(    char);
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
+struct TupleStructFieldVisibility(pub char);
+
+
+// Record Struct Field Type ----------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+struct RecordStructFieldType { x: f32 }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+// Note that changing the type of a field does not change the type of the struct or enum, but
+// adding/removing fields or changing a fields name or visibility does.
+struct RecordStructFieldType {
+    x: u64
+}
+
+
+// Record Struct Field Name ----------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+struct RecordStructFieldName { x: f32 }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+struct RecordStructFieldName { y: f32 }
+
+
+// Record Struct Add Field -----------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+struct RecordStructAddField { x: f32 }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+struct RecordStructAddField {
+    x: f32,
+    y: () }
+
+
+// Record Struct Field Visibility ----------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+struct RecordStructFieldVisibility {     x: f32 }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="type_of")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")]
+#[rustc_clean(cfg="cfail6")]
+struct RecordStructFieldVisibility { pub x: f32 }
+
+
+// Add Lifetime Parameter ------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+struct AddLifetimeParameter<'a>(&'a f32, &'a f64);
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of,generics_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of,generics_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+struct AddLifetimeParameter<'a, 'b>(&'a f32, &'b f64);
+
+
+// Add Lifetime Parameter Bound ------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+struct AddLifetimeParameterBound<'a, 'b>(&'a f32, &'b f64);
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+struct AddLifetimeParameterBound<'a, 'b: 'a>(
+    &'a f32,
+    &'b f64
+);
+
+#[cfg(any(cfail1,cfail4))]
+struct AddLifetimeParameterBoundWhereClause<'a, 'b>(&'a f32, &'b f64);
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+struct AddLifetimeParameterBoundWhereClause<'a, 'b>(
+    &'a f32,
+    &'b f64)
+    where 'b: 'a;
+
+
+// Add Type Parameter ----------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+struct AddTypeParameter<T1>(T1, T1);
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of,generics_of,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of,generics_of,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+struct AddTypeParameter<T1, T2>(
+     // The field contains the parent's Generics, so it's dirty even though its
+     // type hasn't changed.
+    T1,
+    T2
+);
+
+
+// Add Type Parameter Bound ----------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+struct AddTypeParameterBound<T>(T);
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+struct AddTypeParameterBound<T: Send>(
+    T
+);
+
+
+#[cfg(any(cfail1,cfail4))]
+struct AddTypeParameterBoundWhereClause<T>(T);
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+struct AddTypeParameterBoundWhereClause<T>(
+    T
+) where T: Sync;
+
+
+// Empty struct ----------------------------------------------------------------
+// Since we cannot change anything in this case, we just make sure that the
+// fingerprint is stable (i.e., that there are no random influences like memory
+// addresses taken into account by the hashing algorithm).
+// Note: there is no #[cfg(...)], so this is ALWAYS compiled
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub struct EmptyStruct;
+
+
+// Visibility ------------------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+struct     Visibility;
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub struct Visibility;
+
+struct ReferencedType1;
+struct ReferencedType2;
+
+// Tuple Struct Change Field Type Indirectly -----------------------------------
+mod tuple_struct_change_field_type_indirectly {
+    #[cfg(any(cfail1,cfail4))]
+    use super::ReferencedType1 as FieldType;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::ReferencedType2 as FieldType;
+
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    struct TupleStruct(
+        FieldType
+    );
+}
+
+
+// Record Struct Change Field Type Indirectly -----------------------------------
+mod record_struct_change_field_type_indirectly {
+    #[cfg(any(cfail1,cfail4))]
+    use super::ReferencedType1 as FieldType;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::ReferencedType2 as FieldType;
+
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    struct RecordStruct {
+        _x: FieldType
+    }
+}
+
+
+
+
+trait ReferencedTrait1 {}
+trait ReferencedTrait2 {}
+
+// Change Trait Bound Indirectly -----------------------------------------------
+mod change_trait_bound_indirectly {
+    #[cfg(any(cfail1,cfail4))]
+    use super::ReferencedTrait1 as Trait;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::ReferencedTrait2 as Trait;
+
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    struct Struct<T: Trait>(T);
+}
+
+// Change Trait Bound Indirectly In Where Clause -------------------------------
+mod change_trait_bound_indirectly_in_where_clause {
+    #[cfg(any(cfail1,cfail4))]
+    use super::ReferencedTrait1 as Trait;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::ReferencedTrait2 as Trait;
+
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    struct Struct<T>(T) where T : Trait;
+}
diff --git a/tests/incremental/hashes/trait_defs.rs b/tests/incremental/hashes/trait_defs.rs
new file mode 100644
index 00000000000..b583bee2f24
--- /dev/null
+++ b/tests/incremental/hashes/trait_defs.rs
@@ -0,0 +1,1409 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for trait definitions.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// We also test the ICH for trait definitions exported in metadata. Same as
+// above, we want to make sure that the change between rev1 and rev2 also
+// results in a change of the ICH for the trait's metadata, and that it stays
+// the same between rev2 and rev3.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+#![feature(associated_type_defaults)]
+
+
+// Change trait visibility
+#[cfg(any(cfail1,cfail4))]
+trait TraitVisibility { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub trait TraitVisibility { }
+
+
+
+// Change trait unsafety
+#[cfg(any(cfail1,cfail4))]
+trait TraitUnsafety { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+unsafe trait TraitUnsafety { }
+
+
+
+// Add method
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddMethod {
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item_def_ids", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item_def_ids", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub trait TraitAddMethod {
+    fn method();
+}
+
+
+
+// Change name of method
+#[cfg(any(cfail1,cfail4))]
+trait TraitChangeMethodName {
+    fn method();
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item_def_ids", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item_def_ids", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitChangeMethodName {
+    fn methodChanged();
+}
+
+
+
+// Add return type to method
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddReturnType {
+    //---------------------------------------------------------------------
+    //--------------------------
+    //---------------------------------------------------------------------
+    //--------------------------
+    fn method()       ;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddReturnType {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method() -> u32;
+}
+
+
+
+// Change return type of method
+#[cfg(any(cfail1,cfail4))]
+trait TraitChangeReturnType {
+    // --------------------------------------------------------------------
+    // -------------------------
+    // --------------------------------------------------------------------
+    // -------------------------
+    fn method() -> u32;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitChangeReturnType {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method() -> u64;
+}
+
+
+
+// Add parameter to method
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddParameterToMethod {
+    // --------------------------------------------------------------------
+    // -------------------------
+    // --------------------------------------------------------------------
+    // -------------------------
+    fn method(      );
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddParameterToMethod {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method(a: u32);
+}
+
+
+
+// Change name of method parameter
+#[cfg(any(cfail1,cfail4))]
+trait TraitChangeMethodParameterName {
+    //------------------------------------------------------
+    //--------------------------------------------------------------
+    //--------------------------
+    //--------------------------------------------------------------
+    //--------------------------
+    fn method(a: u32);
+
+    //------------------------------------------------------------------
+    //--------------------------
+    //------------------------------------------------------------------
+    //--------------------------
+    fn with_default(x: i32) {}
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitChangeMethodParameterName {
+    // FIXME(#38501) This should preferably always be clean.
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method(b: u32);
+
+    #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn with_default(y: i32) {}
+}
+
+
+
+// Change type of method parameter (i32 => i64)
+#[cfg(any(cfail1,cfail4))]
+trait TraitChangeMethodParameterType {
+    // --------------------------------------------------------------------
+    // -------------------------
+    // --------------------------------------------------------------------
+    // -------------------------
+    fn method(a: i32);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitChangeMethodParameterType {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method(a: i64);
+}
+
+
+
+// Change type of method parameter (&i32 => &mut i32)
+#[cfg(any(cfail1,cfail4))]
+trait TraitChangeMethodParameterTypeRef {
+    // --------------------------------------------------------------------
+    // -------------------------
+    // --------------------------------------------------------------------
+    // -------------------------
+    fn method(a: &    i32);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitChangeMethodParameterTypeRef {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method(a: &mut i32);
+}
+
+
+
+// Change order of method parameters
+#[cfg(any(cfail1,cfail4))]
+trait TraitChangeMethodParametersOrder {
+    // --------------------------------------------------------------------
+    // -------------------------
+    // --------------------------------------------------------------------
+    // -------------------------
+    fn method(a: i32, b: i64);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitChangeMethodParametersOrder {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method(b: i64, a: i32);
+}
+
+
+
+// Add default implementation to method
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddMethodAutoImplementation {
+    // -------------------------------------------------------------
+    // -------------------------
+    // -------------------------------------------------------------
+    // -------------------------
+    fn method()  ;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddMethodAutoImplementation {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method() {}
+}
+
+
+
+// Change order of methods
+#[cfg(any(cfail1,cfail4))]
+trait TraitChangeOrderOfMethods {
+    fn method0();
+    fn method1();
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item_def_ids", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item_def_ids", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitChangeOrderOfMethods {
+    fn method1();
+    fn method0();
+}
+
+
+
+// Change mode of self parameter
+#[cfg(any(cfail1,cfail4))]
+trait TraitChangeModeSelfRefToMut {
+    // --------------------------------------------------------------------
+    // -------------------------
+    // --------------------------------------------------------------------
+    // -------------------------
+    fn method(&    self);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitChangeModeSelfRefToMut {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method(&mut self);
+}
+
+
+
+#[cfg(any(cfail1,cfail4))]
+trait TraitChangeModeSelfOwnToMut: Sized {
+    // ----------------------------------------------------------------------------------
+    // -------------------------
+    // ----------------------------------------------------------------------------------
+    // -------------------------
+    fn method(    self) {}
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitChangeModeSelfOwnToMut: Sized {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,typeck,optimized_mir", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,typeck,optimized_mir", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method(mut self) {}
+}
+
+
+
+#[cfg(any(cfail1,cfail4))]
+trait TraitChangeModeSelfOwnToRef {
+    // --------------------------------------------------------------------------------
+    // -------------------------
+    // --------------------------------------------------------------------------------
+    // -------------------------
+    fn method( self);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitChangeModeSelfOwnToRef {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig,generics_of", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig,generics_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method(&self);
+}
+
+
+
+// Add unsafe modifier to method
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddUnsafeModifier {
+    // --------------------------------------------------------------------
+    // -------------------------
+    // --------------------------------------------------------------------
+    // -------------------------
+    fn method()       ;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddUnsafeModifier {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    unsafe fn method();
+}
+
+
+
+// Add extern modifier to method
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddExternModifier {
+    // --------------------------------------------------------------------
+    // -------------------------
+    // --------------------------------------------------------------------
+    // -------------------------
+    fn method()           ;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddExternModifier {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    extern "C" fn method();
+}
+
+
+
+// Change extern "C" to extern "stdcall"
+#[cfg(any(cfail1,cfail4))]
+trait TraitChangeExternCToRustIntrinsic {
+    // --------------------------------------------------------------------
+    // -------------------------
+    // --------------------------------------------------------------------
+    // -------------------------
+    extern "C"       fn method();
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitChangeExternCToRustIntrinsic {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    extern "stdcall" fn method();
+}
+
+
+
+// Add type parameter to method
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddTypeParameterToMethod {
+    // --------------------------------------------------------------------------------
+    // ---------------
+    // -------------------------
+    // --------------------------------------------------------------------------------
+    // ---------------
+    // -------------------------
+    fn method   ();
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddTypeParameterToMethod {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of",
+        cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of",
+        cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method<T>();
+}
+
+
+
+// Add lifetime parameter to method
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddLifetimeParameterToMethod {
+    // --------------------------------------------------------------------------------
+    // -------------------------
+    // --------------------------------------------------------------------------------
+    // -------------------------
+    fn method    ();
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddLifetimeParameterToMethod {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig,generics_of", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig,generics_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method<'a>();
+}
+
+
+
+// dummy trait for bound
+trait ReferencedTrait0 { }
+trait ReferencedTrait1 { }
+
+// Add trait bound to method type parameter
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddTraitBoundToMethodTypeParameter {
+    // ---------------------------------------------------------------------------
+    // -------------------------
+    // ---------------------------------------------------------------------------
+    // -------------------------
+    fn method<T                  >();
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddTraitBoundToMethodTypeParameter {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method<T: ReferencedTrait0>();
+}
+
+
+
+// Add builtin bound to method type parameter
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddBuiltinBoundToMethodTypeParameter {
+    // ---------------------------------------------------------------------------
+    // -------------------------
+    // ---------------------------------------------------------------------------
+    // -------------------------
+    fn method<T       >();
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddBuiltinBoundToMethodTypeParameter {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method<T: Sized>();
+}
+
+
+
+// Add lifetime bound to method lifetime parameter
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddLifetimeBoundToMethodLifetimeParameter {
+    // -----------
+    // -----------------------------------------------------------------------------
+    // --------------
+    //
+    // -------------------------
+    // -----------
+    // -----------------------------------------------------------------------------
+    // --------------
+    //
+    // -------------------------
+    fn method<'a, 'b    >(a: &'a u32, b: &'b u32);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddLifetimeBoundToMethodLifetimeParameter {
+    #[rustc_clean(
+        except="hir_owner,hir_owner_nodes,generics_of,predicates_of,fn_sig,type_of",
+        cfg="cfail2",
+    )]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        except="hir_owner,hir_owner_nodes,generics_of,predicates_of,fn_sig,type_of",
+        cfg="cfail5",
+    )]
+    #[rustc_clean(cfg="cfail6")]
+    fn method<'a, 'b: 'a>(a: &'a u32, b: &'b u32);
+}
+
+
+
+// Add second trait bound to method type parameter
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddSecondTraitBoundToMethodTypeParameter {
+    // ---------------------------------------------------------------------------
+    // -------------------------
+    // ---------------------------------------------------------------------------
+    // -------------------------
+    fn method<T: ReferencedTrait0                   >();
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddSecondTraitBoundToMethodTypeParameter {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method<T: ReferencedTrait0 + ReferencedTrait1>();
+}
+
+
+
+// Add second builtin bound to method type parameter
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddSecondBuiltinBoundToMethodTypeParameter {
+    // ---------------------------------------------------------------------------
+    // -------------------------
+    // ---------------------------------------------------------------------------
+    // -------------------------
+    fn method<T: Sized       >();
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddSecondBuiltinBoundToMethodTypeParameter {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method<T: Sized + Sync>();
+}
+
+
+
+// Add second lifetime bound to method lifetime parameter
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddSecondLifetimeBoundToMethodLifetimeParameter {
+    // -----------
+    // -----------------------------------------------------------------------------
+    // --------------
+    //
+    // -------------------------
+    // -----------
+    // -----------------------------------------------------------------------------
+    // --------------
+    //
+    // -------------------------
+    fn method<'a, 'b, 'c: 'a     >(a: &'a u32, b: &'b u32, c: &'c u32);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddSecondLifetimeBoundToMethodLifetimeParameter {
+    #[rustc_clean(
+        except="hir_owner,hir_owner_nodes,generics_of,predicates_of,fn_sig,type_of",
+        cfg="cfail2",
+    )]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        except="hir_owner,hir_owner_nodes,generics_of,predicates_of,fn_sig,type_of",
+        cfg="cfail5",
+    )]
+    #[rustc_clean(cfg="cfail6")]
+    fn method<'a, 'b, 'c: 'a + 'b>(a: &'a u32, b: &'b u32, c: &'c u32);
+}
+
+
+
+// Add associated type
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddAssociatedType {
+    //--------------------------
+    //--------------------------
+    // -------------
+
+    //--------------------------
+    //--------------------------
+    //--------------------------
+    //--------------------------
+    fn method();
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item_def_ids", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item_def_ids", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddAssociatedType {
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail6")]
+    type Associated;
+
+    #[rustc_clean(cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method();
+}
+
+
+
+// Add trait bound to associated type
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddTraitBoundToAssociatedType {
+    // -------------------------------------------------------------
+    // -------------------------
+    // -------------------------------------------------------------
+    // -------------------------
+    type Associated                  ;
+
+    fn method();
+}
+
+
+// Apparently the type bound contributes to the predicates of the trait, but
+// does not change the associated item itself.
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddTraitBoundToAssociatedType {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    type Associated: ReferencedTrait0;
+
+    fn method();
+}
+
+
+
+// Add lifetime bound to associated type
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddLifetimeBoundToAssociatedType<'a> {
+    // -------------------------------------------------------------
+    // -------------------------
+    // -------------------------------------------------------------
+    // -------------------------
+    type Associated    ;
+
+    fn method();
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddLifetimeBoundToAssociatedType<'a> {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    type Associated: 'a;
+
+    fn method();
+}
+
+
+
+// Add default to associated type
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddDefaultToAssociatedType {
+    //--------------------------------------------------------------
+    //--------------------------
+    //--------------------------------------------------------------
+    //--------------------------
+    type Associated                 ;
+
+    fn method();
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddDefaultToAssociatedType {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    type Associated = ReferenceType0;
+
+    fn method();
+}
+
+
+
+// Add associated constant
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddAssociatedConstant {
+    fn method();
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item_def_ids", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item_def_ids", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddAssociatedConstant {
+    const Value: u32;
+
+    fn method();
+}
+
+
+
+// Add initializer to associated constant
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddInitializerToAssociatedConstant {
+    //--------------------------------------------------------------
+    //--------------------------
+    //--------------------------------------------------------------
+    //--------------------------
+    const Value: u32    ;
+
+    //--------------------------
+    //--------------------------
+    //--------------------------
+    //--------------------------
+    fn method();
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddInitializerToAssociatedConstant {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    const Value: u32 = 1;
+
+    #[rustc_clean(cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method();
+}
+
+
+
+// Change type of associated constant
+#[cfg(any(cfail1,cfail4))]
+trait TraitChangeTypeOfAssociatedConstant {
+    // ---------------------------------------------------------------------
+    // -------------------------
+    // ---------------------------------------------------------------------
+    // -------------------------
+    const Value: u32;
+
+    // -------------------------
+    // -------------------------
+    // -------------------------
+    // -------------------------
+    fn method();
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitChangeTypeOfAssociatedConstant {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    const Value: f64;
+
+    #[rustc_clean(cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method();
+}
+
+
+
+// Add super trait
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddSuperTrait { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddSuperTrait : ReferencedTrait0 { }
+
+
+
+// Add builtin bound (Send or Copy)
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddBuiltiBound { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddBuiltiBound : Send { }
+
+
+
+// Add 'static lifetime bound to trait
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddStaticLifetimeBound { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddStaticLifetimeBound : 'static { }
+
+
+
+// Add super trait as second bound
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddTraitAsSecondBound : ReferencedTrait0 { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddTraitAsSecondBound : ReferencedTrait0 + ReferencedTrait1 { }
+
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddTraitAsSecondBoundFromBuiltin : Send { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddTraitAsSecondBoundFromBuiltin : Send + ReferencedTrait0 { }
+
+
+
+// Add builtin bound as second bound
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddBuiltinBoundAsSecondBound : ReferencedTrait0 { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddBuiltinBoundAsSecondBound : ReferencedTrait0 + Send { }
+
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddBuiltinBoundAsSecondBoundFromBuiltin : Send { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddBuiltinBoundAsSecondBoundFromBuiltin: Send + Copy { }
+
+
+
+// Add 'static bounds as second bound
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddStaticBoundAsSecondBound : ReferencedTrait0 { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddStaticBoundAsSecondBound : ReferencedTrait0 + 'static { }
+
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddStaticBoundAsSecondBoundFromBuiltin : Send { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddStaticBoundAsSecondBoundFromBuiltin : Send + 'static { }
+
+
+
+// Add type parameter to trait
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddTypeParameterToTrait { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddTypeParameterToTrait<T> { }
+
+
+
+// Add lifetime parameter to trait
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddLifetimeParameterToTrait { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddLifetimeParameterToTrait<'a> { }
+
+
+
+// Add trait bound to type parameter of trait
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddTraitBoundToTypeParameterOfTrait<T> { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddTraitBoundToTypeParameterOfTrait<T: ReferencedTrait0> { }
+
+
+
+// Add lifetime bound to type parameter of trait
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddLifetimeBoundToTypeParameterOfTrait<'a, T> { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddLifetimeBoundToTypeParameterOfTrait<'a, T: 'a> { }
+
+
+
+// Add lifetime bound to lifetime parameter of trait
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddLifetimeBoundToLifetimeParameterOfTrait<'a, 'b> { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddLifetimeBoundToLifetimeParameterOfTrait<'a: 'b, 'b> { }
+
+
+
+// Add builtin bound to type parameter of trait
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddBuiltinBoundToTypeParameterOfTrait<T> { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddBuiltinBoundToTypeParameterOfTrait<T: Send> { }
+
+
+
+// Add second type parameter to trait
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddSecondTypeParameterToTrait<T> { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddSecondTypeParameterToTrait<T, S> { }
+
+
+
+// Add second lifetime parameter to trait
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddSecondLifetimeParameterToTrait<'a> { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddSecondLifetimeParameterToTrait<'a, 'b> { }
+
+
+
+// Add second trait bound to type parameter of trait
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddSecondTraitBoundToTypeParameterOfTrait<T: ReferencedTrait0> { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddSecondTraitBoundToTypeParameterOfTrait<T: ReferencedTrait0 + ReferencedTrait1> { }
+
+
+
+// Add second lifetime bound to type parameter of trait
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddSecondLifetimeBoundToTypeParameterOfTrait<'a, 'b, T: 'a> { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddSecondLifetimeBoundToTypeParameterOfTrait<'a, 'b, T: 'a + 'b> { }
+
+
+
+// Add second lifetime bound to lifetime parameter of trait
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddSecondLifetimeBoundToLifetimeParameterOfTrait<'a: 'b, 'b, 'c> { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddSecondLifetimeBoundToLifetimeParameterOfTrait<'a: 'b + 'c, 'b, 'c> { }
+
+
+
+// Add second builtin bound to type parameter of trait
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddSecondBuiltinBoundToTypeParameterOfTrait<T: Send> { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddSecondBuiltinBoundToTypeParameterOfTrait<T: Send + Sync> { }
+
+
+
+struct ReferenceType0 {}
+struct ReferenceType1 {}
+
+
+
+// Add trait bound to type parameter of trait in where clause
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddTraitBoundToTypeParameterOfTraitWhere<T> { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddTraitBoundToTypeParameterOfTraitWhere<T> where T: ReferencedTrait0 { }
+
+
+
+// Add lifetime bound to type parameter of trait in where clause
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddLifetimeBoundToTypeParameterOfTraitWhere<'a, T> { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddLifetimeBoundToTypeParameterOfTraitWhere<'a, T> where T: 'a { }
+
+
+
+// Add lifetime bound to lifetime parameter of trait in where clause
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddLifetimeBoundToLifetimeParameterOfTraitWhere<'a, 'b> { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddLifetimeBoundToLifetimeParameterOfTraitWhere<'a, 'b> where 'a: 'b { }
+
+
+
+// Add builtin bound to type parameter of trait in where clause
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddBuiltinBoundToTypeParameterOfTraitWhere<T> { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddBuiltinBoundToTypeParameterOfTraitWhere<T> where T: Send { }
+
+
+
+// Add second trait bound to type parameter of trait in where clause
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddSecondTraitBoundToTypeParameterOfTraitWhere<T> where T: ReferencedTrait0 { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddSecondTraitBoundToTypeParameterOfTraitWhere<T>
+    where T: ReferencedTrait0 + ReferencedTrait1 { }
+
+
+
+// Add second lifetime bound to type parameter of trait in where clause
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddSecondLifetimeBoundToTypeParameterOfTraitWhere<'a, 'b, T> where T: 'a { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddSecondLifetimeBoundToTypeParameterOfTraitWhere<'a, 'b, T> where T: 'a + 'b { }
+
+
+
+// Add second lifetime bound to lifetime parameter of trait in where clause
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddSecondLifetimeBoundToLifetimeParameterOfTraitWhere<'a, 'b, 'c> where 'a: 'b { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddSecondLifetimeBoundToLifetimeParameterOfTraitWhere<'a, 'b, 'c> where 'a: 'b + 'c { }
+
+
+
+// Add second builtin bound to type parameter of trait in where clause
+#[cfg(any(cfail1,cfail4))]
+trait TraitAddSecondBuiltinBoundToTypeParameterOfTraitWhere<T> where T: Send { }
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+trait TraitAddSecondBuiltinBoundToTypeParameterOfTraitWhere<T> where T: Send + Sync { }
+
+
+// Change return type of method indirectly by modifying a use statement
+mod change_return_type_of_method_indirectly_use {
+    #[cfg(any(cfail1,cfail4))]
+    use super::ReferenceType0 as ReturnType;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::ReferenceType1 as ReturnType;
+
+    #[rustc_clean(cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    trait TraitChangeReturnType {
+        #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail2")]
+        #[rustc_clean(cfg="cfail3")]
+        #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail5")]
+        #[rustc_clean(cfg="cfail6")]
+        fn method() -> ReturnType;
+    }
+}
+
+
+
+// Change type of method parameter indirectly by modifying a use statement
+mod change_method_parameter_type_indirectly_by_use {
+    #[cfg(any(cfail1,cfail4))]
+    use super::ReferenceType0 as ArgType;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::ReferenceType1 as ArgType;
+
+    #[rustc_clean(cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    trait TraitChangeArgType {
+        #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail2")]
+        #[rustc_clean(cfg="cfail3")]
+        #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig", cfg="cfail5")]
+        #[rustc_clean(cfg="cfail6")]
+        fn method(a: ArgType);
+    }
+}
+
+
+
+// Change trait bound of method type parameter indirectly by modifying a use statement
+mod change_method_parameter_type_bound_indirectly_by_use {
+    #[cfg(any(cfail1,cfail4))]
+    use super::ReferencedTrait0 as Bound;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::ReferencedTrait1 as Bound;
+
+    #[rustc_clean(cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    trait TraitChangeBoundOfMethodTypeParameter {
+        #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+        #[rustc_clean(cfg="cfail3")]
+        #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+        #[rustc_clean(cfg="cfail6")]
+        fn method<T: Bound>(a: T);
+    }
+}
+
+
+
+// Change trait bound of method type parameter in where clause indirectly
+// by modifying a use statement
+mod change_method_parameter_type_bound_indirectly_by_use_where {
+    #[cfg(any(cfail1,cfail4))]
+    use super::ReferencedTrait0 as Bound;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::ReferencedTrait1 as Bound;
+
+    #[rustc_clean(cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    trait TraitChangeBoundOfMethodTypeParameterWhere {
+        #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+        #[rustc_clean(cfg="cfail3")]
+        #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+        #[rustc_clean(cfg="cfail6")]
+        fn method<T>(a: T) where T: Bound;
+    }
+}
+
+
+
+// Change trait bound of trait type parameter indirectly by modifying a use statement
+mod change_method_type_parameter_bound_indirectly {
+    #[cfg(any(cfail1,cfail4))]
+    use super::ReferencedTrait0 as Bound;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::ReferencedTrait1 as Bound;
+
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    trait TraitChangeTraitBound<T: Bound> {
+        fn method(a: T);
+    }
+}
+
+
+
+// Change trait bound of trait type parameter in where clause indirectly
+// by modifying a use statement
+mod change_method_type_parameter_bound_indirectly_where {
+    #[cfg(any(cfail1,cfail4))]
+    use super::ReferencedTrait0 as Bound;
+    #[cfg(not(any(cfail1,cfail4)))]
+    use super::ReferencedTrait1 as Bound;
+
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    trait TraitChangeTraitBoundWhere<T> where T: Bound {
+        fn method(a: T);
+    }
+}
diff --git a/tests/incremental/hashes/trait_impls.rs b/tests/incremental/hashes/trait_impls.rs
new file mode 100644
index 00000000000..3b2e18d17a9
--- /dev/null
+++ b/tests/incremental/hashes/trait_impls.rs
@@ -0,0 +1,617 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for let expressions.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![feature(specialization)]
+#![crate_type="rlib"]
+
+struct Foo;
+
+// Change Method Name -----------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub trait ChangeMethodNameTrait {
+    fn method_name();
+}
+
+#[cfg(any(cfail1,cfail4))]
+impl ChangeMethodNameTrait for Foo {
+    fn method_name() { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item_def_ids", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item_def_ids", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub trait ChangeMethodNameTrait {
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method_name2();
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item_def_ids", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item_def_ids", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl ChangeMethodNameTrait for Foo {
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method_name2() { }
+}
+
+// Change Method Body -----------------------------------------------------------
+//
+// This should affect the method itself, but not the impl.
+
+pub trait ChangeMethodBodyTrait {
+    fn method_name();
+}
+
+#[cfg(any(cfail1,cfail4))]
+impl ChangeMethodBodyTrait for Foo {
+    // ----------------------------------------------------------
+    // -------------------------
+    // ----------------------------------------------------------
+    // -------------------------
+    fn method_name() {
+        //
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl ChangeMethodBodyTrait for Foo {
+    #[rustc_clean(except="hir_owner_nodes,typeck", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner_nodes,typeck", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method_name() {
+        ()
+    }
+}
+
+// Change Method Body (inlined fn) ---------------------------------------------
+//
+// This should affect the method itself, but not the impl.
+
+pub trait ChangeMethodBodyTraitInlined {
+    fn method_name();
+}
+
+#[cfg(any(cfail1,cfail4))]
+impl ChangeMethodBodyTraitInlined for Foo {
+    // ------------------------------------------------------------------------
+    // -------------------------
+    // ------------------------------------------------------------------------
+    // -------------------------
+    #[inline]
+    fn method_name() {
+        // -----
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl ChangeMethodBodyTraitInlined for Foo {
+    #[rustc_clean(except="hir_owner_nodes,typeck,optimized_mir", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner_nodes,typeck,optimized_mir", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    #[inline]
+    fn method_name() {
+        panic!()
+    }
+}
+
+// Change Method Selfness ------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub trait ChangeMethodSelfnessTrait {
+    fn method_name();
+}
+
+#[cfg(any(cfail1,cfail4))]
+impl ChangeMethodSelfnessTrait for Foo {
+    fn method_name() { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+pub trait ChangeMethodSelfnessTrait {
+    fn method_name(&self);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl ChangeMethodSelfnessTrait for Foo {
+    #[rustc_clean(
+        except="hir_owner,hir_owner_nodes,associated_item,generics_of,fn_sig,typeck,optimized_mir",
+        cfg="cfail2",
+    )]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        except="hir_owner,hir_owner_nodes,associated_item,generics_of,fn_sig,typeck,optimized_mir",
+        cfg="cfail5",
+    )]
+    #[rustc_clean(cfg="cfail6")]
+    fn method_name(&self) {
+        ()
+    }
+}
+
+// Change Method Selfness -----------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub trait RemoveMethodSelfnessTrait {
+    fn method_name(&self);
+}
+
+#[cfg(any(cfail1,cfail4))]
+impl RemoveMethodSelfnessTrait for Foo {
+    fn method_name(&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+pub trait RemoveMethodSelfnessTrait {
+    fn method_name();
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl RemoveMethodSelfnessTrait for Foo {
+    #[rustc_clean(
+        except="hir_owner,hir_owner_nodes,associated_item,generics_of,fn_sig,typeck,optimized_mir",
+        cfg="cfail2",
+    )]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        except="hir_owner,hir_owner_nodes,associated_item,generics_of,fn_sig,typeck,optimized_mir",
+        cfg="cfail5",
+    )]
+    #[rustc_clean(cfg="cfail6")]
+    fn method_name() {}
+}
+
+// Change Method Selfmutness -----------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub trait ChangeMethodSelfmutnessTrait {
+    fn method_name(&self);
+}
+
+#[cfg(any(cfail1,cfail4))]
+impl ChangeMethodSelfmutnessTrait for Foo {
+    // -----------------------------------------------------------------------------------------
+    // -------------------------
+    // -----------------------------------------------------------------------------------------
+    // -------------------------
+    fn method_name(&    self) {}
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+pub trait ChangeMethodSelfmutnessTrait {
+    fn method_name(&mut self);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl ChangeMethodSelfmutnessTrait for Foo {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method_name(&mut self) {}
+}
+
+// Change item kind -----------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub trait ChangeItemKindTrait {
+    fn name();
+}
+
+#[cfg(any(cfail1,cfail4))]
+impl ChangeItemKindTrait for Foo {
+    fn name() { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+pub trait ChangeItemKindTrait {
+    type name;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item_def_ids", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item_def_ids", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl ChangeItemKindTrait for Foo {
+    type name = ();
+}
+
+// Remove item -----------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub trait RemoveItemTrait {
+    type TypeName;
+    fn method_name();
+}
+
+#[cfg(any(cfail1,cfail4))]
+impl RemoveItemTrait for Foo {
+    type TypeName = ();
+    fn method_name() { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+pub trait RemoveItemTrait {
+    type TypeName;
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item_def_ids", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item_def_ids", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl RemoveItemTrait for Foo {
+    type TypeName = ();
+}
+
+// Add item -----------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub trait AddItemTrait {
+    type TypeName;
+}
+
+#[cfg(any(cfail1,cfail4))]
+impl AddItemTrait for Foo {
+    type TypeName = ();
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+pub trait AddItemTrait {
+    type TypeName;
+    fn method_name();
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item_def_ids", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item_def_ids", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl AddItemTrait for Foo {
+    type TypeName = ();
+    fn method_name() { }
+}
+
+// Change has-value -----------------------------------------------------------
+
+#[cfg(any(cfail1,cfail4))]
+pub trait ChangeHasValueTrait {
+    //--------------------------------------------------------------
+    //--------------------------
+    //--------------------------------------------------------------
+    //--------------------------
+    fn method_name()   ;
+}
+
+#[cfg(any(cfail1,cfail4))]
+impl ChangeHasValueTrait for Foo {
+    fn method_name() { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub trait ChangeHasValueTrait {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method_name() { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl ChangeHasValueTrait for Foo {
+    fn method_name() { }
+}
+
+// Add default
+
+pub trait AddDefaultTrait {
+    fn method_name();
+}
+
+#[cfg(any(cfail1,cfail4))]
+impl AddDefaultTrait for Foo {
+    // -------------------------------------------------------------
+    // -------------------------
+    // -------------------------------------------------------------
+    // -------------------------
+    fn         method_name() { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl AddDefaultTrait for Foo {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    default fn method_name() { }
+}
+
+// Add arguments
+
+#[cfg(any(cfail1,cfail4))]
+pub trait AddArgumentTrait {
+    fn method_name(&self);
+}
+
+#[cfg(any(cfail1,cfail4))]
+impl AddArgumentTrait for Foo {
+    // -----------------------------------------------------------------------------------------
+    // -------------------------
+    // -----------------------------------------------------------------------------------------
+    // -------------------------
+    fn method_name(&self         ) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+pub trait AddArgumentTrait {
+    fn method_name(&self, x: u32);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl AddArgumentTrait for Foo {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method_name(&self, _x: u32) { }
+}
+
+// Change argument type
+
+#[cfg(any(cfail1,cfail4))]
+pub trait ChangeArgumentTypeTrait {
+    fn method_name(&self, x: u32);
+}
+
+#[cfg(any(cfail1,cfail4))]
+impl ChangeArgumentTypeTrait for Foo {
+    // -----------------------------------------------------------------------------------------
+    // -------------------------
+    // -----------------------------------------------------------------------------------------
+    // -------------------------
+    fn method_name(&self, _x: u32 ) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+pub trait ChangeArgumentTypeTrait {
+    fn method_name(&self, x: char);
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl ChangeArgumentTypeTrait for Foo {
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="hir_owner,hir_owner_nodes,fn_sig,typeck,optimized_mir", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn method_name(&self, _x: char) { }
+}
+
+
+
+struct Bar<T>(T);
+
+// Add Type Parameter To Impl --------------------------------------------------
+trait AddTypeParameterToImpl<T> {
+    fn id(t: T) -> T;
+}
+
+#[cfg(any(cfail1,cfail4))]
+impl AddTypeParameterToImpl<u32> for Bar<u32> {
+    fn id(t: u32) -> u32 { t }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,impl_trait_ref", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,impl_trait_ref", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl<TTT> AddTypeParameterToImpl<TTT> for Bar<TTT> {
+    #[rustc_clean(
+        except="hir_owner,hir_owner_nodes,generics_of,fn_sig,type_of,typeck,optimized_mir",
+        cfg="cfail2",
+    )]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(
+        except="hir_owner,hir_owner_nodes,generics_of,fn_sig,type_of,typeck,optimized_mir",
+        cfg="cfail5",
+    )]
+    #[rustc_clean(cfg="cfail6")]
+    fn id(t: TTT) -> TTT { t }
+}
+
+
+
+// Change Self Type of Impl ----------------------------------------------------
+trait ChangeSelfTypeOfImpl {
+    fn id(self) -> Self;
+}
+
+#[cfg(any(cfail1,cfail4))]
+impl ChangeSelfTypeOfImpl for u32 {
+    fn id(self) -> Self { self }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,impl_trait_ref", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes,impl_trait_ref", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl ChangeSelfTypeOfImpl for u64 {
+    #[rustc_clean(except="fn_sig,typeck,optimized_mir", cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(except="fn_sig,typeck,optimized_mir", cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn id(self) -> Self { self }
+}
+
+
+
+// Add Lifetime Bound to Impl --------------------------------------------------
+trait AddLifetimeBoundToImplParameter {
+    fn id(self) -> Self;
+}
+
+#[cfg(any(cfail1,cfail4))]
+impl<T> AddLifetimeBoundToImplParameter for T {
+    fn id(self) -> Self { self }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl<T: 'static> AddLifetimeBoundToImplParameter for T {
+    #[rustc_clean(cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn id(self) -> Self { self }
+}
+
+
+
+// Add Trait Bound to Impl Parameter -------------------------------------------
+trait AddTraitBoundToImplParameter {
+    fn id(self) -> Self;
+}
+
+#[cfg(any(cfail1,cfail4))]
+impl<T> AddTraitBoundToImplParameter for T {
+    fn id(self) -> Self { self }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl<T: Clone> AddTraitBoundToImplParameter for T {
+    #[rustc_clean(cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    fn id(self) -> Self { self }
+}
+
+
+
+// Add #[no_mangle] to Method --------------------------------------------------
+trait AddNoMangleToMethod {
+    fn add_no_mangle_to_method(&self) { }
+}
+
+#[cfg(any(cfail1,cfail4))]
+impl AddNoMangleToMethod for Foo {
+    // -------------------------
+    // -------------------------
+    // -------------------------
+    // -------------------------
+    // ---------
+    fn add_no_mangle_to_method(&self) { }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl AddNoMangleToMethod for Foo {
+    #[rustc_clean(cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    #[no_mangle]
+    fn add_no_mangle_to_method(&self) { }
+}
+
+
+// Make Method #[inline] -------------------------------------------------------
+trait MakeMethodInline {
+    fn make_method_inline(&self) -> u8 { 0 }
+}
+
+#[cfg(any(cfail1,cfail4))]
+impl MakeMethodInline for Foo {
+    // -------------------------
+    // -------------------------
+    // -------------------------
+    // -------------------------
+    // ------
+    fn make_method_inline(&self) -> u8 { 0 }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+impl MakeMethodInline for Foo {
+    #[rustc_clean(cfg="cfail2")]
+    #[rustc_clean(cfg="cfail3")]
+    #[rustc_clean(cfg="cfail5")]
+    #[rustc_clean(cfg="cfail6")]
+    #[inline]
+    fn make_method_inline(&self) -> u8 { 0 }
+}
diff --git a/tests/incremental/hashes/type_defs.rs b/tests/incremental/hashes/type_defs.rs
new file mode 100644
index 00000000000..79398eb07fe
--- /dev/null
+++ b/tests/incremental/hashes/type_defs.rs
@@ -0,0 +1,220 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for `type` definitions.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// We also test the ICH for `type` definitions exported in metadata. Same as
+// above, we want to make sure that the change between rev1 and rev2 also
+// results in a change of the ICH for the enum's metadata, and that it stays
+// the same between rev2 and rev3.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3
+// compile-flags: -Z query-dep-graph -O
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+
+// Change type (primitive) -----------------------------------------------------
+#[cfg(cfail1)]
+type ChangePrimitiveType = i32;
+
+#[cfg(not(cfail1))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+type ChangePrimitiveType = i64;
+
+
+
+// Change mutability -----------------------------------------------------------
+#[cfg(cfail1)]
+type ChangeMutability = &'static i32;
+
+#[cfg(not(cfail1))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+type ChangeMutability = &'static mut i32;
+
+
+
+// Change mutability -----------------------------------------------------------
+#[cfg(cfail1)]
+type ChangeLifetime<'a> = (&'static i32, &'a i32);
+
+#[cfg(not(cfail1))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+type ChangeLifetime<'a> = (&'a i32, &'a i32);
+
+
+
+// Change type (struct) -----------------------------------------------------------
+struct Struct1;
+struct Struct2;
+
+#[cfg(cfail1)]
+type ChangeTypeStruct = Struct1;
+
+#[cfg(not(cfail1))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+type ChangeTypeStruct = Struct2;
+
+
+
+// Change type (tuple) ---------------------------------------------------------
+#[cfg(cfail1)]
+type ChangeTypeTuple = (u32, u64);
+
+#[cfg(not(cfail1))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+type ChangeTypeTuple = (u32, i64);
+
+
+
+// Change type (enum) ----------------------------------------------------------
+enum Enum1 {
+    Var1,
+    Var2,
+}
+enum Enum2 {
+    Var1,
+    Var2,
+}
+
+#[cfg(cfail1)]
+type ChangeTypeEnum = Enum1;
+
+#[cfg(not(cfail1))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+type ChangeTypeEnum = Enum2;
+
+
+
+// Add tuple field -------------------------------------------------------------
+#[cfg(cfail1)]
+type AddTupleField = (i32, i64);
+
+#[cfg(not(cfail1))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+type AddTupleField = (i32, i64, i16);
+
+
+
+// Change nested tuple field ---------------------------------------------------
+#[cfg(cfail1)]
+type ChangeNestedTupleField = (i32, (i64, i16));
+
+#[cfg(not(cfail1))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+type ChangeNestedTupleField = (i32, (i64, i8));
+
+
+
+// Add type param --------------------------------------------------------------
+#[cfg(cfail1)]
+type AddTypeParam<T1> = (T1, T1);
+
+#[cfg(not(cfail1))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+type AddTypeParam<T1, T2> = (T1, T2);
+
+
+
+// Add type param bound --------------------------------------------------------
+#[cfg(cfail1)]
+type AddTypeParamBound<T1> = (T1, u32);
+
+#[cfg(not(cfail1))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+type AddTypeParamBound<T1: Clone> = (T1, u32);
+
+
+
+// Add type param bound in where clause ----------------------------------------
+#[cfg(cfail1)]
+type AddTypeParamBoundWhereClause<T1> where T1: Clone = (T1, u32);
+
+#[cfg(not(cfail1))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+type AddTypeParamBoundWhereClause<T1> where T1: Clone+Copy = (T1, u32);
+
+
+
+// Add lifetime param ----------------------------------------------------------
+#[cfg(cfail1)]
+type AddLifetimeParam<'a> = (&'a u32, &'a u32);
+
+#[cfg(not(cfail1))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+type AddLifetimeParam<'a, 'b> = (&'a u32, &'b u32);
+
+
+
+// Add lifetime param bound ----------------------------------------------------
+#[cfg(cfail1)]
+type AddLifetimeParamBound<'a, 'b> = (&'a u32, &'b u32);
+
+#[cfg(not(cfail1))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+type AddLifetimeParamBound<'a, 'b: 'a> = (&'a u32, &'b u32);
+
+
+
+// Add lifetime param bound in where clause ------------------------------------
+#[cfg(cfail1)]
+type AddLifetimeParamBoundWhereClause<'a, 'b, 'c>
+where 'b: 'a
+    = (&'a u32, &'b u32, &'c u32);
+
+#[cfg(not(cfail1))]
+#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+type AddLifetimeParamBoundWhereClause<'a, 'b, 'c>
+where 'b: 'a,
+      'c: 'a
+    = (&'a u32, &'b u32, &'c u32);
+
+
+
+// Change Trait Bound Indirectly -----------------------------------------------
+trait ReferencedTrait1 {}
+trait ReferencedTrait2 {}
+
+mod change_trait_bound_indirectly {
+    #[cfg(cfail1)]
+    use super::ReferencedTrait1 as Trait;
+    #[cfg(not(cfail1))]
+    use super::ReferencedTrait2 as Trait;
+
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+    #[rustc_clean(cfg="cfail3")]
+    type ChangeTraitBoundIndirectly<T: Trait> = (T, u32);
+}
+
+
+
+// Change Trait Bound Indirectly In Where Clause -------------------------------
+mod change_trait_bound_indirectly_in_where_clause {
+    #[cfg(cfail1)]
+    use super::ReferencedTrait1 as Trait;
+    #[cfg(not(cfail1))]
+    use super::ReferencedTrait2 as Trait;
+
+    #[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
+    #[rustc_clean(cfg="cfail3")]
+    type ChangeTraitBoundIndirectly<T> where T : Trait = (T, u32);
+}
diff --git a/tests/incremental/hashes/unary_and_binary_exprs.rs b/tests/incremental/hashes/unary_and_binary_exprs.rs
new file mode 100644
index 00000000000..58af51eef07
--- /dev/null
+++ b/tests/incremental/hashes/unary_and_binary_exprs.rs
@@ -0,0 +1,506 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for unary and binary expressions.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+
+// Change constant operand of negation -----------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn const_negation() -> i32 {
+    -10
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn const_negation() -> i32 {
+     -1
+}
+
+
+
+// Change constant operand of bitwise not --------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn const_bitwise_not() -> i32 {
+    !100
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn const_bitwise_not() -> i32 {
+     !99
+}
+
+
+
+// Change variable operand of negation -----------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn var_negation(x: i32, y: i32) -> i32 {
+    -x
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn var_negation(x: i32, y: i32) -> i32 {
+    -y
+}
+
+
+
+// Change variable operand of bitwise not --------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn var_bitwise_not(x: i32, y: i32) -> i32 {
+    !x
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn var_bitwise_not(x: i32, y: i32) -> i32 {
+    !y
+}
+
+
+
+// Change variable operand of deref --------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn var_deref(x: &i32, y: &i32) -> i32 {
+    *x
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn var_deref(x: &i32, y: &i32) -> i32 {
+    *y
+}
+
+
+
+// Change first constant operand of addition -----------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn first_const_add() -> i32 {
+    1 + 3
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn first_const_add() -> i32 {
+    2 + 3
+}
+
+
+
+// Change second constant operand of addition -----------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn second_const_add() -> i32 {
+    1 + 2
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn second_const_add() -> i32 {
+    1 + 3
+}
+
+
+
+// Change first variable operand of addition -----------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn first_var_add(a: i32, b: i32) -> i32 {
+    a + 2
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn first_var_add(a: i32, b: i32) -> i32 {
+    b + 2
+}
+
+
+
+// Change second variable operand of addition ----------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn second_var_add(a: i32, b: i32) -> i32 {
+    1 + a
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn second_var_add(a: i32, b: i32) -> i32 {
+    1 + b
+}
+
+
+
+// Change operator from + to - -------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn plus_to_minus(a: i32) -> i32 {
+    1 + a
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn plus_to_minus(a: i32) -> i32 {
+    1 - a
+}
+
+
+
+// Change operator from + to * -------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn plus_to_mult(a: i32) -> i32 {
+    1 + a
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn plus_to_mult(a: i32) -> i32 {
+    1 * a
+}
+
+
+
+// Change operator from + to / -------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn plus_to_div(a: i32) -> i32 {
+    1 + a
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn plus_to_div(a: i32) -> i32 {
+    1 / a
+}
+
+
+
+// Change operator from + to % -------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn plus_to_mod(a: i32) -> i32 {
+    1 + a
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn plus_to_mod(a: i32) -> i32 {
+    1 % a
+}
+
+
+
+// Change operator from && to || -----------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn and_to_or(a: bool, b: bool) -> bool {
+    a && b
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn and_to_or(a: bool, b: bool) -> bool {
+    a || b
+}
+
+
+
+// Change operator from & to | -------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn bitwise_and_to_bitwise_or(a: i32) -> i32 {
+    1 & a
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn bitwise_and_to_bitwise_or(a: i32) -> i32 {
+    1 | a
+}
+
+
+
+// Change operator from & to ^ -------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn bitwise_and_to_bitwise_xor(a: i32) -> i32 {
+    1 & a
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn bitwise_and_to_bitwise_xor(a: i32) -> i32 {
+    1 ^ a
+}
+
+
+
+// Change operator from & to << ------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn bitwise_and_to_lshift(a: i32) -> i32 {
+    a  & 1
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn bitwise_and_to_lshift(a: i32) -> i32 {
+    a << 1
+}
+
+
+
+// Change operator from & to >> ------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn bitwise_and_to_rshift(a: i32) -> i32 {
+    a  & 1
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn bitwise_and_to_rshift(a: i32) -> i32 {
+    a >> 1
+}
+
+
+
+// Change operator from == to != -----------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn eq_to_uneq(a: i32) -> bool {
+    a == 1
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn eq_to_uneq(a: i32) -> bool {
+    a != 1
+}
+
+
+
+// Change operator from == to < ------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn eq_to_lt(a: i32) -> bool {
+    a == 1
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn eq_to_lt(a: i32) -> bool {
+    a  < 1
+}
+
+
+
+// Change operator from == to > ------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn eq_to_gt(a: i32) -> bool {
+    a == 1
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn eq_to_gt(a: i32) -> bool {
+    a  > 1
+}
+
+
+
+// Change operator from == to <= -----------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn eq_to_le(a: i32) -> bool {
+    a == 1
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn eq_to_le(a: i32) -> bool {
+    a <= 1
+}
+
+
+
+// Change operator from == to >= -----------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn eq_to_ge(a: i32) -> bool {
+    a == 1
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn eq_to_ge(a: i32) -> bool {
+    a >= 1
+}
+
+
+
+// Change type in cast expression ----------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn type_cast(a: u8) -> u64 {
+    let b = a as i32;
+    let c = b as u64;
+    c
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir,typeck", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir,typeck", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn type_cast(a: u8) -> u64 {
+    let b = a as u32;
+    let c = b as u64;
+    c
+}
+
+
+
+// Change value in cast expression ---------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn value_cast(a: u32) -> i32 {
+    1 as i32
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn value_cast(a: u32) -> i32 {
+    2 as i32
+}
+
+
+
+// Change place in assignment --------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn place() -> i32 {
+    let mut x = 10;
+    let mut y = 11;
+    x = 9;
+    x
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn place() -> i32 {
+    let mut x = 10;
+    let mut y = 11;
+    y = 9;
+    x
+}
+
+
+
+// Change r-value in assignment ------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn rvalue() -> i32 {
+    let mut x = 10;
+    x = 9;
+    x
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn rvalue() -> i32 {
+    let mut x = 10;
+    x = 8;
+    x
+}
+
+
+
+// Change index into slice -----------------------------------------------------
+#[cfg(any(cfail1,cfail4))]
+pub fn index_to_slice(s: &[u8], i: usize, j: usize) -> u8 {
+    s[i]
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail2")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(except="hir_owner_nodes,optimized_mir", cfg="cfail5")]
+#[rustc_clean(cfg="cfail6")]
+pub fn index_to_slice(s: &[u8], i: usize, j: usize) -> u8 {
+    s[j]
+}
diff --git a/tests/incremental/hashes/while_let_loops.rs b/tests/incremental/hashes/while_let_loops.rs
new file mode 100644
index 00000000000..c81b0d0afb8
--- /dev/null
+++ b/tests/incremental/hashes/while_let_loops.rs
@@ -0,0 +1,247 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for `while let` loops.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+
+// Change loop body
+#[cfg(any(cfail1,cfail4))]
+pub fn change_loop_body() {
+    let mut _x = 0;
+    while let Some(0u32) = None {
+        _x = 1;
+        break;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_loop_body() {
+    let mut _x = 0;
+    while let Some(0u32) = None {
+        _x = 2;
+        break;
+    }
+}
+
+
+
+// Change loop body
+#[cfg(any(cfail1,cfail4))]
+pub fn change_loop_condition() {
+    let mut _x = 0;
+    while let Some(0u32) = None {
+        _x = 1;
+        break;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_loop_condition() {
+    let mut _x = 0;
+    while let Some(1u32) = None {
+        _x = 1;
+        break;
+    }
+}
+
+
+
+// Add break
+#[cfg(any(cfail1,cfail4))]
+pub fn add_break() {
+    let mut _x = 0;
+    while let Some(0u32) = None {
+        _x = 1;
+        // ---
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_break() {
+    let mut _x = 0;
+    while let Some(0u32) = None {
+        _x = 1;
+        break;
+    }
+}
+
+
+
+// Add loop label
+#[cfg(any(cfail1,cfail4))]
+pub fn add_loop_label() {
+    let mut _x = 0;
+            while let Some(0u32) = None {
+        _x = 1;
+        break;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_loop_label() {
+    let mut _x = 0;
+    'label: while let Some(0u32) = None {
+        _x = 1;
+        break;
+    }
+}
+
+
+
+// Add loop label to break
+#[cfg(any(cfail1,cfail4))]
+pub fn add_loop_label_to_break() {
+    let mut _x = 0;
+    'label: while let Some(0u32) = None {
+        _x = 1;
+        break       ;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_loop_label_to_break() {
+    let mut _x = 0;
+    'label: while let Some(0u32) = None {
+        _x = 1;
+        break 'label;
+    }
+}
+
+
+
+// Change break label
+#[cfg(any(cfail1,cfail4))]
+pub fn change_break_label() {
+    let mut _x = 0;
+    'outer: while let Some(0u32) = None {
+        'inner: while let Some(0u32) = None {
+            _x = 1;
+            break 'inner;
+        }
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_break_label() {
+    let mut _x = 0;
+    'outer: while let Some(0u32) = None {
+        'inner: while let Some(0u32) = None {
+            _x = 1;
+            break 'outer;
+        }
+    }
+}
+
+// Add loop label to continue
+#[cfg(any(cfail1,cfail4))]
+pub fn add_loop_label_to_continue() {
+    let mut _x = 0;
+    'label: while let Some(0u32) = None {
+        _x = 1;
+        continue       ;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_loop_label_to_continue() {
+    let mut _x = 0;
+    'label: while let Some(0u32) = None {
+        _x = 1;
+        continue 'label;
+    }
+}
+
+
+
+// Change continue label
+#[cfg(any(cfail1,cfail4))]
+pub fn change_continue_label() {
+    let mut _x = 0;
+    'outer: while let Some(0u32) = None {
+        'inner: while let Some(0u32) = None {
+            _x = 1;
+            continue 'inner;
+        }
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_continue_label() {
+    let mut _x = 0;
+    'outer: while let Some(0u32) = None {
+        'inner: while let Some(0u32) = None {
+            _x = 1;
+            continue 'outer;
+        }
+    }
+}
+
+
+
+// Change continue to break
+#[cfg(any(cfail1,cfail4))]
+pub fn change_continue_to_break() {
+    let mut _x = 0;
+    while let Some(0u32) = None {
+        _x = 1;
+        continue;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_continue_to_break() {
+    let mut _x = 0;
+    while let Some(0u32) = None {
+        _x = 1;
+        break   ;
+    }
+}
diff --git a/tests/incremental/hashes/while_loops.rs b/tests/incremental/hashes/while_loops.rs
new file mode 100644
index 00000000000..c1cc0b62bc2
--- /dev/null
+++ b/tests/incremental/hashes/while_loops.rs
@@ -0,0 +1,249 @@
+// This test case tests the incremental compilation hash (ICH) implementation
+// for `while` loops.
+
+// The general pattern followed here is: Change one thing between rev1 and rev2
+// and make sure that the hash has changed, then change nothing between rev2 and
+// rev3 and make sure that the hash has not changed.
+
+// build-pass (FIXME(62277): could be check-pass?)
+// revisions: cfail1 cfail2 cfail3 cfail4 cfail5 cfail6
+// compile-flags: -Z query-dep-graph -O
+// [cfail1]compile-flags: -Zincremental-ignore-spans
+// [cfail2]compile-flags: -Zincremental-ignore-spans
+// [cfail3]compile-flags: -Zincremental-ignore-spans
+
+#![allow(warnings)]
+#![feature(rustc_attrs)]
+#![crate_type="rlib"]
+
+
+// Change loop body
+#[cfg(any(cfail1,cfail4))]
+pub fn change_loop_body() {
+    let mut _x = 0;
+    while true {
+        _x = 1;
+        break;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_loop_body() {
+    let mut _x = 0;
+    while true {
+        _x = 2;
+        break;
+    }
+}
+
+
+
+// Change loop body
+#[cfg(any(cfail1,cfail4))]
+pub fn change_loop_condition() {
+    let mut _x = 0;
+    while true  {
+        _x = 1;
+        break;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_loop_condition() {
+    let mut _x = 0;
+    while false {
+        _x = 1;
+        break;
+    }
+}
+
+
+
+// Add break
+#[cfg(any(cfail1,cfail4))]
+pub fn add_break() {
+    let mut _x = 0;
+    while true {
+        _x = 1;
+        // ---
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir, typeck")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir, typeck")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_break() {
+    let mut _x = 0;
+    while true {
+        _x = 1;
+        break;
+    }
+}
+
+
+
+// Add loop label
+#[cfg(any(cfail1,cfail4))]
+pub fn add_loop_label() {
+    let mut _x = 0;
+            while true {
+        _x = 1;
+        break;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_loop_label() {
+    let mut _x = 0;
+    'label: while true {
+        _x = 1;
+        break;
+    }
+}
+
+
+
+// Add loop label to break
+#[cfg(any(cfail1,cfail4))]
+pub fn add_loop_label_to_break() {
+    let mut _x = 0;
+    'label: while true {
+        _x = 1;
+        break       ;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_loop_label_to_break() {
+    let mut _x = 0;
+    'label: while true {
+        _x = 1;
+        break 'label;
+    }
+}
+
+
+
+// Change break label
+#[cfg(any(cfail1,cfail4))]
+pub fn change_break_label() {
+    let mut _x = 0;
+    'outer: while true {
+        'inner: while true {
+            _x = 1;
+            break 'inner;
+        }
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_break_label() {
+    let mut _x = 0;
+    'outer: while true {
+        'inner: while true {
+            _x = 1;
+            break 'outer;
+        }
+    }
+}
+
+
+
+// Add loop label to continue
+#[cfg(any(cfail1,cfail4))]
+pub fn add_loop_label_to_continue() {
+    let mut _x = 0;
+    'label: while true {
+        _x = 1;
+        continue       ;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail6")]
+pub fn add_loop_label_to_continue() {
+    let mut _x = 0;
+    'label: while true {
+        _x = 1;
+        continue 'label;
+    }
+}
+
+
+
+// Change continue label
+#[cfg(any(cfail1,cfail4))]
+pub fn change_continue_label() {
+    let mut _x = 0;
+    'outer: while true {
+        'inner: while true {
+            _x = 1;
+            continue 'inner;
+        }
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_continue_label() {
+    let mut _x = 0;
+    'outer: while true {
+        'inner: while true {
+            _x = 1;
+            continue 'outer;
+        }
+    }
+}
+
+
+
+// Change continue to break
+#[cfg(any(cfail1,cfail4))]
+pub fn change_continue_to_break() {
+    let mut _x = 0;
+    while true {
+        _x = 1;
+        continue;
+    }
+}
+
+#[cfg(not(any(cfail1,cfail4)))]
+#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail3")]
+#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")]
+#[rustc_clean(cfg="cfail6")]
+pub fn change_continue_to_break() {
+    let mut _x = 0;
+    while true {
+        _x = 1;
+        break   ;
+    }
+}