about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-09-19 11:03:09 +0000
committerbors <bors@rust-lang.org>2021-09-19 11:03:09 +0000
commit08a0307b32ec5af243880056d7cf524f2eff8d69 (patch)
treea0d72c00cf6c7918025c7b44f2654d19c9ce8cb7
parent7a3d1a5f3dfeaf5177885fedd7db8ecc70670dc1 (diff)
parent4877ad3d12a89efb08d850628d05dcd7a1416490 (diff)
downloadrust-08a0307b32ec5af243880056d7cf524f2eff8d69.tar.gz
rust-08a0307b32ec5af243880056d7cf524f2eff8d69.zip
Auto merge of #89089 - JohnTitor:rollup-6s6mccx, r=JohnTitor
Rollup of 10 pull requests

Successful merges:

 - #87960 (Suggest replacing an inexisting field for an unmentioned field)
 - #88855 (Allow simd_shuffle to accept vectors of any length)
 - #88966 (Check for shadowing issues involving block labels)
 - #88996 (Fix linting when trailing macro expands to a trailing semi)
 - #89017 (fix potential race in AtomicU64 time monotonizer)
 - #89021 (Add a separate error for `dyn Trait` in `const fn`)
 - #89051 (Add intra-doc links and small changes to `std::os` to be more consistent)
 - #89053 (refactor: VecDeques IntoIter fields to private)
 - #89055 (Suggest better place to add call parentheses for method expressions wrapped in parentheses)
 - #89081 (Fix a typo)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs25
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs8
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs4
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/ops.rs45
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0439.md4
-rw-r--r--compiler/rustc_expand/src/expand.rs15
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs6
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs16
-rw-r--r--compiler/rustc_typeck/src/check/intrinsic.rs7
-rw-r--r--compiler/rustc_typeck/src/check/method/mod.rs3
-rw-r--r--compiler/rustc_typeck/src/check/pat.rs15
-rw-r--r--compiler/rustc_typeck/src/errors.rs8
-rw-r--r--library/alloc/src/collections/vec_deque/into_iter.rs8
-rw-r--r--library/alloc/src/collections/vec_deque/mod.rs2
-rw-r--r--library/std/src/error.rs4
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/os/linux/fs.rs4
-rw-r--r--library/std/src/os/linux/process.rs4
-rw-r--r--library/std/src/os/unix/ffi/mod.rs4
-rw-r--r--library/std/src/os/unix/fs.rs4
-rw-r--r--library/std/src/os/unix/mod.rs7
-rw-r--r--library/std/src/os/unix/net/mod.rs2
-rw-r--r--library/std/src/os/unix/process.rs4
-rw-r--r--library/std/src/os/unix/thread.rs4
-rw-r--r--library/std/src/os/wasi/ffi.rs4
-rw-r--r--library/std/src/os/wasi/fs.rs4
-rw-r--r--library/std/src/os/wasi/mod.rs3
-rw-r--r--library/std/src/os/windows/ffi.rs3
-rw-r--r--library/std/src/os/windows/fs.rs4
-rw-r--r--library/std/src/os/windows/mod.rs16
-rw-r--r--library/std/src/os/windows/process.rs4
-rw-r--r--library/std/src/os/windows/thread.rs4
-rw-r--r--library/std/src/time/monotonic.rs57
-rw-r--r--src/test/ui/consts/const_fn_trait_bound.rs4
-rw-r--r--src/test/ui/consts/const_fn_trait_bound.stock.stderr4
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn.rs10
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn.stderr10
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs4
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr4
-rw-r--r--src/test/ui/error-codes/E0439.rs8
-rw-r--r--src/test/ui/error-codes/E0439.stderr9
-rw-r--r--src/test/ui/issues/issue-51102.stderr5
-rw-r--r--src/test/ui/loops/loops-reject-duplicate-labels-2.rs6
-rw-r--r--src/test/ui/loops/loops-reject-duplicate-labels-2.stderr10
-rw-r--r--src/test/ui/loops/loops-reject-duplicate-labels.rs11
-rw-r--r--src/test/ui/loops/loops-reject-duplicate-labels.stderr26
-rw-r--r--src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs13
-rw-r--r--src/test/ui/loops/loops-reject-lifetime-shadowing-label.stderr10
-rw-r--r--src/test/ui/macros/lint-trailing-macro-call.rs16
-rw-r--r--src/test/ui/macros/lint-trailing-macro-call.stderr18
-rw-r--r--src/test/ui/numeric/numeric-fields.stderr5
-rw-r--r--src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.rs33
-rw-r--r--src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.stderr21
-rw-r--r--src/test/ui/simd/monomorphize-shuffle-index.rs40
-rw-r--r--src/test/ui/simd/shuffle-not-out-of-bounds.rs10
-rw-r--r--src/test/ui/simd/shuffle-not-out-of-bounds.stderr8
-rw-r--r--src/test/ui/simd/shuffle.rs24
-rw-r--r--src/test/ui/typeck/issue-89044-wrapped-expr-method.fixed9
-rw-r--r--src/test/ui/typeck/issue-89044-wrapped-expr-method.rs9
-rw-r--r--src/test/ui/typeck/issue-89044-wrapped-expr-method.stderr14
61 files changed, 506 insertions, 139 deletions
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 1060f911a9e..b309a124e80 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -918,12 +918,29 @@ fn generic_simd_intrinsic(
     }
 
     if let Some(stripped) = name_str.strip_prefix("simd_shuffle") {
-        let n: u64 = stripped.parse().unwrap_or_else(|_| {
-            span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?")
-        });
+        // If this intrinsic is the older "simd_shuffleN" form, simply parse the integer.
+        // If there is no suffix, use the index array length.
+        let n: u64 = if stripped.is_empty() {
+            // Make sure this is actually an array, since typeck only checks the length-suffixed
+            // version of this intrinsic.
+            match args[2].layout.ty.kind() {
+                ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => {
+                    len.try_eval_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else(|| {
+                        span_bug!(span, "could not evaluate shuffle index array length")
+                    })
+                }
+                _ => return_error!(
+                    "simd_shuffle index must be an array of `u32`, got `{}`",
+                    args[2].layout.ty
+                ),
+            }
+        } else {
+            stripped.parse().unwrap_or_else(|_| {
+                span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?")
+            })
+        };
 
         require_simd!(ret_ty, "return");
-
         let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
         require!(
             out_len == n,
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index cd0e9354c24..0861aab2e31 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -665,8 +665,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         if i == 2 && intrinsic.as_str().starts_with("simd_shuffle") {
                             if let mir::Operand::Constant(constant) = arg {
                                 let c = self.eval_mir_constant(constant);
-                                let (llval, ty) =
-                                    self.simd_shuffle_indices(&bx, constant.span, constant.ty(), c);
+                                let (llval, ty) = self.simd_shuffle_indices(
+                                    &bx,
+                                    constant.span,
+                                    self.monomorphize(constant.ty()),
+                                    c,
+                                );
                                 return OperandRef {
                                     val: Immediate(llval),
                                     layout: bx.layout_of(ty),
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 0e5a896a8f1..9eec930f59e 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -384,11 +384,11 @@ impl Checker<'mir, 'tcx> {
                         match pred.skip_binder() {
                             ty::ExistentialPredicate::AutoTrait(_)
                             | ty::ExistentialPredicate::Projection(_) => {
-                                self.check_op(ops::ty::TraitBound(kind))
+                                self.check_op(ops::ty::DynTrait(kind))
                             }
                             ty::ExistentialPredicate::Trait(trait_ref) => {
                                 if Some(trait_ref.def_id) != self.tcx.lang_items().sized_trait() {
-                                    self.check_op(ops::ty::TraitBound(kind))
+                                    self.check_op(ops::ty::DynTrait(kind))
                                 }
                             }
                         }
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
index 2a296750838..1d0ee949a22 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
@@ -599,7 +599,7 @@ pub mod ty {
         }
 
         fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
-            let mut builder = feature_err(
+            let mut err = feature_err(
                 &ccx.tcx.sess.parse_sess,
                 sym::const_fn_trait_bound,
                 span,
@@ -608,12 +608,51 @@ pub mod ty {
 
             match ccx.fn_sig() {
                 Some(fn_sig) if !fn_sig.span.contains(span) => {
-                    builder.span_label(fn_sig.span, "function declared as const here");
+                    err.span_label(fn_sig.span, "function declared as const here");
                 }
                 _ => {}
             }
 
-            builder
+            err
+        }
+    }
+
+    #[derive(Debug)]
+    pub struct DynTrait(pub mir::LocalKind);
+    impl NonConstOp for DynTrait {
+        fn importance(&self) -> DiagnosticImportance {
+            match self.0 {
+                mir::LocalKind::Var | mir::LocalKind::Temp => DiagnosticImportance::Secondary,
+                mir::LocalKind::ReturnPointer | mir::LocalKind::Arg => {
+                    DiagnosticImportance::Primary
+                }
+            }
+        }
+
+        fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
+            if ccx.const_kind() != hir::ConstContext::ConstFn {
+                Status::Allowed
+            } else {
+                Status::Unstable(sym::const_fn_trait_bound)
+            }
+        }
+
+        fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
+            let mut err = feature_err(
+                &ccx.tcx.sess.parse_sess,
+                sym::const_fn_trait_bound,
+                span,
+                "trait objects in const fn are unstable",
+            );
+
+            match ccx.fn_sig() {
+                Some(fn_sig) if !fn_sig.span.contains(span) => {
+                    err.span_label(fn_sig.span, "function declared as const here");
+                }
+                _ => {}
+            }
+
+            err
         }
     }
 
diff --git a/compiler/rustc_error_codes/src/error_codes/E0439.md b/compiler/rustc_error_codes/src/error_codes/E0439.md
index 3e663df866c..24268aef222 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0439.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0439.md
@@ -1,8 +1,10 @@
+#### Note: this error code is no longer emitted by the compiler.
+
 The length of the platform-intrinsic function `simd_shuffle` wasn't specified.
 
 Erroneous code example:
 
-```compile_fail,E0439
+```ignore (no longer emitted)
 #![feature(platform_intrinsics)]
 
 extern "platform-intrinsic" {
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 62066ca9657..d32593f34ad 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -1386,14 +1386,17 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
         // `SEMICOLON_IN_EXPRESSIONS_FROM_MACROS` lint if needed.
         // See #78991 for an investigation of treating macros in this position
         // as statements, rather than expressions, during parsing.
-        if let StmtKind::Expr(expr) = &stmt.kind {
-            if matches!(**expr, ast::Expr { kind: ast::ExprKind::MacCall(..), .. }) {
+        let res = match &stmt.kind {
+            StmtKind::Expr(expr)
+                if matches!(**expr, ast::Expr { kind: ast::ExprKind::MacCall(..), .. }) =>
+            {
                 self.cx.current_expansion.is_trailing_mac = true;
+                // Don't use `assign_id` for this statement - it may get removed
+                // entirely due to a `#[cfg]` on the contained expression
+                noop_flat_map_stmt(stmt, self)
             }
-        }
-
-        let res = assign_id!(self, &mut stmt.id, || noop_flat_map_stmt(stmt, self));
-
+            _ => assign_id!(self, &mut stmt.id, || noop_flat_map_stmt(stmt, self)),
+        };
         self.cx.current_expansion.is_trailing_mac = false;
         res
     }
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index a5dbbffeaa8..a158e0e48e8 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -1652,7 +1652,11 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body<'_>) {
     }
 
     fn expression_label(ex: &hir::Expr<'_>) -> Option<Ident> {
-        if let hir::ExprKind::Loop(_, Some(label), ..) = ex.kind { Some(label.ident) } else { None }
+        match ex.kind {
+            hir::ExprKind::Loop(_, Some(label), ..) => Some(label.ident),
+            hir::ExprKind::Block(_, Some(label)) => Some(label.ident),
+            _ => None,
+        }
     }
 
     fn check_if_label_shadows_lifetime(tcx: TyCtxt<'_>, mut scope: ScopeRef<'_>, label: Ident) {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 78846d8ffb2..322bea3806c 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1212,6 +1212,7 @@ symbols! {
         simd_select_bitmask,
         simd_shl,
         simd_shr,
+        simd_shuffle,
         simd_sub,
         simd_trunc,
         simd_xor,
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 53c1470c601..11b6c93a115 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -1860,6 +1860,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 field,
                 expr_t,
                 expr,
+                None,
             );
         }
         err.emit();
@@ -1886,9 +1887,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             };
         let expr_snippet =
             self.tcx.sess.source_map().span_to_snippet(expr.span).unwrap_or(String::new());
-        if expr_is_call && expr_snippet.starts_with("(") && expr_snippet.ends_with(")") {
-            let after_open = expr.span.lo() + rustc_span::BytePos(1);
-            let before_close = expr.span.hi() - rustc_span::BytePos(1);
+        let is_wrapped = expr_snippet.starts_with("(") && expr_snippet.ends_with(")");
+        let after_open = expr.span.lo() + rustc_span::BytePos(1);
+        let before_close = expr.span.hi() - rustc_span::BytePos(1);
+
+        if expr_is_call && is_wrapped {
             err.multipart_suggestion(
                 "remove wrapping parentheses to call the method",
                 vec![
@@ -1898,12 +1901,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 Applicability::MachineApplicable,
             );
         } else if !self.expr_in_place(expr.hir_id) {
+            // Suggest call parentheses inside the wrapping parentheses
+            let span = if is_wrapped {
+                expr.span.with_lo(after_open).with_hi(before_close)
+            } else {
+                expr.span
+            };
             self.suggest_method_call(
                 &mut err,
                 "use parentheses to call the method",
                 field,
                 expr_t,
                 expr,
+                Some(span),
             );
         } else {
             err.help("methods are immutable and cannot be assigned to");
diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs
index 664954b0eb7..ff7a26853b1 100644
--- a/compiler/rustc_typeck/src/check/intrinsic.rs
+++ b/compiler/rustc_typeck/src/check/intrinsic.rs
@@ -2,7 +2,7 @@
 //! intrinsics that the compiler exposes.
 
 use crate::errors::{
-    SimdShuffleMissingLength, UnrecognizedAtomicOperation, UnrecognizedIntrinsicFunction,
+    UnrecognizedAtomicOperation, UnrecognizedIntrinsicFunction,
     WrongNumberOfGenericArgumentsToIntrinsic,
 };
 use crate::require_same_types;
@@ -468,6 +468,7 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
         | sym::simd_reduce_max
         | sym::simd_reduce_min_nanless
         | sym::simd_reduce_max_nanless => (2, vec![param(0)], param(1)),
+        sym::simd_shuffle => (3, vec![param(0), param(0), param(1)], param(2)),
         name if name.as_str().starts_with("simd_shuffle") => {
             match name.as_str()["simd_shuffle".len()..].parse() {
                 Ok(n) => {
@@ -475,7 +476,9 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
                     (2, params, param(1))
                 }
                 Err(_) => {
-                    tcx.sess.emit_err(SimdShuffleMissingLength { span: it.span, name });
+                    let msg =
+                        format!("unrecognized platform-specific intrinsic function: `{}`", name);
+                    tcx.sess.struct_span_err(it.span, &msg).emit();
                     return;
                 }
             }
diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs
index 2136d925423..8e09aa97dcf 100644
--- a/compiler/rustc_typeck/src/check/method/mod.rs
+++ b/compiler/rustc_typeck/src/check/method/mod.rs
@@ -141,6 +141,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         method_name: Ident,
         self_ty: Ty<'tcx>,
         call_expr: &hir::Expr<'_>,
+        span: Option<Span>,
     ) {
         let params = self
             .probe_for_name(
@@ -159,7 +160,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .unwrap_or(0);
 
         // Account for `foo.bar<T>`;
-        let sugg_span = call_expr.span.shrink_to_hi();
+        let sugg_span = span.unwrap_or_else(|| call_expr.span).shrink_to_hi();
         let (suggestion, applicability) = (
             format!("({})", (0..params).map(|_| "_").collect::<Vec<_>>().join(", ")),
             if params > 0 { Applicability::HasPlaceholders } else { Applicability::MaybeIncorrect },
diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs
index a056ab6aef2..829268e3cb5 100644
--- a/compiler/rustc_typeck/src/check/pat.rs
+++ b/compiler/rustc_typeck/src/check/pat.rs
@@ -1452,7 +1452,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     plural
                 ),
             );
-            if plural == "" {
+
+            if unmentioned_fields.len() == 1 {
                 let input =
                     unmentioned_fields.iter().map(|(_, field)| field.name).collect::<Vec<_>>();
                 let suggested_name = find_best_match_for_name(&input, ident.name, None);
@@ -1473,6 +1474,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         // We don't want to throw `E0027` in case we have thrown `E0026` for them.
                         unmentioned_fields.retain(|&(_, x)| x.name != suggested_name);
                     }
+                } else if inexistent_fields.len() == 1 {
+                    let unmentioned_field = unmentioned_fields[0].1.name;
+                    err.span_suggestion_short(
+                        ident.span,
+                        &format!(
+                            "`{}` has a field named `{}`",
+                            tcx.def_path_str(variant.def_id),
+                            unmentioned_field
+                        ),
+                        unmentioned_field.to_string(),
+                        Applicability::MaybeIncorrect,
+                    );
                 }
             }
         }
diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs
index 1e6a240b2f8..47077779616 100644
--- a/compiler/rustc_typeck/src/errors.rs
+++ b/compiler/rustc_typeck/src/errors.rs
@@ -122,14 +122,6 @@ pub struct AssocTypeBindingNotAllowed {
 }
 
 #[derive(SessionDiagnostic)]
-#[error = "E0439"]
-pub struct SimdShuffleMissingLength {
-    #[message = "invalid `simd_shuffle`, needs length: `{name}`"]
-    pub span: Span,
-    pub name: Symbol,
-}
-
-#[derive(SessionDiagnostic)]
 #[error = "E0436"]
 pub struct FunctionalRecordUpdateOnNonStruct {
     #[message = "functional record update syntax requires a struct"]
diff --git a/library/alloc/src/collections/vec_deque/into_iter.rs b/library/alloc/src/collections/vec_deque/into_iter.rs
index 5f13c3bf303..54a157be0b9 100644
--- a/library/alloc/src/collections/vec_deque/into_iter.rs
+++ b/library/alloc/src/collections/vec_deque/into_iter.rs
@@ -17,7 +17,13 @@ pub struct IntoIter<
     T,
     #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
 > {
-    pub(crate) inner: VecDeque<T, A>,
+    inner: VecDeque<T, A>,
+}
+
+impl<T, A: Allocator> IntoIter<T, A> {
+    pub(super) fn new(inner: VecDeque<T, A>) -> Self {
+        IntoIter { inner }
+    }
 }
 
 #[stable(feature = "collection_debug", since = "1.17.0")]
diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs
index e4b28204158..10144cc17bf 100644
--- a/library/alloc/src/collections/vec_deque/mod.rs
+++ b/library/alloc/src/collections/vec_deque/mod.rs
@@ -2827,7 +2827,7 @@ impl<T, A: Allocator> IntoIterator for VecDeque<T, A> {
     /// Consumes the `VecDeque` into a front-to-back iterator yielding elements by
     /// value.
     fn into_iter(self) -> IntoIter<T, A> {
-        IntoIter { inner: self }
+        IntoIter::new(self)
     }
 }
 
diff --git a/library/std/src/error.rs b/library/std/src/error.rs
index ec9f0122950..8164ec56985 100644
--- a/library/std/src/error.rs
+++ b/library/std/src/error.rs
@@ -182,7 +182,7 @@ impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
     ///
     /// impl fmt::Display for AnError {
     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    ///         write!(f , "An error")
+    ///         write!(f, "An error")
     ///     }
     /// }
     ///
@@ -215,7 +215,7 @@ impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync +
     ///
     /// impl fmt::Display for AnError {
     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    ///         write!(f , "An error")
+    ///         write!(f, "An error")
     ///     }
     /// }
     ///
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 559d2672a0d..f69baba9e73 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -234,6 +234,7 @@
 #![feature(atomic_mut_ptr)]
 #![feature(auto_traits)]
 #![feature(bench_black_box)]
+#![feature(bool_to_option)]
 #![feature(box_syntax)]
 #![feature(c_unwind)]
 #![feature(c_variadic)]
diff --git a/library/std/src/os/linux/fs.rs b/library/std/src/os/linux/fs.rs
index 9b7af97616c..9d18ccbeb24 100644
--- a/library/std/src/os/linux/fs.rs
+++ b/library/std/src/os/linux/fs.rs
@@ -1,4 +1,6 @@
-//! Linux-specific extensions to primitives in the `std::fs` module.
+//! Linux-specific extensions to primitives in the [`std::fs`] module.
+//!
+//! [`std::fs`]: crate::fs
 
 #![stable(feature = "metadata_ext", since = "1.1.0")]
 
diff --git a/library/std/src/os/linux/process.rs b/library/std/src/os/linux/process.rs
index e3e7143c851..540363c0349 100644
--- a/library/std/src/os/linux/process.rs
+++ b/library/std/src/os/linux/process.rs
@@ -1,4 +1,6 @@
-//! Linux-specific extensions to primitives in the `std::process` module.
+//! Linux-specific extensions to primitives in the [`std::process`] module.
+//!
+//! [`std::process`]: crate::process
 
 #![unstable(feature = "linux_pidfd", issue = "82971")]
 
diff --git a/library/std/src/os/unix/ffi/mod.rs b/library/std/src/os/unix/ffi/mod.rs
index c29df6596fd..5b49f50763d 100644
--- a/library/std/src/os/unix/ffi/mod.rs
+++ b/library/std/src/os/unix/ffi/mod.rs
@@ -1,4 +1,4 @@
-//! Unix-specific extension to the primitives in the `std::ffi` module.
+//! Unix-specific extensions to primitives in the [`std::ffi`] module.
 //!
 //! # Examples
 //!
@@ -31,6 +31,8 @@
 //! let bytes = os_str.as_bytes();
 //! assert_eq!(bytes, b"foo");
 //! ```
+//!
+//! [`std::ffi`]: crate::ffi
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/library/std/src/os/unix/fs.rs b/library/std/src/os/unix/fs.rs
index 30eead9b059..0284a428b5d 100644
--- a/library/std/src/os/unix/fs.rs
+++ b/library/std/src/os/unix/fs.rs
@@ -1,4 +1,6 @@
-//! Unix-specific extensions to primitives in the `std::fs` module.
+//! Unix-specific extensions to primitives in the [`std::fs`] module.
+//!
+//! [`std::fs`]: crate::fs
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/library/std/src/os/unix/mod.rs b/library/std/src/os/unix/mod.rs
index 17a02595724..62f750fa607 100644
--- a/library/std/src/os/unix/mod.rs
+++ b/library/std/src/os/unix/mod.rs
@@ -4,8 +4,8 @@
 //! exposes Unix-specific functions that would otherwise be inappropriate as
 //! part of the core `std` library.
 //!
-//! It exposes more ways to deal with platform-specific strings (`OsStr`,
-//! `OsString`), allows to set permissions more granularly, extract low-level
+//! It exposes more ways to deal with platform-specific strings ([`OsStr`],
+//! [`OsString`]), allows to set permissions more granularly, extract low-level
 //! file descriptors from files and sockets, and has platform-specific helpers
 //! for spawning processes.
 //!
@@ -24,6 +24,9 @@
 //!     Ok(())
 //! }
 //! ```
+//!
+//! [`OsStr`]: crate::ffi::OsStr
+//! [`OsString`]: crate::ffi::OsString
 
 #![stable(feature = "rust1", since = "1.0.0")]
 #![doc(cfg(unix))]
diff --git a/library/std/src/os/unix/net/mod.rs b/library/std/src/os/unix/net/mod.rs
index d462bd4b5f7..8ce82208854 100644
--- a/library/std/src/os/unix/net/mod.rs
+++ b/library/std/src/os/unix/net/mod.rs
@@ -1,4 +1,4 @@
-//! Unix-specific networking functionality
+//! Unix-specific networking functionality.
 
 #![stable(feature = "unix_socket", since = "1.10.0")]
 
diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs
index 650dcbabbae..4d23805e479 100644
--- a/library/std/src/os/unix/process.rs
+++ b/library/std/src/os/unix/process.rs
@@ -1,4 +1,6 @@
-//! Unix-specific extensions to primitives in the `std::process` module.
+//! Unix-specific extensions to primitives in the [`std::process`] module.
+//!
+//! [`std::process`]: crate::process
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/library/std/src/os/unix/thread.rs b/library/std/src/os/unix/thread.rs
index 7221da1a9a7..03dcc3a4f9b 100644
--- a/library/std/src/os/unix/thread.rs
+++ b/library/std/src/os/unix/thread.rs
@@ -1,4 +1,6 @@
-//! Unix-specific extensions to primitives in the `std::thread` module.
+//! Unix-specific extensions to primitives in the [`std::thread`] module.
+//!
+//! [`std::thread`]: crate::thread
 
 #![stable(feature = "thread_extensions", since = "1.9.0")]
 
diff --git a/library/std/src/os/wasi/ffi.rs b/library/std/src/os/wasi/ffi.rs
index 17e12a395a6..41dd8702e98 100644
--- a/library/std/src/os/wasi/ffi.rs
+++ b/library/std/src/os/wasi/ffi.rs
@@ -1,4 +1,6 @@
-//! WASI-specific extension to the primitives in the `std::ffi` module
+//! WASI-specific extensions to primitives in the [`std::ffi`] module
+//!
+//! [`std::ffi`]: crate::ffi
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/library/std/src/os/wasi/fs.rs b/library/std/src/os/wasi/fs.rs
index 3df27563e21..907368061d7 100644
--- a/library/std/src/os/wasi/fs.rs
+++ b/library/std/src/os/wasi/fs.rs
@@ -1,4 +1,6 @@
-//! WASI-specific extensions to primitives in the `std::fs` module.
+//! WASI-specific extensions to primitives in the [`std::fs`] module.
+//!
+//! [`std::fs`]: crate::fs
 
 #![deny(unsafe_op_in_unsafe_fn)]
 #![unstable(feature = "wasi_ext", issue = "71213")]
diff --git a/library/std/src/os/wasi/mod.rs b/library/std/src/os/wasi/mod.rs
index d767c149dc5..bbaf328f457 100644
--- a/library/std/src/os/wasi/mod.rs
+++ b/library/std/src/os/wasi/mod.rs
@@ -24,6 +24,9 @@
 //!     Ok(())
 //! }
 //! ```
+//!
+//! [`OsStr`]: crate::ffi::OsStr
+//! [`OsString`]: crate::ffi::OsString
 
 #![stable(feature = "rust1", since = "1.0.0")]
 #![deny(unsafe_op_in_unsafe_fn)]
diff --git a/library/std/src/os/windows/ffi.rs b/library/std/src/os/windows/ffi.rs
index 8d29fa7d66f..a9493a94cac 100644
--- a/library/std/src/os/windows/ffi.rs
+++ b/library/std/src/os/windows/ffi.rs
@@ -1,4 +1,4 @@
-//! Windows-specific extensions to the primitives in the `std::ffi` module.
+//! Windows-specific extensions to primitives in the [`std::ffi`] module.
 //!
 //! # Overview
 //!
@@ -49,6 +49,7 @@
 //! [ill-formed-utf-16]: https://simonsapin.github.io/wtf-8/#ill-formed-utf-16
 //! [`collect`]: crate::iter::Iterator::collect
 //! [U+FFFD]: crate::char::REPLACEMENT_CHARACTER
+//! [`std::ffi`]: crate::ffi
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/library/std/src/os/windows/fs.rs b/library/std/src/os/windows/fs.rs
index 71563a02dcb..be35ab0ca1e 100644
--- a/library/std/src/os/windows/fs.rs
+++ b/library/std/src/os/windows/fs.rs
@@ -1,4 +1,6 @@
-//! Windows-specific extensions for the primitives in the `std::fs` module.
+//! Windows-specific extensions to primitives in the [`std::fs`] module.
+//!
+//! [`std::fs`]: crate::fs
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/library/std/src/os/windows/mod.rs b/library/std/src/os/windows/mod.rs
index 969054dd3b3..52eb3b7c067 100644
--- a/library/std/src/os/windows/mod.rs
+++ b/library/std/src/os/windows/mod.rs
@@ -5,6 +5,22 @@
 //! the core `std` library. These extensions allow developers to use
 //! `std` types and idioms with Windows in a way that the normal
 //! platform-agnostic idioms would not normally support.
+//!
+//! # Examples
+//!
+//! ```no_run
+//! use std::fs::File;
+//! use std::os::windows::prelude::*;
+//!
+//! fn main() -> std::io::Result<()> {
+//!     let f = File::create("foo.txt")?;
+//!     let handle = f.as_raw_handle();
+//!
+//!     // use handle with native windows bindings
+//!
+//!     Ok(())
+//! }
+//! ```
 
 #![stable(feature = "rust1", since = "1.0.0")]
 #![doc(cfg(windows))]
diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs
index b246599dfc0..9510d104806 100644
--- a/library/std/src/os/windows/process.rs
+++ b/library/std/src/os/windows/process.rs
@@ -1,4 +1,6 @@
-//! Extensions to `std::process` for Windows.
+//! Windows-specific extensions to primitives in the [`std::process`] module.
+//!
+//! [`std::process`]: crate::process
 
 #![stable(feature = "process_extensions", since = "1.2.0")]
 
diff --git a/library/std/src/os/windows/thread.rs b/library/std/src/os/windows/thread.rs
index fb1bf66ceed..d81d6d0ac28 100644
--- a/library/std/src/os/windows/thread.rs
+++ b/library/std/src/os/windows/thread.rs
@@ -1,4 +1,6 @@
-//! Extensions to `std::thread` for Windows.
+//! Windows-specific extensions to primitives in the [`std::thread`] module.
+//!
+//! [`std::thread`]: crate::thread
 
 #![stable(feature = "thread_extensions", since = "1.9.0")]
 
diff --git a/library/std/src/time/monotonic.rs b/library/std/src/time/monotonic.rs
index fa96b7abff6..198ae739b55 100644
--- a/library/std/src/time/monotonic.rs
+++ b/library/std/src/time/monotonic.rs
@@ -37,35 +37,36 @@ pub mod inner {
         // This could be a problem for programs that call instants at intervals greater
         // than 68 years. Interstellar probes may want to ensure that actually_monotonic() is true.
         let packed = (secs << 32) | nanos;
-        let old = mono.load(Relaxed);
-
-        if old == UNINITIALIZED || packed.wrapping_sub(old) < u64::MAX / 2 {
-            mono.store(packed, Relaxed);
-            raw
-        } else {
-            // Backslide occurred. We reconstruct monotonized time from the upper 32 bit of the
-            // passed in value and the 64bits loaded from the atomic
-            let seconds_lower = old >> 32;
-            let mut seconds_upper = secs & 0xffff_ffff_0000_0000;
-            if secs & 0xffff_ffff > seconds_lower {
-                // Backslide caused the lower 32bit of the seconds part to wrap.
-                // This must be the case because the seconds part is larger even though
-                // we are in the backslide branch, i.e. the seconds count should be smaller or equal.
-                //
-                // We assume that backslides are smaller than 2^32 seconds
-                // which means we need to add 1 to the upper half to restore it.
-                //
-                // Example:
-                // most recent observed time: 0xA1_0000_0000_0000_0000u128
-                // bits stored in AtomicU64:     0x0000_0000_0000_0000u64
-                // backslide by 1s
-                // caller time is             0xA0_ffff_ffff_0000_0000u128
-                // -> we can fix up the upper half time by adding 1 << 32
-                seconds_upper = seconds_upper.wrapping_add(0x1_0000_0000);
+        let updated = mono.fetch_update(Relaxed, Relaxed, |old| {
+            (old == UNINITIALIZED || packed.wrapping_sub(old) < u64::MAX / 2).then_some(packed)
+        });
+        match updated {
+            Ok(_) => raw,
+            Err(newer) => {
+                // Backslide occurred. We reconstruct monotonized time from the upper 32 bit of the
+                // passed in value and the 64bits loaded from the atomic
+                let seconds_lower = newer >> 32;
+                let mut seconds_upper = secs & 0xffff_ffff_0000_0000;
+                if secs & 0xffff_ffff > seconds_lower {
+                    // Backslide caused the lower 32bit of the seconds part to wrap.
+                    // This must be the case because the seconds part is larger even though
+                    // we are in the backslide branch, i.e. the seconds count should be smaller or equal.
+                    //
+                    // We assume that backslides are smaller than 2^32 seconds
+                    // which means we need to add 1 to the upper half to restore it.
+                    //
+                    // Example:
+                    // most recent observed time: 0xA1_0000_0000_0000_0000u128
+                    // bits stored in AtomicU64:     0x0000_0000_0000_0000u64
+                    // backslide by 1s
+                    // caller time is             0xA0_ffff_ffff_0000_0000u128
+                    // -> we can fix up the upper half time by adding 1 << 32
+                    seconds_upper = seconds_upper.wrapping_add(0x1_0000_0000);
+                }
+                let secs = seconds_upper | seconds_lower;
+                let nanos = newer as u32;
+                ZERO.checked_add_duration(&Duration::new(secs, nanos)).unwrap()
             }
-            let secs = seconds_upper | seconds_lower;
-            let nanos = old as u32;
-            ZERO.checked_add_duration(&Duration::new(secs, nanos)).unwrap()
         }
     }
 }
diff --git a/src/test/ui/consts/const_fn_trait_bound.rs b/src/test/ui/consts/const_fn_trait_bound.rs
index b1ef820d827..19c08b62144 100644
--- a/src/test/ui/consts/const_fn_trait_bound.rs
+++ b/src/test/ui/consts/const_fn_trait_bound.rs
@@ -8,9 +8,9 @@
 const fn test1<T: std::ops::Add>() {}
 //[stock]~^ trait bounds
 const fn test2(_x: &dyn Send) {}
-//[stock]~^ trait bounds
+//[stock]~^ trait objects in const fn are unstable
 const fn test3() -> &'static dyn Send { loop {} }
-//[stock]~^ trait bounds
+//[stock]~^ trait objects in const fn are unstable
 
 
 #[rustc_error]
diff --git a/src/test/ui/consts/const_fn_trait_bound.stock.stderr b/src/test/ui/consts/const_fn_trait_bound.stock.stderr
index 2ad45f3afde..d652b5268a8 100644
--- a/src/test/ui/consts/const_fn_trait_bound.stock.stderr
+++ b/src/test/ui/consts/const_fn_trait_bound.stock.stderr
@@ -7,7 +7,7 @@ LL | const fn test1<T: std::ops::Add>() {}
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
-error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0658]: trait objects in const fn are unstable
   --> $DIR/const_fn_trait_bound.rs:10:16
    |
 LL | const fn test2(_x: &dyn Send) {}
@@ -16,7 +16,7 @@ LL | const fn test2(_x: &dyn Send) {}
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
-error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0658]: trait objects in const fn are unstable
   --> $DIR/const_fn_trait_bound.rs:12:21
    |
 LL | const fn test3() -> &'static dyn Send { loop {} }
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.rs b/src/test/ui/consts/min_const_fn/min_const_fn.rs
index bb525d57197..10347a02074 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn.rs
+++ b/src/test/ui/consts/min_const_fn/min_const_fn.rs
@@ -130,16 +130,16 @@ const fn no_apit(_x: impl std::fmt::Debug) {}
 //~^ ERROR trait bounds other than `Sized`
 //~| ERROR destructor
 const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
-//~^ ERROR trait bounds other than `Sized`
+//~^ ERROR trait objects in const fn are unstable
 const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
-//~^ ERROR trait bounds other than `Sized`
+//~^ ERROR trait objects in const fn are unstable
 
 const fn no_unsafe() { unsafe {} }
 
 const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
-//~^ ERROR trait bounds other than `Sized`
-//~| ERROR trait bounds other than `Sized`
-//~| ERROR trait bounds other than `Sized`
+//~^ ERROR trait objects in const fn are unstable
+//~| ERROR trait objects in const fn are unstable
+//~| ERROR trait objects in const fn are unstable
 
 const fn no_fn_ptrs(_x: fn()) {}
 //~^ ERROR function pointer
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.stderr
index d1c2a04d6a6..1e275d77bac 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr
@@ -279,7 +279,7 @@ LL | const fn no_apit(_x: impl std::fmt::Debug) {}
    |                  |
    |                  constant functions cannot evaluate destructors
 
-error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0658]: trait objects in const fn are unstable
   --> $DIR/min_const_fn.rs:132:23
    |
 LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
@@ -288,7 +288,7 @@ LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
-error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0658]: trait objects in const fn are unstable
   --> $DIR/min_const_fn.rs:134:32
    |
 LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
@@ -297,7 +297,7 @@ LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
-error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0658]: trait objects in const fn are unstable
   --> $DIR/min_const_fn.rs:139:41
    |
 LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
@@ -308,7 +308,7 @@ LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
-error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0658]: trait objects in const fn are unstable
   --> $DIR/min_const_fn.rs:139:42
    |
 LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
@@ -319,7 +319,7 @@ LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
-error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0658]: trait objects in const fn are unstable
   --> $DIR/min_const_fn.rs:139:42
    |
 LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs
index 6ca1e59b3af..1ab8253b414 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs
@@ -7,9 +7,9 @@ struct Hide(HasDyn);
 const fn no_inner_dyn_trait(_x: Hide) {}
 const fn no_inner_dyn_trait2(x: Hide) {
     x.0.field;
-//~^ ERROR trait bounds other than `Sized`
+//~^ ERROR trait objects in const fn are unstable
 }
 const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
-//~^ ERROR trait bounds other than `Sized`
+//~^ ERROR trait objects in const fn are unstable
 
 fn main() {}
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
index 2cad8a862be..6eec1df5aec 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
@@ -1,4 +1,4 @@
-error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0658]: trait objects in const fn are unstable
   --> $DIR/min_const_fn_dyn.rs:9:5
    |
 LL | const fn no_inner_dyn_trait2(x: Hide) {
@@ -9,7 +9,7 @@ LL |     x.0.field;
    = note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
    = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
 
-error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0658]: trait objects in const fn are unstable
   --> $DIR/min_const_fn_dyn.rs:12:66
    |
 LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
