about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/codegen/inherit_overflow.rs14
-rw-r--r--tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff3
-rw-r--r--tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.diff39
-rw-r--r--tests/mir-opt/const_prop/inherit_overflow.rs9
-rw-r--r--tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff26
-rw-r--r--tests/mir-opt/dataflow-const-prop/inherit_overflow.rs7
-rw-r--r--tests/mir-opt/lower_intrinsics.rs7
-rw-r--r--tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.diff83
-rw-r--r--tests/rustdoc-json/reexport/same_name_different_types.rs25
-rw-r--r--tests/rustdoc-ui/check-fail.rs1
-rw-r--r--tests/rustdoc-ui/check-fail.stderr18
-rw-r--r--tests/rustdoc-ui/check.rs1
-rw-r--r--tests/rustdoc-ui/check.stderr12
-rw-r--r--tests/rustdoc-ui/lint-group.rs1
-rw-r--r--tests/rustdoc-ui/lint-group.stderr20
-rw-r--r--tests/rustdoc-ui/rustdoc-all-only-stable-lints.rs6
-rw-r--r--tests/rustdoc/issue-107995.rs28
-rw-r--r--tests/ui/associated-inherent-types/ambiguity.rs16
-rw-r--r--tests/ui/associated-inherent-types/ambiguity.stderr20
-rw-r--r--tests/ui/associated-inherent-types/bugs/ice-substitution.rs23
-rw-r--r--tests/ui/associated-inherent-types/bugs/ice-substitution.stderr6
-rw-r--r--tests/ui/associated-inherent-types/bugs/inference-fail.rs15
-rw-r--r--tests/ui/associated-inherent-types/bugs/inference-fail.stderr9
-rw-r--r--tests/ui/associated-inherent-types/bugs/lack-of-regionck.rs19
-rw-r--r--tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs41
-rw-r--r--tests/ui/associated-inherent-types/dispatch-on-self-type-1.rs39
-rw-r--r--tests/ui/associated-inherent-types/dispatch-on-self-type-2.rs17
-rw-r--r--tests/ui/associated-inherent-types/dispatch-on-self-type-2.stderr19
-rw-r--r--tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.rs31
-rw-r--r--tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.shadowed.stderr15
-rw-r--r--tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.uncovered.stderr9
-rw-r--r--tests/ui/associated-inherent-types/not-found-self-type-differs.alias.stderr16
-rw-r--r--tests/ui/associated-inherent-types/not-found-self-type-differs.local.stderr16
-rw-r--r--tests/ui/associated-inherent-types/not-found-self-type-differs.rs22
-rw-r--r--tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.rs21
-rw-r--r--tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.stderr27
-rw-r--r--tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.rs18
-rw-r--r--tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.stderr14
-rw-r--r--tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.rs20
-rw-r--r--tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr20
-rw-r--r--tests/ui/associated-inherent-types/substitute-params-bad.rs23
-rw-r--r--tests/ui/associated-inherent-types/substitute-params-bad.stderr20
-rw-r--r--tests/ui/associated-inherent-types/substitute-params.rs (renamed from tests/ui/associated-inherent-types/struct-generics.rs)8
-rw-r--r--tests/ui/async-await/in-trait/async-default-fn-overridden.rs66
-rw-r--r--tests/ui/async-await/in-trait/async-default-fn-overridden.stderr11
-rw-r--r--tests/ui/lint/unaligned_references.rs31
-rw-r--r--tests/ui/lint/unaligned_references.stderr29
-rw-r--r--tests/ui/mir/field-projection-invariant.rs24
-rw-r--r--tests/ui/mir/field-projection-mutating-context.rs19
-rw-r--r--tests/ui/mir/field-projection-mutating-context.stderr12
-rw-r--r--tests/ui/mir/field-projection-mutating-context2.rs17
-rw-r--r--tests/ui/mir/field-projection-mutating-context2.stderr10
-rw-r--r--tests/ui/mir/field-ty-ascription-enums.rs15
-rw-r--r--tests/ui/mir/field-ty-ascription.rs37
55 files changed, 1020 insertions, 57 deletions
diff --git a/tests/codegen/inherit_overflow.rs b/tests/codegen/inherit_overflow.rs
new file mode 100644
index 00000000000..0b0b890b2c9
--- /dev/null
+++ b/tests/codegen/inherit_overflow.rs
@@ -0,0 +1,14 @@
+// compile-flags: -Zmir-enable-passes=+Inline,+ConstProp --crate-type lib
+// revisions: ASSERT NOASSERT
+//[ASSERT] compile-flags: -Coverflow-checks=on
+//[NOASSERT] compile-flags: -Coverflow-checks=off
+
+// CHECK-LABEL: define{{.*}} @assertion
+// ASSERT: call void @_ZN4core9panicking5panic17h
+// NOASSERT: ret i8 0
+#[no_mangle]
+pub fn assertion() -> u8 {
+    // Optimized MIR will replace this `CheckedBinaryOp` by `const (0, true)`.
+    // Verify that codegen does or does not emit the panic.
+    <u8 as std::ops::Add>::add(255, 1)
+}
diff --git a/tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff b/tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff
index bea32a67ef4..900061a484b 100644
--- a/tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff
+++ b/tests/mir-opt/const_prop/bad_op_div_by_zero.main.ConstProp.diff
@@ -24,9 +24,10 @@
           StorageLive(_3);                 // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19
 -         _3 = _1;                         // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19
 -         _4 = Eq(_3, const 0_i32);        // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
