about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-12-12 00:58:30 +0000
committerbors <bors@rust-lang.org>2021-12-12 00:58:30 +0000
commite70e4d499dd9dd1f7ff3717b9d91ca5dd0757143 (patch)
treeca2d074d8d0b5f315aa9500d19fae6e994e51761
parent229d0a94128d036fb07dafdb1f73db5eba5ab0d3 (diff)
parent9031ac4840e4da725a5972ac3e6d43f0074b4f3c (diff)
downloadrust-e70e4d499dd9dd1f7ff3717b9d91ca5dd0757143.tar.gz
rust-e70e4d499dd9dd1f7ff3717b9d91ca5dd0757143.zip
Auto merge of #91813 - matthiaskrgr:rollup-nryyeyj, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - #90081 (Make `intrinsics::write_bytes` const)
 - #91643 (asm: Allow using r9 (ARM) and x18 (AArch64) if they are not reserved by the current target)
 - #91737 (Make certain panicky stdlib functions behave better under panic_immediate_abort)
 - #91750 (rustdoc: Add regression test for Iterator as notable trait on &T)
 - #91764 (Do not ICE when suggesting elided lifetimes on non-existent spans.)
 - #91780 (Remove hir::Node::hir_id.)
 - #91797 (Fix zero-sized reference to deallocated memory)
 - #91806 (Make `Unique`s methods `const`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs7
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs1
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs24
-rw-r--r--compiler/rustc_hir/src/hir.rs28
-rw-r--r--compiler/rustc_lint/src/context.rs21
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs1
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs5
-rw-r--r--compiler/rustc_target/src/asm/aarch64.rs20
-rw-r--r--compiler/rustc_target/src/asm/arm.rs19
-rw-r--r--compiler/rustc_target/src/asm/mod.rs34
-rw-r--r--library/alloc/src/vec/drain.rs10
-rw-r--r--library/core/src/intrinsics.rs20
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/option.rs3
-rw-r--r--library/core/src/ptr/unique.rs6
-rw-r--r--library/core/src/result.rs13
-rw-r--r--library/core/src/slice/index.rs15
-rw-r--r--library/core/tests/intrinsics.rs30
-rw-r--r--src/test/rustdoc/doc-notable_trait-mut_t_is_not_ref_t.rs21
-rw-r--r--src/test/ui/asm/aarch64/bad-reg.rs2
-rw-r--r--src/test/ui/asm/aarch64/bad-reg.stderr28
-rw-r--r--src/test/ui/lifetimes/auxiliary/issue-91763-aux.rs47
-rw-r--r--src/test/ui/lifetimes/issue-91763.rs11
-rw-r--r--src/test/ui/lifetimes/issue-91763.stderr14
24 files changed, 289 insertions, 92 deletions
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index 9f27ace25ab..9c28f3c7f58 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -64,7 +64,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         let mut clobber_abis = FxHashMap::default();
         if let Some(asm_arch) = asm_arch {
             for (abi_name, abi_span) in &asm.clobber_abis {
-                match asm::InlineAsmClobberAbi::parse(asm_arch, &self.sess.target, *abi_name) {
+                match asm::InlineAsmClobberAbi::parse(
+                    asm_arch,
+                    |feature| self.sess.target_features.contains(&Symbol::intern(feature)),
+                    &self.sess.target,
+                    *abi_name,
+                ) {
                     Ok(abi) => {
                         // If the abi was already in the list, emit an error
                         match clobber_abis.get(&abi) {
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index ba72e3cfafc..63cc6faf9ec 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -36,6 +36,7 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
     // #[target_feature].
     ("thumb-mode", Some(sym::arm_target_feature)),
     ("thumb2", Some(sym::arm_target_feature)),
+    ("reserve-r9", Some(sym::arm_target_feature)),
 ];
 
 const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 025d2998b00..18dde3bc34e 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -322,6 +322,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             sym::copy => {
                 self.copy_intrinsic(&args[0], &args[1], &args[2], /*nonoverlapping*/ false)?;
             }
+            sym::write_bytes => {
+                self.write_bytes_intrinsic(&args[0], &args[1], &args[2])?;
+            }
             sym::offset => {
                 let ptr = self.read_pointer(&args[0])?;
                 let offset_count = self.read_scalar(&args[1])?.to_machine_isize(self)?;
@@ -567,6 +570,27 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         self.memory.copy(src, align, dst, align, size, nonoverlapping)
     }
 
+    pub(crate) fn write_bytes_intrinsic(
+        &mut self,
+        dst: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::PointerTag>,
+        byte: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::PointerTag>,
+        count: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::PointerTag>,
+    ) -> InterpResult<'tcx> {
+        let layout = self.layout_of(dst.layout.ty.builtin_deref(true).unwrap().ty)?;
+
+        let dst = self.read_pointer(&dst)?;
+        let byte = self.read_scalar(&byte)?.to_u8()?;
+        let count = self.read_scalar(&count)?.to_machine_usize(self)?;
+
+        let len = layout
+            .size
+            .checked_mul(count, self)
+            .ok_or_else(|| err_ub_format!("overflow computing total size of `write_bytes`"))?;
+
+        let bytes = std::iter::repeat(byte).take(len.bytes_usize());
+        self.memory.write_bytes(dst, bytes)
+    }
+
     pub(crate) fn raw_eq_intrinsic(
         &mut self,
         lhs: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::PointerTag>,
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index d393ea68938..9a8bc2efbfa 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3210,34 +3210,6 @@ impl<'hir> Node<'hir> {
         }
     }
 
-    pub fn hir_id(&self) -> Option<HirId> {
-        match self {
-            Node::Item(Item { def_id, .. })
-            | Node::TraitItem(TraitItem { def_id, .. })
-            | Node::ImplItem(ImplItem { def_id, .. })
-            | Node::ForeignItem(ForeignItem { def_id, .. }) => Some(HirId::make_owner(*def_id)),
-            Node::Field(FieldDef { hir_id, .. })
-            | Node::AnonConst(AnonConst { hir_id, .. })
-            | Node::Expr(Expr { hir_id, .. })
-            | Node::Stmt(Stmt { hir_id, .. })
-            | Node::Ty(Ty { hir_id, .. })
-            | Node::Binding(Pat { hir_id, .. })
-            | Node::Pat(Pat { hir_id, .. })
-            | Node::Arm(Arm { hir_id, .. })
-            | Node::Block(Block { hir_id, .. })
-            | Node::Local(Local { hir_id, .. })
-            | Node::Lifetime(Lifetime { hir_id, .. })
-            | Node::Param(Param { hir_id, .. })
-            | Node::Infer(InferArg { hir_id, .. })
-            | Node::GenericParam(GenericParam { hir_id, .. }) => Some(*hir_id),
-            Node::TraitRef(TraitRef { hir_ref_id, .. }) => Some(*hir_ref_id),
-            Node::PathSegment(PathSegment { hir_id, .. }) => *hir_id,
-            Node::Variant(Variant { id, .. }) => Some(*id),
-            Node::Ctor(variant) => variant.ctor_hir_id(),
-            Node::Crate(_) | Node::Visibility(_) => None,
-        }
-    }
-
     /// Returns `Constness::Const` when this node is a const fn/impl/item.
     pub fn constness_for_typeck(&self) -> Constness {
         match self {
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index 4c936dec6f2..3c79020523a 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -22,9 +22,7 @@ use ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
 use rustc_ast as ast;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync;
-use rustc_errors::{
-    add_elided_lifetime_in_path_suggestion, struct_span_err, Applicability, SuggestionStyle,
-};
+use rustc_errors::{struct_span_err, Applicability, SuggestionStyle};
 use rustc_hir as hir;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::{CrateNum, DefId};
@@ -670,23 +668,6 @@ pub trait LintContext: Sized {
                 ) => {
                     db.span_note(span_def, "the macro is defined here");
                 }
-                BuiltinLintDiagnostics::ElidedLifetimesInPaths(
-                    n,
-                    path_span,
-                    incl_angl_brckt,
-                    insertion_span,
-                    anon_lts,
-                ) => {
-                    add_elided_lifetime_in_path_suggestion(
-                        sess.source_map(),
-                        &mut db,
-                        n,
-                        path_span,
-                        incl_angl_brckt,
-                        insertion_span,
-                        anon_lts,
-                    );
-                }
                 BuiltinLintDiagnostics::UnknownCrateTypes(span, note, sugg) => {
                     db.span_suggestion(span, &note, sugg, Applicability::MaybeIncorrect);
                 }
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index feac2a7cfa4..3f504d75dfc 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -289,7 +289,6 @@ pub enum BuiltinLintDiagnostics {
     AbsPathWithModule(Span),
     ProcMacroDeriveResolutionFallback(Span),
     MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),
-    ElidedLifetimesInPaths(usize, Span, bool, Span, String),
     UnknownCrateTypes(Span, String, String),
     UnusedImports(String, Vec<(Span, String)>),
     RedundantImport(Vec<(Span, bool)>, Ident),
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 72ba3f7b980..feb4f82ce8d 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -2115,6 +2115,11 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
                     })
                     .map(|(formatter, span)| (*span, formatter(name)))
                     .collect();
+                if spans_suggs.is_empty() {
+                    // If all the spans come from macros, we cannot extract snippets and then
+                    // `formatters` only contains None and `spans_suggs` is empty.
+                    return;
+                }
                 err.multipart_suggestion_verbose(
                     &format!(
                         "consider using the `{}` lifetime",
diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs
index 76e50678314..4bf909ce46d 100644
--- a/compiler/rustc_target/src/asm/aarch64.rs
+++ b/compiler/rustc_target/src/asm/aarch64.rs
@@ -1,4 +1,5 @@
 use super::{InlineAsmArch, InlineAsmType};
+use crate::spec::Target;
 use rustc_macros::HashStable_Generic;
 use std::fmt;
 
@@ -70,6 +71,22 @@ impl AArch64InlineAsmRegClass {
     }
 }
 
+pub fn reserved_x18(
+    _arch: InlineAsmArch,
+    _has_feature: impl FnMut(&str) -> bool,
+    target: &Target,
+) -> Result<(), &'static str> {
+    if target.os == "android"
+        || target.is_like_fuchsia
+        || target.is_like_osx
+        || target.is_like_windows
+    {
+        Err("x18 is a reserved register on this target")
+    } else {
+        Ok(())
+    }
+}
+
 def_regs! {
     AArch64 AArch64InlineAsmReg AArch64InlineAsmRegClass {
         x0: reg = ["x0", "w0"],
@@ -90,6 +107,7 @@ def_regs! {
         x15: reg = ["x15", "w15"],
         x16: reg = ["x16", "w16"],
         x17: reg = ["x17", "w17"],
+        x18: reg = ["x18", "w18"] % reserved_x18,
         x20: reg = ["x20", "w20"],
         x21: reg = ["x21", "w21"],
         x22: reg = ["x22", "w22"],
@@ -149,8 +167,6 @@ def_regs! {
         p14: preg = ["p14"],
         p15: preg = ["p15"],
         ffr: preg = ["ffr"],
-        #error = ["x18", "w18"] =>
-            "x18 is used as a reserved register on some targets and cannot be used as an operand for inline asm",
         #error = ["x19", "w19"] =>
             "x19 is used internally by LLVM and cannot be used as an operand for inline asm",
         #error = ["x29", "w29", "fp", "wfp"] =>
diff --git a/compiler/rustc_target/src/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs
index 4eeb7fcc71b..b03594b3151 100644
--- a/compiler/rustc_target/src/asm/arm.rs
+++ b/compiler/rustc_target/src/asm/arm.rs
@@ -99,6 +99,22 @@ fn not_thumb1(
     }
 }
 
+fn reserved_r9(
+    arch: InlineAsmArch,
+    mut has_feature: impl FnMut(&str) -> bool,
+    target: &Target,
+) -> Result<(), &'static str> {
+    not_thumb1(arch, &mut has_feature, target)?;
+
+    // We detect this using the reserved-r9 feature instead of using the target
+    // because the relocation model can be changed with compiler options.
+    if has_feature("reserved-r9") {
+        Err("the RWPI static base register (r9) cannot be used as an operand for inline asm")
+    } else {
+        Ok(())
+    }
+}
+
 def_regs! {
     Arm ArmInlineAsmReg ArmInlineAsmRegClass {
         r0: reg = ["r0", "a1"],
@@ -109,6 +125,7 @@ def_regs! {
         r5: reg = ["r5", "v2"],
         r7: reg = ["r7", "v4"] % frame_pointer_r7,
         r8: reg = ["r8", "v5"] % not_thumb1,
+        r9: reg = ["r9", "v6", "rfp"] % reserved_r9,
         r10: reg = ["r10", "sl"] % not_thumb1,
         r11: reg = ["r11", "fp"] % frame_pointer_r11,
         r12: reg = ["r12", "ip"] % not_thumb1,
@@ -195,8 +212,6 @@ def_regs! {
         q15: qreg = ["q15"],
         #error = ["r6", "v3"] =>
             "r6 is used internally by LLVM and cannot be used as an operand for inline asm",
-        #error = ["r9", "v6", "rfp"] =>
-            "r9 is used internally by LLVM and cannot be used as an operand for inline asm",
         #error = ["r13", "sp"] =>
             "the stack pointer cannot be used as an operand for inline asm",
         #error = ["r15", "pc"] =>
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index cf940594bc4..f1f5f4389e3 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -785,6 +785,7 @@ pub enum InlineAsmClobberAbi {
     X86_64SysV,
     Arm,
     AArch64,
+    AArch64NoX18,
     RiscV,
 }
 
@@ -793,6 +794,7 @@ impl InlineAsmClobberAbi {
     /// clobber ABIs for the target.
     pub fn parse(
         arch: InlineAsmArch,
+        has_feature: impl FnMut(&str) -> bool,
         target: &Target,
         name: Symbol,
     ) -> Result<Self, &'static [&'static str]> {
@@ -816,7 +818,13 @@ impl InlineAsmClobberAbi {
                 _ => Err(&["C", "system", "efiapi", "aapcs"]),
             },
             InlineAsmArch::AArch64 => match name {
-                "C" | "system" | "efiapi" => Ok(InlineAsmClobberAbi::AArch64),
+                "C" | "system" | "efiapi" => {
+                    Ok(if aarch64::reserved_x18(arch, has_feature, target).is_err() {
+                        InlineAsmClobberAbi::AArch64NoX18
+                    } else {
+                        InlineAsmClobberAbi::AArch64
+                    })
+                }
                 _ => Err(&["C", "system", "efiapi"]),
             },
             InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => match name {
@@ -891,8 +899,25 @@ impl InlineAsmClobberAbi {
                 AArch64 AArch64InlineAsmReg {
                     x0, x1, x2, x3, x4, x5, x6, x7,
                     x8, x9, x10, x11, x12, x13, x14, x15,
-                    // x18 is platform-reserved or temporary, but we exclude it
-                    // here since it is a reserved register.
+                    x16, x17, x18, x30,
+
+                    // Technically the low 64 bits of v8-v15 are preserved, but
+                    // we have no way of expressing this using clobbers.
+                    v0, v1, v2, v3, v4, v5, v6, v7,
+                    v8, v9, v10, v11, v12, v13, v14, v15,
+                    v16, v17, v18, v19, v20, v21, v22, v23,
+                    v24, v25, v26, v27, v28, v29, v30, v31,
+
+                    p0, p1, p2, p3, p4, p5, p6, p7,
+                    p8, p9, p10, p11, p12, p13, p14, p15,
+                    ffr,
+
+                }
+            },
+            InlineAsmClobberAbi::AArch64NoX18 => clobbered_regs! {
+                AArch64 AArch64InlineAsmReg {
+                    x0, x1, x2, x3, x4, x5, x6, x7,
+                    x8, x9, x10, x11, x12, x13, x14, x15,
                     x16, x17, x30,
 
                     // Technically the low 64 bits of v8-v15 are preserved, but
@@ -910,7 +935,8 @@ impl InlineAsmClobberAbi {
             },
             InlineAsmClobberAbi::Arm => clobbered_regs! {
                 Arm ArmInlineAsmReg {
-                    // r9 is platform-reserved and is treated as callee-saved.
+                    // r9 is either platform-reserved or callee-saved. Either
+                    // way we don't need to clobber it.
                     r0, r1, r2, r3, r12, r14,
 
                     // The finest-grained register variant is used here so that
diff --git a/library/alloc/src/vec/drain.rs b/library/alloc/src/vec/drain.rs
index 089cd4db64c..1bff19d05c1 100644
--- a/library/alloc/src/vec/drain.rs
+++ b/library/alloc/src/vec/drain.rs
@@ -128,10 +128,6 @@ impl<T, A: Allocator> Drop for Drain<'_, T, A> {
 
         let iter = mem::replace(&mut self.iter, (&mut []).iter());
         let drop_len = iter.len();
-        let drop_ptr = iter.as_slice().as_ptr();
-
-        // forget iter so there's no aliasing reference
-        drop(iter);
 
         let mut vec = self.vec;
 
@@ -155,6 +151,12 @@ impl<T, A: Allocator> Drop for Drain<'_, T, A> {
             return;
         }
 
+        // as_slice() must only be called when iter.len() is > 0 because
+        // vec::Splice modifies vec::Drain fields and may grow the vec which would invalidate
+        // the iterator's internal pointers. Creating a reference to deallocated memory
+        // is invalid even when it is zero-length
+        let drop_ptr = iter.as_slice().as_ptr();
+
         unsafe {
             // drop_ptr comes from a slice::Iter which only gives us a &[T] but for drop_in_place
             // a pointer with mutable provenance is necessary. Therefore we must reconstruct
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index f45ee7b6ee8..ad2f6f213de 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -2244,13 +2244,29 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
 /// assert_eq!(*v, 42);
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
 #[inline]
-pub unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
+pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
     extern "rust-intrinsic" {
+        #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
         fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
     }
 
-    debug_assert!(is_aligned_and_not_null(dst), "attempt to write to unaligned or null pointer");
+    #[cfg(debug_assertions)]
+    fn runtime_check<T>(ptr: *mut T) {
+        debug_assert!(
+            is_aligned_and_not_null(ptr),
+            "attempt to write to unaligned or null pointer"
+        );
+    }
+    #[cfg(debug_assertions)]
+    const fn compiletime_check<T>(_ptr: *mut T) {}
+    #[cfg(debug_assertions)]
+    // SAFETY: runtime debug-assertions are a best-effort basis; it's fine to
+    // not do them during compile time
+    unsafe {
+        const_eval_select((dst,), compiletime_check, runtime_check);
+    }
 
     // SAFETY: the safety contract for `write_bytes` must be upheld by the caller.
     unsafe { write_bytes(dst, val, count) }
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 78383b54c5d..d9a40a9b2ec 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -124,6 +124,7 @@
 #![feature(const_option)]
 #![feature(const_pin)]
 #![feature(const_replace)]
+#![feature(const_ptr_is_null)]
 #![feature(const_ptr_offset)]
 #![feature(const_ptr_offset_from)]
 #![feature(const_ptr_read)]
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index 145c7ff5c32..a6e7257448c 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -1671,7 +1671,8 @@ impl<T, E> Option<Result<T, E>> {
 }
 
 // This is a separate function to reduce the code size of .expect() itself.
-#[inline(never)]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[cold]
 #[track_caller]
 const fn expect_failed(msg: &str) -> ! {
diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs
index d650a6f974b..f5c624c225f 100644
--- a/library/core/src/ptr/unique.rs
+++ b/library/core/src/ptr/unique.rs
@@ -92,7 +92,7 @@ impl<T: ?Sized> Unique<T> {
 
     /// Creates a new `Unique` if `ptr` is non-null.
     #[inline]
-    pub fn new(ptr: *mut T) -> Option<Self> {
+    pub const fn new(ptr: *mut T) -> Option<Self> {
         if !ptr.is_null() {
             // SAFETY: The pointer has already been checked and is not null.
             Some(unsafe { Unique { pointer: ptr as _, _marker: PhantomData } })
@@ -115,7 +115,7 @@ impl<T: ?Sized> Unique<T> {
     /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
     #[must_use]
     #[inline]
-    pub unsafe fn as_ref(&self) -> &T {
+    pub const unsafe fn as_ref(&self) -> &T {
         // SAFETY: the caller must guarantee that `self` meets all the
         // requirements for a reference.
         unsafe { &*self.as_ptr() }
@@ -128,7 +128,7 @@ impl<T: ?Sized> Unique<T> {
     /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
     #[must_use]
     #[inline]
-    pub unsafe fn as_mut(&mut self) -> &mut T {
+    pub const unsafe fn as_mut(&mut self) -> &mut T {
         // SAFETY: the caller must guarantee that `self` meets all the
         // requirements for a mutable reference.
         unsafe { &mut *self.as_ptr() }
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index e6b8c8ec338..ab067d57d08 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -1653,6 +1653,7 @@ impl<T> Result<T, T> {
 }
 
 // This is a separate function to reduce the code size of the methods
+#[cfg(not(feature = "panic_immediate_abort"))]
 #[inline(never)]
 #[cold]
 #[track_caller]
@@ -1660,6 +1661,18 @@ fn unwrap_failed(msg: &str, error: &dyn fmt::Debug) -> ! {
     panic!("{}: {:?}", msg, error)
 }
 
+// This is a separate function to avoid constructing a `dyn Debug`
+// that gets immediately thrown away, since vtables don't get cleaned up
+// by dead code elimination if a trait object is constructed even if it goes
+// unused
+#[cfg(feature = "panic_immediate_abort")]
+#[inline]
+#[cold]
+#[track_caller]
+fn unwrap_failed<T>(_msg: &str, _error: &T) -> ! {
+    panic!()
+}
+
 /////////////////////////////////////////////////////////////////////////////
 // Trait implementations
 /////////////////////////////////////////////////////////////////////////////
diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs
index f7224303549..0298bba8d32 100644
--- a/library/core/src/slice/index.rs
+++ b/library/core/src/slice/index.rs
@@ -27,35 +27,40 @@ where
     }
 }
 
-#[inline(never)]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[cold]
 #[track_caller]
 fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
     panic!("range start index {} out of range for slice of length {}", index, len);
 }
 
-#[inline(never)]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[cold]
 #[track_caller]
 fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
     panic!("range end index {} out of range for slice of length {}", index, len);
 }
 
-#[inline(never)]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[cold]
 #[track_caller]
 fn slice_index_order_fail(index: usize, end: usize) -> ! {
     panic!("slice index starts at {} but ends at {}", index, end);
 }
 
-#[inline(never)]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[cold]
 #[track_caller]
 fn slice_start_index_overflow_fail() -> ! {
     panic!("attempted to index slice from after maximum usize");
 }
 
-#[inline(never)]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(feature = "panic_immediate_abort", inline)]
 #[cold]
 #[track_caller]
 fn slice_end_index_overflow_fail() -> ! {
diff --git a/library/core/tests/intrinsics.rs b/library/core/tests/intrinsics.rs
index de163a60c98..84cef53b358 100644
--- a/library/core/tests/intrinsics.rs
+++ b/library/core/tests/intrinsics.rs
@@ -35,3 +35,33 @@ fn test_assume_can_be_in_const_contexts() {
     let rs = unsafe { foo(42, 97) };
     assert_eq!(rs, 0);
 }
+
+#[test]
+#[cfg(not(bootstrap))]
+const fn test_write_bytes_in_const_contexts() {
+    use core::intrinsics::write_bytes;
+
+    const TEST: [u32; 3] = {
+        let mut arr = [1u32, 2, 3];
+        unsafe {
+            write_bytes(arr.as_mut_ptr(), 0, 2);
+        }
+        arr
+    };
+
+    assert!(TEST[0] == 0);
+    assert!(TEST[1] == 0);
+    assert!(TEST[2] == 3);
+
+    const TEST2: [u32; 3] = {
+        let mut arr = [1u32, 2, 3];
+        unsafe {
+            write_bytes(arr.as_mut_ptr(), 1, 2);
+        }
+        arr
+    };
+
+    assert!(TEST2[0] == 16843009);
+    assert!(TEST2[1] == 16843009);
+    assert!(TEST2[2] == 3);
+}
diff --git a/src/test/rustdoc/doc-notable_trait-mut_t_is_not_ref_t.rs b/src/test/rustdoc/doc-notable_trait-mut_t_is_not_ref_t.rs
new file mode 100644
index 00000000000..b359dcea0ff
--- /dev/null
+++ b/src/test/rustdoc/doc-notable_trait-mut_t_is_not_ref_t.rs
@@ -0,0 +1,21 @@
+//! Test case for [#78160].
+//!
+//! A SomeTrait that is implemented for `&mut T` should not be marked as
+//! "notable" for return values that are `&T`.
+//!
+//! [#78160]: https://github.com/rust-lang/rust/issues/78160
+
+#![feature(rustdoc_internals)]
+
+#[doc(primitive = "reference")]
+/// Some useless docs, wouhou!
+///
+/// We need to put this in here, because notable traits
+/// that are implemented on foreign types don't show up.
+mod reference {}
+
+// @has doc_notable_trait_mut_t_is_not_ref_t/fn.fn_no_matches.html
+// @!has - '//code[@class="content"]' "impl<'_, I> Iterator for &'_ mut I"
+pub fn fn_no_matches<'a, T: Iterator + 'a>() -> &'a T {
+    loop {}
+}
diff --git a/src/test/ui/asm/aarch64/bad-reg.rs b/src/test/ui/asm/aarch64/bad-reg.rs
index 4d7a7fd31fe..e346f8d992a 100644
--- a/src/test/ui/asm/aarch64/bad-reg.rs
+++ b/src/test/ui/asm/aarch64/bad-reg.rs
@@ -29,8 +29,6 @@ fn main() {
         //~^ ERROR invalid register `sp`: the stack pointer cannot be used as an operand
         asm!("", in("xzr") foo);
         //~^ ERROR invalid register `xzr`: the zero register cannot be used as an operand
-        asm!("", in("x18") foo);
-        //~^ ERROR invalid register `x18`: x18 is used as a reserved register on some targets and cannot be used as an operand for inline asm
         asm!("", in("x19") foo);
         //~^ ERROR invalid register `x19`: x19 is used internally by LLVM and cannot be used as an operand for inline asm
 
diff --git a/src/test/ui/asm/aarch64/bad-reg.stderr b/src/test/ui/asm/aarch64/bad-reg.stderr
index 091e6077ef4..42f2a5d72ec 100644
--- a/src/test/ui/asm/aarch64/bad-reg.stderr
+++ b/src/test/ui/asm/aarch64/bad-reg.stderr
@@ -74,38 +74,32 @@ error: invalid register `xzr`: the zero register cannot be used as an operand fo
 LL |         asm!("", in("xzr") foo);
    |                  ^^^^^^^^^^^^^
 
-error: invalid register `x18`: x18 is used as a reserved register on some targets and cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:32:18
-   |
-LL |         asm!("", in("x18") foo);
-   |                  ^^^^^^^^^^^^^
-
 error: invalid register `x19`: x19 is used internally by LLVM and cannot be used as an operand for inline asm
-  --> $DIR/bad-reg.rs:34:18
+  --> $DIR/bad-reg.rs:32:18
    |
 LL |         asm!("", in("x19") foo);
    |                  ^^^^^^^^^^^^^
 
 error: register class `preg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:37:18
+  --> $DIR/bad-reg.rs:35:18
    |
 LL |         asm!("", in("p0") foo);
    |                  ^^^^^^^^^^^^
 
 error: register class `preg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:40:20
+  --> $DIR/bad-reg.rs:38:20
    |
 LL |         asm!("{}", in(preg) foo);
    |                    ^^^^^^^^^^^^
 
 error: register class `preg` can only be used as a clobber, not as an input or output
-  --> $DIR/bad-reg.rs:42:20
+  --> $DIR/bad-reg.rs:40:20
    |
 LL |         asm!("{}", out(preg) _);
    |                    ^^^^^^^^^^^
 
 error: register `x0` conflicts with register `x0`
-  --> $DIR/bad-reg.rs:48:32
+  --> $DIR/bad-reg.rs:46:32
    |
 LL |         asm!("", in("x0") foo, in("w0") bar);
    |                  ------------  ^^^^^^^^^^^^ register `x0`
@@ -113,7 +107,7 @@ LL |         asm!("", in("x0") foo, in("w0") bar);
    |                  register `x0`
 
 error: register `x0` conflicts with register `x0`
-  --> $DIR/bad-reg.rs:50:32
+  --> $DIR/bad-reg.rs:48:32
    |
 LL |         asm!("", in("x0") foo, out("x0") bar);
    |                  ------------  ^^^^^^^^^^^^^ register `x0`
@@ -121,13 +115,13 @@ LL |         asm!("", in("x0") foo, out("x0") bar);
    |                  register `x0`
    |
 help: use `lateout` instead of `out` to avoid conflict
-  --> $DIR/bad-reg.rs:50:18
+  --> $DIR/bad-reg.rs:48:18
    |
 LL |         asm!("", in("x0") foo, out("x0") bar);
    |                  ^^^^^^^^^^^^
 
 error: register `v0` conflicts with register `v0`
-  --> $DIR/bad-reg.rs:53:32
+  --> $DIR/bad-reg.rs:51:32
    |
 LL |         asm!("", in("v0") foo, in("q0") bar);
    |                  ------------  ^^^^^^^^^^^^ register `v0`
@@ -135,7 +129,7 @@ LL |         asm!("", in("v0") foo, in("q0") bar);
    |                  register `v0`
 
 error: register `v0` conflicts with register `v0`
-  --> $DIR/bad-reg.rs:55:32
+  --> $DIR/bad-reg.rs:53:32
    |
 LL |         asm!("", in("v0") foo, out("q0") bar);
    |                  ------------  ^^^^^^^^^^^^^ register `v0`
@@ -143,10 +137,10 @@ LL |         asm!("", in("v0") foo, out("q0") bar);
    |                  register `v0`
    |
 help: use `lateout` instead of `out` to avoid conflict
-  --> $DIR/bad-reg.rs:55:18
+  --> $DIR/bad-reg.rs:53:18
    |
 LL |         asm!("", in("v0") foo, out("q0") bar);
    |                  ^^^^^^^^^^^^
 
-error: aborting due to 19 previous errors
+error: aborting due to 18 previous errors
 
diff --git a/src/test/ui/lifetimes/auxiliary/issue-91763-aux.rs b/src/test/ui/lifetimes/auxiliary/issue-91763-aux.rs
new file mode 100644
index 00000000000..0335f72b784
--- /dev/null
+++ b/src/test/ui/lifetimes/auxiliary/issue-91763-aux.rs
@@ -0,0 +1,47 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+//#![feature(proc_macro_diagnostic, proc_macro_span, proc_macro_def_site)]
+
+extern crate proc_macro;
+
+use proc_macro::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree};
+use std::iter::FromIterator;
+
+#[proc_macro_attribute]
+pub fn repro(_args: TokenStream, input: TokenStream) -> TokenStream {
+    let call_site = Span::call_site();
+    let span = input.into_iter().nth(8).unwrap().span();
+
+    //fn f(_: &::std::fmt::Formatter) {}
+    TokenStream::from_iter([
+        TokenTree::Ident(Ident::new("fn", call_site)),
+        TokenTree::Ident(Ident::new("f", call_site)),
+        TokenTree::Group(Group::new(
+            Delimiter::Parenthesis,
+            TokenStream::from_iter([
+                TokenTree::Ident(Ident::new("_", call_site)),
+                TokenTree::Punct(punct(':', Spacing::Alone, call_site)),
+                TokenTree::Punct(punct('&', Spacing::Alone, call_site)),
+                TokenTree::Punct(punct(':', Spacing::Joint, span)),
+                TokenTree::Punct(punct(':', Spacing::Alone, span)),
+                TokenTree::Ident(Ident::new("std", span)),
+                TokenTree::Punct(punct(':', Spacing::Joint, span)),
+                TokenTree::Punct(punct(':', Spacing::Alone, span)),
+                TokenTree::Ident(Ident::new("fmt", span)),
+                TokenTree::Punct(punct(':', Spacing::Joint, span)),
+                TokenTree::Punct(punct(':', Spacing::Alone, span)),
+                TokenTree::Ident(Ident::new("Formatter", span)),
+            ]),
+        )),
+        TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::new())),
+    ])
+}
+
+fn punct(ch: char, spacing: Spacing, span: Span) -> Punct {
+    let mut punct = Punct::new(ch, spacing);
+    punct.set_span(span);
+    punct
+}
diff --git a/src/test/ui/lifetimes/issue-91763.rs b/src/test/ui/lifetimes/issue-91763.rs
new file mode 100644
index 00000000000..2e8807fe639
--- /dev/null
+++ b/src/test/ui/lifetimes/issue-91763.rs
@@ -0,0 +1,11 @@
+// aux-build:issue-91763-aux.rs
+
+#![deny(elided_lifetimes_in_paths)]
+
+extern crate issue_91763_aux;
+
+#[issue_91763_aux::repro]
+fn f() -> Ptr<Thing>;
+//~^ ERROR hidden lifetime parameters in types are deprecated
+
+fn main() {}
diff --git a/src/test/ui/lifetimes/issue-91763.stderr b/src/test/ui/lifetimes/issue-91763.stderr
new file mode 100644
index 00000000000..1b1912c8e45
--- /dev/null
+++ b/src/test/ui/lifetimes/issue-91763.stderr
@@ -0,0 +1,14 @@
+error: hidden lifetime parameters in types are deprecated
+  --> $DIR/issue-91763.rs:8:20
+   |
+LL | fn f() -> Ptr<Thing>;
+   |                    ^ expected named lifetime parameter
+   |
+note: the lint level is defined here
+  --> $DIR/issue-91763.rs:3:9
+   |
+LL | #![deny(elided_lifetimes_in_paths)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+