about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_middle/src/mir/mono.rs9
-rw-r--r--compiler/rustc_mir/src/monomorphize/collector.rs46
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs41
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs23
-rw-r--r--compiler/rustc_resolve/src/late.rs30
-rw-r--r--compiler/rustc_resolve/src/lib.rs9
-rw-r--r--library/alloc/src/vec/mod.rs5
-rw-r--r--library/alloc/tests/vec.rs48
-rw-r--r--library/core/src/array/iter.rs2
-rw-r--r--library/core/src/iter/traits/iterator.rs5
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/macros/mod.rs6
-rw-r--r--library/core/src/num/f32.rs29
-rw-r--r--library/core/src/num/f64.rs29
-rw-r--r--library/core/src/num/int_macros.rs30
-rw-r--r--library/core/src/num/uint_macros.rs30
-rw-r--r--src/test/ui/consts/const-eval/auxiliary/post_monomorphization_error.rs20
-rw-r--r--src/test/ui/consts/const-eval/issue-85155.rs21
-rw-r--r--src/test/ui/consts/const-eval/issue-85155.stderr15
-rw-r--r--src/test/ui/matches2021.rs12
-rw-r--r--src/test/ui/resolve/issue-85348.rs12
-rw-r--r--src/test/ui/resolve/issue-85348.stderr25
-rw-r--r--src/test/ui/resolve/shadow-const-param.rs20
-rw-r--r--src/test/ui/resolve/shadow-const-param.stderr20
-rw-r--r--src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr (renamed from src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.stderr)32
-rw-r--r--src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs3
-rw-r--r--src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr122
27 files changed, 444 insertions, 201 deletions
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index edf2e539765..0109580a0bb 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -186,6 +186,15 @@ impl<'tcx> MonoItem<'tcx> {
     pub fn codegen_dep_node(&self, tcx: TyCtxt<'tcx>) -> DepNode {
         crate::dep_graph::make_compile_mono_item(tcx, self)
     }
+
+    /// Returns the item's `CrateNum`
+    pub fn krate(&self) -> CrateNum {
+        match self {
+            MonoItem::Fn(ref instance) => instance.def_id().krate,
+            MonoItem::Static(def_id) => def_id.krate,
+            MonoItem::GlobalAsm(..) => LOCAL_CRATE,
+        }
+    }
 }
 
 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for MonoItem<'tcx> {
diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs
index ef79f36b3b5..afe4457bf43 100644
--- a/compiler/rustc_mir/src/monomorphize/collector.rs
+++ b/compiler/rustc_mir/src/monomorphize/collector.rs
@@ -184,7 +184,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::{par_iter, MTLock, MTRef, ParallelIterator};
 use rustc_errors::{ErrorReported, FatalError};
 use rustc_hir as hir;
-use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
+use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_hir::lang_items::LangItem;
 use rustc_index::bit_set::GrowableBitSet;
@@ -342,7 +342,8 @@ fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionMode) -> Vec<MonoItem<
         .collect()
 }
 
-// Collect all monomorphized items reachable from `starting_point`
+/// Collect all monomorphized items reachable from `starting_point`, and emit a note diagnostic if a
+/// post-monorphization error is encountered during a collection step.
 fn collect_items_rec<'tcx>(
     tcx: TyCtxt<'tcx>,
     starting_point: Spanned<MonoItem<'tcx>>,
@@ -359,6 +360,31 @@ fn collect_items_rec<'tcx>(
     let mut neighbors = Vec::new();
     let recursion_depth_reset;
 
+    //
+    // Post-monomorphization errors MVP
+    //
+    // We can encounter errors while monomorphizing an item, but we don't have a good way of
+    // showing a complete stack of spans ultimately leading to collecting the erroneous one yet.
+    // (It's also currently unclear exactly which diagnostics and information would be interesting
+    // to report in such cases)
+    //
+    // This leads to suboptimal error reporting: a post-monomorphization error (PME) will be
+    // shown with just a spanned piece of code causing the error, without information on where
+    // it was called from. This is especially obscure if the erroneous mono item is in a
+    // dependency. See for example issue #85155, where, before minimization, a PME happened two
+    // crates downstream from libcore's stdarch, without a way to know which dependency was the
+    // cause.
+    //
+    // If such an error occurs in the current crate, its span will be enough to locate the
+    // source. If the cause is in another crate, the goal here is to quickly locate which mono
+    // item in the current crate is ultimately responsible for causing the error.
+    //
+    // To give at least _some_ context to the user: while collecting mono items, we check the
+    // error count. If it has changed, a PME occurred, and we trigger some diagnostics about the
+    // current step of mono items collection.
+    //
+    let error_count = tcx.sess.diagnostic().err_count();
+
     match starting_point.node {
         MonoItem::Static(def_id) => {
             let instance = Instance::mono(tcx, def_id);
@@ -411,6 +437,22 @@ fn collect_items_rec<'tcx>(
         }
     }
 