diff --git a/src/test/ui/error-codes/E0439.rs b/src/test/ui/error-codes/E0439.rs
deleted file mode 100644
index 86e9cb55a9c..00000000000
--- a/src/test/ui/error-codes/E0439.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-#![feature(platform_intrinsics)]
-
-extern "platform-intrinsic" {
-    fn simd_shuffle<A,B>(a: A, b: A, c: [u32; 8]) -> B; //~ ERROR E0439
-}
-
-fn main () {
-}
diff --git a/src/test/ui/error-codes/E0439.stderr b/src/test/ui/error-codes/E0439.stderr
deleted file mode 100644
index 8021f7d3951..00000000000
--- a/src/test/ui/error-codes/E0439.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0439]: invalid `simd_shuffle`, needs length: `simd_shuffle`
-  --> $DIR/E0439.rs:4:5
-   |
-LL |     fn simd_shuffle<A,B>(a: A, b: A, c: [u32; 8]) -> B;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0439`.
diff --git a/src/test/ui/issues/issue-51102.stderr b/src/test/ui/issues/issue-51102.stderr
index eb9eb680200..09c52292dcc 100644
--- a/src/test/ui/issues/issue-51102.stderr
+++ b/src/test/ui/issues/issue-51102.stderr
@@ -2,7 +2,10 @@ error[E0026]: struct `SimpleStruct` does not have a field named `state`
   --> $DIR/issue-51102.rs:13:17
    |
 LL |                 state: 0,
-   |                 ^^^^^ struct `SimpleStruct` does not have this field
+   |                 ^^^^^
+   |                 |
+   |                 struct `SimpleStruct` does not have this field
+   |                 help: `SimpleStruct` has a field named `no_state_here`
 
 error[E0025]: field `no_state_here` bound multiple times in the pattern
   --> $DIR/issue-51102.rs:24:17
diff --git a/src/test/ui/loops/loops-reject-duplicate-labels-2.rs b/src/test/ui/loops/loops-reject-duplicate-labels-2.rs
index 3a860f508ff..68a19a8f6f7 100644
--- a/src/test/ui/loops/loops-reject-duplicate-labels-2.rs
+++ b/src/test/ui/loops/loops-reject-duplicate-labels-2.rs
@@ -1,7 +1,7 @@
 // check-pass
+#![feature(label_break_value)]
 
-
-// Issue #21633: reject duplicate loop labels in function bodies.
+// Issue #21633: reject duplicate loop labels and block labels in function bodies.
 //
 // This is testing the generalization (to the whole function body)
 // discussed here:
@@ -26,6 +26,8 @@ pub fn foo() {
     { 'lt: loop { break; } }
     { 'lt: while let Some(_) = None::<i32> { break; } }
                                          //~^ WARN label name `'lt` shadows a label name that is already in scope