+-         assert(!move _4, "attempt to divide `{}` by zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
 +         _3 = const 0_i32;                // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:18: +2:19
 +         _4 = const true;                 // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
-          assert(!move _4, "attempt to divide `{}` by zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
++         assert(!const true, "attempt to divide `{}` by zero", const 1_i32) -> bb1; // scope 1 at $DIR/bad_op_div_by_zero.rs:+2:14: +2:19
       }
   
       bb1: {
diff --git a/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.diff b/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.diff
new file mode 100644
index 00000000000..d03c23a3fb5
--- /dev/null
+++ b/tests/mir-opt/const_prop/inherit_overflow.main.ConstProp.diff
@@ -0,0 +1,39 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+  
+  fn main() -> () {
+      let mut _0: ();                      // return place in scope 0 at $DIR/inherit_overflow.rs:+0:11: +0:11
+      let mut _1: u8;                      // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+      let mut _2: u8;                      // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+      let mut _3: u8;                      // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+      scope 1 {
+      }
+      scope 2 (inlined <u8 as Add>::add) { // at $DIR/inherit_overflow.rs:8:13: 8:47
+          debug self => _2;                // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+          debug other => _3;               // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+          let mut _4: (u8, bool);          // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+      }
+  
+      bb0: {
+          StorageLive(_1);                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+          StorageLive(_2);                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+          _2 = const u8::MAX;              // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+          StorageLive(_3);                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+          _3 = const 1_u8;                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+-         _4 = CheckedAdd(_2, _3);         // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+-         assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> bb1; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
++         _4 = const (0_u8, true);         // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
++         assert(!const true, "attempt to compute `{} + {}`, which would overflow", _2, _3) -> bb1; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+      }
+  
+      bb1: {
+-         _1 = move (_4.0: u8);            // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
++         _1 = const 0_u8;                 // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+          StorageDead(_3);                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+          StorageDead(_2);                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+          StorageDead(_1);                 // scope 0 at $DIR/inherit_overflow.rs:+3:47: +3:48
+          _0 = const ();                   // scope 0 at $DIR/inherit_overflow.rs:+0:11: +4:2
+          return;                          // scope 0 at $DIR/inherit_overflow.rs:+4:2: +4:2
+      }
+  }
+  
diff --git a/tests/mir-opt/const_prop/inherit_overflow.rs b/tests/mir-opt/const_prop/inherit_overflow.rs
new file mode 100644
index 00000000000..541a8c5c3af
--- /dev/null
+++ b/tests/mir-opt/const_prop/inherit_overflow.rs
@@ -0,0 +1,9 @@
+// unit-test: ConstProp
+// compile-flags: -Zmir-enable-passes=+Inline
+
+// EMIT_MIR inherit_overflow.main.ConstProp.diff
+fn main() {
+    // After inlining, this will contain a `CheckedBinaryOp`.
+    // Propagating the overflow is ok as codegen will just skip emitting the panic.
+    let _ = <u8 as std::ops::Add>::add(255, 1);
+}
diff --git a/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff
index a4ebd0c8c18..944afed8f46 100644
--- a/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff
+++ b/tests/mir-opt/dataflow-const-prop/checked.main.DataflowConstProp.diff
@@ -61,7 +61,7 @@
 -         assert(!move (_10.1: bool), "attempt to compute `{} + {}`, which would overflow", move _9, const 1_i32) -> bb2; // scope 4 at $DIR/checked.rs:+6:13: +6:18
 +         _9 = const i32::MAX;             // scope 4 at $DIR/checked.rs:+6:13: +6:14
 +         _10 = CheckedAdd(const i32::MAX, const 1_i32); // scope 4 at $DIR/checked.rs:+6:13: +6:18
-+         assert(!move (_10.1: bool), "attempt to compute `{} + {}`, which would overflow", const i32::MAX, const 1_i32) -> bb2; // scope 4 at $DIR/checked.rs:+6:13: +6:18
++         assert(!const true, "attempt to compute `{} + {}`, which would overflow", const i32::MAX, const 1_i32) -> bb2; // scope 4 at $DIR/checked.rs:+6:13: +6:18
       }
   
       bb2: {
diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff
index 33122f465fe..29781e9ce18 100644
--- a/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff
+++ b/tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff
@@ -5,26 +5,34 @@
       let mut _0: ();                      // return place in scope 0 at $DIR/inherit_overflow.rs:+0:11: +0:11
       let mut _1: u8;                      // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
       let mut _2: u8;                      // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+      let mut _3: u8;                      // in scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
       scope 1 {
       }
-      scope 2 (inlined <u8 as Add>::add) { // at $DIR/inherit_overflow.rs:7:13: 7:47
-          debug self => _1;                // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
-          debug other => _2;               // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
-          let mut _3: (u8, bool);          // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+      scope 2 (inlined <u8 as Add>::add) { // at $DIR/inherit_overflow.rs:8:13: 8:47
+          debug self => _2;                // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+          debug other => _3;               // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+          let mut _4: (u8, bool);          // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
       }
   
       bb0: {
           StorageLive(_1);                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
-          _1 = const u8::MAX;              // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
           StorageLive(_2);                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
-          _2 = const 1_u8;                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
-          _3 = CheckedAdd(const u8::MAX, const 1_u8); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
-          assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> bb1; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+          _2 = const u8::MAX;              // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+          StorageLive(_3);                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+          _3 = const 1_u8;                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+-         _4 = CheckedAdd(_2, _3);         // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+-         assert(!move (_4.1: bool), "attempt to compute `{} + {}`, which would overflow", _2, _3) -> bb1; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
++         _4 = CheckedAdd(const u8::MAX, const 1_u8); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
++         assert(!const true, "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> bb1; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
       }
   
       bb1: {
+-         _1 = move (_4.0: u8);            // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
++         _1 = const 0_u8;                 // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
+          StorageDead(_3);                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
           StorageDead(_2);                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
-          StorageDead(_1);                 // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
+          StorageDead(_1);                 // scope 0 at $DIR/inherit_overflow.rs:+3:47: +3:48
+          _0 = const ();                   // scope 0 at $DIR/inherit_overflow.rs:+0:11: +4:2
           return;                          // scope 0 at $DIR/inherit_overflow.rs:+4:2: +4:2
       }
   }
diff --git a/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs b/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs
index 2f2d9d0102d..f4aba60f0c8 100644
--- a/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs
+++ b/tests/mir-opt/dataflow-const-prop/inherit_overflow.rs
@@ -1,8 +1,9 @@
-// compile-flags: -Zunsound-mir-opts
+// unit-test: DataflowConstProp
+// compile-flags: -Zmir-enable-passes=+Inline
 
 // EMIT_MIR inherit_overflow.main.DataflowConstProp.diff
 fn main() {
-    // After inlining, this will contain a `CheckedBinaryOp`. The overflow
-    // must be ignored by the constant propagation to avoid triggering a panic.
+    // After inlining, this will contain a `CheckedBinaryOp`.
+    // Propagating the overflow is ok as codegen will just skip emitting the panic.
     let _ = <u8 as std::ops::Add>::add(255, 1);
 }
diff --git a/tests/mir-opt/lower_intrinsics.rs b/tests/mir-opt/lower_intrinsics.rs
index 66dae0e46b9..7147be43ca5 100644
--- a/tests/mir-opt/lower_intrinsics.rs
+++ b/tests/mir-opt/lower_intrinsics.rs
@@ -72,3 +72,10 @@ pub fn assume() {
         std::intrinsics::assume(true);
     }
 }
+
+// EMIT_MIR lower_intrinsics.with_overflow.LowerIntrinsics.diff
+pub fn with_overflow(a: i32, b: i32) {
+    let _x = core::intrinsics::add_with_overflow(a, b);
+    let _y = core::intrinsics::sub_with_overflow(a, b);
+    let _z = core::intrinsics::mul_with_overflow(a, b);
+}
diff --git a/tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.diff b/tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.diff
new file mode 100644
index 00000000000..9870a70dec5
--- /dev/null
+++ b/tests/mir-opt/lower_intrinsics.with_overflow.LowerIntrinsics.diff
@@ -0,0 +1,83 @@
+- // MIR for `with_overflow` before LowerIntrinsics
++ // MIR for `with_overflow` after LowerIntrinsics
+  
+  fn with_overflow(_1: i32, _2: i32) -> () {
+      debug a => _1;                       // in scope 0 at $DIR/lower_intrinsics.rs:+0:22: +0:23
+      debug b => _2;                       // in scope 0 at $DIR/lower_intrinsics.rs:+0:30: +0:31
+      let mut _0: ();                      // return place in scope 0 at $DIR/lower_intrinsics.rs:+0:38: +0:38
+      let _3: (i32, bool);                 // in scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:11
+      let mut _4: i32;                     // in scope 0 at $DIR/lower_intrinsics.rs:+1:50: +1:51
+      let mut _5: i32;                     // in scope 0 at $DIR/lower_intrinsics.rs:+1:53: +1:54
+      let mut _7: i32;                     // in scope 0 at $DIR/lower_intrinsics.rs:+2:50: +2:51
+      let mut _8: i32;                     // in scope 0 at $DIR/lower_intrinsics.rs:+2:53: +2:54
+      let mut _10: i32;                    // in scope 0 at $DIR/lower_intrinsics.rs:+3:50: +3:51
+      let mut _11: i32;                    // in scope 0 at $DIR/lower_intrinsics.rs:+3:53: +3:54
+      scope 1 {
+          debug _x => _3;                  // in scope 1 at $DIR/lower_intrinsics.rs:+1:9: +1:11
+          let _6: (i32, bool);             // in scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:11
+          scope 2 {
+              debug _y => _6;              // in scope 2 at $DIR/lower_intrinsics.rs:+2:9: +2:11
+              let _9: (i32, bool);         // in scope 2 at $DIR/lower_intrinsics.rs:+3:9: +3:11
+              scope 3 {
+                  debug _z => _9;          // in scope 3 at $DIR/lower_intrinsics.rs:+3:9: +3:11
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_3);                 // scope 0 at $DIR/lower_intrinsics.rs:+1:9: +1:11
+          StorageLive(_4);                 // scope 0 at $DIR/lower_intrinsics.rs:+1:50: +1:51
+          _4 = _1;                         // scope 0 at $DIR/lower_intrinsics.rs:+1:50: +1:51
+          StorageLive(_5);                 // scope 0 at $DIR/lower_intrinsics.rs:+1:53: +1:54
+          _5 = _2;                         // scope 0 at $DIR/lower_intrinsics.rs:+1:53: +1:54
+-         _3 = add_with_overflow::<i32>(move _4, move _5) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:55
+-                                          // mir::Constant
+-                                          // + span: $DIR/lower_intrinsics.rs:78:14: 78:49
+-                                          // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> (i32, bool) {add_with_overflow::<i32>}, val: Value(<ZST>) }
++         _3 = CheckedAdd(move _4, move _5); // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:55
++         goto -> bb1;                     // scope 0 at $DIR/lower_intrinsics.rs:+1:14: +1:55
+      }
+  
+      bb1: {
+          StorageDead(_5);                 // scope 0 at $DIR/lower_intrinsics.rs:+1:54: +1:55
+          StorageDead(_4);                 // scope 0 at $DIR/lower_intrinsics.rs:+1:54: +1:55
+          StorageLive(_6);                 // scope 1 at $DIR/lower_intrinsics.rs:+2:9: +2:11
+          StorageLive(_7);                 // scope 1 at $DIR/lower_intrinsics.rs:+2:50: +2:51
+          _7 = _1;                         // scope 1 at $DIR/lower_intrinsics.rs:+2:50: +2:51
+          StorageLive(_8);                 // scope 1 at $DIR/lower_intrinsics.rs:+2:53: +2:54
+          _8 = _2;                         // scope 1 at $DIR/lower_intrinsics.rs:+2:53: +2:54
+-         _6 = sub_with_overflow::<i32>(move _7, move _8) -> bb2; // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:55
+-                                          // mir::Constant
+-                                          // + span: $DIR/lower_intrinsics.rs:79:14: 79:49
+-                                          // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> (i32, bool) {sub_with_overflow::<i32>}, val: Value(<ZST>) }
++         _6 = CheckedSub(move _7, move _8); // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:55
++         goto -> bb2;                     // scope 1 at $DIR/lower_intrinsics.rs:+2:14: +2:55
+      }
+  
+      bb2: {
+          StorageDead(_8);                 // scope 1 at $DIR/lower_intrinsics.rs:+2:54: +2:55
+          StorageDead(_7);                 // scope 1 at $DIR/lower_intrinsics.rs:+2:54: +2:55
+          StorageLive(_9);                 // scope 2 at $DIR/lower_intrinsics.rs:+3:9: +3:11
+          StorageLive(_10);                // scope 2 at $DIR/lower_intrinsics.rs:+3:50: +3:51
+          _10 = _1;                        // scope 2 at $DIR/lower_intrinsics.rs:+3:50: +3:51
+          StorageLive(_11);                // scope 2 at $DIR/lower_intrinsics.rs:+3:53: +3:54
+          _11 = _2;                        // scope 2 at $DIR/lower_intrinsics.rs:+3:53: +3:54
+-         _9 = mul_with_overflow::<i32>(move _10, move _11) -> bb3; // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:55
+-                                          // mir::Constant
+-                                          // + span: $DIR/lower_intrinsics.rs:80:14: 80:49
+-                                          // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> (i32, bool) {mul_with_overflow::<i32>}, val: Value(<ZST>) }
++         _9 = CheckedMul(move _10, move _11); // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:55
++         goto -> bb3;                     // scope 2 at $DIR/lower_intrinsics.rs:+3:14: +3:55
+      }
+  
+      bb3: {
+          StorageDead(_11);                // scope 2 at $DIR/lower_intrinsics.rs:+3:54: +3:55
+          StorageDead(_10);                // scope 2 at $DIR/lower_intrinsics.rs:+3:54: +3:55
+          _0 = const ();                   // scope 0 at $DIR/lower_intrinsics.rs:+0:38: +4:2
+          StorageDead(_9);                 // scope 2 at $DIR/lower_intrinsics.rs:+4:1: +4:2
+          StorageDead(_6);                 // scope 1 at $DIR/lower_intrinsics.rs:+4:1: +4:2
+          StorageDead(_3);                 // scope 0 at $DIR/lower_intrinsics.rs:+4:1: +4:2
+          return;                          // scope 0 at $DIR/lower_intrinsics.rs:+4:2: +4:2
+      }
+  }
+  
diff --git a/tests/rustdoc-json/reexport/same_name_different_types.rs b/tests/rustdoc-json/reexport/same_name_different_types.rs
new file mode 100644
index 00000000000..2314a4eb909
--- /dev/null
+++ b/tests/rustdoc-json/reexport/same_name_different_types.rs
@@ -0,0 +1,25 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/107677>.
+
+#![feature(no_core)]
+#![no_core]
+
+pub mod nested {
+    // @set foo_struct = "$.index[*][?(@.docs == 'Foo the struct')].id"
+
+    /// Foo the struct
+    pub struct Foo {}
+
+    // @set foo_fn = "$.index[*][?(@.docs == 'Foo the function')].id"
+
+    #[allow(non_snake_case)]
+    /// Foo the function
+    pub fn Foo() {}
+}
+
+// @ismany "$.index[*][?(@.inner.name == 'Foo' && @.kind == 'import')].inner.id" $foo_fn $foo_struct
+// @ismany "$.index[*][?(@.inner.name == 'Bar' && @.kind == 'import')].inner.id" $foo_fn $foo_struct
+
+// @count "$.index[*][?(@.inner.name == 'Foo' && @.kind == 'import')]" 2
+pub use nested::Foo;
+// @count "$.index[*][?(@.inner.name == 'Bar' && @.kind == 'import')]" 2
+pub use Foo as Bar;
diff --git a/tests/rustdoc-ui/check-fail.rs b/tests/rustdoc-ui/check-fail.rs
index c5e1759ee2d..02632b4ce7d 100644
--- a/tests/rustdoc-ui/check-fail.rs
+++ b/tests/rustdoc-ui/check-fail.rs
@@ -2,6 +2,7 @@
 
 #![feature(rustdoc_missing_doc_code_examples)]
 #![deny(missing_docs)]
+#![deny(rustdoc::missing_doc_code_examples)]
 #![deny(rustdoc::all)]
 
 //! ```rust,testharness
diff --git a/tests/rustdoc-ui/check-fail.stderr b/tests/rustdoc-ui/check-fail.stderr
index d8aeccbfc31..f05e457af64 100644
--- a/tests/rustdoc-ui/check-fail.stderr
+++ b/tests/rustdoc-ui/check-fail.stderr
@@ -1,5 +1,5 @@
 error: missing documentation for a function
-  --> $DIR/check-fail.rs:12:1
+  --> $DIR/check-fail.rs:13:1
    |
 LL | pub fn foo() {}
    | ^^^^^^^^^^^^
@@ -11,7 +11,7 @@ LL | #![deny(missing_docs)]
    |         ^^^^^^^^^^^^
 
 error: missing code example in this documentation
-  --> $DIR/check-fail.rs:12:1
+  --> $DIR/check-fail.rs:13:1
    |
 LL | pub fn foo() {}
    | ^^^^^^^^^^^^^^^
@@ -19,12 +19,11 @@ LL | pub fn foo() {}
 note: the lint level is defined here
   --> $DIR/check-fail.rs:5:9
    |
-LL | #![deny(rustdoc::all)]
-   |         ^^^^^^^^^^^^
-   = note: `#[deny(rustdoc::missing_doc_code_examples)]` implied by `#[deny(rustdoc::all)]`
+LL | #![deny(rustdoc::missing_doc_code_examples)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: unknown attribute `testharness`. Did you mean `test_harness`?
-  --> $DIR/check-fail.rs:7:1
+  --> $DIR/check-fail.rs:8:1
    |
 LL | / //! ```rust,testharness
 LL | |
@@ -33,10 +32,15 @@ LL | | //! ```
    | |_______^
    |
    = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
+note: the lint level is defined here
+  --> $DIR/check-fail.rs:6:9
+   |
+LL | #![deny(rustdoc::all)]
+   |         ^^^^^^^^^^^^
    = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(rustdoc::all)]`
 
 error: unknown attribute `testharness`. Did you mean `test_harness`?
-  --> $DIR/check-fail.rs:16:1
+  --> $DIR/check-fail.rs:17:1
    |
 LL | / /// hello
 LL | |
diff --git a/tests/rustdoc-ui/check.rs b/tests/rustdoc-ui/check.rs
index f70b0336151..e389a81bb33 100644
--- a/tests/rustdoc-ui/check.rs
+++ b/tests/rustdoc-ui/check.rs
@@ -7,6 +7,7 @@
 //~^^ WARN
 
 #![warn(missing_docs)]
+#![warn(rustdoc::missing_doc_code_examples)]
 #![warn(rustdoc::all)]
 
 pub fn foo() {}
diff --git a/tests/rustdoc-ui/check.stderr b/tests/rustdoc-ui/check.stderr
index d379f33f2bd..c5ed5d0c3ef 100644
--- a/tests/rustdoc-ui/check.stderr
+++ b/tests/rustdoc-ui/check.stderr
@@ -17,7 +17,7 @@ LL | #![warn(missing_docs)]
    |         ^^^^^^^^^^^^
 
 warning: missing documentation for a function
-  --> $DIR/check.rs:12:1
+  --> $DIR/check.rs:13:1
    |
 LL | pub fn foo() {}
    | ^^^^^^^^^^^^
@@ -27,7 +27,7 @@ warning: no documentation found for this crate's top-level module
    = help: The following guide may be of use:
            https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html
 note: the lint level is defined here
-  --> $DIR/check.rs:10:9
+  --> $DIR/check.rs:11:9
    |
 LL | #![warn(rustdoc::all)]
    |         ^^^^^^^^^^^^
@@ -45,10 +45,14 @@ LL | |
 LL | | pub fn foo() {}
    | |_______________^
    |
-   = note: `#[warn(rustdoc::missing_doc_code_examples)]` implied by `#[warn(rustdoc::all)]`
+note: the lint level is defined here
+  --> $DIR/check.rs:10:9
+   |
+LL | #![warn(rustdoc::missing_doc_code_examples)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: missing code example in this documentation
-  --> $DIR/check.rs:12:1
+  --> $DIR/check.rs:13:1
    |
 LL | pub fn foo() {}
    | ^^^^^^^^^^^^^^^
diff --git a/tests/rustdoc-ui/lint-group.rs b/tests/rustdoc-ui/lint-group.rs
index 09aca6d2b27..ad88157f64f 100644
--- a/tests/rustdoc-ui/lint-group.rs
+++ b/tests/rustdoc-ui/lint-group.rs
@@ -6,6 +6,7 @@
 //! println!("sup");
 //! ```
 
+#![deny(rustdoc::missing_doc_code_examples)]
 #![deny(rustdoc::all)]
 
 /// what up, let's make an [error]
diff --git a/tests/rustdoc-ui/lint-group.stderr b/tests/rustdoc-ui/lint-group.stderr
index 4f2c9658891..7ff09fcc45a 100644
--- a/tests/rustdoc-ui/lint-group.stderr
+++ b/tests/rustdoc-ui/lint-group.stderr
@@ -1,5 +1,5 @@
 error: missing code example in this documentation
-  --> $DIR/lint-group.rs:18:1
+  --> $DIR/lint-group.rs:19:1
    |
 LL | /// wait, this doesn't have a doctest?
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,12 +7,11 @@ LL | /// wait, this doesn't have a doctest?
 note: the lint level is defined here
   --> $DIR/lint-group.rs:9:9
    |
-LL | #![deny(rustdoc::all)]
-   |         ^^^^^^^^^^^^
-   = note: `#[deny(rustdoc::missing_doc_code_examples)]` implied by `#[deny(rustdoc::all)]`
+LL | #![deny(rustdoc::missing_doc_code_examples)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: documentation test in private item
-  --> $DIR/lint-group.rs:21:1
+  --> $DIR/lint-group.rs:22:1
    |
 LL | / /// wait, this *does* have a doctest?
 LL | | ///
@@ -21,16 +20,21 @@ LL | | /// println!("sup");
 LL | | /// ```
    | |_______^
    |
+note: the lint level is defined here
+  --> $DIR/lint-group.rs:10:9
+   |
+LL | #![deny(rustdoc::all)]
+   |         ^^^^^^^^^^^^
    = note: `#[deny(rustdoc::private_doc_tests)]` implied by `#[deny(rustdoc::all)]`
 
 error: missing code example in this documentation
-  --> $DIR/lint-group.rs:28:1
+  --> $DIR/lint-group.rs:29:1
    |
 LL | /// <unknown>
    | ^^^^^^^^^^^^^
 
 error: unresolved link to `error`
-  --> $DIR/lint-group.rs:11:29
+  --> $DIR/lint-group.rs:12:29
    |
 LL | /// what up, let's make an [error]
    |                             ^^^^^ no item named `error` in scope
@@ -39,7 +43,7 @@ LL | /// what up, let's make an [error]
    = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(rustdoc::all)]`
 
 error: unclosed HTML tag `unknown`
-  --> $DIR/lint-group.rs:28:5
+  --> $DIR/lint-group.rs:29:5
    |
 LL | /// <unknown>
    |     ^^^^^^^^^
diff --git a/tests/rustdoc-ui/rustdoc-all-only-stable-lints.rs b/tests/rustdoc-ui/rustdoc-all-only-stable-lints.rs
new file mode 100644
index 00000000000..e106d06aff5
--- /dev/null
+++ b/tests/rustdoc-ui/rustdoc-all-only-stable-lints.rs
@@ -0,0 +1,6 @@
+// check-pass
+
+// Ensure `rustdoc::all` only affects stable lints. See #106289.
+
+#![deny(unknown_lints)]
+#![allow(rustdoc::all)]
diff --git a/tests/rustdoc/issue-107995.rs b/tests/rustdoc/issue-107995.rs
new file mode 100644
index 00000000000..1273e4fdd12
--- /dev/null
+++ b/tests/rustdoc/issue-107995.rs
@@ -0,0 +1,28 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/107995>.
+
+#![crate_name = "foo"]
+
+// @has 'foo/fn.foo.html'
+// @has - '//*[@class="docblock"]//a[@href="fn.bar.html"]' 'bar`'
+/// A foo, see also [ bar`]
+pub fn foo() {}
+
+// @has 'foo/fn.bar.html'
+// @has - '//*[@class="docblock"]' 'line Path line'
+// @has - '//*[@class="docblock"]//a[@href="struct.Path.html"]' 'Path'
+#[doc = "line ["]
+#[doc = "Path"]
+#[doc = "] line"]
+pub fn bar() {}
+
+// @has 'foo/fn.another.html'
+// @has - '//*[@class="docblock"]//a[@href="struct.Path.html"]' 'Path'
+/// [ `Path`]
+pub fn another() {}
+
+// @has 'foo/fn.last.html'
+// @has - '//*[@class="docblock"]//a[@href="struct.Path.html"]' 'Path'
+/// [ Path`]
+pub fn last() {}
+
+pub struct Path;
diff --git a/tests/ui/associated-inherent-types/ambiguity.rs b/tests/ui/associated-inherent-types/ambiguity.rs
new file mode 100644
index 00000000000..73920555b3e
--- /dev/null
+++ b/tests/ui/associated-inherent-types/ambiguity.rs
@@ -0,0 +1,16 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct Wrapper<T>(T);
+
+impl Wrapper<i32> {
+    type Foo = i32;
+}
+
+impl Wrapper<()> {
+    type Foo = ();
+}
+
+fn main() {
+    let _: Wrapper<_>::Foo = (); //~ ERROR multiple applicable items in scope
+}
diff --git a/tests/ui/associated-inherent-types/ambiguity.stderr b/tests/ui/associated-inherent-types/ambiguity.stderr
new file mode 100644
index 00000000000..155c296cbb3
--- /dev/null
+++ b/tests/ui/associated-inherent-types/ambiguity.stderr
@@ -0,0 +1,20 @@
+error[E0034]: multiple applicable items in scope
+  --> $DIR/ambiguity.rs:15:24
+   |
+LL |     let _: Wrapper<_>::Foo = ();
+   |                        ^^^ multiple `Foo` found
+   |
+note: candidate #1 is defined in an impl for the type `Wrapper<i32>`
+  --> $DIR/ambiguity.rs:7:5
+   |
+LL |     type Foo = i32;
+   |     ^^^^^^^^
+note: candidate #2 is defined in an impl for the type `Wrapper<()>`
+  --> $DIR/ambiguity.rs:11:5
+   |
+LL |     type Foo = ();
+   |     ^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0034`.
diff --git a/tests/ui/associated-inherent-types/bugs/ice-substitution.rs b/tests/ui/associated-inherent-types/bugs/ice-substitution.rs
new file mode 100644
index 00000000000..53ac79e0561
--- /dev/null
+++ b/tests/ui/associated-inherent-types/bugs/ice-substitution.rs
@@ -0,0 +1,23 @@
+// known-bug: unknown
+// failure-status: 101
+// normalize-stderr-test "note: .*\n\n" -> ""
+// normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
+// rustc-env:RUST_BACKTRACE=0
+
+// FIXME: I presume a type variable that couldn't be solved by `resolve_vars_if_possible`
+//        escapes the InferCtxt snapshot.
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct Cont<T>(T);
+
+impl<T: Copy> Cont<T> {
+    type Out = Vec<T>;
+}
+
+pub fn weird<T: Copy>(x: T) {
+    let _: Cont<_>::Out = vec![true];
+}
+
+fn main() {}
diff --git a/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr b/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr
new file mode 100644
index 00000000000..7b0d1c50516
--- /dev/null
+++ b/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr
@@ -0,0 +1,6 @@
+error: the compiler unexpectedly panicked. this is a bug.
+
+query stack during panic:
+#0 [typeck] type-checking `weird`
+#1 [typeck_item_bodies] type-checking all item bodies
+end of query stack
diff --git a/tests/ui/associated-inherent-types/bugs/inference-fail.rs b/tests/ui/associated-inherent-types/bugs/inference-fail.rs
new file mode 100644
index 00000000000..a920b412b1a
--- /dev/null
+++ b/tests/ui/associated-inherent-types/bugs/inference-fail.rs
@@ -0,0 +1,15 @@
+// known-bug: unknown
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct S<T>(T);
+
+impl S<()> {
+    type P = i128;
+}
+
+fn main() {
+    // We fail to infer `_ == ()` here.
+    let _: S<_>::P;
+}
diff --git a/tests/ui/associated-inherent-types/bugs/inference-fail.stderr b/tests/ui/associated-inherent-types/bugs/inference-fail.stderr
new file mode 100644
index 00000000000..425691bd6c4
--- /dev/null
+++ b/tests/ui/associated-inherent-types/bugs/inference-fail.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+  --> $DIR/inference-fail.rs:14:14
+   |
+LL |     let _: S<_>::P;
+   |              ^ cannot infer type
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/associated-inherent-types/bugs/lack-of-regionck.rs b/tests/ui/associated-inherent-types/bugs/lack-of-regionck.rs
new file mode 100644
index 00000000000..632dbf3854b
--- /dev/null
+++ b/tests/ui/associated-inherent-types/bugs/lack-of-regionck.rs
@@ -0,0 +1,19 @@
+// known-bug: unknown
+// check-pass
+
+// We currently don't region-check inherent associated type projections at all.
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features, dead_code)]
+
+struct S<T>(T);
+
+impl S<&'static ()> {
+    type T = ();
+}
+
+fn usr<'a>() {
+    let _: S::<&'a ()>::T; // this should *fail* but it doesn't!
+}
+
+fn main() {}
diff --git a/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs b/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs
new file mode 100644
index 00000000000..f846bfa4168
--- /dev/null
+++ b/tests/ui/associated-inherent-types/dispatch-on-self-type-0.rs
@@ -0,0 +1,41 @@
+// check-pass
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+// Check that inherent associated types are dispatched on the concrete Self type.
+
+struct Select<T>(T);
+
+impl Select<u8> {
+    type Projection = ();
+}
+
+impl Select<String> {
+    type Projection = bool;
+}
+
+struct Choose<T>(T);
+struct NonCopy;
+
+impl<T: Copy> Choose<T> {
+    type Result = Vec<T>;
+}
+
+impl Choose<NonCopy> {
+    type Result = ();
+}
+
+fn main() {
+    let _: Select<String>::Projection = false;
+    let _: Select<u8>::Projection = ();
+
+    let _: Choose<NonCopy>::Result = ();
+    let _: Choose<bool>::Result = vec![true];
+}
+
+// Test if we use the correct `ParamEnv` when proving obligations.
+
+pub fn parameterized<T: Copy>(x: T) {
+    let _: Choose<T>::Result = vec![x];
+}
diff --git a/tests/ui/associated-inherent-types/dispatch-on-self-type-1.rs b/tests/ui/associated-inherent-types/dispatch-on-self-type-1.rs
new file mode 100644
index 00000000000..9b0fa8dc6f3
--- /dev/null
+++ b/tests/ui/associated-inherent-types/dispatch-on-self-type-1.rs
@@ -0,0 +1,39 @@
+// check-pass
+
+#![feature(inherent_associated_types, auto_traits, negative_impls)]
+#![allow(incomplete_features)]
+
+use std::cmp::Ordering;
+
+// Check that inherent associated types are dispatched on the concrete Self type.
+
+struct Select<T, U>(T, U);
+
+impl<T: Ordinary, U: Ordinary> Select<T, U> {
+    type Type = ();
+}
+
+impl<T: Ordinary> Select<T, Special> {
+    type Type = bool;
+}
+
+impl<T: Ordinary> Select<Special, T> {
+    type Type = Ordering;
+}
+
+impl Select<Special, Special> {
+    type Type = (bool, bool);
+}
+
+fn main() {
+    let _: Select<String, Special>::Type = false;
+    let _: Select<Special, Special>::Type = (true, false);
+    let _: Select<Special, u8>::Type = Ordering::Equal;
+    let _: Select<i128, ()>::Type = ();
+}
+
+enum Special {}
+
+impl !Ordinary for Special {}
+
+auto trait Ordinary {}
diff --git a/tests/ui/associated-inherent-types/dispatch-on-self-type-2.rs b/tests/ui/associated-inherent-types/dispatch-on-self-type-2.rs
new file mode 100644
index 00000000000..7b205952f52
--- /dev/null
+++ b/tests/ui/associated-inherent-types/dispatch-on-self-type-2.rs
@@ -0,0 +1,17 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct Parameterized<T, U>(T, U);
+
+impl Parameterized<(), ()> {
+    type Output = bool;
+}
+
+impl<T> Parameterized<bool, T> {
+    type Result = T;
+}
+
+fn main() {
+    let _: Parameterized<(), ()>::Output = String::new(); //~ ERROR mismatched types
+    let _: Parameterized<bool, u32>::Result = (); //~ ERROR mismatched types
+}
diff --git a/tests/ui/associated-inherent-types/dispatch-on-self-type-2.stderr b/tests/ui/associated-inherent-types/dispatch-on-self-type-2.stderr
new file mode 100644
index 00000000000..c9a48872af4
--- /dev/null
+++ b/tests/ui/associated-inherent-types/dispatch-on-self-type-2.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+  --> $DIR/dispatch-on-self-type-2.rs:15:44
+   |
+LL |     let _: Parameterized<(), ()>::Output = String::new();
+   |            -----------------------------   ^^^^^^^^^^^^^ expected `bool`, found `String`
+   |            |
+   |            expected due to this
+
+error[E0308]: mismatched types
+  --> $DIR/dispatch-on-self-type-2.rs:16:47
+   |
+LL |     let _: Parameterized<bool, u32>::Result = ();
+   |            --------------------------------   ^^ expected `u32`, found `()`
+   |            |
+   |            expected due to this
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.rs b/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.rs
new file mode 100644
index 00000000000..d2efb24c666
--- /dev/null
+++ b/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.rs
@@ -0,0 +1,31 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+// Check that it's okay to report “[inherent] associated type […] not found” for inherent associated
+// type candidates that are not applicable (due to unsuitable Self type) even if there exists a
+// “shadowed” associated type from a trait with the same name since its use would be ambiguous
+// anyway if the IAT didn't exist.
+// FIXME(inherent_associated_types): Figure out which error would be more helpful here.
+
+// revisions: shadowed uncovered
+
+struct S<T>(T);
+
+trait Tr {
+    type Pr;
+}
+
+impl<T> Tr for S<T> {
+    type Pr = ();
+}
+
+#[cfg(shadowed)]
+impl S<()> {
+    type Pr = i32;
+}
+
+fn main() {
+    let _: S::<bool>::Pr = ();
+    //[shadowed]~^ ERROR associated type `Pr` not found
+    //[uncovered]~^^ ERROR ambiguous associated type
+}
diff --git a/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.shadowed.stderr b/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.shadowed.stderr
new file mode 100644
index 00000000000..3561db354c0
--- /dev/null
+++ b/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.shadowed.stderr
@@ -0,0 +1,15 @@
+error[E0220]: associated type `Pr` not found for `S<bool>` in the current scope
+  --> $DIR/not-found-self-type-differs-shadowing-trait-item.rs:28:23
+   |
+LL | struct S<T>(T);
+   | ----------- associated item `Pr` not found for this struct
+...
+LL |     let _: S::<bool>::Pr = ();
+   |                       ^^ associated item not found in `S<bool>`
+   |
+   = note: the associated type was found for
+           - `S<()>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0220`.
diff --git a/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.uncovered.stderr b/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.uncovered.stderr
new file mode 100644
index 00000000000..88c72042ce2
--- /dev/null
+++ b/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.uncovered.stderr
@@ -0,0 +1,9 @@
+error[E0223]: ambiguous associated type
+  --> $DIR/not-found-self-type-differs-shadowing-trait-item.rs:28:12
+   |
+LL |     let _: S::<bool>::Pr = ();
+   |            ^^^^^^^^^^^^^ help: use the fully-qualified path: `<S<bool> as Tr>::Pr`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0223`.
diff --git a/tests/ui/associated-inherent-types/not-found-self-type-differs.alias.stderr b/tests/ui/associated-inherent-types/not-found-self-type-differs.alias.stderr
new file mode 100644
index 00000000000..4396435a6dd
--- /dev/null
+++ b/tests/ui/associated-inherent-types/not-found-self-type-differs.alias.stderr
@@ -0,0 +1,16 @@
+error[E0220]: associated type `Proj` not found for `Family<Option<()>>` in the current scope
+  --> $DIR/not-found-self-type-differs.rs:17:34
+   |
+LL | struct Family<T>(T);
+   | ---------------- associated item `Proj` not found for this struct
+...
+LL | type Alias = Family<Option<()>>::Proj;
+   |                                  ^^^^ associated item not found in `Family<Option<()>>`
+   |
+   = note: the associated type was found for
+           - `Family<()>`
+           - `Family<Result<T, ()>>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0220`.
diff --git a/tests/ui/associated-inherent-types/not-found-self-type-differs.local.stderr b/tests/ui/associated-inherent-types/not-found-self-type-differs.local.stderr
new file mode 100644
index 00000000000..d527db02217
--- /dev/null
+++ b/tests/ui/associated-inherent-types/not-found-self-type-differs.local.stderr
@@ -0,0 +1,16 @@
+error[E0220]: associated type `Proj` not found for `Family<PathBuf>` in the current scope
+  --> $DIR/not-found-self-type-differs.rs:21:40
+   |
+LL | struct Family<T>(T);
+   | ---------------- associated item `Proj` not found for this struct
+...
+LL |     let _: Family<std::path::PathBuf>::Proj = ();
+   |                                        ^^^^ associated item not found in `Family<PathBuf>`
+   |
+   = note: the associated type was found for
+           - `Family<()>`
+           - `Family<Result<T, ()>>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0220`.
diff --git a/tests/ui/associated-inherent-types/not-found-self-type-differs.rs b/tests/ui/associated-inherent-types/not-found-self-type-differs.rs
new file mode 100644
index 00000000000..93f58dcb6e6
--- /dev/null
+++ b/tests/ui/associated-inherent-types/not-found-self-type-differs.rs
@@ -0,0 +1,22 @@
+// revisions: local alias
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct Family<T>(T);
+
+impl Family<()> {
+    type Proj = ();
+}
+
+impl<T> Family<Result<T, ()>> {
+    type Proj = Self;
+}
+
+#[cfg(alias)]
+type Alias = Family<Option<()>>::Proj; //[alias]~ ERROR associated type `Proj` not found for `Family<Option<()>>`
+
+fn main() {
+    #[cfg(local)]
+    let _: Family<std::path::PathBuf>::Proj = (); //[local]~ ERROR associated type `Proj` not found for `Family<PathBuf>`
+}
diff --git a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.rs b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.rs
new file mode 100644
index 00000000000..b00830fa1c1
--- /dev/null
+++ b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.rs
@@ -0,0 +1,21 @@
+// Regression test for issue #104251.
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct Container<T: ?Sized>(T);
+
+impl<T> Container<T> {
+    type Yield = i32;
+}
+
+struct Duple<T, U>(T, U);
+
+impl<T: Copy, U: Send> Duple<T, U> {
+    type Combination = (T, U);
+}
+
+fn main() {
+    let _: Container<[u8]>::Yield = 1; //~ ERROR the associated type `Yield` exists for `Container<[u8]>`, but its trait bounds were not satisfied
+    let _: Duple<String, std::rc::Rc<str>>::Combination; //~ ERROR the associated type `Combination` exists for `Duple<String, Rc<str>>`, but its trait bounds were not satisfied
+}
diff --git a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.stderr b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.stderr
new file mode 100644
index 00000000000..73657906761
--- /dev/null
+++ b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.stderr
@@ -0,0 +1,27 @@
+error: the associated type `Yield` exists for `Container<[u8]>`, but its trait bounds were not satisfied
+  --> $DIR/not-found-unsatisfied-bounds-0.rs:19:29
+   |
+LL | struct Container<T: ?Sized>(T);
+   | --------------------------- associated item `Yield` not found for this struct
+...
+LL |     let _: Container<[u8]>::Yield = 1;
+   |                             ^^^^^ associated type cannot be referenced on `Container<[u8]>` due to unsatisfied trait bounds
+   |
+   = note: the following trait bounds were not satisfied:
+           `[u8]: Sized`
+
+error: the associated type `Combination` exists for `Duple<String, Rc<str>>`, but its trait bounds were not satisfied
+  --> $DIR/not-found-unsatisfied-bounds-0.rs:20:45
+   |
+LL | struct Duple<T, U>(T, U);
+   | ------------------ associated item `Combination` not found for this struct
+...
+LL |     let _: Duple<String, std::rc::Rc<str>>::Combination;
+   |                                             ^^^^^^^^^^^ associated type cannot be referenced on `Duple<String, Rc<str>>` due to unsatisfied trait bounds
+   |
+   = note: the following trait bounds were not satisfied:
+           `Rc<str>: Send`
+           `String: Copy`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.rs b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.rs
new file mode 100644
index 00000000000..c80b1364ae3
--- /dev/null
+++ b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.rs
@@ -0,0 +1,18 @@
+// fail-check
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+// Test if we use the correct `ParamEnv` when proving obligations.
+
+fn parameterized<T>() {
+    let _: Container<T>::Proj = String::new(); //~ ERROR the associated type `Proj` exists for `Container<T>`, but its trait bounds were not satisfied
+}
+
+struct Container<T>(T);
+
+impl<T: Clone> Container<T> {
+    type Proj = String;
+}
+
+fn main() {}
diff --git a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.stderr b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.stderr
new file mode 100644
index 00000000000..230bfa538b4
--- /dev/null
+++ b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.stderr
@@ -0,0 +1,14 @@
+error: the associated type `Proj` exists for `Container<T>`, but its trait bounds were not satisfied
+  --> $DIR/not-found-unsatisfied-bounds-1.rs:9:26
+   |
+LL |     let _: Container<T>::Proj = String::new();
+   |                          ^^^^ associated type cannot be referenced on `Container<T>` due to unsatisfied trait bounds
+...
+LL | struct Container<T>(T);
+   | ------------------- associated item `Proj` not found for this struct
+   |
+   = note: the following trait bounds were not satisfied:
+           `T: Clone`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.rs b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.rs
new file mode 100644
index 00000000000..5b0e8de9c58
--- /dev/null
+++ b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.rs
@@ -0,0 +1,20 @@
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct S<A, B>(A, B);
+struct Featureless;
+
+trait One {}
+trait Two {}
+
+impl<T: One> S<Featureless, T> {
+    type X = ();
+}
+
+impl<T: Two> S<T, Featureless> {
+    type X = String;
+}
+
+fn main() {
+    let _: S::<Featureless, Featureless>::X; //~ ERROR the associated type `X` exists for `S<Featureless, Featureless>`, but its trait bounds were not satisfied
+}
diff --git a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr
new file mode 100644
index 00000000000..3ddab25deb5
--- /dev/null
+++ b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr
@@ -0,0 +1,20 @@
+error: the associated type `X` exists for `S<Featureless, Featureless>`, but its trait bounds were not satisfied
+  --> $DIR/not-found-unsatisfied-bounds-in-multiple-impls.rs:19:43
+   |
+LL | struct S<A, B>(A, B);
+   | -------------- associated item `X` not found for this struct
+LL | struct Featureless;
+   | ------------------
+   | |
+   | doesn't satisfy `Featureless: One`
+   | doesn't satisfy `Featureless: Two`
+...
+LL |     let _: S::<Featureless, Featureless>::X;
+   |                                           ^ associated type cannot be referenced on `S<Featureless, Featureless>` due to unsatisfied trait bounds
+   |
+   = note: the following trait bounds were not satisfied:
+           `Featureless: One`
+           `Featureless: Two`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/associated-inherent-types/substitute-params-bad.rs b/tests/ui/associated-inherent-types/substitute-params-bad.rs
new file mode 100644
index 00000000000..00eb1a14da4
--- /dev/null
+++ b/tests/ui/associated-inherent-types/substitute-params-bad.rs
@@ -0,0 +1,23 @@
+// Regression test for issue #105305 and for
+// https://github.com/rust-lang/rust/issues/107468#issuecomment-1409096700
+
+#![feature(inherent_associated_types)]
+#![allow(incomplete_features)]
+
+struct S<T>(T);
+
+impl<T, 'a> S<T> { //~ ERROR lifetime parameters must be declared prior to type and const parameters
+    type P = T;
+}
+
+struct Subj<T>(T);
+
+impl<T, S> Subj<(T, S)> {
+    type Un = (T, S);
+}
+
+fn main() {
+    type A = S<()>::P;
+
+    let _: Subj<(i32, i32)>::Un = 0i32; //~ ERROR mismatched types
+}
diff --git a/tests/ui/associated-inherent-types/substitute-params-bad.stderr b/tests/ui/associated-inherent-types/substitute-params-bad.stderr
new file mode 100644
index 00000000000..7a7808ba67b
--- /dev/null
+++ b/tests/ui/associated-inherent-types/substitute-params-bad.stderr
@@ -0,0 +1,20 @@
+error: lifetime parameters must be declared prior to type and const parameters
+  --> $DIR/substitute-params-bad.rs:9:9
+   |
+LL | impl<T, 'a> S<T> {
+   |     ----^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, T>`
+
+error[E0308]: mismatched types
+  --> $DIR/substitute-params-bad.rs:22:35
+   |
+LL |     let _: Subj<(i32, i32)>::Un = 0i32;
+   |            --------------------   ^^^^ expected `(i32, i32)`, found `i32`
+   |            |
+   |            expected due to this
+   |
+   = note: expected tuple `(i32, i32)`
+               found type `i32`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/associated-inherent-types/struct-generics.rs b/tests/ui/associated-inherent-types/substitute-params.rs
index 8952b379173..e94d6833159 100644
--- a/tests/ui/associated-inherent-types/struct-generics.rs
+++ b/tests/ui/associated-inherent-types/substitute-params.rs
@@ -9,7 +9,15 @@ impl<T> S<T> {
     type P = T;
 }
 
+impl<T> S<(T,)> {
+    type Un = T;
+}
+
 fn main() {
+    // Regression test for issue #104240.
     type A = S<()>::P;
     let _: A = ();
+
+    // Regression test for issue #107468.
+    let _: S<(i32,)>::Un = 0i32;
 }
diff --git a/tests/ui/async-await/in-trait/async-default-fn-overridden.rs b/tests/ui/async-await/in-trait/async-default-fn-overridden.rs
new file mode 100644
index 00000000000..0fd1a2703db
--- /dev/null
+++ b/tests/ui/async-await/in-trait/async-default-fn-overridden.rs
@@ -0,0 +1,66 @@
+// run-pass
+// edition:2021
+
+#![feature(async_fn_in_trait)]
+//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use
+
+use std::future::Future;
+
+trait AsyncTrait {
+    async fn default_impl() {
+        assert!(false);
+    }
+
+    async fn call_default_impl() {
+        Self::default_impl().await
+    }
+}
+
+struct AsyncType;
+
+impl AsyncTrait for AsyncType {
+    async fn default_impl() {
+        // :)
+    }
+}
+
+async fn async_main() {
+    // Should not assert false
+    AsyncType::call_default_impl().await;
+}
+
+// ------------------------------------------------------------------------- //
+// Implementation Details Below...
+
+use std::pin::Pin;
+use std::task::*;
+
+pub fn noop_waker() -> Waker {
+    let raw = RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE);
+
+    // SAFETY: the contracts for RawWaker and RawWakerVTable are upheld
+    unsafe { Waker::from_raw(raw) }
+}
+
+const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop);
+
+unsafe fn noop_clone(_p: *const ()) -> RawWaker {
+    RawWaker::new(std::ptr::null(), &NOOP_WAKER_VTABLE)
+}
+
+unsafe fn noop(_p: *const ()) {}
+
+fn main() {
+    let mut fut = async_main();
+
+    // Poll loop, just to test the future...
+    let waker = noop_waker();
+    let ctx = &mut Context::from_waker(&waker);
+
+    loop {
+        match unsafe { Pin::new_unchecked(&mut fut).poll(ctx) } {
+            Poll::Pending => {}
+            Poll::Ready(()) => break,
+        }
+    }
+}
diff --git a/tests/ui/async-await/in-trait/async-default-fn-overridden.stderr b/tests/ui/async-await/in-trait/async-default-fn-overridden.stderr
new file mode 100644
index 00000000000..61a826258d0
--- /dev/null
+++ b/tests/ui/async-await/in-trait/async-default-fn-overridden.stderr
@@ -0,0 +1,11 @@
+warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/async-default-fn-overridden.rs:4:12
+   |
+LL | #![feature(async_fn_in_trait)]
+   |            ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/unaligned_references.rs b/tests/ui/lint/unaligned_references.rs
index 04b66885e85..0c9c79c08b2 100644
--- a/tests/ui/lint/unaligned_references.rs
+++ b/tests/ui/lint/unaligned_references.rs
@@ -13,6 +13,20 @@ pub struct Packed2 {
     z: u8,
 }
 
+trait Foo {
+    fn evil(&self);
+}
+
+// Test for #108122
+#[automatically_derived]
+impl Foo for Packed2 {
+    fn evil(&self) {
+        unsafe {
+            &self.x; //~ ERROR reference to packed field
+        }
+    }
+}
+
 fn main() {
     unsafe {
         let good = Good { data: 0, ptr: &0, data2: [0, 0], aligned: [0; 32] };
@@ -37,6 +51,7 @@ fn main() {
         let _ = &packed2.x; //~ ERROR reference to packed field
         let _ = &packed2.y; // ok, has align 2 in packed(2) struct
         let _ = &packed2.z; // ok, has align 1
+        packed2.evil();
     }
 
     unsafe {
@@ -71,22 +86,10 @@ fn main() {
         #[repr(packed)]
         struct Misalign<T>(u8, T);
 
-        let m1 = Misalign(
-            0,
-            Wrapper {
-                a: U16(10),
-                b: HasDrop,
-            },
-        );
+        let m1 = Misalign(0, Wrapper { a: U16(10), b: HasDrop });
         let _ref = &m1.1.a; //~ ERROR reference to packed field
 
-        let m2 = Misalign(
-            0,
-            Wrapper2 {
-                a: U16(10),
-                b: HasDrop,
-            },
-        );
+        let m2 = Misalign(0, Wrapper2 { a: U16(10), b: HasDrop });
         let _ref = &m2.1.a; //~ ERROR reference to packed field
     }
 }
diff --git a/tests/ui/lint/unaligned_references.stderr b/tests/ui/lint/unaligned_references.stderr
index 07b59464bde..775dcac678e 100644
--- a/tests/ui/lint/unaligned_references.stderr
+++ b/tests/ui/lint/unaligned_references.stderr
@@ -1,5 +1,14 @@
 error[E0793]: reference to packed field is unaligned
-  --> $DIR/unaligned_references.rs:20:17
+  --> $DIR/unaligned_references.rs:25:13
+   |
+LL |             &self.x;
+   |             ^^^^^^^
+   |
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+error[E0793]: reference to packed field is unaligned
+  --> $DIR/unaligned_references.rs:34:17
    |
 LL |         let _ = &good.ptr;
    |                 ^^^^^^^^^
@@ -8,7 +17,7 @@ LL |         let _ = &good.ptr;
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 error[E0793]: reference to packed field is unaligned
-  --> $DIR/unaligned_references.rs:21:17
+  --> $DIR/unaligned_references.rs:35:17
    |
 LL |         let _ = &good.data;
    |                 ^^^^^^^^^^
@@ -17,7 +26,7 @@ LL |         let _ = &good.data;
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 error[E0793]: reference to packed field is unaligned
-  --> $DIR/unaligned_references.rs:23:17
+  --> $DIR/unaligned_references.rs:37:17
    |
 LL |         let _ = &good.data as *const _;
    |                 ^^^^^^^^^^
@@ -26,7 +35,7 @@ LL |         let _ = &good.data as *const _;
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 error[E0793]: reference to packed field is unaligned
-  --> $DIR/unaligned_references.rs:24:27
+  --> $DIR/unaligned_references.rs:38:27
    |
 LL |         let _: *const _ = &good.data;
    |                           ^^^^^^^^^^
@@ -35,7 +44,7 @@ LL |         let _: *const _ = &good.data;
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 error[E0793]: reference to packed field is unaligned
-  --> $DIR/unaligned_references.rs:26:17
+  --> $DIR/unaligned_references.rs:40:17
    |
 LL |         let _ = good.data.clone();
    |                 ^^^^^^^^^^^^^^^^^
@@ -44,7 +53,7 @@ LL |         let _ = good.data.clone();
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 error[E0793]: reference to packed field is unaligned
-  --> $DIR/unaligned_references.rs:28:17
+  --> $DIR/unaligned_references.rs:42:17
    |
 LL |         let _ = &good.data2[0];
    |                 ^^^^^^^^^^^^^^
@@ -53,7 +62,7 @@ LL |         let _ = &good.data2[0];
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 error[E0793]: reference to packed field is unaligned
-  --> $DIR/unaligned_references.rs:37:17
+  --> $DIR/unaligned_references.rs:51:17
    |
 LL |         let _ = &packed2.x;
    |                 ^^^^^^^^^^
@@ -62,7 +71,7 @@ LL |         let _ = &packed2.x;
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 error[E0793]: reference to packed field is unaligned
-  --> $DIR/unaligned_references.rs:81:20
+  --> $DIR/unaligned_references.rs:90:20
    |
 LL |         let _ref = &m1.1.a;
    |                    ^^^^^^^
@@ -71,7 +80,7 @@ LL |         let _ref = &m1.1.a;
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 error[E0793]: reference to packed field is unaligned
-  --> $DIR/unaligned_references.rs:90:20
+  --> $DIR/unaligned_references.rs:93:20
    |
 LL |         let _ref = &m2.1.a;
    |                    ^^^^^^^
@@ -79,6 +88,6 @@ LL |         let _ref = &m2.1.a;
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
-error: aborting due to 9 previous errors
+error: aborting due to 10 previous errors
 
 For more information about this error, try `rustc --explain E0793`.
diff --git a/tests/ui/mir/field-projection-invariant.rs b/tests/ui/mir/field-projection-invariant.rs
new file mode 100644
index 00000000000..b5d6add043c
--- /dev/null
+++ b/tests/ui/mir/field-projection-invariant.rs
@@ -0,0 +1,24 @@
+// build-pass
+struct Inv<'a>(&'a mut &'a ());
+enum Foo<T> {
+    Bar,
+    Var(T),
+}
+type Supertype = Foo<for<'a> fn(Inv<'a>, Inv<'a>)>;
+
+fn foo(x: Foo<for<'a, 'b> fn(Inv<'a>, Inv<'b>)>) {
+    match x {
+        Supertype::Bar => {}
+        Supertype::Var(x) => {}
+    }
+}
+
+fn foo_nested(x: Foo<Foo<for<'a, 'b> fn(Inv<'a>, Inv<'b>)>>) {
+    match x {
+        Foo::Bar => {}
+        Foo::Var(Supertype::Bar) => {}
+        Foo::Var(Supertype::Var(x)) => {}
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/mir/field-projection-mutating-context.rs b/tests/ui/mir/field-projection-mutating-context.rs
new file mode 100644
index 00000000000..a1002c088dc
--- /dev/null
+++ b/tests/ui/mir/field-projection-mutating-context.rs
@@ -0,0 +1,19 @@
+use std::sync::Mutex;
+
+static GLOBAL: Mutex<&'static str> = Mutex::new("global str");
+
+struct Foo<T>(T); // `T` is covariant.
+
+fn foo() {
+    let mut x: Foo<for<'a> fn(&'a str)> = Foo(|_| ());
+    let Foo(ref mut y): Foo<fn(&'static str)> = x;
+    //~^ ERROR mismatched types
+    *y = |s| *GLOBAL.lock().unwrap() = s;
+    let string = String::from("i am shortlived");
+    (x.0)(&string);
+}
+
+fn main() {
+    foo();
+    println!("{}", GLOBAL.lock().unwrap());
+}
diff --git a/tests/ui/mir/field-projection-mutating-context.stderr b/tests/ui/mir/field-projection-mutating-context.stderr
new file mode 100644
index 00000000000..9b18b3427ad
--- /dev/null
+++ b/tests/ui/mir/field-projection-mutating-context.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+  --> $DIR/field-projection-mutating-context.rs:9:13
+   |
+LL |     let Foo(ref mut y): Foo<fn(&'static str)> = x;
+   |             ^^^^^^^^^ one type is more general than the other
+   |
+   = note: expected fn pointer `for<'a> fn(&'a str)`
+              found fn pointer `fn(&str)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/mir/field-projection-mutating-context2.rs b/tests/ui/mir/field-projection-mutating-context2.rs
new file mode 100644
index 00000000000..dd9c44a16d3
--- /dev/null
+++ b/tests/ui/mir/field-projection-mutating-context2.rs
@@ -0,0 +1,17 @@
+use std::sync::Mutex;
+
+static GLOBAL: Mutex<&'static str> = Mutex::new("global str");
+
+struct Foo<T>(T); // `T` is covariant.
+
+fn foo<'a>(mut x: Foo<fn(&'a str)>, string: &'a str) {
+    let Foo(ref mut y): Foo<fn(&'static str)> = x;
+    //~^ ERROR lifetime may not live long enough
+    *y = |s| *GLOBAL.lock().unwrap() = s;
+    (x.0)(&string);
+}
+
+fn main() {
+    foo(Foo(|_| ()), &String::from("i am shortlived"));
+    println!("{}", GLOBAL.lock().unwrap());
+}
diff --git a/tests/ui/mir/field-projection-mutating-context2.stderr b/tests/ui/mir/field-projection-mutating-context2.stderr
new file mode 100644
index 00000000000..a7b66fe10ce
--- /dev/null
+++ b/tests/ui/mir/field-projection-mutating-context2.stderr
@@ -0,0 +1,10 @@
+error: lifetime may not live long enough
+  --> $DIR/field-projection-mutating-context2.rs:8:25
+   |
+LL | fn foo<'a>(mut x: Foo<fn(&'a str)>, string: &'a str) {
+   |        -- lifetime `'a` defined here
+LL |     let Foo(ref mut y): Foo<fn(&'static str)> = x;
+   |                         ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/mir/field-ty-ascription-enums.rs b/tests/ui/mir/field-ty-ascription-enums.rs
new file mode 100644
index 00000000000..179af617090
--- /dev/null
+++ b/tests/ui/mir/field-ty-ascription-enums.rs
@@ -0,0 +1,15 @@
+// build-pass
+
+enum Foo<T> {
+    Var(T),
+} // `T` is covariant.
+
+fn foo<'b>(x: Foo<for<'a> fn(&'a ())>) {
+    let Foo::Var(x): Foo<fn(&'b ())> = x;
+}
+
+fn foo_nested<'b>(x: Foo<Foo<for<'a> fn(&'a ())>>) {
+    let Foo::Var(Foo::Var(x)): Foo<Foo<fn(&'b ())>> = x;
+}
+
+fn main() {}
diff --git a/tests/ui/mir/field-ty-ascription.rs b/tests/ui/mir/field-ty-ascription.rs
new file mode 100644
index 00000000000..178c7916bc5
--- /dev/null
+++ b/tests/ui/mir/field-ty-ascription.rs
@@ -0,0 +1,37 @@
+// build-pass
+
+struct Foo<T>(T); // `T` is covariant.
+
+struct Bar<T> {
+    x: T,
+} // `T` is covariant.
+
+fn bar<'b>(x: Bar<for<'a> fn(&'a ())>) {
+    let Bar { x }: Bar<fn(&'b ())> = x;
+}
+
+fn bar_nested<'b>(x: Bar<Bar<for<'a> fn(&'a ())>>) {
+    let Bar { x: Bar { x } }: Bar<Bar<fn(&'b ())>> = x;
+}
+
+fn bar_foo_nested<'b>(x: Bar<Foo<for<'a> fn(&'a ())>>) {
+    let Bar { x: Foo ( x ) }: Bar<Foo<fn(&'b ())>> = x;
+}
+
+fn foo<'b>(x: Foo<for<'a> fn(&'a ())>) {
+    let Foo(y): Foo<fn(&'b ())> = x;
+}
+
+fn foo_nested<'b>(x: Foo<Foo<for<'a> fn(&'a ())>>) {
+    let Foo(Foo(y)): Foo<Foo<fn(&'b ())>> = x;
+}
+
+fn tuple<'b>(x: (u32, for<'a> fn(&'a ()))) {
+    let (_, y): (u32, fn(&'b ())) = x;
+}
+
+fn tuple_nested<'b>(x: (u32, (u32, for<'a> fn(&'a ())))) {
+    let (_, (_, y)): (u32, (u32, fn(&'b ()))) = x;
+}
+
+fn main() {}