about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-12-20 13:58:08 +0000
committerbors <bors@rust-lang.org>2022-12-20 13:58:08 +0000
commit65bd2a6a73d6a74fb1266a1d96b23de8810a5fb2 (patch)
tree6d8890ea02b4e081f670c45d95809c568a502875
parent8a746f4ac3a489efb724cde813607f3b96c2df7b (diff)
parent8db5dd49834d197de3db7d0a201df5bc493833cb (diff)
downloadrust-65bd2a6a73d6a74fb1266a1d96b23de8810a5fb2.tar.gz
rust-65bd2a6a73d6a74fb1266a1d96b23de8810a5fb2.zip
Auto merge of #105951 - matthiaskrgr:rollup-aqxz888, r=matthiaskrgr
Rollup of 7 pull requests

Successful merges:

 - #105835 (Refactor post borrowck cleanup passes)
 - #105930 (Disable `NormalizeArrayLen`)
 - #105938 (Update coerce_unsized tracking issue from #27732 to #18598)
 - #105939 (Improve description of struct-fields GUI test)
 - #105943 (Add regression test for #102206)
 - #105944 (Add regression test for #80816)
 - #105945 (Add regression test for #57404)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs65
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs5
-rw-r--r--compiler/rustc_mir_transform/src/normalize_array_len.rs3
-rw-r--r--compiler/rustc_mir_transform/src/remove_false_edges.rs29
-rw-r--r--library/alloc/src/boxed.rs2
-rw-r--r--library/alloc/src/rc.rs4
-rw-r--r--library/alloc/src/sync.rs4
-rw-r--r--library/core/src/cell.rs12
-rw-r--r--library/core/src/marker.rs2
-rw-r--r--library/core/src/ops/mod.rs2
-rw-r--r--library/core/src/ops/unsize.rs20
-rw-r--r--library/core/src/ptr/non_null.rs2
-rw-r--r--src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff7
-rw-r--r--src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff7
-rw-r--r--src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff12
-rw-r--r--src/test/mir-opt/lower_array_len_e2e.rs2
-rw-r--r--src/test/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff (renamed from src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff)14
-rw-r--r--src/test/mir-opt/remove_fake_borrows.rs2
-rw-r--r--src/test/rustdoc-gui/struct-fields.goml2
-rw-r--r--src/test/ui/async-await/issues/issue-102206.rs8
-rw-r--r--src/test/ui/async-await/issues/issue-102206.stderr23
-rw-r--r--src/test/ui/inference/issue-80816.rs54
-rw-r--r--src/test/ui/inference/issue-80816.stderr27
-rw-r--r--src/test/ui/typeck/issue-57404.rs7
-rw-r--r--src/test/ui/typeck/issue-57404.stderr16
25 files changed, 207 insertions, 124 deletions
diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs
index 3378923c22c..d435d3ee69b 100644
--- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs
+++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs
@@ -1,39 +1,44 @@
-//! This module provides a pass to replacing the following statements with
-//! [`Nop`]s
+//! This module provides a pass that removes parts of MIR that are no longer relevant after
+//! analysis phase and borrowck. In particular, it removes false edges, user type annotations and
+//! replaces following statements with [`Nop`]s:
 //!
 //!   - [`AscribeUserType`]
 //!   - [`FakeRead`]
 //!   - [`Assign`] statements with a [`Shallow`] borrow
 //!
-//! The `CleanFakeReadsAndBorrows` "pass" is actually implemented as two
-//! traversals (aka visits) of the input MIR. The first traversal,
-//! `DeleteAndRecordFakeReads`, deletes the fake reads and finds the
-//! temporaries read by [`ForMatchGuard`] reads, and `DeleteFakeBorrows`
-//! deletes the initialization of those temporaries.
-//!
 //! [`AscribeUserType`]: rustc_middle::mir::StatementKind::AscribeUserType
-//! [`Shallow`]: rustc_middle::mir::BorrowKind::Shallow
-//! [`FakeRead`]: rustc_middle::mir::StatementKind::FakeRead
 //! [`Assign`]: rustc_middle::mir::StatementKind::Assign
-//! [`ForMatchGuard`]: rustc_middle::mir::FakeReadCause::ForMatchGuard
+//! [`FakeRead`]: rustc_middle::mir::StatementKind::FakeRead
 //! [`Nop`]: rustc_middle::mir::StatementKind::Nop