+    // Check for PMEs and emit a diagnostic if one happened. To try to show relevant edges of the
+    // mono item graph where the PME diagnostics are currently the most problematic (e.g. ones
+    // involving a dependency, and the lack of context is confusing) in this MVP, we focus on
+    // diagnostics on edges crossing a crate boundary: the collected mono items which are not
+    // defined in the local crate.
+    if tcx.sess.diagnostic().err_count() > error_count && starting_point.node.krate() != LOCAL_CRATE
+    {
+        tcx.sess.span_note_without_error(
+            starting_point.span,
+            &format!(
+                "the above error was encountered while instantiating `{}`",
+                starting_point.node
+            ),
+        );
+    }
+
     record_accesses(tcx, starting_point.node, neighbors.iter().map(|i| &i.node), inlining_map);
 
     for neighbour in neighbors {
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 7e64c5f189e..971b6dd9e1c 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -42,7 +42,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
             self.warn_unused_unsafe(
                 hir_id,
                 block_span,
-                Some(self.tcx.sess.source_map().guess_head_span(enclosing_span)),
+                Some((self.tcx.sess.source_map().guess_head_span(enclosing_span), "block")),
             );
             f(self);
         } else {
@@ -52,7 +52,15 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
             f(self);
 
             if let SafetyContext::UnsafeBlock { used: false, span, hir_id } = self.safety_context {
-                self.warn_unused_unsafe(hir_id, span, self.body_unsafety.unsafe_fn_sig_span());
+                self.warn_unused_unsafe(
+                    hir_id,
+                    span,
+                    if self.unsafe_op_in_unsafe_fn_allowed() {
+                        self.body_unsafety.unsafe_fn_sig_span().map(|span| (span, "fn"))
+                    } else {
+                        None
+                    },
+                );
             }
             self.safety_context = prev_context;
             return;
@@ -72,16 +80,20 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
             SafetyContext::UnsafeFn if unsafe_op_in_unsafe_fn_allowed => {}
             SafetyContext::UnsafeFn => {
                 // unsafe_op_in_unsafe_fn is disallowed
-                struct_span_err!(
-                    self.tcx.sess,
+                self.tcx.struct_span_lint_hir(
+                    UNSAFE_OP_IN_UNSAFE_FN,
+                    self.hir_context,
                     span,
-                    E0133,
-                    "{} is unsafe and requires unsafe block",
-                    description,
+                    |lint| {
+                        lint.build(&format!(
+                            "{} is unsafe and requires unsafe block (error E0133)",
+                            description,
+                        ))
+                        .span_label(span, description)
+                        .note(note)
+                        .emit();
+                    },
                 )
-                .span_label(span, description)
-                .note(note)
-                .emit();
             }
             SafetyContext::Safe => {
                 let fn_sugg = if unsafe_op_in_unsafe_fn_allowed { " function or" } else { "" };
@@ -104,18 +116,15 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
         &self,
         hir_id: hir::HirId,
         block_span: Span,
-        enclosing_span: Option<Span>,
+        enclosing_unsafe: Option<(Span, &'static str)>,
     ) {
         let block_span = self.tcx.sess.source_map().guess_head_span(block_span);
         self.tcx.struct_span_lint_hir(UNUSED_UNSAFE, hir_id, block_span, |lint| {
             let msg = "unnecessary `unsafe` block";
             let mut db = lint.build(msg);
             db.span_label(block_span, msg);
-            if let Some(enclosing_span) = enclosing_span {
-                db.span_label(
-                    enclosing_span,
-                    format!("because it's nested under this `unsafe` block"),
-                );
+            if let Some((span, kind)) = enclosing_unsafe {
+                db.span_label(span, format!("because it's nested under this `unsafe` {}", kind));
             }
             db.emit();
         });
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 6ea46f5c528..a1eafd65d64 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -425,24 +425,29 @@ impl<'a> Resolver<'a> {
                 }
                 err
             }
-            ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, name, binding) => {
-                let res = binding.res();
-                let shadows_what = res.descr();
+            ResolutionError::BindingShadowsSomethingUnacceptable {
+                shadowing_binding_descr,
+                name,
+                participle,
+                article,
+                shadowed_binding_descr,
+                shadowed_binding_span,
+            } => {
                 let mut err = struct_span_err!(
                     self.session,
                     span,
                     E0530,
                     "{}s cannot shadow {}s",
-                    what_binding,
-                    shadows_what
+                    shadowing_binding_descr,
+                    shadowed_binding_descr,
                 );
                 err.span_label(
                     span,
-                    format!("cannot be named the same as {} {}", res.article(), shadows_what),
+                    format!("cannot be named the same as {} {}", article, shadowed_binding_descr),
                 );
-                let participle = if binding.is_import() { "imported" } else { "defined" };
-                let msg = format!("the {} `{}` is {} here", shadows_what, name, participle);
-                err.span_label(binding.span, msg);
+                let msg =
+                    format!("the {} `{}` is {} here", shadowed_binding_descr, name, participle);
+                err.span_label(shadowed_binding_span, msg);
                 err
             }
             ResolutionError::ForwardDeclaredTyParam => {
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index ffa825b7d46..662d39f6ef3 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -1763,13 +1763,33 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                 // to something unusable as a pattern (e.g., constructor function),
                 // but we still conservatively report an error, see
                 // issues/33118#issuecomment-233962221 for one reason why.
+                let binding = binding.expect("no binding for a ctor or static");
                 self.report_error(
                     ident.span,
-                    ResolutionError::BindingShadowsSomethingUnacceptable(
-                        pat_src.descr(),
-                        ident.name,
-                        binding.expect("no binding for a ctor or static"),
-                    ),
+                    ResolutionError::BindingShadowsSomethingUnacceptable {
+                        shadowing_binding_descr: pat_src.descr(),
+                        name: ident.name,
+                        participle: if binding.is_import() { "imported" } else { "defined" },
+                        article: binding.res().article(),
+                        shadowed_binding_descr: binding.res().descr(),
+                        shadowed_binding_span: binding.span,
+                    },
+                );
+                None
+            }
+            Res::Def(DefKind::ConstParam, def_id) => {
+                // Same as for DefKind::Const above, but here, `binding` is `None`, so we
+                // have to construct the error differently
+                self.report_error(
+                    ident.span,
+                    ResolutionError::BindingShadowsSomethingUnacceptable {
+                        shadowing_binding_descr: pat_src.descr(),
+                        name: ident.name,
+                        participle: "defined",
+                        article: res.article(),
+                        shadowed_binding_descr: res.descr(),
+                        shadowed_binding_span: self.r.opt_span(def_id).expect("const parameter defined outside of local crate"),
+                    }
                 );
                 None
             }
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 5793b79e647..76d845f782e 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -233,7 +233,14 @@ enum ResolutionError<'a> {
         /* current */ &'static str,
     ),
     /// Error E0530: `X` bindings cannot shadow `Y`s.
-    BindingShadowsSomethingUnacceptable(&'static str, Symbol, &'a NameBinding<'a>),
+    BindingShadowsSomethingUnacceptable {
+        shadowing_binding_descr: &'static str,
+        name: Symbol,
+        participle: &'static str,
+        article: &'static str,
+        shadowed_binding_descr: &'static str,
+        shadowed_binding_span: Span,
+    },
     /// Error E0128: generic parameters with a default cannot use forward-declared identifiers.
     ForwardDeclaredTyParam, // FIXME(const_generics_defaults)
     /// ERROR E0770: the type of const parameters must not depend on other generic parameters.
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 1c33ff555d6..105c60e7bf0 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -1619,6 +1619,8 @@ impl<T, A: Allocator> Vec<T, A> {
                 let prev_ptr = ptr.add(gap.write.wrapping_sub(1));
 
                 if same_bucket(&mut *read_ptr, &mut *prev_ptr) {
+                    // Increase `gap.read` now since the drop may panic.
+                    gap.read += 1;
                     /* We have found duplicate, drop it in-place */
                     ptr::drop_in_place(read_ptr);
                 } else {
@@ -1631,9 +1633,8 @@ impl<T, A: Allocator> Vec<T, A> {
 
                     /* We have filled that place, so go further */
                     gap.write += 1;
+                    gap.read += 1;
                 }
-
-                gap.read += 1;
             }
 
             /* Technically we could let `gap` clean up with its Drop, but
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index ad69234403b..36c81b49709 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -2234,48 +2234,50 @@ fn test_vec_dedup() {
 #[test]
 fn test_vec_dedup_panicking() {
     #[derive(Debug)]
-    struct Panic {
-        drop_counter: &'static AtomicU32,
+    struct Panic<'a> {
+        drop_counter: &'a Cell<u32>,
         value: bool,
         index: usize,
     }
 
-    impl PartialEq for Panic {
+    impl<'a> PartialEq for Panic<'a> {
         fn eq(&self, other: &Self) -> bool {
             self.value == other.value
         }
     }
 
-    impl Drop for Panic {
+    impl<'a> Drop for Panic<'a> {
         fn drop(&mut self) {
-            let x = self.drop_counter.fetch_add(1, Ordering::SeqCst);
-            assert!(x != 4);
+            self.drop_counter.set(self.drop_counter.get() + 1);
+            if !std::thread::panicking() {
+                assert!(self.index != 4);
+            }
         }
     }
 
-    static DROP_COUNTER: AtomicU32 = AtomicU32::new(0);
+    let drop_counter = &Cell::new(0);
     let expected = [
-        Panic { drop_counter: &DROP_COUNTER, value: false, index: 0 },
-        Panic { drop_counter: &DROP_COUNTER, value: false, index: 5 },
-        Panic { drop_counter: &DROP_COUNTER, value: true, index: 6 },
-        Panic { drop_counter: &DROP_COUNTER, value: true, index: 7 },
+        Panic { drop_counter, value: false, index: 0 },
+        Panic { drop_counter, value: false, index: 5 },
+        Panic { drop_counter, value: true, index: 6 },
+        Panic { drop_counter, value: true, index: 7 },
     ];
     let mut vec = vec![
-        Panic { drop_counter: &DROP_COUNTER, value: false, index: 0 },
+        Panic { drop_counter, value: false, index: 0 },
         // these elements get deduplicated
-        Panic { drop_counter: &DROP_COUNTER, value: false, index: 1 },
-        Panic { drop_counter: &DROP_COUNTER, value: false, index: 2 },
-        Panic { drop_counter: &DROP_COUNTER, value: false, index: 3 },
-        Panic { drop_counter: &DROP_COUNTER, value: false, index: 4 },
-        // here it panics
-        Panic { drop_counter: &DROP_COUNTER, value: false, index: 5 },
-        Panic { drop_counter: &DROP_COUNTER, value: true, index: 6 },
-        Panic { drop_counter: &DROP_COUNTER, value: true, index: 7 },
+        Panic { drop_counter, value: false, index: 1 },
+        Panic { drop_counter, value: false, index: 2 },
+        Panic { drop_counter, value: false, index: 3 },
+        Panic { drop_counter, value: false, index: 4 },
+        // here it panics while dropping the item with index==4
+        Panic { drop_counter, value: false, index: 5 },
+        Panic { drop_counter, value: true, index: 6 },
+        Panic { drop_counter, value: true, index: 7 },
     ];
 
-    let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
-        vec.dedup();
-    }));
+    let _ = catch_unwind(AssertUnwindSafe(|| vec.dedup())).unwrap_err();
+
+    assert_eq!(drop_counter.get(), 4);
 
     let ok = vec.iter().zip(expected.iter()).all(|(x, y)| x.index == y.index);
 
diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs
index c36542f6314..aedbeab6610 100644
--- a/library/core/src/array/iter.rs
+++ b/library/core/src/array/iter.rs
@@ -139,7 +139,7 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
         // SAFETY: Callers are only allowed to pass an index that is in bounds
         // Additionally Self: TrustedRandomAccess is only implemented for T: Copy which means even
         // multiple repeated reads of the same index would be safe and the
-        // values aree !Drop, thus won't suffer from double drops.
+        // values are !Drop, thus won't suffer from double drops.
         unsafe { self.data.get_unchecked(self.alive.start + idx).assume_init_read() }
     }
 }
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index e6ed34d3f05..1eef0f9064c 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -80,11 +80,6 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
         label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
     ),
     on(
-        _Self = "[]",
-        label = "arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)`",
-        note = "see <https://github.com/rust-lang/rust/pull/65819> for more details"
-    ),
-    on(
         _Self = "{integral}",
         note = "if you want to iterate between `start` until a value `end`, use the exclusive range \
               syntax `start..end` or the inclusive range syntax `start..=end`"
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 337182c0c9f..a023edaca9e 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -168,6 +168,7 @@
 #![feature(no_coverage)] // rust-lang/rust#84605
 #![feature(int_error_matching)]
 #![deny(unsafe_op_in_unsafe_fn)]
+#![deny(or_patterns_back_compat)]
 
 // allow using `core::` in intra-doc links
 #[allow(unused_extern_crates)]
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index feadf5b4c7c..7eb65483b99 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -138,7 +138,7 @@ macro_rules! assert_ne {
 #[unstable(feature = "assert_matches", issue = "82775")]
 #[allow_internal_unstable(core_panic)]
 macro_rules! assert_matches {
-    ($left:expr, $( $pattern:pat )|+ $( if $guard: expr )? $(,)?) => ({
+    ($left:expr, $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => ({
         match $left {
             $( $pattern )|+ $( if $guard )? => {}
             ref left_val => {
@@ -150,7 +150,7 @@ macro_rules! assert_matches {
             }
         }
     });
-    ($left:expr, $( $pattern:pat )|+ $( if $guard: expr )?, $($arg:tt)+) => ({
+    ($left:expr, $( $pattern:pat_param )|+ $( if $guard: expr )?, $($arg:tt)+) => ({
         match $left {
             $( $pattern )|+ $( if $guard )? => {}
             ref left_val => {
@@ -315,7 +315,7 @@ macro_rules! debug_assert_matches {
 #[macro_export]
 #[stable(feature = "matches_macro", since = "1.42.0")]
 macro_rules! matches {
-    ($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )? $(,)?) => {
+    ($expression:expr, $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => {
         match $expression {
             $( $pattern )|+ $( if $guard )? => true,
             _ => false
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index 0d6d919d998..77132cddca2 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -854,35 +854,6 @@ impl f32 {
         self.to_bits().to_ne_bytes()
     }
 
-    /// Return the memory representation of this floating point number as a byte array in
-    /// native byte order.
-    ///
-    /// [`to_ne_bytes`] should be preferred over this whenever possible.
-    ///
-    /// [`to_ne_bytes`]: f32::to_ne_bytes
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(num_as_ne_bytes)]
-    /// let num = 12.5f32;
-    /// let bytes = num.as_ne_bytes();
-    /// assert_eq!(
-    ///     bytes,
-    ///     if cfg!(target_endian = "big") {
-    ///         &[0x41, 0x48, 0x00, 0x00]
-    ///     } else {
-    ///         &[0x00, 0x00, 0x48, 0x41]
-    ///     }
-    /// );
-    /// ```
-    #[unstable(feature = "num_as_ne_bytes", issue = "76976")]
-    #[inline]
-    pub fn as_ne_bytes(&self) -> &[u8; 4] {
-        // SAFETY: `f32` is a plain old datatype so we can always transmute to it
-        unsafe { &*(self as *const Self as *const _) }
-    }
-
     /// Create a floating point value from its representation as a byte array in big endian.
     ///
     /// # Examples
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 42214e7b50d..4c3f1fd16a0 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -868,35 +868,6 @@ impl f64 {
         self.to_bits().to_ne_bytes()
     }
 
-    /// Return the memory representation of this floating point number as a byte array in
-    /// native byte order.
-    ///
-    /// [`to_ne_bytes`] should be preferred over this whenever possible.
-    ///
-    /// [`to_ne_bytes`]: f64::to_ne_bytes
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(num_as_ne_bytes)]
-    /// let num = 12.5f64;
-    /// let bytes = num.as_ne_bytes();
-    /// assert_eq!(
-    ///     bytes,
-    ///     if cfg!(target_endian = "big") {
-    ///         &[0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
-    ///     } else {
-    ///         &[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]
-    ///     }
-    /// );
-    /// ```
-    #[unstable(feature = "num_as_ne_bytes", issue = "76976")]
-    #[inline]
-    pub fn as_ne_bytes(&self) -> &[u8; 8] {
-        // SAFETY: `f64` is a plain old datatype so we can always transmute to it
-        unsafe { &*(self as *const Self as *const _) }
-    }
-
     /// Create a floating point value from its representation as a byte array in big endian.
     ///
     /// # Examples
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 47b2b30563c..4af86ed98f2 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -1842,36 +1842,6 @@ macro_rules! int_impl {
             unsafe { mem::transmute(self) }
         }
 
-        /// Return the memory representation of this integer as a byte array in
-        /// native byte order.
-        ///
-        /// [`to_ne_bytes`] should be preferred over this whenever possible.
-        ///
-        /// [`to_ne_bytes`]: Self::to_ne_bytes
-        ///
-        /// # Examples
-        ///
-        /// ```
-        /// #![feature(num_as_ne_bytes)]
-        #[doc = concat!("let num = ", $swap_op, stringify!($SelfT), ";")]
-        /// let bytes = num.as_ne_bytes();
-        /// assert_eq!(
-        ///     bytes,
-        ///     if cfg!(target_endian = "big") {
-        #[doc = concat!("        &", $be_bytes)]
-        ///     } else {
-        #[doc = concat!("        &", $le_bytes)]
-        ///     }
-        /// );
-        /// ```
-        #[unstable(feature = "num_as_ne_bytes", issue = "76976")]
-        #[inline]
-        pub fn as_ne_bytes(&self) -> &[u8; mem::size_of::<Self>()] {
-            // SAFETY: integers are plain old datatypes so we can always transmute them to
-            // arrays of bytes
-            unsafe { &*(self as *const Self as *const _) }
-        }
-
         /// Create an integer value from its representation as a byte array in
         /// big endian.
         ///
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index f9fd28b6a8c..a525e02d5e1 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -1672,36 +1672,6 @@ macro_rules! uint_impl {
             unsafe { mem::transmute(self) }
         }
 
-        /// Return the memory representation of this integer as a byte array in
-        /// native byte order.
-        ///
-        /// [`to_ne_bytes`] should be preferred over this whenever possible.
-        ///
-        /// [`to_ne_bytes`]: Self::to_ne_bytes
-        ///
-        /// # Examples
-        ///
-        /// ```
-        /// #![feature(num_as_ne_bytes)]
-        #[doc = concat!("let num = ", $swap_op, stringify!($SelfT), ";")]
-        /// let bytes = num.as_ne_bytes();
-        /// assert_eq!(
-        ///     bytes,
-        ///     if cfg!(target_endian = "big") {
-        #[doc = concat!("        &", $be_bytes)]
-        ///     } else {
-        #[doc = concat!("        &", $le_bytes)]
-        ///     }
-        /// );
-        /// ```
-        #[unstable(feature = "num_as_ne_bytes", issue = "76976")]
-        #[inline]
-        pub fn as_ne_bytes(&self) -> &[u8; mem::size_of::<Self>()] {
-            // SAFETY: integers are plain old datatypes so we can always transmute them to
-            // arrays of bytes
-            unsafe { &*(self as *const Self as *const _) }
-        }
-
         /// Create a native endian integer value from its representation
         /// as a byte array in big endian.
         ///
diff --git a/src/test/ui/consts/const-eval/auxiliary/post_monomorphization_error.rs b/src/test/ui/consts/const-eval/auxiliary/post_monomorphization_error.rs
new file mode 100644
index 00000000000..bdeaa0cd360
--- /dev/null
+++ b/src/test/ui/consts/const-eval/auxiliary/post_monomorphization_error.rs
@@ -0,0 +1,20 @@
+// Auxiliary crate used for testing post-monomorphization errors cross-crate.
+// It duplicates the setup used in `stdarch` to validate its intrinsics' const arguments.
+
+struct ValidateConstImm<const IMM: i32, const MIN: i32, const MAX: i32>;
+impl<const IMM: i32, const MIN: i32, const MAX: i32> ValidateConstImm<IMM, MIN, MAX> {
+    pub(crate) const VALID: () = {
+        let _ = 1 / ((IMM >= MIN && IMM <= MAX) as usize);
+    };
+}
+
+macro_rules! static_assert_imm1 {
+    ($imm:ident) => {
+        let _ = $crate::ValidateConstImm::<$imm, 0, { (1 << 1) - 1 }>::VALID;
+    };
+}
+
+// This function triggers an error whenever the const argument does not fit in 1-bit.
+pub fn stdarch_intrinsic<const IMM1: i32>() {
+    static_assert_imm1!(IMM1);
+}
diff --git a/src/test/ui/consts/const-eval/issue-85155.rs b/src/test/ui/consts/const-eval/issue-85155.rs
new file mode 100644
index 00000000000..c3216d53d05
--- /dev/null
+++ b/src/test/ui/consts/const-eval/issue-85155.rs
@@ -0,0 +1,21 @@
+// This is a test with a setup similar to issue 85155, which triggers a const eval error: a const
+// argument value is outside the range expected by the `stdarch` intrinsic.
+//
+// It's not the exact code mentioned in that issue because it depends both on `stdarch` intrinsics
+// only available on x64, and internal implementation details of `stdarch`. But mostly because these
+// are not important to trigger the diagnostics issue: it's specifically about the lack of context
+// in the diagnostics of post-monomorphization errors (PMEs) for consts, happening in a dependency.
+// Therefore, its setup is reproduced with an aux crate, which will similarly trigger a PME
+// depending on the const argument value, like the `stdarch` intrinsics would.
+//
+// aux-build: post_monomorphization_error.rs
+// build-fail: this is a post-monomorphization error, it passes check runs and requires building
+//             to actually fail.
+
+extern crate post_monomorphization_error;
+
+fn main() {
+    // This function triggers a PME whenever the const argument does not fit in 1-bit.
+    post_monomorphization_error::stdarch_intrinsic::<2>();
+    //~^ NOTE the above error was encountered while instantiating
+}
diff --git a/src/test/ui/consts/const-eval/issue-85155.stderr b/src/test/ui/consts/const-eval/issue-85155.stderr
new file mode 100644
index 00000000000..0a1edfb8a33
--- /dev/null
+++ b/src/test/ui/consts/const-eval/issue-85155.stderr
@@ -0,0 +1,15 @@
+error[E0080]: evaluation of constant value failed
+  --> $DIR/auxiliary/post_monomorphization_error.rs:7:17
+   |
+LL |         let _ = 1 / ((IMM >= MIN && IMM <= MAX) as usize);
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to divide `1_usize` by zero
+
+note: the above error was encountered while instantiating `fn stdarch_intrinsic::<2_i32>`
+  --> $DIR/issue-85155.rs:19:5
+   |
+LL |     post_monomorphization_error::stdarch_intrinsic::<2>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/matches2021.rs b/src/test/ui/matches2021.rs
new file mode 100644
index 00000000000..1090b1578ba
--- /dev/null
+++ b/src/test/ui/matches2021.rs
@@ -0,0 +1,12 @@
+// run-pass
+// edition:2021
+// compile-flags: -Zunstable-options
+
+// regression test for https://github.com/rust-lang/rust/pull/85678
+
+#![feature(assert_matches)]
+
+fn main() {
+    assert!(matches!((), ()));
+    assert_matches!((), ());
+}
diff --git a/src/test/ui/resolve/issue-85348.rs b/src/test/ui/resolve/issue-85348.rs
new file mode 100644
index 00000000000..3a33c193408
--- /dev/null
+++ b/src/test/ui/resolve/issue-85348.rs
@@ -0,0 +1,12 @@
+// Checks whether shadowing a const parameter leads to an ICE (#85348).
+
+impl<const N: usize> ArrayWindowsExample {
+//~^ ERROR: cannot find type `ArrayWindowsExample` in this scope [E0412]
+    fn next() {
+        let mut N;
+        //~^ ERROR: let bindings cannot shadow const parameters [E0530]
+        //~| ERROR: type annotations needed [E0282]
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/resolve/issue-85348.stderr b/src/test/ui/resolve/issue-85348.stderr
new file mode 100644
index 00000000000..f475c26f32b
--- /dev/null
+++ b/src/test/ui/resolve/issue-85348.stderr
@@ -0,0 +1,25 @@
+error[E0530]: let bindings cannot shadow const parameters
+  --> $DIR/issue-85348.rs:6:17
+   |
+LL | impl<const N: usize> ArrayWindowsExample {
+   |            - the const parameter `N` is defined here
+...
+LL |         let mut N;
+   |                 ^ cannot be named the same as a const parameter
+
+error[E0412]: cannot find type `ArrayWindowsExample` in this scope
+  --> $DIR/issue-85348.rs:3:22
+   |
+LL | impl<const N: usize> ArrayWindowsExample {
+   |                      ^^^^^^^^^^^^^^^^^^^ not found in this scope
+
+error[E0282]: type annotations needed
+  --> $DIR/issue-85348.rs:6:13
+   |
+LL |         let mut N;
+   |             ^^^^^ consider giving `N` a type
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0282, E0412, E0530.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/src/test/ui/resolve/shadow-const-param.rs b/src/test/ui/resolve/shadow-const-param.rs
new file mode 100644
index 00000000000..c435c16dc67
--- /dev/null
+++ b/src/test/ui/resolve/shadow-const-param.rs
@@ -0,0 +1,20 @@
+// Checks that const parameters cannot be shadowed with fresh bindings
+// even in syntactically unambiguous contexts. See
+// https://github.com/rust-lang/rust/issues/33118#issuecomment-233962221
+
+fn foo<const N: i32>(i: i32) -> bool {
+    match i {
+        N @ _ => true,
+        //~^ ERROR: match bindings cannot shadow const parameters [E0530]
+    }
+}
+
+fn bar<const N: i32>(i: i32) -> bool {
+    let N @ _ = 0;
+    //~^ ERROR: let bindings cannot shadow const parameters [E0530]
+    match i {
+        N @ _ => true,
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/resolve/shadow-const-param.stderr b/src/test/ui/resolve/shadow-const-param.stderr
new file mode 100644
index 00000000000..fbd0d811000
--- /dev/null
+++ b/src/test/ui/resolve/shadow-const-param.stderr
@@ -0,0 +1,20 @@
+error[E0530]: match bindings cannot shadow const parameters
+  --> $DIR/shadow-const-param.rs:7:9
+   |
+LL | fn foo<const N: i32>(i: i32) -> bool {
+   |              - the const parameter `N` is defined here
+LL |     match i {
+LL |         N @ _ => true,
+   |         ^ cannot be named the same as a const parameter
+
+error[E0530]: let bindings cannot shadow const parameters
+  --> $DIR/shadow-const-param.rs:13:9
+   |
+LL | fn bar<const N: i32>(i: i32) -> bool {
+   |              - the const parameter `N` is defined here
+LL |     let N @ _ = 0;
+   |         ^ cannot be named the same as a const parameter
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0530`.
diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr
index ad93267ca01..9a522fac65f 100644
--- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.stderr
+++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr
@@ -1,18 +1,18 @@
 error: call to unsafe function is unsafe and requires unsafe block (error E0133)
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:9:5
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:12:5
    |
 LL |     unsf();
    |     ^^^^^^ call to unsafe function
    |
 note: the lint level is defined here
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:1:9
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:4:9
    |
 LL | #![deny(unsafe_op_in_unsafe_fn)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error: dereference of raw pointer is unsafe and requires unsafe block (error E0133)
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:11:5
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:14:5
    |
 LL |     *PTR;
    |     ^^^^ dereference of raw pointer
@@ -20,7 +20,7 @@ LL |     *PTR;
    = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
 
 error: use of mutable static is unsafe and requires unsafe block (error E0133)
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:13:5
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:16:5
    |
 LL |     VOID = ();
    |     ^^^^^^^^^ use of mutable static
@@ -28,25 +28,25 @@ LL |     VOID = ();
    = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
 
 error: unnecessary `unsafe` block
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:16:5
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:19:5
    |
 LL |     unsafe {}
    |     ^^^^^^ unnecessary `unsafe` block
    |
 note: the lint level is defined here
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:2:9
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:5:9
    |
 LL | #![deny(unused_unsafe)]
    |         ^^^^^^^^^^^^^
 
 error: call to unsafe function is unsafe and requires unsafe block (error E0133)
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:24:5
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:27:5
    |
 LL |     unsf();
    |     ^^^^^^ call to unsafe function
    |
 note: the lint level is defined here
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:22:8
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:25:8
    |
 LL | #[deny(warnings)]
    |        ^^^^^^^^
@@ -54,7 +54,7 @@ LL | #[deny(warnings)]
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error: dereference of raw pointer is unsafe and requires unsafe block (error E0133)
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:26:5
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:29:5
    |
 LL |     *PTR;
    |     ^^^^ dereference of raw pointer
@@ -62,7 +62,7 @@ LL |     *PTR;
    = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
 
 error: use of mutable static is unsafe and requires unsafe block (error E0133)
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:28:5
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5
    |
 LL |     VOID = ();
    |     ^^^^^^^^^ use of mutable static
@@ -70,13 +70,13 @@ LL |     VOID = ();
    = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
 
 error: unnecessary `unsafe` block
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:30:5
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:33:5
    |
 LL |     unsafe {}
    |     ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:44:14
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:47:14
    |
 LL |     unsafe { unsafe { unsf() } }
    |     ------   ^^^^^^ unnecessary `unsafe` block
@@ -84,7 +84,7 @@ LL |     unsafe { unsafe { unsf() } }
    |     because it's nested under this `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:55:5
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:58:5
    |
 LL | unsafe fn allow_level() {
    | ----------------------- because it's nested under this `unsafe` fn
@@ -93,7 +93,7 @@ LL |     unsafe { unsf() }
    |     ^^^^^^ unnecessary `unsafe` block
 
 error: unnecessary `unsafe` block
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:67:9
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:70:9
    |
 LL | unsafe fn nested_allow_level() {
    | ------------------------------ because it's nested under this `unsafe` fn
@@ -102,7 +102,7 @@ LL |         unsafe { unsf() }
    |         ^^^^^^ unnecessary `unsafe` block
 
 error[E0133]: call to unsafe function is unsafe and requires unsafe block
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:73:5
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:76:5
    |
 LL |     unsf();
    |     ^^^^^^ call to unsafe function
@@ -110,7 +110,7 @@ LL |     unsf();
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
-  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:77:9
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:80:9
    |
 LL |         unsf();
    |         ^^^^^^ call to unsafe function
diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs
index c8400a6fc4d..7ca714b85c2 100644
--- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs
+++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs
@@ -1,3 +1,6 @@
+// revisions: mir thir
+// [thir]compile-flags: -Zthir-unsafeck
+
 #![deny(unsafe_op_in_unsafe_fn)]
 #![deny(unused_unsafe)]
 
diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr
new file mode 100644
index 00000000000..ad87690bb52
--- /dev/null
+++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr
@@ -0,0 +1,122 @@
+error: call to unsafe function is unsafe and requires unsafe block (error E0133)
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:12:5
+   |
+LL |     unsf();
+   |     ^^^^^^ call to unsafe function
+   |
+note: the lint level is defined here
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:4:9
+   |
+LL | #![deny(unsafe_op_in_unsafe_fn)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error: dereference of raw pointer is unsafe and requires unsafe block (error E0133)
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:14:5
+   |
+LL |     *PTR;
+   |     ^^^^ dereference of raw pointer
+   |
+   = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
+
+error: use of mutable static is unsafe and requires unsafe block (error E0133)
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:16:5
+   |
+LL |     VOID = ();
+   |     ^^^^ use of mutable static
+   |
+   = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error: unnecessary `unsafe` block
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:19:5
+   |
+LL |     unsafe {}
+   |     ^^^^^^ unnecessary `unsafe` block
+   |
+note: the lint level is defined here
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:5:9
+   |
+LL | #![deny(unused_unsafe)]
+   |         ^^^^^^^^^^^^^
+
+error: call to unsafe function is unsafe and requires unsafe block (error E0133)
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:27:5
+   |
+LL |     unsf();
+   |     ^^^^^^ call to unsafe function
+   |
+note: the lint level is defined here
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:25:8
+   |
+LL | #[deny(warnings)]
+   |        ^^^^^^^^
+   = note: `#[deny(unsafe_op_in_unsafe_fn)]` implied by `#[deny(warnings)]`
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error: dereference of raw pointer is unsafe and requires unsafe block (error E0133)
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:29:5
+   |
+LL |     *PTR;
+   |     ^^^^ dereference of raw pointer
+   |
+   = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
+
+error: use of mutable static is unsafe and requires unsafe block (error E0133)
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5
+   |
+LL |     VOID = ();
+   |     ^^^^ use of mutable static
+   |
+   = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
+
+error: unnecessary `unsafe` block
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:33:5
+   |
+LL |     unsafe {}
+   |     ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:47:14
+   |
+LL |     unsafe { unsafe { unsf() } }
+   |     ------   ^^^^^^ unnecessary `unsafe` block
+   |     |
+   |     because it's nested under this `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:58:5
+   |
+LL | unsafe fn allow_level() {
+   | ----------------------- because it's nested under this `unsafe` fn
+...
+LL |     unsafe { unsf() }
+   |     ^^^^^^ unnecessary `unsafe` block
+
+error: unnecessary `unsafe` block
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:70:9
+   |
+LL | unsafe fn nested_allow_level() {
+   | ------------------------------ because it's nested under this `unsafe` fn
+...
+LL |         unsafe { unsf() }
+   |         ^^^^^^ unnecessary `unsafe` block
+
+error[E0133]: call to unsafe function is unsafe and requires unsafe block
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:76:5
+   |
+LL |     unsf();
+   |     ^^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+  --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:80:9
+   |
+LL |         unsf();
+   |         ^^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error: aborting due to 13 previous errors
+
+For more information about this error, try `rustc --explain E0133`.