+    { 'bl: {} }
+    { 'bl: {} } //~ WARN label name `'bl` shadows a label name that is already in scope
 }
 
 
diff --git a/src/test/ui/loops/loops-reject-duplicate-labels-2.stderr b/src/test/ui/loops/loops-reject-duplicate-labels-2.stderr
index 6c53d04e107..2c372fcff7a 100644
--- a/src/test/ui/loops/loops-reject-duplicate-labels-2.stderr
+++ b/src/test/ui/loops/loops-reject-duplicate-labels-2.stderr
@@ -62,5 +62,13 @@ LL |     { 'lt: loop { break; } }
 LL |     { 'lt: while let Some(_) = None::<i32> { break; } }
    |       ^^^ label `'lt` already in scope
 
-warning: 8 warnings emitted
+warning: label name `'bl` shadows a label name that is already in scope
+  --> $DIR/loops-reject-duplicate-labels-2.rs:30:7
+   |
+LL |     { 'bl: {} }
+   |       --- first declared here
+LL |     { 'bl: {} }
+   |       ^^^ label `'bl` already in scope
+
+warning: 9 warnings emitted
 
diff --git a/src/test/ui/loops/loops-reject-duplicate-labels.rs b/src/test/ui/loops/loops-reject-duplicate-labels.rs
index d9334ce3857..c34bcf3df1d 100644
--- a/src/test/ui/loops/loops-reject-duplicate-labels.rs
+++ b/src/test/ui/loops/loops-reject-duplicate-labels.rs
@@ -1,8 +1,7 @@
 // check-pass
+#![feature(label_break_value)]
 
-
-// Issue #21633: reject duplicate loop labels in function bodies.
-// This is testing the exact cases that are in the issue description.
+// Issue #21633: reject duplicate loop labels and block labels in function bodies.
 
 #[allow(unused_labels)]
 fn foo() {
@@ -24,6 +23,8 @@ fn foo() {
     'lt: loop { break; }
     'lt: while let Some(_) = None::<i32> { break; }
                                    //~^ WARN label name `'lt` shadows a label name that is already in scope
+    'bl: {}
+    'bl: {} //~ WARN label name `'bl` shadows a label name that is already in scope
 }
 
 // Note however that it is okay for the same label to be reused in
@@ -33,6 +34,8 @@ struct S;
 impl S {
     fn m1(&self) { 'okay: loop { break 'okay; } }
     fn m2(&self) { 'okay: loop { break 'okay; } }
+    fn m3(&self) { 'okay: { break 'okay; } }
+    fn m4(&self) { 'okay: { break 'okay; } }
 }
 
 
@@ -40,5 +43,7 @@ pub fn main() {
     let s = S;
     s.m1();
     s.m2();
+    s.m3();
+    s.m4();
     foo();
 }
diff --git a/src/test/ui/loops/loops-reject-duplicate-labels.stderr b/src/test/ui/loops/loops-reject-duplicate-labels.stderr
index 5bdf64849f3..3bf3af763ec 100644
--- a/src/test/ui/loops/loops-reject-duplicate-labels.stderr
+++ b/src/test/ui/loops/loops-reject-duplicate-labels.stderr
@@ -1,5 +1,5 @@
 warning: label name `'fl` shadows a label name that is already in scope
-  --> $DIR/loops-reject-duplicate-labels.rs:10:5
+  --> $DIR/loops-reject-duplicate-labels.rs:9:5
    |
 LL |     'fl: for _ in 0..10 { break; }
    |     --- first declared here
@@ -7,7 +7,7 @@ LL |     'fl: loop { break; }
    |     ^^^ label `'fl` already in scope
 
 warning: label name `'lf` shadows a label name that is already in scope
-  --> $DIR/loops-reject-duplicate-labels.rs:13:5
+  --> $DIR/loops-reject-duplicate-labels.rs:12:5
    |
 LL |     'lf: loop { break; }
    |     --- first declared here
@@ -15,7 +15,7 @@ LL |     'lf: for _ in 0..10 { break; }
    |     ^^^ label `'lf` already in scope
 
 warning: label name `'wl` shadows a label name that is already in scope
-  --> $DIR/loops-reject-duplicate-labels.rs:15:5
+  --> $DIR/loops-reject-duplicate-labels.rs:14:5
    |
 LL |     'wl: while 2 > 1 { break; }
    |     --- first declared here
@@ -23,7 +23,7 @@ LL |     'wl: loop { break; }
    |     ^^^ label `'wl` already in scope
 
 warning: label name `'lw` shadows a label name that is already in scope
-  --> $DIR/loops-reject-duplicate-labels.rs:17:5
+  --> $DIR/loops-reject-duplicate-labels.rs:16:5
    |
 LL |     'lw: loop { break; }
    |     --- first declared here
@@ -31,7 +31,7 @@ LL |     'lw: while 2 > 1 { break; }
    |     ^^^ label `'lw` already in scope
 
 warning: label name `'fw` shadows a label name that is already in scope
-  --> $DIR/loops-reject-duplicate-labels.rs:19:5
+  --> $DIR/loops-reject-duplicate-labels.rs:18:5
    |
 LL |     'fw: for _ in 0..10 { break; }
    |     --- first declared here
@@ -39,7 +39,7 @@ LL |     'fw: while 2 > 1 { break; }
    |     ^^^ label `'fw` already in scope
 
 warning: label name `'wf` shadows a label name that is already in scope
-  --> $DIR/loops-reject-duplicate-labels.rs:21:5
+  --> $DIR/loops-reject-duplicate-labels.rs:20:5
    |
 LL |     'wf: while 2 > 1 { break; }
    |     --- first declared here
@@ -47,7 +47,7 @@ LL |     'wf: for _ in 0..10 { break; }
    |     ^^^ label `'wf` already in scope
 
 warning: label name `'tl` shadows a label name that is already in scope
-  --> $DIR/loops-reject-duplicate-labels.rs:23:5
+  --> $DIR/loops-reject-duplicate-labels.rs:22:5
    |
 LL |     'tl: while let Some(_) = None::<i32> { break; }
    |     --- first declared here
@@ -55,12 +55,20 @@ LL |     'tl: loop { break; }
    |     ^^^ label `'tl` already in scope
 
 warning: label name `'lt` shadows a label name that is already in scope
-  --> $DIR/loops-reject-duplicate-labels.rs:25:5
+  --> $DIR/loops-reject-duplicate-labels.rs:24:5
    |
 LL |     'lt: loop { break; }
    |     --- first declared here
 LL |     'lt: while let Some(_) = None::<i32> { break; }
    |     ^^^ label `'lt` already in scope
 
-warning: 8 warnings emitted
+warning: label name `'bl` shadows a label name that is already in scope
+  --> $DIR/loops-reject-duplicate-labels.rs:27:5
+   |
+LL |     'bl: {}
+   |     --- first declared here
+LL |     'bl: {}
+   |     ^^^ label `'bl` already in scope
+
+warning: 9 warnings emitted
 
diff --git a/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs b/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs
index 3212b78b08c..ce2d07eb06a 100644
--- a/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs
+++ b/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs
@@ -1,10 +1,10 @@
 // check-pass
-
+#![feature(label_break_value)]
 #![allow(dead_code, unused_variables)]
 
-// Issue #21633:  reject duplicate loop labels in function bodies.
+// Issue #21633:  reject duplicate loop labels and block labels in function bodies.
 //
-// Test rejection of lifetimes in *expressions* that shadow loop labels.
+// Test rejection of lifetimes in *expressions* that shadow labels.
 
 fn foo() {
     // Reusing lifetime `'a` in function item is okay.
@@ -23,8 +23,13 @@ fn foo() {
         assert_eq!((*b)(&z), z);
         break 'a;
     }
-}
 
+    'b: {
+        let b = Box::new(|x: &()| ()) as Box<dyn for <'b> Fn(&'b ())>;
+        //~^ WARN lifetime name `'b` shadows a label name that is already in scope
+        break 'b;
+    }
+}
 
 pub fn main() {
     foo();
diff --git a/src/test/ui/loops/loops-reject-lifetime-shadowing-label.stderr b/src/test/ui/loops/loops-reject-lifetime-shadowing-label.stderr
index dcee1a80090..9702b71600b 100644
--- a/src/test/ui/loops/loops-reject-lifetime-shadowing-label.stderr
+++ b/src/test/ui/loops/loops-reject-lifetime-shadowing-label.stderr
@@ -6,5 +6,13 @@ LL |     'a: loop {
 LL |         let b = Box::new(|x: &i8| *x) as Box<dyn for <'a> Fn(&'a i8) -> i8>;
    |                                                       ^^ label `'a` already in scope
 
-warning: 1 warning emitted
+warning: lifetime name `'b` shadows a label name that is already in scope
+  --> $DIR/loops-reject-lifetime-shadowing-label.rs:28:55
+   |
+LL |     'b: {
+   |     -- first declared here
+LL |         let b = Box::new(|x: &()| ()) as Box<dyn for <'b> Fn(&'b ())>;
+   |                                                       ^^ label `'b` already in scope
+
+warning: 2 warnings emitted
 
diff --git a/src/test/ui/macros/lint-trailing-macro-call.rs b/src/test/ui/macros/lint-trailing-macro-call.rs
new file mode 100644
index 00000000000..f8e84756391
--- /dev/null
+++ b/src/test/ui/macros/lint-trailing-macro-call.rs
@@ -0,0 +1,16 @@
+// check-pass
+//
+// Ensures that we properly lint
+// a removed 'expression' resulting from a macro
+// in trailing expression position
+
+macro_rules! expand_it {
+    () => {
+        #[cfg(FALSE)] 25; //~  WARN trailing semicolon in macro
+                          //~| WARN this was previously
+    }
+}
+
+fn main() {
+    expand_it!()
+}
diff --git a/src/test/ui/macros/lint-trailing-macro-call.stderr b/src/test/ui/macros/lint-trailing-macro-call.stderr
new file mode 100644
index 00000000000..a98a559c8af
--- /dev/null
+++ b/src/test/ui/macros/lint-trailing-macro-call.stderr
@@ -0,0 +1,18 @@
+warning: trailing semicolon in macro used in expression position
+  --> $DIR/lint-trailing-macro-call.rs:9:25
+   |
+LL |         #[cfg(FALSE)] 25;
+   |                         ^
+...
+LL |     expand_it!()
+   |     ------------ in this macro invocation
+   |
+   = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
+   = note: macro invocations at the end of a block are treated as expressions
+   = note: to ignore the value produced by the macro, add a semicolon after the invocation of `expand_it`
+   = note: this warning originates in the macro `expand_it` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/numeric/numeric-fields.stderr b/src/test/ui/numeric/numeric-fields.stderr
index b328fbe2cfb..668405ed638 100644
--- a/src/test/ui/numeric/numeric-fields.stderr
+++ b/src/test/ui/numeric/numeric-fields.stderr
@@ -16,7 +16,10 @@ error[E0026]: struct `S` does not have a field named `0x1`
   --> $DIR/numeric-fields.rs:7:17
    |
 LL |         S{0: a, 0x1: b, ..} => {}
-   |                 ^^^ struct `S` does not have this field
+   |                 ^^^
+   |                 |
+   |                 struct `S` does not have this field
+   |                 help: `S` has a field named `1`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.rs
new file mode 100644
index 00000000000..9611780ac07
--- /dev/null
+++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.rs
@@ -0,0 +1,33 @@
+// build-fail
+
+// Test that the simd_shuffle intrinsic produces ok-ish error
+// messages when misused.
+
+#![feature(repr_simd, platform_intrinsics)]
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+pub struct Simd<T, const N: usize>([T; N]);
+
+extern "platform-intrinsic" {
+    fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
+}
+
+fn main() {
+    const I: [u32; 2] = [0; 2];
+    const I2: [f32; 2] = [0.; 2];
+    let v = Simd::<u32, 4>([0; 4]);
+
+    unsafe {
+        let _: Simd<u32, 2> = simd_shuffle(v, v, I);
+
+        let _: Simd<u32, 4> = simd_shuffle(v, v, I);
+        //~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
+
+        let _: Simd<f32, 2> = simd_shuffle(v, v, I);
+        //~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
+
+        let _: Simd<u32, 2> = simd_shuffle(v, v, I2);
+        //~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
+    }
+}
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.stderr
new file mode 100644
index 00000000000..9eeb000fd26
--- /dev/null
+++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-shuffle.stderr
@@ -0,0 +1,21 @@
+error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `Simd<u32, 4_usize>` with length 4
+  --> $DIR/simd-intrinsic-generic-shuffle.rs:24:31
+   |
+LL |         let _: Simd<u32, 4> = simd_shuffle(v, v, I);
+   |                               ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `u32` (element of input `Simd<u32, 4_usize>`), found `Simd<f32, 2_usize>` with element type `f32`
+  --> $DIR/simd-intrinsic-generic-shuffle.rs:27:31
+   |
+LL |         let _: Simd<f32, 2> = simd_shuffle(v, v, I);
+   |                               ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: simd_shuffle index must be an array of `u32`, got `[f32; 2]`
+  --> $DIR/simd-intrinsic-generic-shuffle.rs:30:31
+   |
+LL |         let _: Simd<u32, 2> = simd_shuffle(v, v, I2);
+   |                               ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd/monomorphize-shuffle-index.rs b/src/test/ui/simd/monomorphize-shuffle-index.rs
new file mode 100644
index 00000000000..2467baa08b0
--- /dev/null
+++ b/src/test/ui/simd/monomorphize-shuffle-index.rs
@@ -0,0 +1,40 @@
+//run-pass
+#![feature(repr_simd, platform_intrinsics)]
+
+extern "platform-intrinsic" {
+    fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
+}
+
+#[derive(Copy, Clone)]
+#[repr(simd)]
+struct Simd<T, const N: usize>([T; N]);
+
+trait Shuffle<const N: usize> {
+    const I: [u32; N];
+
+    unsafe fn shuffle<T, const M: usize>(&self, a: Simd<T, M>, b: Simd<T, M>) -> Simd<T, N> {
+        simd_shuffle(a, b, Self::I)
+    }
+}
+
+fn main() {
+    struct I1;
+    impl Shuffle<4> for I1 {
+        const I: [u32; 4] = [0, 2, 4, 6];
+    }
+
+    struct I2;
+    impl Shuffle<2> for I2 {
+        const I: [u32; 2] = [1, 5];
+    }
+
+    let a = Simd::<u8, 4>([0, 1, 2, 3]);
+    let b = Simd::<u8, 4>([4, 5, 6, 7]);
+    unsafe {
+        let x: Simd<u8, 4> = I1.shuffle(a, b);
+        assert_eq!(x.0, [0, 2, 4, 6]);
+
+        let y: Simd<u8, 2> = I2.shuffle(a, b);
+        assert_eq!(y.0, [1, 5]);
+    }
+}
diff --git a/src/test/ui/simd/shuffle-not-out-of-bounds.rs b/src/test/ui/simd/shuffle-not-out-of-bounds.rs
index 8a533453e75..aae6ce4663f 100644
--- a/src/test/ui/simd/shuffle-not-out-of-bounds.rs
+++ b/src/test/ui/simd/shuffle-not-out-of-bounds.rs
@@ -188,4 +188,14 @@ fn main() {
          48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33,
          32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17,
          16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1));
+
+    extern "platform-intrinsic" {
+        fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
+    }
+    let v = u8x2(0, 0);
+    const I: [u32; 2] = [4, 4];
+    unsafe {
+        let _: u8x2 = simd_shuffle(v, v, I);
+        //~^ ERROR invalid monomorphization of `simd_shuffle` intrinsic
+    }
 }