+//! [`Shallow`]: rustc_middle::mir::BorrowKind::Shallow
 
 use crate::MirPass;
-use rustc_middle::mir::visit::MutVisitor;
-use rustc_middle::mir::{Body, BorrowKind, Location, Rvalue};
-use rustc_middle::mir::{Statement, StatementKind};
+use rustc_middle::mir::{Body, BorrowKind, Rvalue, StatementKind, TerminatorKind};
 use rustc_middle::ty::TyCtxt;
 
-pub struct CleanupNonCodegenStatements;
+pub struct CleanupPostBorrowck;
 
-pub struct DeleteNonCodegenStatements<'tcx> {
-    tcx: TyCtxt<'tcx>,
-}
+impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck {
+    fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+        for basic_block in body.basic_blocks.as_mut() {
+            for statement in basic_block.statements.iter_mut() {
+                match statement.kind {
+                    StatementKind::AscribeUserType(..)
+                    | StatementKind::Assign(box (_, Rvalue::Ref(_, BorrowKind::Shallow, _)))
+                    | StatementKind::FakeRead(..) => statement.make_nop(),
+                    _ => (),
+                }
+            }
+            let terminator = basic_block.terminator_mut();
+            match terminator.kind {
+                TerminatorKind::FalseEdge { real_target, .. }
+                | TerminatorKind::FalseUnwind { real_target, .. } => {
+                    terminator.kind = TerminatorKind::Goto { target: real_target };
+                }
+                _ => {}
+            }
+        }
 
-impl<'tcx> MirPass<'tcx> for CleanupNonCodegenStatements {
-    fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        let mut delete = DeleteNonCodegenStatements { tcx };
-        delete.visit_body_preserves_cfg(body);
         body.user_type_annotations.raw.clear();
 
         for decl in &mut body.local_decls {
@@ -41,19 +46,3 @@ impl<'tcx> MirPass<'tcx> for CleanupNonCodegenStatements {
         }
     }
 }
-
-impl<'tcx> MutVisitor<'tcx> for DeleteNonCodegenStatements<'tcx> {
-    fn tcx(&self) -> TyCtxt<'tcx> {
-        self.tcx
-    }
-
-    fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) {
-        match statement.kind {
-            StatementKind::AscribeUserType(..)
-            | StatementKind::Assign(box (_, Rvalue::Ref(_, BorrowKind::Shallow, _)))
-            | StatementKind::FakeRead(..) => statement.make_nop(),
-            _ => (),
-        }
-        self.super_statement(statement, location);
-    }
-}
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 93200b28830..aba5a8580f1 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -77,8 +77,6 @@ mod match_branches;
 mod multiple_return_terminators;
 mod normalize_array_len;
 mod nrvo;
-// This pass is public to allow external drivers to perform MIR cleanup
-pub mod remove_false_edges;
 mod remove_noop_landing_pads;
 mod remove_storage_markers;
 mod remove_uninit_drops;
@@ -494,10 +492,9 @@ fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>
 /// After this series of passes, no lifetime analysis based on borrowing can be done.
 fn run_analysis_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
     let passes: &[&dyn MirPass<'tcx>] = &[
-        &remove_false_edges::RemoveFalseEdges,
+        &cleanup_post_borrowck::CleanupPostBorrowck,
         &simplify_branches::SimplifyConstCondition::new("initial"),
         &remove_noop_landing_pads::RemoveNoopLandingPads,
-        &cleanup_post_borrowck::CleanupNonCodegenStatements,
         &simplify::SimplifyCfg::new("early-opt"),
         &deref_separator::Derefer,
     ];
diff --git a/compiler/rustc_mir_transform/src/normalize_array_len.rs b/compiler/rustc_mir_transform/src/normalize_array_len.rs
index a159e617178..1708b287e56 100644
--- a/compiler/rustc_mir_transform/src/normalize_array_len.rs
+++ b/compiler/rustc_mir_transform/src/normalize_array_len.rs
@@ -16,7 +16,8 @@ pub struct NormalizeArrayLen;
 
 impl<'tcx> MirPass<'tcx> for NormalizeArrayLen {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
-        sess.mir_opt_level() >= 4
+        // See #105929
+        sess.mir_opt_level() >= 4 && sess.opts.unstable_opts.unsound_mir_opts
     }
 
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
diff --git a/compiler/rustc_mir_transform/src/remove_false_edges.rs b/compiler/rustc_mir_transform/src/remove_false_edges.rs
deleted file mode 100644
index 71f5ccf7e24..00000000000
--- a/compiler/rustc_mir_transform/src/remove_false_edges.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-use rustc_middle::mir::{Body, TerminatorKind};
-use rustc_middle::ty::TyCtxt;
-
-use crate::MirPass;
-
-/// Removes `FalseEdge` and `FalseUnwind` terminators from the MIR.
-///
-/// These are only needed for borrow checking, and can be removed afterwards.
-///
-/// FIXME: This should probably have its own MIR phase.
-pub struct RemoveFalseEdges;
-
-impl<'tcx> MirPass<'tcx> for RemoveFalseEdges {
-    fn run_pass(&self, _: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        for block in body.basic_blocks_mut() {
-            let terminator = block.terminator_mut();
-            terminator.kind = match terminator.kind {
-                TerminatorKind::FalseEdge { real_target, .. } => {
-                    TerminatorKind::Goto { target: real_target }
-                }
-                TerminatorKind::FalseUnwind { real_target, .. } => {
-                    TerminatorKind::Goto { target: real_target }
-                }
-
-                _ => continue,
-            }
-        }
-    }
-}
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index e5f6b0c0c65..b154688fb08 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -2033,7 +2033,7 @@ impl<Args: Tuple, F: Fn<Args> + ?Sized, A: Allocator> Fn<Args> for Box<F, A> {
     }
 }
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Box<U, A>> for Box<T, A> {}
 
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 38e31b1802a..80a5913daa6 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -336,7 +336,7 @@ impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Rc<T> {}
 #[stable(feature = "rc_ref_unwind_safe", since = "1.58.0")]
 impl<T: RefUnwindSafe + ?Sized> RefUnwindSafe for Rc<T> {}
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Rc<U>> for Rc<T> {}
 
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
@@ -2190,7 +2190,7 @@ impl<T: ?Sized> !marker::Send for Weak<T> {}
 #[stable(feature = "rc_weak", since = "1.4.0")]
 impl<T: ?Sized> !marker::Sync for Weak<T> {}
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {}
 
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index f7dc4d1094c..ddcd863aa3e 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -254,7 +254,7 @@ unsafe impl<T: ?Sized + Sync + Send> Sync for Arc<T> {}
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Arc<T> {}
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}
 
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
@@ -306,7 +306,7 @@ unsafe impl<T: ?Sized + Sync + Send> Send for Weak<T> {}
 #[stable(feature = "arc_weak", since = "1.4.0")]
 unsafe impl<T: ?Sized + Sync + Send> Sync for Weak<T> {}
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {}
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Weak<U>> for Weak<T> {}
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 47cce2aa39b..b4e173ce03d 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -568,7 +568,7 @@ impl<T: Default> Cell<T> {
     }
 }
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: CoerceUnsized<U>, U> CoerceUnsized<Cell<U>> for Cell<T> {}
 
 impl<T> Cell<[T]> {
@@ -1266,7 +1266,7 @@ impl<T> const From<T> for RefCell<T> {
     }
 }
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: CoerceUnsized<U>, U> CoerceUnsized<RefCell<U>> for RefCell<T> {}
 
 struct BorrowRef<'b> {
@@ -1492,7 +1492,7 @@ impl<'b, T: ?Sized> Ref<'b, T> {
     }
 }
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<'b, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Ref<'b, U>> for Ref<'b, T> {}
 
 #[stable(feature = "std_guard_impls", since = "1.20.0")]
@@ -1738,7 +1738,7 @@ impl<T: ?Sized> DerefMut for RefMut<'_, T> {
     }
 }
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<'b, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<RefMut<'b, U>> for RefMut<'b, T> {}
 
 #[stable(feature = "std_guard_impls", since = "1.20.0")]
@@ -2074,7 +2074,7 @@ impl<T> const From<T> for UnsafeCell<T> {
     }
 }
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: CoerceUnsized<U>, U> CoerceUnsized<UnsafeCell<U>> for UnsafeCell<T> {}
 
 /// [`UnsafeCell`], but [`Sync`].