diff --git a/src/test/ui/simd/shuffle-not-out-of-bounds.stderr b/src/test/ui/simd/shuffle-not-out-of-bounds.stderr
index 07253a4ae46..737fb5e6e51 100644
--- a/src/test/ui/simd/shuffle-not-out-of-bounds.stderr
+++ b/src/test/ui/simd/shuffle-not-out-of-bounds.stderr
@@ -71,6 +71,12 @@ LL | |          16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1));
    |
    = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 6 previous errors
+error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: shuffle index #0 is out of bounds (limit 4)
+  --> $DIR/shuffle-not-out-of-bounds.rs:198:23
+   |
+LL |         let _: u8x2 = simd_shuffle(v, v, I);
+   |                       ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0511`.
diff --git a/src/test/ui/simd/shuffle.rs b/src/test/ui/simd/shuffle.rs
new file mode 100644
index 00000000000..3592adfdc6a
--- /dev/null
+++ b/src/test/ui/simd/shuffle.rs
@@ -0,0 +1,24 @@
+//run-pass
+#![feature(repr_simd, platform_intrinsics)]
+
+extern "platform-intrinsic" {
+    fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
+}
+
+#[derive(Copy, Clone)]
+#[repr(simd)]
+struct Simd<T, const N: usize>([T; N]);
+
+fn main() {
+    const I1: [u32; 4] = [0, 2, 4, 6];
+    const I2: [u32; 2] = [1, 5];
+    let a = Simd::<u8, 4>([0, 1, 2, 3]);
+    let b = Simd::<u8, 4>([4, 5, 6, 7]);
+    unsafe {
+        let x: Simd<u8, 4> = simd_shuffle(a, b, I1);
+        assert_eq!(x.0, [0, 2, 4, 6]);
+
+        let y: Simd<u8, 2> = simd_shuffle(a, b, I2);
+        assert_eq!(y.0, [1, 5]);
+    }
+}
diff --git a/src/test/ui/typeck/issue-89044-wrapped-expr-method.fixed b/src/test/ui/typeck/issue-89044-wrapped-expr-method.fixed
new file mode 100644
index 00000000000..0a3086a345d
--- /dev/null
+++ b/src/test/ui/typeck/issue-89044-wrapped-expr-method.fixed
@@ -0,0 +1,9 @@
+// run-rustfix
+
+fn main() {
+    let a = Some(42);
+    println!(
+        "The value is {}.",
+        (a.unwrap()) //~ERROR [E0615]
+    );
+}
diff --git a/src/test/ui/typeck/issue-89044-wrapped-expr-method.rs b/src/test/ui/typeck/issue-89044-wrapped-expr-method.rs
new file mode 100644
index 00000000000..83617e035e9
--- /dev/null
+++ b/src/test/ui/typeck/issue-89044-wrapped-expr-method.rs
@@ -0,0 +1,9 @@
+// run-rustfix
+
+fn main() {
+    let a = Some(42);
+    println!(
+        "The value is {}.",
+        (a.unwrap) //~ERROR [E0615]
+    );
+}
diff --git a/src/test/ui/typeck/issue-89044-wrapped-expr-method.stderr b/src/test/ui/typeck/issue-89044-wrapped-expr-method.stderr
new file mode 100644
index 00000000000..6fa0915dcaf
--- /dev/null
+++ b/src/test/ui/typeck/issue-89044-wrapped-expr-method.stderr
@@ -0,0 +1,14 @@
+error[E0615]: attempted to take value of method `unwrap` on type `Option<{integer}>`
+  --> $DIR/issue-89044-wrapped-expr-method.rs:7:12
+   |
+LL |         (a.unwrap)
+   |            ^^^^^^ method, not a field
+   |
+help: use parentheses to call the method
+   |
+LL |         (a.unwrap())
+   |                  ++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0615`.