@@ -2164,7 +2164,7 @@ impl<T> const From<T> for SyncUnsafeCell<T> {
     }
 }
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 //#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
 impl<T: CoerceUnsized<U>, U> CoerceUnsized<SyncUnsafeCell<U>> for SyncUnsafeCell<T> {}
 
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 42c34280197..4b85c1112b9 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -126,7 +126,7 @@ pub trait Sized {
 /// [`Rc`]: ../../std/rc/struct.Rc.html
 /// [RFC982]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
 /// [nomicon-coerce]: ../../nomicon/coercions.html
-#[unstable(feature = "unsize", issue = "27732")]
+#[unstable(feature = "unsize", issue = "18598")]
 #[lang = "unsize"]
 #[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)]
 pub trait Unsize<T: ?Sized> {
diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs
index eb2a92f4644..97d9b750d92 100644
--- a/library/core/src/ops/mod.rs
+++ b/library/core/src/ops/mod.rs
@@ -201,7 +201,7 @@ pub(crate) use self::try_trait::{ChangeOutputType, NeverShortCircuit};
 #[unstable(feature = "generator_trait", issue = "43122")]
 pub use self::generator::{Generator, GeneratorState};
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 pub use self::unsize::CoerceUnsized;
 
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
diff --git a/library/core/src/ops/unsize.rs b/library/core/src/ops/unsize.rs
index a920b9165c1..b51f12580ea 100644
--- a/library/core/src/ops/unsize.rs
+++ b/library/core/src/ops/unsize.rs
@@ -31,41 +31,41 @@ use crate::marker::Unsize;
 /// [dst-coerce]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
 /// [unsize]: crate::marker::Unsize
 /// [nomicon-coerce]: ../../nomicon/coercions.html
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 #[lang = "coerce_unsized"]
 pub trait CoerceUnsized<T: ?Sized> {
     // Empty.
 }
 
 // &mut T -> &mut U
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
 // &mut T -> &U
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {}
 // &mut T -> *mut U
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {}
 // &mut T -> *const U
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {}
 
 // &T -> &U
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
 // &T -> *const U
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {}
 
 // *mut T -> *mut U
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
 // *mut T -> *const U
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
 
 // *const T -> *const U
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
 
 /// `DispatchFromDyn` is used in the implementation of object safety checks (specifically allowing
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index c4348169c78..af79d4bbd83 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -712,7 +712,7 @@ impl<T: ?Sized> const Clone for NonNull<T> {
 #[stable(feature = "nonnull", since = "1.25.0")]
 impl<T: ?Sized> Copy for NonNull<T> {}
 
-#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[unstable(feature = "coerce_unsized", issue = "18598")]
 impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {}
 
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
index 624376769b7..44445731e72 100644
--- a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
+++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.32bit.diff
@@ -12,7 +12,6 @@
       let mut _7: usize;                   // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33
       let mut _8: bool;                    // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33
       let mut _9: &[u32; 3];               // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
-      let mut _10: &[u32; 3];              // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
   
       bb0: {
           StorageLive(_1);                 // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
@@ -25,16 +24,14 @@
                                            // + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
           _4 = _9;                         // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
           _3 = _4;                         // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
-          StorageLive(_10);                // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
-          _10 = _3;                        // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
           _2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
           StorageDead(_3);                 // scope 0 at $DIR/slice_len.rs:+1:18: +1:19
           StorageLive(_6);                 // scope 0 at $DIR/slice_len.rs:+1:31: +1:32
           _6 = const 1_usize;              // scope 0 at $DIR/slice_len.rs:+1:31: +1:32
-          _7 = const 3_usize;              // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
-          StorageDead(_10);                // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+-         _7 = Len((*_2));                 // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
 -         _8 = Lt(_6, _7);                 // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
++         _7 = const 3_usize;              // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
 +         _8 = const true;                 // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
       }
diff --git a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
index 624376769b7..44445731e72 100644
--- a/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
+++ b/src/test/mir-opt/const_prop/slice_len.main.ConstProp.64bit.diff
@@ -12,7 +12,6 @@
       let mut _7: usize;                   // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33
       let mut _8: bool;                    // in scope 0 at $DIR/slice_len.rs:+1:5: +1:33
       let mut _9: &[u32; 3];               // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
-      let mut _10: &[u32; 3];              // in scope 0 at $DIR/slice_len.rs:+1:6: +1:19
   
       bb0: {
           StorageLive(_1);                 // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
@@ -25,16 +24,14 @@
                                            // + literal: Const { ty: &[u32; 3], val: Unevaluated(main, [], Some(promoted[0])) }
           _4 = _9;                         // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
           _3 = _4;                         // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
-          StorageLive(_10);                // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
-          _10 = _3;                        // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
           _2 = move _3 as &[u32] (Pointer(Unsize)); // scope 0 at $DIR/slice_len.rs:+1:6: +1:19
           StorageDead(_3);                 // scope 0 at $DIR/slice_len.rs:+1:18: +1:19
           StorageLive(_6);                 // scope 0 at $DIR/slice_len.rs:+1:31: +1:32
           _6 = const 1_usize;              // scope 0 at $DIR/slice_len.rs:+1:31: +1:32
-          _7 = const 3_usize;              // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
-          StorageDead(_10);                // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
+-         _7 = Len((*_2));                 // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
 -         _8 = Lt(_6, _7);                 // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
 -         assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, _6) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
++         _7 = const 3_usize;              // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
 +         _8 = const true;                 // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
 +         assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> bb1; // scope 0 at $DIR/slice_len.rs:+1:5: +1:33
       }
diff --git a/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff b/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff
index 2368c021eda..e97b46f6ecc 100644
--- a/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff
+++ b/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff
@@ -22,7 +22,6 @@
       let mut _20: *const T;               // in scope 0 at $DIR/issue_76432.rs:+3:70: +3:84
       let mut _21: *const T;               // in scope 0 at $DIR/issue_76432.rs:+3:70: +3:84
       let mut _22: !;                      // in scope 0 at $SRC_DIR/core/src/panic.rs:LL:COL
-      let mut _23: &[T; 3];                // in scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
       scope 1 {
           debug v => _2;                   // in scope 1 at $DIR/issue_76432.rs:+1:9: +1:10
           let _13: &T;                     // in scope 1 at $DIR/issue_76432.rs:+3:10: +3:16
@@ -52,17 +51,16 @@
           StorageDead(_6);                 // scope 0 at $DIR/issue_76432.rs:+1:28: +1:29
           _4 = &_5;                        // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
           _3 = _4;                         // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
-          StorageLive(_23);                // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
-          _23 = _3;                        // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
           _2 = move _3 as &[T] (Pointer(Unsize)); // scope 0 at $DIR/issue_76432.rs:+1:19: +1:29
           StorageDead(_3);                 // scope 0 at $DIR/issue_76432.rs:+1:28: +1:29
           StorageDead(_4);                 // scope 0 at $DIR/issue_76432.rs:+1:29: +1:30
           StorageLive(_9);                 // scope 1 at $DIR/issue_76432.rs:+2:5: +5:6
-          _10 = const 3_usize;             // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
-          StorageDead(_23);                // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
+          _10 = Len((*_2));                // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
           _11 = const 3_usize;             // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
-          _12 = const true;                // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
-          goto -> bb2;                     // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
+-         _12 = Eq(move _10, const 3_usize); // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
+-         switchInt(move _12) -> [0: bb1, otherwise: bb2]; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
++         nop;                             // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
++         switchInt(move _10) -> [3: bb2, otherwise: bb1]; // scope 1 at $DIR/issue_76432.rs:+3:9: +3:33
       }
   
       bb1: {
diff --git a/src/test/mir-opt/lower_array_len_e2e.rs b/src/test/mir-opt/lower_array_len_e2e.rs
index 49b35d509f0..d8e4e521ee6 100644
--- a/src/test/mir-opt/lower_array_len_e2e.rs
+++ b/src/test/mir-opt/lower_array_len_e2e.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Z mir-opt-level=4
+// compile-flags: -Z mir-opt-level=4 -Zunsound-mir-opts
 
 // EMIT_MIR lower_array_len_e2e.array_bound.PreCodegen.after.mir
 pub fn array_bound<const N: usize>(index: usize, slice: &[u8; N]) -> u8 {
diff --git a/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff b/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff
index bb5920b28ca..0b3da98a5a1 100644
--- a/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff
+++ b/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff
@@ -1,5 +1,5 @@
-- // MIR for `match_guard` before CleanupNonCodegenStatements
-+ // MIR for `match_guard` after CleanupNonCodegenStatements
+- // MIR for `match_guard` before CleanupPostBorrowck
++ // MIR for `match_guard` after CleanupPostBorrowck
   
   fn match_guard(_1: Option<&&i32>, _2: bool) -> i32 {
       debug x => _1;                       // in scope 0 at $DIR/remove_fake_borrows.rs:+0:16: +0:17
@@ -29,7 +29,8 @@
       }
   
       bb3: {
-          goto -> bb4;                     // scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16
+-         falseEdge -> [real: bb4, imaginary: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16
++         goto -> bb4;                     // scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16
       }
   
       bb4: {
@@ -62,15 +63,12 @@
   
       bb6: {
           StorageDead(_8);                 // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
-          goto -> bb1;                     // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
+-         falseEdge -> [real: bb1, imaginary: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
++         goto -> bb1;                     // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
       }
   
       bb7: {
           return;                          // scope 0 at $DIR/remove_fake_borrows.rs:+5:2: +5:2
       }
-  
-      bb8 (cleanup): {
-          resume;                          // scope 0 at $DIR/remove_fake_borrows.rs:+0:1: +5:2
-      }
   }
   
diff --git a/src/test/mir-opt/remove_fake_borrows.rs b/src/test/mir-opt/remove_fake_borrows.rs
index a980f386b69..d26c6f5d7e5 100644
--- a/src/test/mir-opt/remove_fake_borrows.rs
+++ b/src/test/mir-opt/remove_fake_borrows.rs
@@ -2,7 +2,7 @@
 
 // ignore-wasm32-bare compiled with panic=abort by default
 
-// EMIT_MIR remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff
+// EMIT_MIR remove_fake_borrows.match_guard.CleanupPostBorrowck.diff
 fn match_guard(x: Option<&&i32>, c: bool) -> i32 {
     match x {
         Some(0) if c => 0,
diff --git a/src/test/rustdoc-gui/struct-fields.goml b/src/test/rustdoc-gui/struct-fields.goml
index 3ec60b58cfd..fa3e16cb81e 100644
--- a/src/test/rustdoc-gui/struct-fields.goml
+++ b/src/test/rustdoc-gui/struct-fields.goml
@@ -1,5 +1,5 @@
+// This test ensures that each field is on its own line (In other words, they have display: block).
 goto: "file://" + |DOC_PATH| + "/test_docs/struct.StructWithPublicUndocumentedFields.html"
 
-// Both fields must be on their own line. In other words, they have display: block.
 store-property: (first_top, "//*[@id='structfield.first']", "offsetTop")
 assert-property-false: ("//*[@id='structfield.second']", { "offsetTop": |first_top| })
diff --git a/src/test/ui/async-await/issues/issue-102206.rs b/src/test/ui/async-await/issues/issue-102206.rs
new file mode 100644
index 00000000000..a3a2ebc5896
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-102206.rs
@@ -0,0 +1,8 @@
+// edition:2021
+
+async fn foo() {}
+
+fn main() {
+    std::mem::size_of_val(foo());
+    //~^ ERROR: mismatched types
+}
diff --git a/src/test/ui/async-await/issues/issue-102206.stderr b/src/test/ui/async-await/issues/issue-102206.stderr
new file mode 100644
index 00000000000..2ab790ac761
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-102206.stderr
@@ -0,0 +1,23 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-102206.rs:6:27
+   |
+LL |     std::mem::size_of_val(foo());
+   |     --------------------- ^^^^^
+   |     |                     |
+   |     |                     expected reference, found opaque type
+   |     |                     help: consider borrowing here: `&foo()`
+   |     arguments to this function are incorrect
+   |
+note: while checking the return type of the `async fn`
+  --> $DIR/issue-102206.rs:3:16
+   |
+LL | async fn foo() {}
+   |                ^ checked the `Output` of this `async fn`, found opaque type
+   = note: expected reference `&_`
+            found opaque type `impl Future<Output = ()>`
+note: function defined here
+  --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/inference/issue-80816.rs b/src/test/ui/inference/issue-80816.rs
new file mode 100644
index 00000000000..ead320a4fe4
--- /dev/null
+++ b/src/test/ui/inference/issue-80816.rs
@@ -0,0 +1,54 @@
+#![allow(unreachable_code)]
+
+use std::marker::PhantomData;
+use std::ops::Deref;
+use std::sync::Arc;
+
+pub struct Guard<T> {
+    _phantom: PhantomData<T>,
+}
+impl<T> Deref for Guard<T> {
+    type Target = T;
+    fn deref(&self) -> &T {
+        unimplemented!()
+    }
+}
+
+pub struct DirectDeref<T>(T);
+impl<T> Deref for DirectDeref<Arc<T>> {
+    type Target = T;
+    fn deref(&self) -> &T {
+        unimplemented!()
+    }
+}
+
+pub trait Access<T> {
+    type Guard: Deref<Target = T>;
+    fn load(&self) -> Self::Guard {
+        unimplemented!()
+    }
+}
+impl<T, A: Access<T>, P: Deref<Target = A>> Access<T> for P {
+    //~^ NOTE: required for `Arc<ArcSwapAny<Arc<usize>>>` to implement `Access<_>`
+    type Guard = A::Guard;
+}
+impl<T> Access<T> for ArcSwapAny<T> {
+    //~^ NOTE: multiple `impl`s satisfying `ArcSwapAny<Arc<usize>>: Access<_>` found
+    type Guard = Guard<T>;
+}
+impl<T> Access<T> for ArcSwapAny<Arc<T>> {
+    type Guard = DirectDeref<Arc<T>>;
+}
+
+pub struct ArcSwapAny<T> {
+    _phantom_arc: PhantomData<T>,
+}
+
+pub fn foo() {
+    let s: Arc<ArcSwapAny<Arc<usize>>> = unimplemented!();
+    let guard: Guard<Arc<usize>> = s.load();
+    //~^ ERROR: type annotations needed
+    //~| HELP: try using a fully qualified path to specify the expected types
+}
+
+fn main() {}
diff --git a/src/test/ui/inference/issue-80816.stderr b/src/test/ui/inference/issue-80816.stderr
new file mode 100644
index 00000000000..bd833340df4
--- /dev/null
+++ b/src/test/ui/inference/issue-80816.stderr
@@ -0,0 +1,27 @@
+error[E0283]: type annotations needed
+  --> $DIR/issue-80816.rs:49:38
+   |
+LL |     let guard: Guard<Arc<usize>> = s.load();
+   |                                      ^^^^
+   |
+note: multiple `impl`s satisfying `ArcSwapAny<Arc<usize>>: Access<_>` found
+  --> $DIR/issue-80816.rs:35:1
+   |
+LL | impl<T> Access<T> for ArcSwapAny<T> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | impl<T> Access<T> for ArcSwapAny<Arc<T>> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: required for `Arc<ArcSwapAny<Arc<usize>>>` to implement `Access<_>`
+  --> $DIR/issue-80816.rs:31:45
+   |
+LL | impl<T, A: Access<T>, P: Deref<Target = A>> Access<T> for P {
+   |                                             ^^^^^^^^^     ^
+help: try using a fully qualified path to specify the expected types
+   |
+LL |     let guard: Guard<Arc<usize>> = <Arc<ArcSwapAny<Arc<usize>>> as Access<T>>::load(&s);
+   |                                    ++++++++++++++++++++++++++++++++++++++++++++++++++ ~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/src/test/ui/typeck/issue-57404.rs b/src/test/ui/typeck/issue-57404.rs
new file mode 100644
index 00000000000..ecabca66a00
--- /dev/null
+++ b/src/test/ui/typeck/issue-57404.rs
@@ -0,0 +1,7 @@
+#![feature(unboxed_closures)]
+#![feature(fn_traits)]
+
+fn main() {
+    let handlers: Option<Box<dyn for<'a> FnMut<&'a mut (), Output=()>>> = None;
+    handlers.unwrap().as_mut().call_mut(&mut ()); //~ ERROR: `&mut ()` is not a tuple
+}
diff --git a/src/test/ui/typeck/issue-57404.stderr b/src/test/ui/typeck/issue-57404.stderr
new file mode 100644
index 00000000000..5065ac32ad2
--- /dev/null
+++ b/src/test/ui/typeck/issue-57404.stderr
@@ -0,0 +1,16 @@
+error[E0277]: `&mut ()` is not a tuple
+  --> $DIR/issue-57404.rs:6:41
+   |
+LL |     handlers.unwrap().as_mut().call_mut(&mut ());
+   |                                -------- -^^^^^^
+   |                                |        |
+   |                                |        the trait `Tuple` is not implemented for `&mut ()`
+   |                                |        help: consider removing the leading `&`-reference
+   |                                required by a bound introduced by this call
+   |
+note: required by a bound in `call_mut`
+  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.