commit 211f244b8ce86e0c82f0d995e4e423ba12928a98
parent 99de0744e69608ee87924b0d162e2d2e35295e2f
Author: agoloman <agoloman@mozilla.com>
Date: Tue, 2 Dec 2025 02:32:13 +0200
Revert "Bug 2002715 - Upgrade rustc-dev to 1.82.0. r=firefox-build-system-reviewers,sergesanspaille" for causing bc failures @mod.rs.
This reverts commit 6f09aa2f216bae6a7cd5c6600e9636b4cc55e330.
Diffstat:
12 files changed, 3721 insertions(+), 104 deletions(-)
diff --git a/build/build-rust/cargo-vendor-std-1.79.patch b/build/build-rust/cargo-vendor-std-1.79.patch
@@ -0,0 +1,431 @@
+Teaches Cargo to source all std dependencies from vendored sources in the rust-src
+component, making -Zbuild-std compatible with vendored builds.
+
+This was originally landed in https://github.com/rust-lang/cargo/pull/8834
+but was backed out for causing breakage in other situations. It works fine
+for Firefox's usecase, though.
+
+Most of these changes just add/edit tests for the functionality. Only the
+change to src/cargo/core/compiler/standard_lib.rs is important.
+
+diff --git a/src/cargo/core/compiler/standard_lib.rs b/src/cargo/core/compiler/standard_lib.rs
+index 3e387bddd..41be56056 100644
+--- a/src/cargo/core/compiler/standard_lib.rs
++++ b/src/cargo/core/compiler/standard_lib.rs
+@@ -11,6 +11,7 @@ use crate::ops::{self, Packages};
+ use crate::util::errors::CargoResult;
+ use crate::GlobalContext;
+ use std::collections::{HashMap, HashSet};
++use std::fs;
+ use std::path::PathBuf;
+ use std::rc::Rc;
+
+@@ -67,34 +68,54 @@ pub fn resolve_std<'gctx>(
+ build_config: &BuildConfig,
+ crates: &[String],
+ ) -> CargoResult<(PackageSet<'gctx>, Resolve, ResolvedFeatures)> {
++ let gctx = ws.gctx();
+ if build_config.build_plan {
+- ws.gctx()
++ gctx
+ .shell()
+ .warn("-Zbuild-std does not currently fully support --build-plan")?;
+ }
+
+ let src_path = detect_sysroot_src_path(target_data)?;
+- let to_patch = [
+- "rustc-std-workspace-core",
+- "rustc-std-workspace-alloc",
+- "rustc-std-workspace-std",
+- ];
+- let patches = to_patch
+- .iter()
+- .map(|&name| {
+- let source_path = SourceId::for_path(&src_path.join("library").join(name))?;
+- let dep = Dependency::parse(name, None, source_path)?;
++
++ // Special std packages should be pulled from `library/` and should be
++ // prefixed with `rustc-std-workspace-` in certain places.
++ let libs_prefix = "library/";
++ let special_std_prefix = "rustc-std-workspace-";
++ let libs_path = src_path.join(libs_prefix);
++
++ // Crates in rust-src to build. libsysroot is in some sense the "root" package
++ // of std, as nothing else depends on it, so it must be explicitly added.
++ let mut members = vec![format!("{}sysroot", libs_prefix)];
++
++ // If rust-src contains a "vendor" directory, then patch in all the crates it contains.
++ let vendor_path = src_path.join("vendor");
++ let vendor_dir = fs::read_dir(vendor_path)?;
++ let patches = vendor_dir
++ .into_iter()
++ .map(|entry| {
++ let entry = entry?;
++ let name = entry
++ .file_name()
++ .into_string()
++ .map_err(|_| anyhow::anyhow!("package name wasn't utf8"))?;
++
++ // Remap the rustc-std-workspace crates to the actual rust-src libraries
++ let path = if let Some(real_name) = name.strip_prefix(special_std_prefix) {
++ // Record this crate as something to build in the workspace
++ members.push(format!("{}{}", libs_prefix, real_name));
++ libs_path.join(&name)
++ } else {
++ entry.path()
++ };
++ let source_path = SourceId::for_path(&path)?;
++ let package = crate::sources::PathSource::new(&path, source_path, gctx).root_package()?;
++ let dep = Dependency::parse(package.name(), None, source_path)?;
+ Ok(dep)
+ })
+ .collect::<CargoResult<Vec<_>>>()?;
++
+ let crates_io_url = crate::sources::CRATES_IO_INDEX.parse().unwrap();
+ let patch = HashMap::from([(crates_io_url, patches)]);
+- let members = vec![
+- String::from("library/std"),
+- String::from("library/core"),
+- String::from("library/alloc"),
+- String::from("library/sysroot"),
+- ];
+ let ws_config = crate::core::WorkspaceConfig::Root(crate::core::WorkspaceRootConfig::new(
+ &src_path,
+ &Some(members),
+@@ -115,7 +136,6 @@ pub fn resolve_std<'gctx>(
+ None,
+ );
+
+- let gctx = ws.gctx();
+ // This is a delicate hack. In order for features to resolve correctly,
+ // the resolver needs to run a specific "current" member of the workspace.
+ // Thus, in order to set the features for `std`, we need to set `sysroot`
+diff --git a/tests/testsuite/mock-std/library/test/Cargo.toml b/tests/testsuite/mock-std/library/test/Cargo.toml
+index b9f51eda7..fed5f3973 100644
+--- a/tests/testsuite/mock-std/library/test/Cargo.toml
++++ b/tests/testsuite/mock-std/library/test/Cargo.toml
+@@ -9,3 +9,4 @@ std = { path = "../std" }
+ panic_unwind = { path = "../panic_unwind" }
+ compiler_builtins = { path = "../compiler_builtins" }
+ registry-dep-using-std = { version = "*", features = ['mockbuild'] }
++registry-dep-only-used-by-test = { version = "*" }
+diff --git a/tests/testsuite/mock-std/library/test/src/lib.rs b/tests/testsuite/mock-std/library/test/src/lib.rs
+index a112855f5..224b89bb2 100644
+--- a/tests/testsuite/mock-std/library/test/src/lib.rs
++++ b/tests/testsuite/mock-std/library/test/src/lib.rs
+@@ -7,4 +7,5 @@ extern crate test;
+ pub use test::*;
+
+ pub fn custom_api() {
++ registry_dep_only_used_by_test::wow_testing_is_so_easy();
+ }
+diff --git a/tests/testsuite/mock-std/vendor/registry-dep-only-used-by-test/Cargo.toml b/tests/testsuite/mock-std/vendor/registry-dep-only-used-by-test/Cargo.toml
+new file mode 100644
+index 000000000..31ba65a98
+--- /dev/null
++++ b/tests/testsuite/mock-std/vendor/registry-dep-only-used-by-test/Cargo.toml
+@@ -0,0 +1,9 @@
++[package]
++name = "registry-dep-only-used-by-test"
++version = "1.0.0"
++authors = ["Alex Crichton <alex@alexcrichton.com>"]
++edition = "2018"
++
++[dependencies]
++
++[features]
+diff --git a/tests/testsuite/mock-std/vendor/registry-dep-only-used-by-test/src/lib.rs b/tests/testsuite/mock-std/vendor/registry-dep-only-used-by-test/src/lib.rs
+new file mode 100644
+index 000000000..a68d2aeef
+--- /dev/null
++++ b/tests/testsuite/mock-std/vendor/registry-dep-only-used-by-test/src/lib.rs
+@@ -0,0 +1,2 @@
++pub fn wow_testing_is_so_easy() {
++}
+\ No newline at end of file
+diff --git a/tests/testsuite/mock-std/vendor/registry-dep-using-alloc/Cargo.toml b/tests/testsuite/mock-std/vendor/registry-dep-using-alloc/Cargo.toml
+new file mode 100644
+index 000000000..f7e4ab232
+--- /dev/null
++++ b/tests/testsuite/mock-std/vendor/registry-dep-using-alloc/Cargo.toml
+@@ -0,0 +1,12 @@
++[package]
++name = "registry-dep-using-alloc"
++version = "1.0.0"
++authors = ["Alex Crichton <alex@alexcrichton.com>"]
++edition = "2018"
++
++[dependencies]
++rustc-std-workspace-alloc = { version = "*", optional = true }
++rustc-std-workspace-core = { version = "*", optional = true }
++
++[features]
++mockbuild = ["rustc-std-workspace-alloc", "rustc-std-workspace-core"]
+\ No newline at end of file
+diff --git a/tests/testsuite/mock-std/vendor/registry-dep-using-alloc/src/lib.rs b/tests/testsuite/mock-std/vendor/registry-dep-using-alloc/src/lib.rs
+new file mode 100644
+index 000000000..b9ab30339
+--- /dev/null
++++ b/tests/testsuite/mock-std/vendor/registry-dep-using-alloc/src/lib.rs
+@@ -0,0 +1,9 @@
++#[cfg(feature = "mockbuild")]
++pub fn custom_api() {
++}
++
++#[cfg(not(feature = "mockbuild"))]
++pub fn non_sysroot_api() {
++ core::custom_api();
++ alloc::custom_api();
++}
+\ No newline at end of file
+diff --git a/tests/testsuite/mock-std/vendor/registry-dep-using-core/Cargo.toml b/tests/testsuite/mock-std/vendor/registry-dep-using-core/Cargo.toml
+new file mode 100644
+index 000000000..befb83a63
+--- /dev/null
++++ b/tests/testsuite/mock-std/vendor/registry-dep-using-core/Cargo.toml
+@@ -0,0 +1,11 @@
++[package]
++name = "registry-dep-using-core"
++version = "1.0.0"
++authors = ["Alex Crichton <alex@alexcrichton.com>"]
++edition = "2018"
++
++[dependencies]
++rustc-std-workspace-core = { version = "*", optional = true }
++
++[features]
++mockbuild = ["rustc-std-workspace-core"]
+\ No newline at end of file
+diff --git a/tests/testsuite/mock-std/vendor/registry-dep-using-core/src/lib.rs b/tests/testsuite/mock-std/vendor/registry-dep-using-core/src/lib.rs
+new file mode 100644
+index 000000000..f9dbac0f4
+--- /dev/null
++++ b/tests/testsuite/mock-std/vendor/registry-dep-using-core/src/lib.rs
+@@ -0,0 +1,8 @@
++#[cfg(feature = "mockbuild")]
++pub fn custom_api() {
++}
++
++#[cfg(not(feature = "mockbuild"))]
++pub fn non_sysroot_api() {
++ core::custom_api();
++}
+\ No newline at end of file
+diff --git a/tests/testsuite/mock-std/vendor/registry-dep-using-std/Cargo.toml b/tests/testsuite/mock-std/vendor/registry-dep-using-std/Cargo.toml
+new file mode 100644
+index 000000000..71ef0a42f
+--- /dev/null
++++ b/tests/testsuite/mock-std/vendor/registry-dep-using-std/Cargo.toml
+@@ -0,0 +1,11 @@
++[package]
++name = "registry-dep-using-std"
++version = "1.0.0"
++authors = ["Alex Crichton <alex@alexcrichton.com>"]
++edition = "2018"
++
++[dependencies]
++rustc-std-workspace-std = { version = "*", optional = true }
++
++[features]
++mockbuild = ["rustc-std-workspace-std"]
+\ No newline at end of file
+diff --git a/tests/testsuite/mock-std/vendor/registry-dep-using-std/src/lib.rs b/tests/testsuite/mock-std/vendor/registry-dep-using-std/src/lib.rs
+new file mode 100644
+index 000000000..f3af39178
+--- /dev/null
++++ b/tests/testsuite/mock-std/vendor/registry-dep-using-std/src/lib.rs
+@@ -0,0 +1,8 @@
++#[cfg(feature = "mockbuild")]
++pub fn custom_api() {
++}
++
++#[cfg(not(feature = "mockbuild"))]
++pub fn non_sysroot_api() {
++ std::custom_api();
++}
+\ No newline at end of file
+diff --git a/tests/testsuite/mock-std/vendor/rustc-std-workspace-alloc/Cargo.toml b/tests/testsuite/mock-std/vendor/rustc-std-workspace-alloc/Cargo.toml
+new file mode 100644
+index 000000000..4465a08a8
+--- /dev/null
++++ b/tests/testsuite/mock-std/vendor/rustc-std-workspace-alloc/Cargo.toml
+@@ -0,0 +1 @@
++this file shouldn't be read
+\ No newline at end of file
+diff --git a/tests/testsuite/mock-std/vendor/rustc-std-workspace-core/Cargo.toml b/tests/testsuite/mock-std/vendor/rustc-std-workspace-core/Cargo.toml
+new file mode 100644
+index 000000000..4465a08a8
+--- /dev/null
++++ b/tests/testsuite/mock-std/vendor/rustc-std-workspace-core/Cargo.toml
+@@ -0,0 +1 @@
++this file shouldn't be read
+\ No newline at end of file
+diff --git a/tests/testsuite/mock-std/vendor/rustc-std-workspace-std/Cargo.toml b/tests/testsuite/mock-std/vendor/rustc-std-workspace-std/Cargo.toml
+new file mode 100644
+index 000000000..4465a08a8
+--- /dev/null
++++ b/tests/testsuite/mock-std/vendor/rustc-std-workspace-std/Cargo.toml
+@@ -0,0 +1 @@
++this file shouldn't be read
+\ No newline at end of file
+diff --git a/tests/testsuite/standard_lib.rs b/tests/testsuite/standard_lib.rs
+index d3be303ea..486a9b4e0 100644
+--- a/tests/testsuite/standard_lib.rs
++++ b/tests/testsuite/standard_lib.rs
+@@ -15,71 +15,18 @@ struct Setup {
+ }
+
+ fn setup() -> Setup {
+- // Our mock sysroot requires a few packages from crates.io, so make sure
+- // they're "published" to crates.io. Also edit their code a bit to make sure
+- // that they have access to our custom crates with custom apis.
++ // Register a version of one of the std dependencies that doesn't compile.
++ // This ensures that the mock-std's vendor is actually being used.
+ Package::new("registry-dep-using-core", "1.0.0")
+ .file(
+ "src/lib.rs",
+ "
+- #![no_std]
+-
+- #[cfg(feature = \"mockbuild\")]
+- pub fn custom_api() {
+- }
+-
+- #[cfg(not(feature = \"mockbuild\"))]
+- pub fn non_sysroot_api() {
+- core::custom_api();
+- }
++ don't compile me bro!!
+ ",
+ )
+ .add_dep(Dependency::new("rustc-std-workspace-core", "*").optional(true))
+ .feature("mockbuild", &["rustc-std-workspace-core"])
+ .publish();
+- Package::new("registry-dep-using-alloc", "1.0.0")
+- .file(
+- "src/lib.rs",
+- "
+- #![no_std]
+-
+- extern crate alloc;
+-
+- #[cfg(feature = \"mockbuild\")]
+- pub fn custom_api() {
+- }
+-
+- #[cfg(not(feature = \"mockbuild\"))]
+- pub fn non_sysroot_api() {
+- core::custom_api();
+- alloc::custom_api();
+- }
+- ",
+- )
+- .add_dep(Dependency::new("rustc-std-workspace-core", "*").optional(true))
+- .add_dep(Dependency::new("rustc-std-workspace-alloc", "*").optional(true))
+- .feature(
+- "mockbuild",
+- &["rustc-std-workspace-core", "rustc-std-workspace-alloc"],
+- )
+- .publish();
+- Package::new("registry-dep-using-std", "1.0.0")
+- .file(
+- "src/lib.rs",
+- "
+- #[cfg(feature = \"mockbuild\")]
+- pub fn custom_api() {
+- }
+-
+- #[cfg(not(feature = \"mockbuild\"))]
+- pub fn non_sysroot_api() {
+- std::custom_api();
+- }
+- ",
+- )
+- .add_dep(Dependency::new("rustc-std-workspace-std", "*").optional(true))
+- .feature("mockbuild", &["rustc-std-workspace-std"])
+- .publish();
+
+ let p = ProjectBuilder::new(paths::root().join("rustc-wrapper"))
+ .file(
+@@ -335,6 +282,81 @@ fn depend_same_as_std() {
+ fn test() {
+ let setup = setup();
+
++ // Our mock sysroot requires a few packages from crates.io, so make sure
++ // they're "published" to crates.io. Also edit their code a bit to make sure
++ // that they have access to our custom crates with custom apis.
++ Package::new("registry-dep-using-core", "1.0.0")
++ .file(
++ "src/lib.rs",
++ "
++ #![no_std]
++
++ #[cfg(feature = \"mockbuild\")]
++ pub fn custom_api() {
++ }
++
++ #[cfg(not(feature = \"mockbuild\"))]
++ pub fn non_sysroot_api() {
++ core::custom_api();
++ }
++ ",
++ )
++ .add_dep(Dependency::new("rustc-std-workspace-core", "*").optional(true))
++ .feature("mockbuild", &["rustc-std-workspace-core"])
++ .publish();
++ Package::new("registry-dep-using-alloc", "1.0.0")
++ .file(
++ "src/lib.rs",
++ "
++ #![no_std]
++
++ extern crate alloc;
++
++ #[cfg(feature = \"mockbuild\")]
++ pub fn custom_api() {
++ }
++
++ #[cfg(not(feature = \"mockbuild\"))]
++ pub fn non_sysroot_api() {
++ core::custom_api();
++ alloc::custom_api();
++ }
++ ",
++ )
++ .add_dep(Dependency::new("rustc-std-workspace-core", "*").optional(true))
++ .add_dep(Dependency::new("rustc-std-workspace-alloc", "*").optional(true))
++ .feature(
++ "mockbuild",
++ &["rustc-std-workspace-core", "rustc-std-workspace-alloc"],
++ )
++ .publish();
++ Package::new("registry-dep-using-std", "1.0.0")
++ .file(
++ "src/lib.rs",
++ "
++ #[cfg(feature = \"mockbuild\")]
++ pub fn custom_api() {
++ }
++
++ #[cfg(not(feature = \"mockbuild\"))]
++ pub fn non_sysroot_api() {
++ std::custom_api();
++ }
++ ",
++ )
++ .add_dep(Dependency::new("rustc-std-workspace-std", "*").optional(true))
++ .feature("mockbuild", &["rustc-std-workspace-std"])
++ .publish();
++ Package::new("registry-dep-only-used-by-test", "1.0.0")
++ .file(
++ "src/lib.rs",
++ "
++ pub fn wow_testing_is_so_easy() {
++ }
++ ",
++ )
++ .publish();
++
+ let p = project()
+ .file(
+ "src/lib.rs",
diff --git a/build/build-rust/rename_AddressOf_to_RawBorrow_inside_the_compiler.patch b/build/build-rust/rename_AddressOf_to_RawBorrow_inside_the_compiler.patch
@@ -0,0 +1,919 @@
+From 35709be02d43b40e7f720408f8a88bf6e9d5501d Mon Sep 17 00:00:00 2001
+From: Ralf Jung <post@ralfj.de>
+Date: Mon, 12 Aug 2024 10:57:57 +0200
+Subject: [PATCH] rename AddressOf -> RawBorrow inside the compiler
+
+diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs
+index 1f0b0981c8f29..e07d7dd309ae2 100644
+--- a/compiler/rustc_borrowck/src/def_use.rs
++++ b/compiler/rustc_borrowck/src/def_use.rs
+@@ -55,8 +55,8 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> {
+ PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention) |
+ PlaceContext::NonUse(NonUseContext::AscribeUserTy(_)) |
+
+- PlaceContext::MutatingUse(MutatingUseContext::AddressOf) |
+- PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) |
++ PlaceContext::MutatingUse(MutatingUseContext::RawBorrow) |
++ PlaceContext::NonMutatingUse(NonMutatingUseContext::RawBorrow) |
+ PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect) |
+ PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
+ PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) |
+diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
+index 30dd45d847c9b..a529df76bcbc7 100644
+--- a/compiler/rustc_borrowck/src/lib.rs
++++ b/compiler/rustc_borrowck/src/lib.rs
+@@ -1242,7 +1242,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
+ );
+ }
+
+- &Rvalue::AddressOf(mutability, place) => {
++ &Rvalue::RawPtr(mutability, place) => {
+ let access_kind = match mutability {
+ Mutability::Mut => (
+ Deep,
+diff --git a/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
+index f090da031a04b..a57041cd04c52 100644
+--- a/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
++++ b/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
+@@ -269,7 +269,7 @@ impl<'cx, 'tcx> LoanInvalidationsGenerator<'cx, 'tcx> {
+ self.access_place(location, place, access_kind, LocalMutationIsAllowed::No);
+ }
+
+- &Rvalue::AddressOf(mutability, place) => {
++ &Rvalue::RawPtr(mutability, place) => {
+ let access_kind = match mutability {
+ Mutability::Mut => (
+ Deep,
+diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
+index a2669da1b04e8..6983cda6ddf3b 100644
+--- a/compiler/rustc_borrowck/src/type_check/mod.rs
++++ b/compiler/rustc_borrowck/src/type_check/mod.rs
+@@ -756,7 +756,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
+ PlaceContext::MutatingUse(_) => ty::Invariant,
+ PlaceContext::NonUse(StorageDead | StorageLive | VarDebugInfo) => ty::Invariant,
+ PlaceContext::NonMutatingUse(
+- Inspect | Copy | Move | PlaceMention | SharedBorrow | FakeBorrow | AddressOf
++ Inspect | Copy | Move | PlaceMention | SharedBorrow | FakeBorrow | RawBorrow
+ | Projection,
+ ) => ty::Covariant,
+ PlaceContext::NonUse(AscribeUserTy(variance)) => variance,
+@@ -2468,7 +2468,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
+ self.check_operand(right, location);
+ }
+
+- Rvalue::AddressOf(..)
++ Rvalue::RawPtr(..)
+ | Rvalue::ThreadLocalRef(..)
+ | Rvalue::Len(..)
+ | Rvalue::Discriminant(..)
+@@ -2485,7 +2485,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
+ | Rvalue::ThreadLocalRef(_)
+ | Rvalue::Repeat(..)
+ | Rvalue::Ref(..)
+- | Rvalue::AddressOf(..)
++ | Rvalue::RawPtr(..)
+ | Rvalue::Len(..)
+ | Rvalue::Cast(..)
+ | Rvalue::ShallowInitBox(..)
+diff --git a/compiler/rustc_codegen_cranelift/src/analyze.rs b/compiler/rustc_codegen_cranelift/src/analyze.rs
+index c5762638a6b13..72380f50385a1 100644
+--- a/compiler/rustc_codegen_cranelift/src/analyze.rs
++++ b/compiler/rustc_codegen_cranelift/src/analyze.rs
+@@ -25,7 +25,7 @@ pub(crate) fn analyze(fx: &FunctionCx<'_, '_, '_>) -> IndexVec<Local, SsaKind> {
+ for stmt in bb.statements.iter() {
+ match &stmt.kind {
+ Assign(place_and_rval) => match &place_and_rval.1 {
+- Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
++ Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
+ flag_map[place.local] = SsaKind::NotSsa;
+ }
+ _ => {}
+diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
+index 9bc7b57c53745..f1d885bf1bce8 100644
+--- a/compiler/rustc_codegen_cranelift/src/base.rs
++++ b/compiler/rustc_codegen_cranelift/src/base.rs
+@@ -595,7 +595,7 @@ fn codegen_stmt<'tcx>(
+ let val = cplace.to_cvalue(fx);
+ lval.write_cvalue(fx, val)
+ }
+- Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
++ Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
+ let place = codegen_place(fx, place);
+ let ref_ = place.place_ref(fx, lval.layout());
+ lval.write_cvalue(fx, ref_);
+diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+index 6794365c9beef..c8cf341628c32 100644
+--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
++++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+@@ -220,14 +220,14 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
+ | MutatingUseContext::SetDiscriminant
+ | MutatingUseContext::AsmOutput
+ | MutatingUseContext::Borrow
+- | MutatingUseContext::AddressOf
++ | MutatingUseContext::RawBorrow
+ | MutatingUseContext::Projection,
+ )
+ | PlaceContext::NonMutatingUse(
+ NonMutatingUseContext::Inspect
+ | NonMutatingUseContext::SharedBorrow
+ | NonMutatingUseContext::FakeBorrow
+- | NonMutatingUseContext::AddressOf
++ | NonMutatingUseContext::RawBorrow
+ | NonMutatingUseContext::Projection,
+ ) => {
+ self.locals[local] = LocalKind::Memory;
+diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+index 3c2c29ac7f7d2..d94c6f8ddcec3 100644
+--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
++++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+@@ -584,7 +584,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
+ mir::Rvalue::CopyForDeref(place) => {
+ self.codegen_operand(bx, &mir::Operand::Copy(place))
+ }
+- mir::Rvalue::AddressOf(mutability, place) => {
++ mir::Rvalue::RawPtr(mutability, place) => {
+ let mk_ptr =
+ move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| Ty::new_ptr(tcx, ty, mutability);
+ self.codegen_place_to_pointer(bx, place, mk_ptr)
+@@ -813,7 +813,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
+ cg_value.len(bx.cx())
+ }
+
+- /// Codegen an `Rvalue::AddressOf` or `Rvalue::Ref`
++ /// Codegen an `Rvalue::RawPtr` or `Rvalue::Ref`
+ fn codegen_place_to_pointer(
+ &mut self,
+ bx: &mut Bx,
+@@ -1085,7 +1085,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
+ }
+ mir::Rvalue::Ref(..) |
+ mir::Rvalue::CopyForDeref(..) |
+- mir::Rvalue::AddressOf(..) |
++ mir::Rvalue::RawPtr(..) |
+ mir::Rvalue::Len(..) |
+ mir::Rvalue::Cast(..) | // (*)
+ mir::Rvalue::ShallowInitBox(..) | // (*)
+diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
+index 32a9247bcc70a..86a5afa65ba87 100644
+--- a/compiler/rustc_const_eval/src/check_consts/check.rs
++++ b/compiler/rustc_const_eval/src/check_consts/check.rs
+@@ -431,13 +431,13 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
+ return;
+ }
+ }
+- Rvalue::AddressOf(mutbl, place) => {
++ Rvalue::RawPtr(mutbl, place) => {
+ if let Some(reborrowed_place_ref) = place_as_reborrow(self.tcx, self.body, place) {
+ let ctx = match mutbl {
+ Mutability::Not => {
+- PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf)
++ PlaceContext::NonMutatingUse(NonMutatingUseContext::RawBorrow)
+ }
+- Mutability::Mut => PlaceContext::MutatingUse(MutatingUseContext::AddressOf),
++ Mutability::Mut => PlaceContext::MutatingUse(MutatingUseContext::RawBorrow),
+ };
+ self.visit_local(reborrowed_place_ref.local, ctx, location);
+ self.visit_projection(reborrowed_place_ref, ctx, location);
+@@ -472,7 +472,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
+ }
+
+ Rvalue::Ref(_, BorrowKind::Mut { .. }, place)
+- | Rvalue::AddressOf(Mutability::Mut, place) => {
++ | Rvalue::RawPtr(Mutability::Mut, place) => {
+ // Inside mutable statics, we allow arbitrary mutable references.
+ // We've allowed `static mut FOO = &mut [elements];` for a long time (the exact
+ // reasons why are lost to history), and there is no reason to restrict that to
+@@ -493,7 +493,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
+ }
+
+ Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Fake(_), place)
+- | Rvalue::AddressOf(Mutability::Not, place) => {
++ | Rvalue::RawPtr(Mutability::Not, place) => {
+ let borrowed_place_has_mut_interior = qualifs::in_place::<HasMutInterior, _>(
+ self.ccx,
+ &mut |local| self.qualifs.has_mut_interior(self.ccx, local, location),
+diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
+index c0f2d113c7e31..c566dc7fa844d 100644
+--- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs
++++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs
+@@ -291,7 +291,7 @@ where
+ in_operand::<Q, _>(cx, in_local, lhs) || in_operand::<Q, _>(cx, in_local, rhs)
+ }
+
+- Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
++ Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
+ // Special-case reborrows to be more like a copy of the reference.
+ if let Some((place_base, ProjectionElem::Deref)) = place.as_ref().last_projection() {
+ let base_ty = place_base.ty(cx.body, cx.tcx).ty;
+diff --git a/compiler/rustc_const_eval/src/check_consts/resolver.rs b/compiler/rustc_const_eval/src/check_consts/resolver.rs
+index ea3a5264357c9..681184f7fbcde 100644
+--- a/compiler/rustc_const_eval/src/check_consts/resolver.rs
++++ b/compiler/rustc_const_eval/src/check_consts/resolver.rs
+@@ -96,7 +96,7 @@ where
+ }
+
+ fn address_of_allows_mutation(&self) -> bool {
+- // Exact set of permissions granted by AddressOf is undecided. Conservatively assume that
++ // Exact set of permissions granted by RawPtr is undecided. Conservatively assume that
+ // it might allow mutation until resolution of #56604.
+ true
+ }
+@@ -170,7 +170,7 @@ where
+ self.super_rvalue(rvalue, location);
+
+ match rvalue {
+- mir::Rvalue::AddressOf(_mt, borrowed_place) => {
++ mir::Rvalue::RawPtr(_mt, borrowed_place) => {
+ if !borrowed_place.is_indirect() && self.address_of_allows_mutation() {
+ let place_ty = borrowed_place.ty(self.ccx.body, self.ccx.tcx).ty;
+ if Q::in_any_value_of_ty(self.ccx, place_ty) {
+diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
+index aaee6f6d247f8..70cfba1922c6e 100644
+--- a/compiler/rustc_const_eval/src/interpret/step.rs
++++ b/compiler/rustc_const_eval/src/interpret/step.rs
+@@ -234,7 +234,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
+ self.write_immediate(*val, &dest)?;
+ }
+
+- AddressOf(_, place) => {
++ RawPtr(_, place) => {
+ // Figure out whether this is an addr_of of an already raw place.
+ let place_base_raw = if place.is_indirect_first_projection() {
+ let ty = self.frame().body.local_decls[place.local].ty;
+diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
+index 7cd97166ed1e9..03a76d44cc987 100644
+--- a/compiler/rustc_hir_typeck/src/cast.rs
++++ b/compiler/rustc_hir_typeck/src/cast.rs
+@@ -967,7 +967,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
+ // need to special-case obtaining a raw pointer
+ // from a region pointer to a vector.
+
+- // Coerce to a raw pointer so that we generate AddressOf in MIR.
++ // Coerce to a raw pointer so that we generate RawPtr in MIR.
+ let array_ptr_type = Ty::new_ptr(fcx.tcx, m_expr.ty, m_expr.mutbl);
+ fcx.coerce(self.expr, self.expr_ty, array_ptr_type, AllowTwoPhase::No, None)
+ .unwrap_or_else(|_| {
+diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
+index 5dd0e69cf1fe6..212eda666ca05 100644
+--- a/compiler/rustc_middle/src/mir/pretty.rs
++++ b/compiler/rustc_middle/src/mir/pretty.rs
+@@ -1038,7 +1038,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
+
+ CopyForDeref(ref place) => write!(fmt, "deref_copy {place:#?}"),
+
+- AddressOf(mutability, ref place) => {
++ RawPtr(mutability, ref place) => {
+ write!(fmt, "&raw {mut_str} {place:?}", mut_str = mutability.ptr_str())
+ }
+
+diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs
+index 3009ca8d8097a..bc7dfa6205e71 100644
+--- a/compiler/rustc_middle/src/mir/statement.rs
++++ b/compiler/rustc_middle/src/mir/statement.rs
+@@ -423,7 +423,7 @@ impl<'tcx> Rvalue<'tcx> {
+ | Rvalue::Repeat(_, _)
+ | Rvalue::Ref(_, _, _)
+ | Rvalue::ThreadLocalRef(_)
+- | Rvalue::AddressOf(_, _)
++ | Rvalue::RawPtr(_, _)
+ | Rvalue::Len(_)
+ | Rvalue::Cast(
+ CastKind::IntToInt
+diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
+index 1119ff6ff3d60..51b4154ddab78 100644
+--- a/compiler/rustc_middle/src/mir/syntax.rs
++++ b/compiler/rustc_middle/src/mir/syntax.rs
+@@ -1293,14 +1293,14 @@ pub enum Rvalue<'tcx> {
+ /// nature of this operation?
+ ThreadLocalRef(DefId),
+
+- /// Creates a pointer with the indicated mutability to the place.
++ /// Creates a raw pointer with the indicated mutability to the place.
+ ///
+- /// This is generated by pointer casts like `&v as *const _` or raw address of expressions like
+- /// `&raw v` or `addr_of!(v)`.
++ /// This is generated by pointer casts like `&v as *const _` or raw borrow expressions like
++ /// `&raw const v`.
+ ///
+ /// Like with references, the semantics of this operation are heavily dependent on the aliasing
+ /// model.
+- AddressOf(Mutability, Place<'tcx>),
++ RawPtr(Mutability, Place<'tcx>),
+
+ /// Yields the length of the place, as a `usize`.
+ ///
+diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
+index 1075344dc00f3..8d57d0d865469 100644
+--- a/compiler/rustc_middle/src/mir/tcx.rs
++++ b/compiler/rustc_middle/src/mir/tcx.rs
+@@ -170,7 +170,7 @@ impl<'tcx> Rvalue<'tcx> {
+ let place_ty = place.ty(local_decls, tcx).ty;
+ Ty::new_ref(tcx, reg, place_ty, bk.to_mutbl_lossy())
+ }
+- Rvalue::AddressOf(mutability, ref place) => {
++ Rvalue::RawPtr(mutability, ref place) => {
+ let place_ty = place.ty(local_decls, tcx).ty;
+ Ty::new_ptr(tcx, place_ty, mutability)
+ }
+diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
+index 3921176873c81..bfb129495ce83 100644
+--- a/compiler/rustc_middle/src/mir/visit.rs
++++ b/compiler/rustc_middle/src/mir/visit.rs
+@@ -682,13 +682,13 @@ macro_rules! make_mir_visitor {
+ );
+ }
+
+- Rvalue::AddressOf(m, path) => {
++ Rvalue::RawPtr(m, path) => {
+ let ctx = match m {
+ Mutability::Mut => PlaceContext::MutatingUse(
+- MutatingUseContext::AddressOf
++ MutatingUseContext::RawBorrow
+ ),
+ Mutability::Not => PlaceContext::NonMutatingUse(
+- NonMutatingUseContext::AddressOf
++ NonMutatingUseContext::RawBorrow
+ ),
+ };
+ self.visit_place(path, ctx, location);
+@@ -1299,8 +1299,8 @@ pub enum NonMutatingUseContext {
+ /// FIXME: do we need to distinguish shallow and deep fake borrows? In fact, do we need to
+ /// distinguish fake and normal deep borrows?
+ FakeBorrow,
+- /// AddressOf for *const pointer.
+- AddressOf,
++ /// `&raw const`.
++ RawBorrow,
+ /// PlaceMention statement.
+ ///
+ /// This statement is executed as a check that the `Place` is live without reading from it,
+@@ -1333,8 +1333,8 @@ pub enum MutatingUseContext {
+ Drop,
+ /// Mutable borrow.
+ Borrow,
+- /// AddressOf for *mut pointer.
+- AddressOf,
++ /// `&raw mut`.
++ RawBorrow,
+ /// Used as base for another place, e.g., `x` in `x.y`. Could potentially mutate the place.
+ /// For example, the projection `x.y` is marked as a mutation in these cases:
+ /// ```ignore (illustrative)
+@@ -1386,8 +1386,8 @@ impl PlaceContext {
+ pub fn is_address_of(&self) -> bool {
+ matches!(
+ self,
+- PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf)
+- | PlaceContext::MutatingUse(MutatingUseContext::AddressOf)
++ PlaceContext::NonMutatingUse(NonMutatingUseContext::RawBorrow)
++ | PlaceContext::MutatingUse(MutatingUseContext::RawBorrow)
+ )
+ }
+
+diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
+index f2ea32275f9b1..aca1390935ef1 100644
+--- a/compiler/rustc_middle/src/thir.rs
++++ b/compiler/rustc_middle/src/thir.rs
+@@ -407,7 +407,7 @@ pub enum ExprKind<'tcx> {
+ arg: ExprId,
+ },
+ /// A `&raw [const|mut] $place_expr` raw borrow resulting in type `*[const|mut] T`.
+- AddressOf {
++ RawBorrow {
+ mutability: hir::Mutability,
+ arg: ExprId,
+ },
+diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs
+index f198881043739..e246ecebbec0b 100644
+--- a/compiler/rustc_middle/src/thir/visit.rs
++++ b/compiler/rustc_middle/src/thir/visit.rs
+@@ -92,7 +92,7 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
+ }
+ VarRef { id: _ } | UpvarRef { closure_def_id: _, var_hir_id: _ } => {}
+ Borrow { arg, borrow_kind: _ } => visitor.visit_expr(&visitor.thir()[arg]),
+- AddressOf { arg, mutability: _ } => visitor.visit_expr(&visitor.thir()[arg]),
++ RawBorrow { arg, mutability: _ } => visitor.visit_expr(&visitor.thir()[arg]),
+ Break { value, label: _ } => {
+ if let Some(value) = value {
+ visitor.visit_expr(&visitor.thir()[value])
+diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
+index 56896d945e5f3..0b13ceb574d04 100644
+--- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
++++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
+@@ -244,8 +244,8 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
+ ExprKind::Borrow { borrow_kind, arg } => Ok(
+ Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?)
+ ),
+- ExprKind::AddressOf { mutability, arg } => Ok(
+- Rvalue::AddressOf(*mutability, self.parse_place(*arg)?)
++ ExprKind::RawBorrow { mutability, arg } => Ok(
++ Rvalue::RawPtr(*mutability, self.parse_place(*arg)?)
+ ),
+ ExprKind::Binary { op, lhs, rhs } => Ok(
+ Rvalue::BinaryOp(*op, Box::new((self.parse_operand(*lhs)?, self.parse_operand(*rhs)?)))
+diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs
+index b80d9de70c8da..07784982631f8 100644
+--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
++++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
+@@ -542,7 +542,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
+ | ExprKind::PointerCoercion { .. }
+ | ExprKind::Repeat { .. }
+ | ExprKind::Borrow { .. }
+- | ExprKind::AddressOf { .. }
++ | ExprKind::RawBorrow { .. }
+ | ExprKind::Match { .. }
+ | ExprKind::If { .. }
+ | ExprKind::Loop { .. }
+diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+index 379d2140c09c5..0c9571da3cf7f 100644
+--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
++++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+@@ -512,7 +512,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
+ | ExprKind::NeverToAny { .. }
+ | ExprKind::Use { .. }
+ | ExprKind::Borrow { .. }
+- | ExprKind::AddressOf { .. }
++ | ExprKind::RawBorrow { .. }
+ | ExprKind::Adt { .. }
+ | ExprKind::Loop { .. }
+ | ExprKind::LogicalOp { .. }
+diff --git a/compiler/rustc_mir_build/src/build/expr/category.rs b/compiler/rustc_mir_build/src/build/expr/category.rs
+index e07ba6b6e9383..e0349e3e3f668 100644
+--- a/compiler/rustc_mir_build/src/build/expr/category.rs
++++ b/compiler/rustc_mir_build/src/build/expr/category.rs
+@@ -51,7 +51,7 @@ impl Category {
+ | ExprKind::Use { .. }
+ | ExprKind::Adt { .. }
+ | ExprKind::Borrow { .. }
+- | ExprKind::AddressOf { .. }
++ | ExprKind::RawBorrow { .. }
+ | ExprKind::Yield { .. }
+ | ExprKind::Call { .. }
+ | ExprKind::InlineAsm { .. } => Some(Category::Rvalue(RvalueFunc::Into)),
+diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
+index 01b32b8e05e49..1c805ed20cc36 100644
+--- a/compiler/rustc_mir_build/src/build/expr/into.rs
++++ b/compiler/rustc_mir_build/src/build/expr/into.rs
+@@ -303,12 +303,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
+ this.cfg.push_assign(block, source_info, destination, borrow);
+ block.unit()
+ }
+- ExprKind::AddressOf { mutability, arg } => {
++ ExprKind::RawBorrow { mutability, arg } => {
+ let place = match mutability {
+ hir::Mutability::Not => this.as_read_only_place(block, arg),
+ hir::Mutability::Mut => this.as_place(block, arg),
+ };
+- let address_of = Rvalue::AddressOf(mutability, unpack!(block = place));
++ let address_of = Rvalue::RawPtr(mutability, unpack!(block = place));
+ this.cfg.push_assign(block, source_info, destination, address_of);
+ block.unit()
+ }
+diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
+index 9b85ad0ad0891..e4e5844d2ef8e 100644
+--- a/compiler/rustc_mir_build/src/check_unsafety.rs
++++ b/compiler/rustc_mir_build/src/check_unsafety.rs
+@@ -397,7 +397,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
+ | ExprKind::Scope { .. }
+ | ExprKind::Cast { .. } => {}
+
+- ExprKind::AddressOf { .. }
++ ExprKind::RawBorrow { .. }
+ | ExprKind::Adt { .. }
+ | ExprKind::Array { .. }
+ | ExprKind::Binary { .. }
+@@ -498,7 +498,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
+ }
+ }
+ }
+- ExprKind::AddressOf { arg, .. } => {
++ ExprKind::RawBorrow { arg, .. } => {
+ if let ExprKind::Scope { value: arg, .. } = self.thir[arg].kind
+ // THIR desugars UNSAFE_STATIC into *UNSAFE_STATIC_REF, where
+ // UNSAFE_STATIC_REF holds the addr of the UNSAFE_STATIC, so: take two steps
+diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
+index d4de5fac96eb0..2cbaed2cc6258 100644
+--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
++++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
+@@ -143,7 +143,7 @@ impl<'tcx> Cx<'tcx> {
+ arg: self.thir.exprs.push(expr),
+ },
+ Adjust::Borrow(AutoBorrow::RawPtr(mutability)) => {
+- ExprKind::AddressOf { mutability, arg: self.thir.exprs.push(expr) }
++ ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) }
+ }
+ Adjust::DynStar => ExprKind::Cast { source: self.thir.exprs.push(expr) },
+ };
+@@ -396,7 +396,7 @@ impl<'tcx> Cx<'tcx> {
+ }
+
+ hir::ExprKind::AddrOf(hir::BorrowKind::Raw, mutability, arg) => {
+- ExprKind::AddressOf { mutability, arg: self.mirror_expr(arg) }
++ ExprKind::RawBorrow { mutability, arg: self.mirror_expr(arg) }
+ }
+
+ hir::ExprKind::Block(blk, _) => ExprKind::Block { block: self.mirror_block(blk) },
+diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+index 85b9dacb1293c..bc1acd51c6911 100644
+--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
++++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+@@ -325,7 +325,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
+ Assign { .. } | AssignOp { .. } | InlineAsm { .. } | Let { .. } => true,
+
+ // These evaluate to a value.
+- AddressOf { .. }
++ RawBorrow { .. }
+ | Adt { .. }
+ | Array { .. }
+ | Binary { .. }
+diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs
+index 2d4b39e7b08f3..ce7774f594882 100644
+--- a/compiler/rustc_mir_build/src/thir/print.rs
++++ b/compiler/rustc_mir_build/src/thir/print.rs
+@@ -379,8 +379,8 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
+ self.print_expr(*arg, depth_lvl + 2);
+ print_indented!(self, ")", depth_lvl);
+ }
+- AddressOf { mutability, arg } => {
+- print_indented!(self, "AddressOf {", depth_lvl);
++ RawBorrow { mutability, arg } => {
++ print_indented!(self, "RawBorrow {", depth_lvl);
+ print_indented!(self, format!("mutability: {:?}", mutability), depth_lvl + 1);
+ print_indented!(self, "arg:", depth_lvl + 1);
+ self.print_expr(*arg, depth_lvl + 2);
+diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
+index 2ec3b53bc9814..d7e738b8829e0 100644
+--- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
++++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
+@@ -703,7 +703,7 @@ where
+ statements: vec![
+ self.assign(
+ ptr,
+- Rvalue::AddressOf(Mutability::Mut, tcx.mk_place_index(self.place, cur)),
++ Rvalue::RawPtr(Mutability::Mut, tcx.mk_place_index(self.place, cur)),
+ ),
+ self.assign(
+ cur.into(),
+diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
+index 885fdd0d58bea..e8e78fb8a89ee 100644
+--- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
++++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
+@@ -94,7 +94,7 @@ where
+ match rvalue {
+ // We ignore fake borrows as these get removed after analysis and shouldn't effect
+ // the layout of generators.
+- Rvalue::AddressOf(_, borrowed_place)
++ Rvalue::RawPtr(_, borrowed_place)
+ | Rvalue::Ref(_, BorrowKind::Mut { .. } | BorrowKind::Shared, borrowed_place) => {
+ if !borrowed_place.is_indirect() {
+ self.trans.gen_(borrowed_place.local);
+diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs
+index 7822fb17f7298..ddfd0739358d1 100644
+--- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs
++++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs
+@@ -351,7 +351,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> {
+ && let Some((_, rvalue)) = statement.kind.as_assign()
+ && let mir::Rvalue::Ref(_, mir::BorrowKind::Mut { .. }, place)
+ // FIXME: Does `&raw const foo` allow mutation? See #90413.
+- | mir::Rvalue::AddressOf(_, place) = rvalue
++ | mir::Rvalue::RawPtr(_, place) = rvalue
+ && let LookupResult::Exact(mpi) = self.move_data().rev_lookup.find(place.as_ref())
+ {
+ on_all_children_bits(self.move_data(), mpi, |child| {
+diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
+index 48bdb1316012f..24a4b32ceb7c4 100644
+--- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs
++++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
+@@ -189,13 +189,13 @@ impl DefUse {
+
+ // All other contexts are uses...
+ PlaceContext::MutatingUse(
+- MutatingUseContext::AddressOf
++ MutatingUseContext::RawBorrow
+ | MutatingUseContext::Borrow
+ | MutatingUseContext::Drop
+ | MutatingUseContext::Retag,
+ )
+ | PlaceContext::NonMutatingUse(
+- NonMutatingUseContext::AddressOf
++ NonMutatingUseContext::RawBorrow
+ | NonMutatingUseContext::Copy
+ | NonMutatingUseContext::Inspect
+ | NonMutatingUseContext::Move
+diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+index 86091379f5a92..14390723ba4b6 100644
+--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
++++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+@@ -432,7 +432,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
+ }
+ Rvalue::CopyForDeref(..) => unreachable!(),
+ Rvalue::Ref(..)
+- | Rvalue::AddressOf(..)
++ | Rvalue::RawPtr(..)
+ | Rvalue::Discriminant(..)
+ | Rvalue::Len(..)
+ | Rvalue::NullaryOp(
+diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs
+index 139fd592f69a3..2b20a35b61e29 100644
+--- a/compiler/rustc_mir_dataflow/src/value_analysis.rs
++++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs
+@@ -177,7 +177,7 @@ pub trait ValueAnalysis<'tcx> {
+ match rvalue {
+ Rvalue::Use(operand) => self.handle_operand(operand, state),
+ Rvalue::CopyForDeref(place) => self.handle_operand(&Operand::Copy(*place), state),
+- Rvalue::Ref(..) | Rvalue::AddressOf(..) => {
++ Rvalue::Ref(..) | Rvalue::RawPtr(..) => {
+ // We don't track such places.
+ ValueOrPlace::TOP
+ }
+diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs
+index 16977a63c598e..12a68790374e5 100644
+--- a/compiler/rustc_mir_transform/src/add_retag.rs
++++ b/compiler/rustc_mir_transform/src/add_retag.rs
+@@ -131,9 +131,9 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
+ // Ptr-creating operations already do their own internal retagging, no
+ // need to also add a retag statement.
+ // *Except* if we are deref'ing a Box, because those get desugared to directly working
+- // with the inner raw pointer! That's relevant for `AddressOf` as Miri otherwise makes it
++ // with the inner raw pointer! That's relevant for `RawPtr` as Miri otherwise makes it
+ // a NOP when the original pointer is already raw.
+- Rvalue::AddressOf(_mutbl, place) => {
++ Rvalue::RawPtr(_mutbl, place) => {
+ // Using `is_box_global` here is a bit sketchy: if this code is
+ // generic over the allocator, we'll not add a retag! This is a hack
+ // to make Stacked Borrows compatible with custom allocator code.
+diff --git a/compiler/rustc_mir_transform/src/check_alignment.rs b/compiler/rustc_mir_transform/src/check_alignment.rs
+index a1dbd7dc50ec7..5dfdcfc8b9446 100644
+--- a/compiler/rustc_mir_transform/src/check_alignment.rs
++++ b/compiler/rustc_mir_transform/src/check_alignment.rs
+@@ -71,7 +71,7 @@ struct PointerFinder<'tcx, 'a> {
+ impl<'tcx, 'a> Visitor<'tcx> for PointerFinder<'tcx, 'a> {
+ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
+ // We want to only check reads and writes to Places, so we specifically exclude
+- // Borrows and AddressOf.
++ // Borrow and RawBorrow.
+ match context {
+ PlaceContext::MutatingUse(
+ MutatingUseContext::Store
+diff --git a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
+index 370e930b74098..71af099199ea9 100644
+--- a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
++++ b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
+@@ -40,7 +40,7 @@ impl<'tcx> Visitor<'tcx> for DeduceReadOnly {
+ // This is a mutation, so mark it as such.
+ true
+ }
+- PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) => {
++ PlaceContext::NonMutatingUse(NonMutatingUseContext::RawBorrow) => {
+ // Whether mutating though a `&raw const` is allowed is still undecided, so we
+ // disable any sketchy `readonly` optimizations for now.
+ // But we only need to do this if the pointer would point into the argument.
+diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs
+index 054cdbc6bad9f..ed924761892c7 100644
+--- a/compiler/rustc_mir_transform/src/dest_prop.rs
++++ b/compiler/rustc_mir_transform/src/dest_prop.rs
+@@ -576,7 +576,7 @@ impl WriteInfo {
+ Rvalue::ThreadLocalRef(_)
+ | Rvalue::NullaryOp(_, _)
+ | Rvalue::Ref(_, _, _)
+- | Rvalue::AddressOf(_, _)
++ | Rvalue::RawPtr(_, _)
+ | Rvalue::Len(_)
+ | Rvalue::Discriminant(_)
+ | Rvalue::CopyForDeref(_) => (),
+diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
+index e16911d79c378..90e3ba26a438e 100644
+--- a/compiler/rustc_mir_transform/src/gvn.rs
++++ b/compiler/rustc_mir_transform/src/gvn.rs
+@@ -45,7 +45,7 @@
+ //!
+ //! # Handling of references
+ //!
+-//! We handle references by assigning a different "provenance" index to each Ref/AddressOf rvalue.
++//! We handle references by assigning a different "provenance" index to each Ref/RawPtr rvalue.
+ //! This ensure that we do not spuriously merge borrows that should not be merged. Meanwhile, we
+ //! consider all the derefs of an immutable reference to a freeze type to give the same value:
+ //! ```ignore (MIR)
+@@ -832,7 +832,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
+ self.simplify_place_projection(place, location);
+ return self.new_pointer(*place, AddressKind::Ref(borrow_kind));
+ }
+- Rvalue::AddressOf(mutbl, ref mut place) => {
++ Rvalue::RawPtr(mutbl, ref mut place) => {
+ self.simplify_place_projection(place, location);
+ return self.new_pointer(*place, AddressKind::Address(mutbl));
+ }
+diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
+index 1589653968c2e..3ec553d0ba0c5 100644
+--- a/compiler/rustc_mir_transform/src/instsimplify.rs
++++ b/compiler/rustc_mir_transform/src/instsimplify.rs
+@@ -141,7 +141,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
+
+ /// Transform `&(*a)` ==> `a`.
+ fn simplify_ref_deref(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
+- if let Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) = rvalue {
++ if let Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) = rvalue {
+ if let Some((base, ProjectionElem::Deref)) = place.as_ref().last_projection() {
+ if rvalue.ty(self.local_decls, self.tcx) != base.ty(self.local_decls, self.tcx).ty {
+ return;
+diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
+index 7202cc2d0427e..7eed47cf2398e 100644
+--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
++++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
+@@ -419,8 +419,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
+ }
+
+ // Do not try creating references (#67862)
+- Rvalue::AddressOf(_, place) | Rvalue::Ref(_, _, place) => {
+- trace!("skipping AddressOf | Ref for {:?}", place);
++ Rvalue::RawPtr(_, place) | Rvalue::Ref(_, _, place) => {
++ trace!("skipping RawPtr | Ref for {:?}", place);
+
+ // This may be creating mutable references or immutable references to cells.
+ // If that happens, the pointed to value could be mutated via that reference.
+@@ -616,7 +616,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
+ ImmTy::from_scalar(Scalar::from_target_usize(len, self), layout).into()
+ }
+
+- Ref(..) | AddressOf(..) => return None,
++ Ref(..) | RawPtr(..) => return None,
+
+ NullaryOp(ref null_op, ty) => {
+ let op_layout = self.use_ecx(|this| this.ecx.layout_of(ty))?;
+@@ -969,9 +969,9 @@ impl<'tcx> Visitor<'tcx> for CanConstProp {
+ // mutation.
+ | NonMutatingUse(NonMutatingUseContext::SharedBorrow)
+ | NonMutatingUse(NonMutatingUseContext::FakeBorrow)
+- | NonMutatingUse(NonMutatingUseContext::AddressOf)
++ | NonMutatingUse(NonMutatingUseContext::RawBorrow)
+ | MutatingUse(MutatingUseContext::Borrow)
+- | MutatingUse(MutatingUseContext::AddressOf) => {
++ | MutatingUse(MutatingUseContext::RawBorrow) => {
+ trace!("local {:?} can't be propagated because it's used: {:?}", local, context);
+ self.can_const_prop[local] = ConstPropMode::NoPropagation;
+ }
+diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs
+index e407929c9a7fd..cbc3169f2f10a 100644
+--- a/compiler/rustc_mir_transform/src/large_enums.rs
++++ b/compiler/rustc_mir_transform/src/large_enums.rs
+@@ -214,7 +214,7 @@ impl EnumSizeOpt {
+ source_info,
+ kind: StatementKind::Assign(Box::new((
+ dst,
+- Rvalue::AddressOf(Mutability::Mut, *lhs),
++ Rvalue::RawPtr(Mutability::Mut, *lhs),
+ ))),
+ };
+
+@@ -238,7 +238,7 @@ impl EnumSizeOpt {
+ source_info,
+ kind: StatementKind::Assign(Box::new((
+ src,
+- Rvalue::AddressOf(Mutability::Not, *rhs),
++ Rvalue::RawPtr(Mutability::Not, *rhs),
+ ))),
+ };
+
+diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs
+index 48a3266ae6f0d..6e84914ef972c 100644
+--- a/compiler/rustc_mir_transform/src/promote_consts.rs
++++ b/compiler/rustc_mir_transform/src/promote_consts.rs
+@@ -551,7 +551,7 @@ impl<'tcx> Validator<'_, 'tcx> {
+ self.validate_operand(rhs)?;
+ }
+
+- Rvalue::AddressOf(_, place) => {
++ Rvalue::RawPtr(_, place) => {
+ // We accept `&raw *`, i.e., raw reborrows -- creating a raw pointer is
+ // no problem, only using it is.
+ if let Some((place_base, ProjectionElem::Deref)) = place.as_ref().last_projection()
+diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs
+index 76e65099e9028..973a191d786e1 100644
+--- a/compiler/rustc_mir_transform/src/ref_prop.rs
++++ b/compiler/rustc_mir_transform/src/ref_prop.rs
+@@ -227,7 +227,7 @@ fn compute_replacement<'tcx>(
+ }
+ }
+ }
+- Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
++ Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
+ let mut place = *place;
+ // Try to see through `place` in order to collapse reborrow chains.
+ if place.projection.first() == Some(&PlaceElem::Deref)
+diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs
+index ea4f5fca59e67..9c3f903e0eab7 100644
+--- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs
++++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs
+@@ -343,7 +343,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
+ .tcx
+ .mk_place_elems(&[PlaceElem::Deref, PlaceElem::Field(field, field_ty)]),
+ };
+- self.put_temp_rvalue(Rvalue::AddressOf(Mutability::Mut, place))
++ self.put_temp_rvalue(Rvalue::RawPtr(Mutability::Mut, place))
+ }
+
+ /// If given Self is an enum puts `to_drop: *mut FieldTy` on top of
+@@ -363,7 +363,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
+ PlaceElem::Field(field, field_ty),
+ ]),
+ };
+- self.put_temp_rvalue(Rvalue::AddressOf(Mutability::Mut, place))
++ self.put_temp_rvalue(Rvalue::RawPtr(Mutability::Mut, place))
+ }
+
+ /// If given Self is an enum puts `to_drop: *mut FieldTy` on top of
+diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs
+index fb870425f6ef8..76591f526250c 100644
+--- a/compiler/rustc_mir_transform/src/ssa.rs
++++ b/compiler/rustc_mir_transform/src/ssa.rs
+@@ -2,9 +2,9 @@
+ //! 1/ They are only assigned-to once, either as a function parameter, or in an assign statement;
+ //! 2/ This single assignment dominates all uses;
+ //!
+-//! As we do not track indirect assignments, a local that has its address taken (either by
+-//! AddressOf or by borrowing) is considered non-SSA. However, it is UB to modify through an
+-//! immutable borrow of a `Freeze` local. Those can still be considered to be SSA.
++//! As we do not track indirect assignments, a local that has its address taken (via a borrow or raw
++//! borrow operator) is considered non-SSA. However, it is UB to modify through an immutable borrow
++//! of a `Freeze` local. Those can still be considered to be SSA.
+
+ use rustc_data_structures::graph::dominators::Dominators;
+ use rustc_index::bit_set::BitSet;
+@@ -262,7 +262,7 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor<'tcx, '_> {
+ PlaceContext::MutatingUse(MutatingUseContext::Projection)
+ | PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) => bug!(),
+ // Anything can happen with raw pointers, so remove them.
+- PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf)
++ PlaceContext::NonMutatingUse(NonMutatingUseContext::RawBorrow)
+ | PlaceContext::MutatingUse(_) => {
+ self.assignments[local] = Set1::Many;
+ }
+diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs
+index 491ae1c0d083f..36908036796c1 100644
+--- a/compiler/rustc_mir_transform/src/validate.rs
++++ b/compiler/rustc_mir_transform/src/validate.rs
+@@ -1345,7 +1345,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
+ }
+ Rvalue::Repeat(_, _)
+ | Rvalue::ThreadLocalRef(_)
+- | Rvalue::AddressOf(_, _)
++ | Rvalue::RawPtr(_, _)
+ | Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::UbChecks, _)
+ | Rvalue::Discriminant(_) => {}
+ }
+diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
+index da705e6f9598a..c442ca861d35b 100644
+--- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
++++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
+@@ -174,7 +174,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
+ ThreadLocalRef(def_id) => {
+ stable_mir::mir::Rvalue::ThreadLocalRef(tables.crate_item(*def_id))
+ }
+- AddressOf(mutability, place) => {
++ RawPtr(mutability, place) => {
+ stable_mir::mir::Rvalue::AddressOf(mutability.stable(tables), place.stable(tables))
+ }
+ Len(place) => stable_mir::mir::Rvalue::Len(place.stable(tables)),
+diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs
+index 2492688352342..4ded935b801d3 100644
+--- a/compiler/rustc_ty_utils/src/consts.rs
++++ b/compiler/rustc_ty_utils/src/consts.rs
+@@ -192,7 +192,7 @@ fn recurse_build<'tcx>(
+ ExprKind::Borrow { arg, .. } => {
+ let arg_node = &body.exprs[*arg];
+
+- // Skip reborrows for now until we allow Deref/Borrow/AddressOf
++ // Skip reborrows for now until we allow Deref/Borrow/RawBorrow
+ // expressions.
+ // FIXME(generic_const_exprs): Verify/explain why this is sound
+ if let ExprKind::Deref { arg } = arg_node.kind {
+@@ -202,7 +202,7 @@ fn recurse_build<'tcx>(
+ }
+ }
+ // FIXME(generic_const_exprs): We may want to support these.
+- ExprKind::AddressOf { .. } | ExprKind::Deref { .. } => maybe_supported_error(
++ ExprKind::RawBorrow { .. } | ExprKind::Deref { .. } => maybe_supported_error(
+ GenericConstantTooComplexSub::AddressAndDerefNotSupported(node.span),
+ )?,
+ ExprKind::Repeat { .. } | ExprKind::Array { .. } => {
+@@ -343,7 +343,7 @@ impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> {
+ | thir::ExprKind::VarRef { .. }
+ | thir::ExprKind::UpvarRef { .. }
+ | thir::ExprKind::Borrow { .. }
+- | thir::ExprKind::AddressOf { .. }
++ | thir::ExprKind::RawBorrow { .. }
+ | thir::ExprKind::Break { .. }
+ | thir::ExprKind::Continue { .. }
+ | thir::ExprKind::Return { .. }
+diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+index 553af913ef9df..95fbf0b2ea20a 100644
+--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
++++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+@@ -110,7 +110,7 @@ fn check_rvalue<'tcx>(
+ ) -> McfResult {
+ match rvalue {
+ Rvalue::ThreadLocalRef(_) => Err((span, "cannot access thread local storage in const fn".into())),
+- Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
++ Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
+ check_place(tcx, *place, span, body, msrv)
+ },
+ Rvalue::CopyForDeref(place) => check_place(tcx, *place, span, body, msrv),
diff --git a/build/build-rust/rust-compiler-intrinsics.patch b/build/build-rust/rust-compiler-intrinsics.patch
@@ -0,0 +1,95 @@
+The version of `rustc` we build had some `compiler-builtins` updates that broke stuff. Later version
+of rustc in the 1.82 train landed more `compiler-builtins` updates that unbroke the stuff. We need at
+least some of that to make the version of rustc we landed on work.
+
+See also: <https://github.com/rust-lang/rust/pull/128691>
+
+diff --git a/Cargo.lock b/Cargo.lock
+index 13b8eaea068..c2b8483b5b2 100644
+--- a/Cargo.lock
++++ b/Cargo.lock
+@@ -739,9 +739,9 @@ checksum = "55b672471b4e9f9e95499ea597ff64941a309b2cdbffcc46f2cc5e2d971fd335"
+
+ [[package]]
+ name = "compiler_builtins"
+-version = "0.1.114"
++version = "0.1.123"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "eb58b199190fcfe0846f55a3b545cd6b07a34bdd5930a476ff856f3ebcc5558a"
++checksum = "b47fcbecb558bdad78c7d3a998523c60a50dd6cd046d5fe74163e309e878fff7"
+ dependencies = [
+ "cc",
+ "rustc-std-workspace-core",
+diff --git a/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml b/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml
+index 9ea53e8f848..8d577c836d6 100644
+--- a/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml
++++ b/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml
+@@ -58,9 +58,9 @@ dependencies = [
+
+ [[package]]
+ name = "compiler_builtins"
+-version = "0.1.106"
++version = "0.1.123"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+-checksum = "f4ab134a739bafec76aa91ccb15d519a54e569350644a1fea6528d5a0d407e22"
++checksum = "b47fcbecb558bdad78c7d3a998523c60a50dd6cd046d5fe74163e309e878fff7"
+ dependencies = [
+ "cc",
+ "rustc-std-workspace-core",
+diff --git a/compiler/rustc_codegen_gcc/build_system/build_sysroot/Cargo.lock b/compiler/rustc_codegen_gcc/build_system/build_sysroot/Cargo.lock
+index d6ec1f87d01..771f2f18dce 100644
+--- a/compiler/rustc_codegen_gcc/build_system/build_sysroot/Cargo.lock
++++ b/compiler/rustc_codegen_gcc/build_system/build_sysroot/Cargo.lock
+@@ -50,7 +50,7 @@ dependencies = [
+
+ [[package]]
+ name = "compiler_builtins"
+-version = "0.1.109"
++version = "0.1.118"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "f11973008a8cf741fe6d22f339eba21fd0ca81e2760a769ba8243ed6c21edd7e"
+ dependencies = [
+diff --git a/compiler/rustc_codegen_gcc/build_system/build_sysroot/Cargo.toml b/compiler/rustc_codegen_gcc/build_system/build_sysroot/Cargo.toml
+index e4669923623..05503128f2a 100644
+--- a/compiler/rustc_codegen_gcc/build_system/build_sysroot/Cargo.toml
++++ b/compiler/rustc_codegen_gcc/build_system/build_sysroot/Cargo.toml
+@@ -6,9 +6,7 @@ resolver = "2"
+
+ [dependencies]
+ core = { path = "./sysroot_src/library/core" }
+-# TODO: after the sync, revert to using version 0.1.
+-# compiler_builtins = "0.1"
+-compiler_builtins = "=0.1.109"
++compiler_builtins = "0.1"
+ alloc = { path = "./sysroot_src/library/alloc" }
+ std = { path = "./sysroot_src/library/std", features = ["panic_unwind", "backtrace"] }
+ test = { path = "./sysroot_src/library/test" }
+diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
+index 479eb0a2ba7..4365bcc4ad0 100644
+--- a/library/alloc/Cargo.toml
++++ b/library/alloc/Cargo.toml
+@@ -10,10 +10,7 @@ edition = "2021"
+
+ [dependencies]
+ core = { path = "../core" }
+-compiler_builtins = { version = "0.1.114", features = ['rustc-dep-of-std'] }
+-
+-[target.'cfg(not(any(target_arch = "aarch64", target_arch = "x86", target_arch = "x86_64")))'.dependencies]
+-compiler_builtins = { version = "0.1.114", features = ["no-f16-f128"] }
++compiler_builtins = { version = "0.1.123", features = ['rustc-dep-of-std'] }
+
+ [dev-dependencies]
+ rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
+diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
+index fe601855cc1..b0462d28237 100644
+--- a/library/std/Cargo.toml
++++ b/library/std/Cargo.toml
+@@ -17,7 +17,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
+ panic_unwind = { path = "../panic_unwind", optional = true }
+ panic_abort = { path = "../panic_abort" }
+ core = { path = "../core", public = true }
+-compiler_builtins = { version = "0.1.114" }
++compiler_builtins = { version = "0.1.123" }
+ profiler_builtins = { path = "../profiler_builtins", optional = true }
+ unwind = { path = "../unwind" }
+ hashbrown = { version = "0.14", default-features = false, features = [
diff --git a/build/build-rust/rust-vendor-std.patch b/build/build-rust/rust-vendor-std.patch
@@ -2,115 +2,87 @@ Teaches Rust's build system to vendor `std`'s dependencies into the
`rust-src` component.
This was originally landed in <https://github.com/rust-lang/rust/pull/78790>,
-and <https://github.com/rust-lang/cargo/pull/8834>, but was backed out for
-causing breakage in other situations.
+but was backed out for causing some breakage for distro maintainers who
+need to build Rust itself in a vendored/offline context. It doesn't actually
+fetch anything interesting from Crates.io, just the magic fake `std`/`core` crates
+that exist to make the build work right. Those crates *are* vendored but
+their contents are ignored in favour of the actual stdlib.
-Since then, things have changed in cargo, such that it is now possible to use
-a simpler approach that only relies on tweaking what is shipped in rust.
+For Firefox's purposes, these patches still work fine, and are necessary
+to make `-Zbuild-std` work in a vendored environment.
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
-index 4957de2e1b7..b903e1be4aa 100644
+index 58f86aa996d..ef8c1584011 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
-@@ -941,6 +941,101 @@ fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
- &dst_src,
- );
+@@ -941,6 +941,35 @@ fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
+ builder.copy_link(&builder.src.join(file), &dst_src.join(file));
+ }
-+ // cargo's -Z build-std doesn't work properly alongside vendoring.
-+ // To work around the issue, we vendor the libstd dependencies in the
-+ // rust-src package, and alter libstd's Cargo.toml to contain
-+ // patch.crates-io entries pointing to the vendored versions.
-+ let root_dir = dst_src.join("library");
-+ let root_lock = root_dir.join("Cargo.lock");
-+ if root_lock.exists() {
-+ use std::collections::HashMap;
++ // libsysroot includes std and everything else, so vendoring it
++ // creates exactly what's needed for `cargo -Zbuild-std` or any
++ // other analysis of the stdlib's source. Cargo also needs help
++ // finding the lock, so we copy it to libsysroot temporarily.
++ //
++ // Note that this requires std to only have one version of each
++ // crate. e.g. two versions of getopts won't be patchable.
++ let dst_libsysroot = dst_src.join("library/sysroot");
++ let dst_vendor = dst_src.join("vendor");
++ let root_lock = dst_src.join("Cargo.lock");
++ let temp_lock = dst_libsysroot.join("Cargo.lock");
+
-+ use toml::map::Map;
-+ use toml::Value;
++ // `cargo vendor` will delete everything from the lockfile that
++ // isn't used by libsysroot, so we need to not use any links!
++ builder.really_copy(&root_lock, &temp_lock);
+
-+ let dst_vendor = dst_src.join("vendor");
++ let mut cmd = command(&builder.initial_cargo);
++ cmd.arg("vendor").arg(dst_vendor).current_dir(&dst_libsysroot);
++ cmd.env("RUSTC_BOOTSTRAP", "1");
++ builder.info("Dist src");
++ let _time = timeit(builder);
++ builder.run(
++ &mut cmd,
++ crate::utils::exec::OutputMode::Print,
++ crate::utils::exec::OutputMode::Print,
++ );
+
-+ let mut cmd = command(&builder.initial_cargo);
-+ cmd.arg("vendor").arg(&dst_vendor).current_dir(&root_dir);
-+ // library/std/Cargo.toml uses the `public-dependency` nightly cargo feature.
-+ cmd.env("RUSTC_BOOTSTRAP", "1");
-+ builder.info("Dist src");
-+ let _time = timeit(builder);
-+ builder.run(
-+ &mut cmd,
-+ crate::utils::exec::OutputMode::Print,
-+ crate::utils::exec::OutputMode::Print,
-+ );
-+
-+ // Ideally, we would add the .cargo/config.toml that `cargo vendor` outputs,
-+ // but cargo doesn't read it when building libstd. So instead, we add
-+ // [patch.crates-io] entries to Cargo.toml for all vendored packages.
-+ let cargo_toml_path = root_lock.with_extension("toml");
-+ let cargo_toml_str = t!(std::fs::read_to_string(&cargo_toml_path));
-+ let mut manifest: Value = t!(toml::from_str(&cargo_toml_str));
-+
-+ let patch_table = t!(manifest
-+ .get_mut("patch")
-+ .and_then(|p| p.as_table_mut())
-+ .and_then(|p| p.get_mut("crates-io"))
-+ .and_then(|c| c.as_table_mut())
-+ .ok_or("[patch.crates-io] section not found"));
-+
-+ let mut packages_by_name: HashMap<String, Vec<String>> = HashMap::new();
-+
-+ for entry in builder.read_dir(&dst_vendor) {
-+ let path = entry.path();
-+
-+ // Check for Cargo.toml
-+ let crate_cargo_toml_path = path.join("Cargo.toml");
-+ if !crate_cargo_toml_path.exists() {
-+ continue;
-+ }
-+
-+ // Parse package name from Cargo.toml
-+ let crate_cargo_toml_str = t!(std::fs::read_to_string(&crate_cargo_toml_path));
-+ let crate_cargo_toml: Value = t!(toml::from_str(&crate_cargo_toml_str));
-+ let pkg_name = t!(crate_cargo_toml
-+ .get("package")
-+ .and_then(|p| p.get("name"))
-+ .and_then(|n| n.as_str())
-+ .ok_or("package.name not found"));
-+ let dir_name = path.file_name().unwrap().to_string_lossy().into_owned();
-+ packages_by_name
-+ .entry(pkg_name.to_string())
-+ .or_insert_with(Vec::new)
-+ .push(dir_name);
-+ }
-+
-+ for (pkg_name, dirs) in &packages_by_name {
-+ for dir_name in dirs.iter() {
-+ // What we want in the normal case:
-+ // [patch.crates-io.crate]
-+ // path = "../vendor/crate"
-+ // When the directory name is different (usually when it contains a
-+ // version) we want the following:
-+ // [patch.crates-io.crate-version]
-+ // package = "crate"
-+ // path = "../vendor/crate-version"
-+ let mut patch_value = Map::new();
-+ let name = dir_name.replace('.', "_").replace('+', "_");
-+ if &name != pkg_name {
-+ patch_value.insert("package".to_string(), pkg_name.clone().into());
-+ }
-+ patch_value
-+ .insert("path".to_string(), format!("../vendor/{}", dir_name).into());
-+ patch_table.insert(name, patch_value.into());
-+ }
-+ }
-+
-+ // Cargo.toml may be a hardlink to the one in the repository, and
-+ // we don't want to modify that, so break the hardlink first.
-+ t!(std::fs::remove_file(&cargo_toml_path));
-+
-+ let new_cargo_toml = t!(toml::to_string_pretty(&manifest));
-+ t!(std::fs::write(&cargo_toml_path, new_cargo_toml));
-+ }
++ builder.remove(&temp_lock);
+
tarball.generate()
}
}
+diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
+index 453fb39327d..af579af9eca 100644
+--- a/src/bootstrap/src/lib.rs
++++ b/src/bootstrap/src/lib.rs
+@@ -1732,6 +1732,30 @@ fn read_stamp_file(&self, stamp: &Path) -> Vec<(PathBuf, DependencyType)> {
+ paths
+ }
+
++ /// Copies a file from `src` to `dst` and doesn't use links, so
++ /// that the copy can be modified without affecting the original.
++ pub fn really_copy(&self, src: &Path, dst: &Path) {
++ if self.config.dry_run() {
++ return;
++ }
++ self.verbose_than(1, || println!("Copy {:?} to {:?}", src, dst));
++ if src == dst {
++ return;
++ }
++ let _ = fs::remove_file(dst);
++ let metadata = t!(src.symlink_metadata());
++ if let Err(e) = fs::copy(src, dst) {
++ panic!("failed to copy `{}` to `{}`: {}", src.display(), dst.display(), e)
++ }
++ t!(fs::set_permissions(dst, metadata.permissions()));
++ let file_times = fs::FileTimes::new()
++ .set_accessed(t!(metadata.accessed()))
++ .set_modified(t!(metadata.modified()));
++
++ let dst_file = t!(fs::File::open(dst));
++ t!(dst_file.set_times(file_times));
++ }
++
+ /// Links a file from `src` to `dst`.
+ /// Attempts to use hard links if possible, falling back to copying.
+ /// You can neither rely on this being a copy nor it being a link,
diff --git a/build/build-rust/soft_deprecate_the_addr_of_macros.patch b/build/build-rust/soft_deprecate_the_addr_of_macros.patch
@@ -0,0 +1,29 @@
+From b8464961a2681585a6231b93cd7e85e50022c2b3 Mon Sep 17 00:00:00 2001
+From: Ralf Jung <post@ralfj.de>
+Date: Sat, 13 Jul 2024 13:56:05 +0200
+Subject: [PATCH] soft-deprecate the addr_of macros
+
+diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
+index 25d8f4a0adbd9..3fe5212cea779 100644
+--- a/library/core/src/ptr/mod.rs
++++ b/library/core/src/ptr/mod.rs
+@@ -2209,6 +2209,9 @@ impl<F: FnPtr> fmt::Debug for F {
+
+ /// Creates a `const` raw pointer to a place, without creating an intermediate reference.
+ ///
++/// `addr_of!(expr)` is equivalent to `&raw const expr`. The macro is *soft-deprecated*;
++/// use `&raw const` instead.
++///
+ /// Creating a reference with `&`/`&mut` is only allowed if the pointer is properly aligned
+ /// and points to initialized data. For cases where those requirements do not hold,
+ /// raw pointers should be used instead. However, `&expr as *const _` creates a reference
+@@ -2283,6 +2286,9 @@ pub macro addr_of($place:expr) {
+
+ /// Creates a `mut` raw pointer to a place, without creating an intermediate reference.
+ ///
++/// `addr_of_mut!(expr)` is equivalent to `&raw mut expr`. The macro is *soft-deprecated*;
++/// use `&raw mut` instead.
++///
+ /// Creating a reference with `&`/`&mut` is only allowed if the pointer is properly aligned
+ /// and points to initialized data. For cases where those requirements do not hold,
+ /// raw pointers should be used instead. However, `&mut expr as *mut _` creates a reference
diff --git a/build/build-rust/stabilize-const_fn_floating_point_arithmetic.patch b/build/build-rust/stabilize-const_fn_floating_point_arithmetic.patch
@@ -0,0 +1,960 @@
+commit d2c024b53a34386d4d4c968cd0403c9194f1db4f
+Author: Ralf Jung <post@ralfj.de>
+Date: Sat Aug 3 11:17:43 2024 +0200
+
+ stabilize const_fn_floating_point_arithmetic
+
+diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
+index 3ded81b90ff..4232c241ad4 100644
+--- a/compiler/rustc_const_eval/src/check_consts/check.rs
++++ b/compiler/rustc_const_eval/src/check_consts/check.rs
+@@ -569,46 +569,42 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
+ Rvalue::NullaryOp(
+ NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) | NullOp::UbChecks,
+ _,
+ ) => {}
+ Rvalue::ShallowInitBox(_, _) => {}
+
+ Rvalue::UnaryOp(_, operand) => {
+ let ty = operand.ty(self.body, self.tcx);
+- if is_int_bool_or_char(ty) {
+- // Int, bool, and char operations are fine.
+- } else if ty.is_floating_point() {
+- self.check_op(ops::FloatingPointOp);
++ if is_int_bool_float_or_char(ty) {
++ // Int, bool, float, and char operations are fine.
+ } else {
+ span_bug!(self.span, "non-primitive type in `Rvalue::UnaryOp`: {:?}", ty);
+ }
+ }
+
+ Rvalue::BinaryOp(op, box (lhs, rhs)) => {
+ let lhs_ty = lhs.ty(self.body, self.tcx);
+ let rhs_ty = rhs.ty(self.body, self.tcx);
+
+- if is_int_bool_or_char(lhs_ty) && is_int_bool_or_char(rhs_ty) {
+- // Int, bool, and char operations are fine.
++ if is_int_bool_float_or_char(lhs_ty) && is_int_bool_float_or_char(rhs_ty) {
++ // Int, bool, float, and char operations are fine.
+ } else if lhs_ty.is_fn_ptr() || lhs_ty.is_unsafe_ptr() {
+ assert!(matches!(
+ op,
+ BinOp::Eq
+ | BinOp::Ne
+ | BinOp::Le
+ | BinOp::Lt
+ | BinOp::Ge
+ | BinOp::Gt
+ | BinOp::Offset
+ ));
+
+ self.check_op(ops::RawPtrComparison);
+- } else if lhs_ty.is_floating_point() || rhs_ty.is_floating_point() {
+- self.check_op(ops::FloatingPointOp);
+ } else {
+ span_bug!(
+ self.span,
+ "non-primitive type in `Rvalue::BinaryOp`: {:?} ⚬ {:?}",
+ lhs_ty,
+ rhs_ty
+ );
+ }
+@@ -1003,17 +999,17 @@ fn place_as_reborrow<'tcx>(
+ return None;
+ }
+ }
+ }
+ _ => None,
+ }
+ }
+
+-fn is_int_bool_or_char(ty: Ty<'_>) -> bool {
+- ty.is_bool() || ty.is_integral() || ty.is_char()
++fn is_int_bool_float_or_char(ty: Ty<'_>) -> bool {
++ ty.is_bool() || ty.is_integral() || ty.is_char() || ty.is_floating_point()
+ }
+
+ fn emit_unstable_in_stable_error(ccx: &ConstCx<'_, '_>, span: Span, gate: Symbol) {
+ let attr_span = ccx.tcx.def_span(ccx.def_id()).shrink_to_lo();
+
+ ccx.dcx().emit_err(UnstableInStable { gate: gate.to_string(), span, attr_span });
+ }
+diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs
+index f47a2ec8f75..0b2024ac51f 100644
+--- a/compiler/rustc_const_eval/src/check_consts/ops.rs
++++ b/compiler/rustc_const_eval/src/check_consts/ops.rs
+@@ -50,38 +50,16 @@ fn status_in_item(&self, _ccx: &ConstCx<'_, 'tcx>) -> Status {
+
+ fn importance(&self) -> DiagImportance {
+ DiagImportance::Primary
+ }
+
+ fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx>;
+ }
+
+-#[derive(Debug)]
+-pub struct FloatingPointOp;
+-impl<'tcx> NonConstOp<'tcx> for FloatingPointOp {
+- fn status_in_item(&self, ccx: &ConstCx<'_, 'tcx>) -> Status {
+- if ccx.const_kind() == hir::ConstContext::ConstFn {
+- Status::Unstable(sym::const_fn_floating_point_arithmetic)
+- } else {
+- Status::Allowed
+- }
+- }
+-
+- #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
+- fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
+- feature_err(
+- &ccx.tcx.sess,
+- sym::const_fn_floating_point_arithmetic,
+- span,
+- format!("floating point arithmetic is not allowed in {}s", ccx.const_kind()),
+- )
+- }
+-}
+-
+ /// A function call where the callee is a pointer.
+ #[derive(Debug)]
+ pub struct FnCallIndirect;
+ impl<'tcx> NonConstOp<'tcx> for FnCallIndirect {
+ fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
+ ccx.dcx().create_err(errors::UnallowedFnPointerCall { span, kind: ccx.const_kind() })
+ }
+ }
+diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
+index 689e2d2771e..63d6b4a07f0 100644
+--- a/compiler/rustc_feature/src/accepted.rs
++++ b/compiler/rustc_feature/src/accepted.rs
+@@ -108,16 +108,18 @@ macro_rules! declare_features {
+ /// Allows use of the `#[collapse_debuginfo]` attribute.
+ (accepted, collapse_debuginfo, "1.79.0", Some(100758)),
+ /// Allows usage of the `compile_error!` macro.
+ (accepted, compile_error, "1.20.0", Some(40872)),
+ /// Allows `impl Trait` in function return types.
+ (accepted, conservative_impl_trait, "1.26.0", Some(34511)),
+ /// Allows calling constructor functions in `const fn`.
+ (accepted, const_constructor, "1.40.0", Some(61456)),
++ /// Allows basic arithmetic on floating point types in a `const fn`.
++ (accepted, const_fn_floating_point_arithmetic, "CURRENT_RUSTC_VERSION", Some(57241)),
+ /// Allows using and casting function pointers in a `const fn`.
+ (accepted, const_fn_fn_ptr_basics, "1.61.0", Some(57563)),
+ /// Allows trait bounds in `const fn`.
+ (accepted, const_fn_trait_bound, "1.61.0", Some(93706)),
+ /// Allows calling `transmute` in const fn
+ (accepted, const_fn_transmute, "1.56.0", Some(53605)),
+ /// Allows accessing fields of unions inside `const` functions.
+ (accepted, const_fn_union, "1.56.0", Some(51909)),
+diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
+index a3dfd44a094..45be9097fe0 100644
+--- a/compiler/rustc_feature/src/unstable.rs
++++ b/compiler/rustc_feature/src/unstable.rs
+@@ -397,18 +397,16 @@ pub fn internal(&self, feature: Symbol) -> bool {
+ /// Allows to use the `#[cmse_nonsecure_entry]` attribute.
+ (unstable, cmse_nonsecure_entry, "1.48.0", Some(75835)),
+ /// Allows `async {}` expressions in const contexts.
+ (unstable, const_async_blocks, "1.53.0", Some(85368)),
+ /// Allows `const || {}` closures in const contexts.
+ (incomplete, const_closures, "1.68.0", Some(106003)),
+ /// Allows the definition of `const extern fn` and `const unsafe extern fn`.
+ (unstable, const_extern_fn, "1.40.0", Some(64926)),
+- /// Allows basic arithmetic on floating point types in a `const fn`.
+- (unstable, const_fn_floating_point_arithmetic, "1.48.0", Some(57241)),
+ /// Allows `for _ in _` loops in const contexts.
+ (unstable, const_for, "1.56.0", Some(87575)),
+ /// Allows using `&mut` in constant functions.
+ (unstable, const_mut_refs, "1.41.0", Some(57349)),
+ /// Be more precise when looking for live drops in a const context.
+ (unstable, const_precise_live_drops, "1.46.0", Some(73255)),
+ /// Allows references to types with interior mutability within constants
+ (unstable, const_refs_to_cell, "1.51.0", Some(80384)),
+diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
+index e74900ff747..8746d68e810 100644
+--- a/library/core/src/lib.rs
++++ b/library/core/src/lib.rs
+@@ -187,26 +187,26 @@
+ #![feature(unchecked_shifts)]
+ #![feature(utf16_extra)]
+ #![feature(utf16_extra_const)]
+ #![feature(variant_count)]
+ // tidy-alphabetical-end
+ //
+ // Language features:
+ // tidy-alphabetical-start
++#![cfg_attr(bootstrap, feature(const_fn_floating_point_arithmetic))]
+ #![feature(abi_unadjusted)]
+ #![feature(adt_const_params)]
+ #![feature(allow_internal_unsafe)]
+ #![feature(allow_internal_unstable)]
+ #![feature(asm_const)]
+ #![feature(auto_traits)]
+ #![feature(cfg_sanitize)]
+ #![feature(cfg_target_has_atomic)]
+ #![feature(cfg_target_has_atomic_equal_alignment)]
+-#![feature(const_fn_floating_point_arithmetic)]
+ #![feature(const_for)]
+ #![feature(const_mut_refs)]
+ #![feature(const_precise_live_drops)]
+ #![feature(const_refs_to_cell)]
+ #![feature(decl_macro)]
+ #![feature(deprecated_suggestion)]
+ #![feature(doc_cfg)]
+ #![feature(doc_cfg_hide)]
+diff --git a/src/tools/clippy/tests/ui/floating_point_abs.fixed b/src/tools/clippy/tests/ui/floating_point_abs.fixed
+index 5312a8b29c6..33183c76972 100644
+--- a/src/tools/clippy/tests/ui/floating_point_abs.fixed
++++ b/src/tools/clippy/tests/ui/floating_point_abs.fixed
+@@ -1,9 +1,8 @@
+-#![feature(const_fn_floating_point_arithmetic)]
+ #![warn(clippy::suboptimal_flops)]
+
+ /// Allow suboptimal ops in constant context
+ pub const fn in_const_context(num: f64) -> f64 {
+ if num >= 0.0 { num } else { -num }
+ }
+
+ struct A {
+diff --git a/src/tools/clippy/tests/ui/floating_point_abs.rs b/src/tools/clippy/tests/ui/floating_point_abs.rs
+index 8619177130c..a08d5bbcef5 100644
+--- a/src/tools/clippy/tests/ui/floating_point_abs.rs
++++ b/src/tools/clippy/tests/ui/floating_point_abs.rs
+@@ -1,9 +1,8 @@
+-#![feature(const_fn_floating_point_arithmetic)]
+ #![warn(clippy::suboptimal_flops)]
+
+ /// Allow suboptimal ops in constant context
+ pub const fn in_const_context(num: f64) -> f64 {
+ if num >= 0.0 { num } else { -num }
+ }
+
+ struct A {
+diff --git a/src/tools/clippy/tests/ui/floating_point_abs.stderr b/src/tools/clippy/tests/ui/floating_point_abs.stderr
+index f5a778c5b76..0c1f68f3b7f 100644
+--- a/src/tools/clippy/tests/ui/floating_point_abs.stderr
++++ b/src/tools/clippy/tests/ui/floating_point_abs.stderr
+@@ -1,53 +1,53 @@
+ error: manual implementation of `abs` method
+- --> tests/ui/floating_point_abs.rs:15:5
++ --> tests/ui/floating_point_abs.rs:14:5
+ |
+ LL | if num >= 0.0 { num } else { -num }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.abs()`
+ |
+ = note: `-D clippy::suboptimal-flops` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`
+
+ error: manual implementation of `abs` method
+- --> tests/ui/floating_point_abs.rs:19:5
++ --> tests/ui/floating_point_abs.rs:18:5
+ |
+ LL | if 0.0 < num { num } else { -num }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.abs()`
+
+ error: manual implementation of `abs` method
+- --> tests/ui/floating_point_abs.rs:23:5
++ --> tests/ui/floating_point_abs.rs:22:5
+ |
+ LL | if a.a > 0.0 { a.a } else { -a.a }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.a.abs()`
+
+ error: manual implementation of `abs` method
+- --> tests/ui/floating_point_abs.rs:27:5
++ --> tests/ui/floating_point_abs.rs:26:5
+ |
+ LL | if 0.0 >= num { -num } else { num }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.abs()`
+
+ error: manual implementation of `abs` method
+- --> tests/ui/floating_point_abs.rs:31:5
++ --> tests/ui/floating_point_abs.rs:30:5
+ |
+ LL | if a.a < 0.0 { -a.a } else { a.a }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.a.abs()`
+
+ error: manual implementation of negation of `abs` method
+- --> tests/ui/floating_point_abs.rs:35:5
++ --> tests/ui/floating_point_abs.rs:34:5
+ |
+ LL | if num < 0.0 { num } else { -num }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-num.abs()`
+
+ error: manual implementation of negation of `abs` method
+- --> tests/ui/floating_point_abs.rs:39:5
++ --> tests/ui/floating_point_abs.rs:38:5
+ |
+ LL | if 0.0 >= num { num } else { -num }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-num.abs()`
+
+ error: manual implementation of negation of `abs` method
+- --> tests/ui/floating_point_abs.rs:44:12
++ --> tests/ui/floating_point_abs.rs:43:12
+ |
+ LL | a: if a.a >= 0.0 { -a.a } else { a.a },
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-a.a.abs()`
+
+ error: aborting due to 8 previous errors
+
+diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.fixed b/src/tools/clippy/tests/ui/floating_point_mul_add.fixed
+index 3ce2edf2c71..164aac2601a 100644
+--- a/src/tools/clippy/tests/ui/floating_point_mul_add.fixed
++++ b/src/tools/clippy/tests/ui/floating_point_mul_add.fixed
+@@ -1,9 +1,8 @@
+-#![feature(const_fn_floating_point_arithmetic)]
+ #![warn(clippy::suboptimal_flops)]
+
+ /// Allow suboptimal_ops in constant context
+ pub const fn in_const_context() {
+ let a: f64 = 1234.567;
+ let b: f64 = 45.67834;
+ let c: f64 = 0.0004;
+
+diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.rs b/src/tools/clippy/tests/ui/floating_point_mul_add.rs
+index b5e4a8db4db..ae024b7f224 100644
+--- a/src/tools/clippy/tests/ui/floating_point_mul_add.rs
++++ b/src/tools/clippy/tests/ui/floating_point_mul_add.rs
+@@ -1,9 +1,8 @@
+-#![feature(const_fn_floating_point_arithmetic)]
+ #![warn(clippy::suboptimal_flops)]
+
+ /// Allow suboptimal_ops in constant context
+ pub const fn in_const_context() {
+ let a: f64 = 1234.567;
+ let b: f64 = 45.67834;
+ let c: f64 = 0.0004;
+
+diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.stderr b/src/tools/clippy/tests/ui/floating_point_mul_add.stderr
+index 3e1a071de73..9c75909f715 100644
+--- a/src/tools/clippy/tests/ui/floating_point_mul_add.stderr
++++ b/src/tools/clippy/tests/ui/floating_point_mul_add.stderr
+@@ -1,83 +1,83 @@
+ error: multiply and add expressions can be calculated more efficiently and accurately
+- --> tests/ui/floating_point_mul_add.rs:20:13
++ --> tests/ui/floating_point_mul_add.rs:19:13
+ |
+ LL | let _ = a * b + c;
+ | ^^^^^^^^^ help: consider using: `a.mul_add(b, c)`
+ |
+ = note: `-D clippy::suboptimal-flops` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`
+
+ error: multiply and add expressions can be calculated more efficiently and accurately
+- --> tests/ui/floating_point_mul_add.rs:21:13
++ --> tests/ui/floating_point_mul_add.rs:20:13
+ |
+ LL | let _ = a * b - c;
+ | ^^^^^^^^^ help: consider using: `a.mul_add(b, -c)`
+
+ error: multiply and add expressions can be calculated more efficiently and accurately
+- --> tests/ui/floating_point_mul_add.rs:22:13
++ --> tests/ui/floating_point_mul_add.rs:21:13
+ |
+ LL | let _ = c + a * b;
+ | ^^^^^^^^^ help: consider using: `a.mul_add(b, c)`
+
+ error: multiply and add expressions can be calculated more efficiently and accurately
+- --> tests/ui/floating_point_mul_add.rs:23:13
++ --> tests/ui/floating_point_mul_add.rs:22:13
+ |
+ LL | let _ = c - a * b;
+ | ^^^^^^^^^ help: consider using: `a.mul_add(-b, c)`
+
+ error: multiply and add expressions can be calculated more efficiently and accurately
+- --> tests/ui/floating_point_mul_add.rs:24:13
++ --> tests/ui/floating_point_mul_add.rs:23:13
+ |
+ LL | let _ = a + 2.0 * 4.0;
+ | ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4.0, a)`
+
+ error: multiply and add expressions can be calculated more efficiently and accurately
+- --> tests/ui/floating_point_mul_add.rs:25:13
++ --> tests/ui/floating_point_mul_add.rs:24:13
+ |
+ LL | let _ = a + 2. * 4.;
+ | ^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4., a)`
+
+ error: multiply and add expressions can be calculated more efficiently and accurately
+- --> tests/ui/floating_point_mul_add.rs:27:13
++ --> tests/ui/floating_point_mul_add.rs:26:13
+ |
+ LL | let _ = (a * b) + c;
+ | ^^^^^^^^^^^ help: consider using: `a.mul_add(b, c)`
+
+ error: multiply and add expressions can be calculated more efficiently and accurately
+- --> tests/ui/floating_point_mul_add.rs:28:13
++ --> tests/ui/floating_point_mul_add.rs:27:13
+ |
+ LL | let _ = c + (a * b);
+ | ^^^^^^^^^^^ help: consider using: `a.mul_add(b, c)`
+
+ error: multiply and add expressions can be calculated more efficiently and accurately
+- --> tests/ui/floating_point_mul_add.rs:29:13
++ --> tests/ui/floating_point_mul_add.rs:28:13
+ |
+ LL | let _ = a * b * c + d;
+ | ^^^^^^^^^^^^^ help: consider using: `(a * b).mul_add(c, d)`
+
+ error: multiply and add expressions can be calculated more efficiently and accurately
+- --> tests/ui/floating_point_mul_add.rs:31:13
++ --> tests/ui/floating_point_mul_add.rs:30:13
+ |
+ LL | let _ = a.mul_add(b, c) * a.mul_add(b, c) + a.mul_add(b, c) + c;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `a.mul_add(b, c).mul_add(a.mul_add(b, c), a.mul_add(b, c))`
+
+ error: multiply and add expressions can be calculated more efficiently and accurately
+- --> tests/ui/floating_point_mul_add.rs:32:13
++ --> tests/ui/floating_point_mul_add.rs:31:13
+ |
+ LL | let _ = 1234.567_f64 * 45.67834_f64 + 0.0004_f64;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1234.567_f64.mul_add(45.67834_f64, 0.0004_f64)`
+
+ error: multiply and add expressions can be calculated more efficiently and accurately
+- --> tests/ui/floating_point_mul_add.rs:34:13
++ --> tests/ui/floating_point_mul_add.rs:33:13
+ |
+ LL | let _ = (a * a + b).sqrt();
+ | ^^^^^^^^^^^ help: consider using: `a.mul_add(a, b)`
+
+ error: multiply and add expressions can be calculated more efficiently and accurately
+- --> tests/ui/floating_point_mul_add.rs:37:13
++ --> tests/ui/floating_point_mul_add.rs:36:13
+ |
+ LL | let _ = a - (b * u as f64);
+ | ^^^^^^^^^^^^^^^^^^ help: consider using: `b.mul_add(-(u as f64), a)`
+
+ error: aborting due to 13 previous errors
+
+diff --git a/src/tools/clippy/tests/ui/floating_point_rad.fixed b/src/tools/clippy/tests/ui/floating_point_rad.fixed
+index a710bd9bd60..2f93d233cb4 100644
+--- a/src/tools/clippy/tests/ui/floating_point_rad.fixed
++++ b/src/tools/clippy/tests/ui/floating_point_rad.fixed
+@@ -1,9 +1,8 @@
+-#![feature(const_fn_floating_point_arithmetic)]
+ #![warn(clippy::suboptimal_flops)]
+
+ /// Allow suboptimal_flops in constant context
+ pub const fn const_context() {
+ let x = 3f32;
+ let _ = x * 180f32 / std::f32::consts::PI;
+ }
+
+diff --git a/src/tools/clippy/tests/ui/floating_point_rad.rs b/src/tools/clippy/tests/ui/floating_point_rad.rs
+index 14656f021df..9690effc4e1 100644
+--- a/src/tools/clippy/tests/ui/floating_point_rad.rs
++++ b/src/tools/clippy/tests/ui/floating_point_rad.rs
+@@ -1,9 +1,8 @@
+-#![feature(const_fn_floating_point_arithmetic)]
+ #![warn(clippy::suboptimal_flops)]
+
+ /// Allow suboptimal_flops in constant context
+ pub const fn const_context() {
+ let x = 3f32;
+ let _ = x * 180f32 / std::f32::consts::PI;
+ }
+
+diff --git a/src/tools/clippy/tests/ui/floating_point_rad.stderr b/src/tools/clippy/tests/ui/floating_point_rad.stderr
+index 64674342c2b..b834f5374e0 100644
+--- a/src/tools/clippy/tests/ui/floating_point_rad.stderr
++++ b/src/tools/clippy/tests/ui/floating_point_rad.stderr
+@@ -1,53 +1,53 @@
+ error: conversion to radians can be done more accurately
+- --> tests/ui/floating_point_rad.rs:11:13
++ --> tests/ui/floating_point_rad.rs:10:13
+ |
+ LL | let _ = degrees as f64 * std::f64::consts::PI / 180.0;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(degrees as f64).to_radians()`
+ |
+ = note: `-D clippy::suboptimal-flops` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`
+
+ error: conversion to degrees can be done more accurately
+- --> tests/ui/floating_point_rad.rs:12:13
++ --> tests/ui/floating_point_rad.rs:11:13
+ |
+ LL | let _ = degrees as f64 * 180.0 / std::f64::consts::PI;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(degrees as f64).to_degrees()`
+
+ error: conversion to degrees can be done more accurately
+- --> tests/ui/floating_point_rad.rs:17:13
++ --> tests/ui/floating_point_rad.rs:16:13
+ |
+ LL | let _ = x * 180f32 / std::f32::consts::PI;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_degrees()`
+
+ error: conversion to degrees can be done more accurately
+- --> tests/ui/floating_point_rad.rs:18:13
++ --> tests/ui/floating_point_rad.rs:17:13
+ |
+ LL | let _ = 90. * 180f64 / std::f64::consts::PI;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.0_f64.to_degrees()`
+
+ error: conversion to degrees can be done more accurately
+- --> tests/ui/floating_point_rad.rs:19:13
++ --> tests/ui/floating_point_rad.rs:18:13
+ |
+ LL | let _ = 90.5 * 180f64 / std::f64::consts::PI;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.5_f64.to_degrees()`
+
+ error: conversion to radians can be done more accurately
+- --> tests/ui/floating_point_rad.rs:20:13
++ --> tests/ui/floating_point_rad.rs:19:13
+ |
+ LL | let _ = x * std::f32::consts::PI / 180f32;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_radians()`
+
+ error: conversion to radians can be done more accurately
+- --> tests/ui/floating_point_rad.rs:21:13
++ --> tests/ui/floating_point_rad.rs:20:13
+ |
+ LL | let _ = 90. * std::f32::consts::PI / 180f32;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.0_f64.to_radians()`
+
+ error: conversion to radians can be done more accurately
+- --> tests/ui/floating_point_rad.rs:22:13
++ --> tests/ui/floating_point_rad.rs:21:13
+ |
+ LL | let _ = 90.5 * std::f32::consts::PI / 180f32;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.5_f64.to_radians()`
+
+ error: aborting due to 8 previous errors
+
+diff --git a/tests/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs b/tests/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs
+index c7078e46fa6..efc0a1c2fba 100644
+--- a/tests/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs
++++ b/tests/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.rs
+@@ -1,11 +1,7 @@
+ #![feature(const_extern_fn)]
+
+-const extern "C" fn unsize(x: &[u8; 3]) -> &[u8] { x }
+-const unsafe extern "C" fn closure() -> fn() { || {} }
+-const unsafe extern "C" fn use_float() { 1.0 + 1.0; }
+-//~^ ERROR floating point arithmetic
+ const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
+ //~^ ERROR pointers cannot be cast to integers
+
+
+ fn main() {}
+diff --git a/tests/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr b/tests/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr
+index 29fa90d611c..9cdeec159be 100644
+--- a/tests/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr
++++ b/tests/ui/consts/const-extern-fn/const-extern-fn-min-const-fn.stderr
+@@ -1,22 +1,11 @@
+-error[E0658]: floating point arithmetic is not allowed in constant functions
+- --> $DIR/const-extern-fn-min-const-fn.rs:5:42
+- |
+-LL | const unsafe extern "C" fn use_float() { 1.0 + 1.0; }
+- | ^^^^^^^^^
+- |
+- = note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
+- = help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
+- = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+-
+ error: pointers cannot be cast to integers during const eval
+- --> $DIR/const-extern-fn-min-const-fn.rs:7:48
++ --> $DIR/const-extern-fn-min-const-fn.rs:3:48
+ |
+ LL | const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
+ | ^^^^^^^^^^^^
+ |
+ = note: at compile-time, pointers do not have an integer value
+ = note: avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
+
+-error: aborting due to 2 previous errors
++error: aborting due to 1 previous error
+
+-For more information about this error, try `rustc --explain E0658`.
+diff --git a/tests/ui/consts/const-extern-fn/const-extern-fn.rs b/tests/ui/consts/const-extern-fn/const-extern-fn.rs
+index 57f5da8d0af..4b164767064 100644
+--- a/tests/ui/consts/const-extern-fn/const-extern-fn.rs
++++ b/tests/ui/consts/const-extern-fn/const-extern-fn.rs
+@@ -12,24 +12,41 @@
+ const unsafe extern "C" fn bar1(val: bool) -> bool {
+ !val
+ }
+
+ const unsafe extern "C" fn bar2(val: bool) -> bool {
+ !val
+ }
+
++#[allow(improper_ctypes_definitions)]
++const extern "C" fn unsize(x: &[u8; 3]) -> &[u8] {
++ x
++}
++
++#[allow(improper_ctypes_definitions)]
++const unsafe extern "C" fn closure() -> fn() {
++ || {}
++}
++
++const unsafe extern "C" fn use_float() -> f32 {
++ 1.0 + 1.0
++}
+
+ fn main() {
+ let a: [u8; foo1(25) as usize] = [0; 26];
+ let b: [u8; foo2(25) as usize] = [0; 26];
+ assert_eq!(a, b);
+
+ let bar1_res = unsafe { bar1(false) };
+ let bar2_res = unsafe { bar2(false) };
+ assert!(bar1_res);
+ assert_eq!(bar1_res, bar2_res);
+
+ let _foo1_cast: extern "C" fn(u8) -> u8 = foo1;
+ let _foo2_cast: extern "C" fn(u8) -> u8 = foo2;
+ let _bar1_cast: unsafe extern "C" fn(bool) -> bool = bar1;
+ let _bar2_cast: unsafe extern "C" fn(bool) -> bool = bar2;
++
++ unsize(&[0, 1, 2]);
++ unsafe { closure(); }
++ unsafe { use_float(); }
+ }
+diff --git a/tests/ui/consts/const_fn_floating_point_arithmetic.gated.stderr b/tests/ui/consts/const_fn_floating_point_arithmetic.gated.stderr
+deleted file mode 100644
+index e1b8154a287..00000000000
+--- a/tests/ui/consts/const_fn_floating_point_arithmetic.gated.stderr
++++ /dev/null
+@@ -1,8 +0,0 @@
+-error: fatal error triggered by #[rustc_error]
+- --> $DIR/const_fn_floating_point_arithmetic.rs:20:1
+- |
+-LL | fn main() {}
+- | ^^^^^^^^^
+-
+-error: aborting due to 1 previous error
+-
+diff --git a/tests/ui/consts/const_fn_floating_point_arithmetic.rs b/tests/ui/consts/const_fn_floating_point_arithmetic.rs
+deleted file mode 100644
+index b0d0bc6b9f4..00000000000
+--- a/tests/ui/consts/const_fn_floating_point_arithmetic.rs
++++ /dev/null
+@@ -1,20 +0,0 @@
+-// gate-test-const_fn_floating_point_arithmetic
+-
+-//@ revisions: stock gated
+-
+-#![feature(rustc_attrs)]
+-#![cfg_attr(gated, feature(const_fn_floating_point_arithmetic))]
+-
+-const fn add(f: f32) -> f32 { f + 2.0 }
+-//[stock]~^ floating point arithmetic
+-const fn sub(f: f32) -> f32 { 2.0 - f }
+-//[stock]~^ floating point arithmetic
+-const fn mul(f: f32, g: f32) -> f32 { f * g }
+-//[stock]~^ floating point arithmetic
+-const fn div(f: f32, g: f32) -> f32 { f / g }
+-//[stock]~^ floating point arithmetic
+-const fn neg(f: f32) -> f32 { -f }
+-//[stock]~^ floating point arithmetic
+-
+-#[rustc_error]
+-fn main() {} //[gated]~ fatal error triggered by #[rustc_error]
+diff --git a/tests/ui/consts/const_fn_floating_point_arithmetic.stock.stderr b/tests/ui/consts/const_fn_floating_point_arithmetic.stock.stderr
+deleted file mode 100644
+index b5b94786ebb..00000000000
+--- a/tests/ui/consts/const_fn_floating_point_arithmetic.stock.stderr
++++ /dev/null
+@@ -1,53 +0,0 @@
+-error[E0658]: floating point arithmetic is not allowed in constant functions
+- --> $DIR/const_fn_floating_point_arithmetic.rs:8:31
+- |
+-LL | const fn add(f: f32) -> f32 { f + 2.0 }
+- | ^^^^^^^
+- |
+- = note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
+- = help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
+- = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+-
+-error[E0658]: floating point arithmetic is not allowed in constant functions
+- --> $DIR/const_fn_floating_point_arithmetic.rs:10:31
+- |
+-LL | const fn sub(f: f32) -> f32 { 2.0 - f }
+- | ^^^^^^^
+- |
+- = note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
+- = help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
+- = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+-
+-error[E0658]: floating point arithmetic is not allowed in constant functions
+- --> $DIR/const_fn_floating_point_arithmetic.rs:12:39
+- |
+-LL | const fn mul(f: f32, g: f32) -> f32 { f * g }
+- | ^^^^^
+- |
+- = note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
+- = help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
+- = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+-
+-error[E0658]: floating point arithmetic is not allowed in constant functions
+- --> $DIR/const_fn_floating_point_arithmetic.rs:14:39
+- |
+-LL | const fn div(f: f32, g: f32) -> f32 { f / g }
+- | ^^^^^
+- |
+- = note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
+- = help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
+- = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+-
+-error[E0658]: floating point arithmetic is not allowed in constant functions
+- --> $DIR/const_fn_floating_point_arithmetic.rs:16:31
+- |
+-LL | const fn neg(f: f32) -> f32 { -f }
+- | ^^
+- |
+- = note: see issue #57241 <https://github.com/rust-lang/rust/issues/57241> for more information
+- = help: add `#![feature(const_fn_floating_point_arithmetic)]` to the crate attributes to enable
+- = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+-
+-error: aborting due to 5 previous errors
+-
+-For more information about this error, try `rustc --explain E0658`.
+diff --git a/tests/ui/consts/const_let_eq_float.rs b/tests/ui/consts/const_let_eq_float.rs
+index 30d839cdc2a..c9ca6b8b7ea 100644
+--- a/tests/ui/consts/const_let_eq_float.rs
++++ b/tests/ui/consts/const_let_eq_float.rs
+@@ -1,12 +1,10 @@
+ //@ run-pass
+
+-#![feature(const_fn_floating_point_arithmetic)]
+-
+ struct Foo<T>(T);
+ struct Bar<T> { x: T }
+ struct W(f32);
+ struct A { a: f32 }
+
+ #[allow(redundant_semicolons)]
+ const fn basics((a,): (f32,)) -> f32 {
+ // Deferred assignment:
+diff --git a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs
+index bb240fb4ad6..dc653370e51 100644
+--- a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs
++++ b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs
+@@ -1,14 +1,14 @@
+ #![unstable(feature = "humans",
+ reason = "who ever let humans program computers,
+ we're apparently really bad at it",
+ issue = "none")]
+
+-#![feature(const_fn_floating_point_arithmetic, foo, foo2)]
++#![feature(const_refs_to_cell, foo, foo2)]
+ #![feature(staged_api)]
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature="foo", issue = "none")]
+ const fn foo() -> u32 { 42 }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "rust1", since = "1.0.0")]
+@@ -20,19 +20,23 @@ const fn foo2() -> u32 { 42 }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "rust1", since = "1.0.0")]
+ // can't call non-min_const_fn
+ const fn bar2() -> u32 { foo2() } //~ ERROR not yet stable as a const fn
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "rust1", since = "1.0.0")]
+-// Const-stable functions cannot rely on unstable const-eval features.
+-const fn bar3() -> u32 { (5f32 + 6f32) as u32 }
+-//~^ ERROR const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
++// conformity is required
++const fn bar3() -> u32 {
++ let x = std::cell::Cell::new(0u32);
++ x.get()
++ //~^ ERROR const-stable function cannot use `#[feature(const_refs_to_cell)]`
++ //~| ERROR cannot call non-const fn
++}
+
+ // check whether this function cannot be called even with the feature gate active
+ #[unstable(feature = "foo2", issue = "none")]
+ const fn foo2_gated() -> u32 { 42 }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "rust1", since = "1.0.0")]
+ // can't call non-min_const_fn
+diff --git a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr
+index 7ec2508ca93..e5f8fa25b64 100644
+--- a/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr
++++ b/tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr
+@@ -9,35 +9,44 @@ LL | const fn bar() -> u32 { foo() }
+ error: `foo2` is not yet stable as a const fn
+ --> $DIR/min_const_fn_libstd_stability.rs:24:26
+ |
+ LL | const fn bar2() -> u32 { foo2() }
+ | ^^^^^^
+ |
+ = help: const-stable functions can only call other const-stable functions
+
+-error: const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
+- --> $DIR/min_const_fn_libstd_stability.rs:29:26
++error: const-stable function cannot use `#[feature(const_refs_to_cell)]`
++ --> $DIR/min_const_fn_libstd_stability.rs:31:5
+ |
+-LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 }
+- | ^^^^^^^^^^^^^
++LL | x.get()
++ | ^
+ |
+ help: if it is not part of the public API, make this function unstably const
+ |
+ LL + #[rustc_const_unstable(feature = "...", issue = "...")]
+-LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 }
++LL | const fn bar3() -> u32 {
+ |
+ help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
+ |
+-LL + #[rustc_allow_const_fn_unstable(const_fn_floating_point_arithmetic)]
+-LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 }
++LL + #[rustc_allow_const_fn_unstable(const_refs_to_cell)]
++LL | const fn bar3() -> u32 {
+ |
+
++error[E0015]: cannot call non-const fn `Cell::<u32>::get` in constant functions
++ --> $DIR/min_const_fn_libstd_stability.rs:31:7
++ |
++LL | x.get()
++ | ^^^^^
++ |
++ = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
++
+ error: `foo2_gated` is not yet stable as a const fn
+- --> $DIR/min_const_fn_libstd_stability.rs:39:32
++ --> $DIR/min_const_fn_libstd_stability.rs:43:32
+ |
+ LL | const fn bar2_gated() -> u32 { foo2_gated() }
+ | ^^^^^^^^^^^^
+ |
+ = help: const-stable functions can only call other const-stable functions
+
+-error: aborting due to 4 previous errors
++error: aborting due to 5 previous errors
+
++For more information about this error, try `rustc --explain E0015`.
+diff --git a/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs b/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs
+index 03084c8674d..f2a54b8a13d 100644
+--- a/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs
++++ b/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.rs
+@@ -1,14 +1,14 @@
+ #![unstable(feature = "humans",
+ reason = "who ever let humans program computers,
+ we're apparently really bad at it",
+ issue = "none")]
+
+-#![feature(const_fn_floating_point_arithmetic, foo, foo2)]
++#![feature(const_refs_to_cell, foo, foo2)]
+ #![feature(staged_api)]
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature="foo", issue = "none")]
+ const unsafe fn foo() -> u32 { 42 }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "rust1", since = "1.0.0")]
+@@ -18,22 +18,16 @@
+ #[unstable(feature = "foo2", issue = "none")]
+ const unsafe fn foo2() -> u32 { 42 }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "rust1", since = "1.0.0")]
+ // can't call non-min_const_fn
+ const unsafe fn bar2() -> u32 { unsafe { foo2() } } //~ ERROR not yet stable as a const fn
+
+-#[stable(feature = "rust1", since = "1.0.0")]
+-#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
+-// conformity is required
+-const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 }
+-//~^ ERROR const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
+-
+ // check whether this function cannot be called even with the feature gate active
+ #[unstable(feature = "foo2", issue = "none")]
+ const unsafe fn foo2_gated() -> u32 { 42 }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_stable(feature = "rust1", since = "1.0.0")]
+ // can't call non-min_const_fn
+ const unsafe fn bar2_gated() -> u32 { unsafe { foo2_gated() } }
+diff --git a/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr b/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
+index 72c1f175d1d..353b117efbc 100644
+--- a/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
++++ b/tests/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
+@@ -9,35 +9,18 @@ LL | const unsafe fn bar() -> u32 { unsafe { foo() } }
+ error: `foo2` is not yet stable as a const fn
+ --> $DIR/min_const_unsafe_fn_libstd_stability.rs:24:42
+ |
+ LL | const unsafe fn bar2() -> u32 { unsafe { foo2() } }
+ | ^^^^^^
+ |
+ = help: const-stable functions can only call other const-stable functions
+
+-error: const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
+- --> $DIR/min_const_unsafe_fn_libstd_stability.rs:29:33
+- |
+-LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 }
+- | ^^^^^^^^^^^^^
+- |
+-help: if it is not part of the public API, make this function unstably const
+- |
+-LL + #[rustc_const_unstable(feature = "...", issue = "...")]
+-LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 }
+- |
+-help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
+- |
+-LL + #[rustc_allow_const_fn_unstable(const_fn_floating_point_arithmetic)]
+-LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 }
+- |
+-
+ error: `foo2_gated` is not yet stable as a const fn
+- --> $DIR/min_const_unsafe_fn_libstd_stability.rs:39:48
++ --> $DIR/min_const_unsafe_fn_libstd_stability.rs:33:48
+ |
+ LL | const unsafe fn bar2_gated() -> u32 { unsafe { foo2_gated() } }
+ | ^^^^^^^^^^^^
+ |
+ = help: const-stable functions can only call other const-stable functions
+
+-error: aborting due to 4 previous errors
++error: aborting due to 3 previous errors
+
+diff --git a/tests/ui/internal/internal-unstable-const.rs b/tests/ui/internal/internal-unstable-const.rs
+deleted file mode 100644
+index 4ec2426dfee..00000000000
+--- a/tests/ui/internal/internal-unstable-const.rs
++++ /dev/null
+@@ -1,13 +0,0 @@
+-// Don't allow unstable features in stable functions without `allow_internal_unstable`.
+-
+-#![stable(feature = "rust1", since = "1.0.0")]
+-#![feature(staged_api)]
+-#![feature(const_fn_floating_point_arithmetic)]
+-
+-#[stable(feature = "rust1", since = "1.0.0")]
+-#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
+-pub const fn foo() -> f32 {
+- 1.0 + 1.0 //~ ERROR const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
+-}
+-
+-fn main() {}
+diff --git a/tests/ui/internal/internal-unstable-const.stderr b/tests/ui/internal/internal-unstable-const.stderr
+deleted file mode 100644
+index ed9196d2b63..00000000000
+--- a/tests/ui/internal/internal-unstable-const.stderr
++++ /dev/null
+@@ -1,19 +0,0 @@
+-error: const-stable function cannot use `#[feature(const_fn_floating_point_arithmetic)]`
+- --> $DIR/internal-unstable-const.rs:10:5
+- |
+-LL | 1.0 + 1.0
+- | ^^^^^^^^^
+- |
+-help: if it is not part of the public API, make this function unstably const
+- |
+-LL + #[rustc_const_unstable(feature = "...", issue = "...")]
+-LL | pub const fn foo() -> f32 {
+- |
+-help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
+- |
+-LL + #[rustc_allow_const_fn_unstable(const_fn_floating_point_arithmetic)]
+-LL | pub const fn foo() -> f32 {
+- |
+-
+-error: aborting due to 1 previous error
+-
diff --git a/build/build-rust/stabilize-iter_repeat_n.patch b/build/build-rust/stabilize-iter_repeat_n.patch
@@ -0,0 +1,143 @@
+commit dad808353e3 (HEAD)
+Author: Scott McMurray <scottmcm@users.noreply.github.com>
+Date: 2024-08-19T22:39:04-0700 (Monday)
+
+ Stabilize `iter::repeat_n`
+
+diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
+index 28b08ef5611..6d23f9bb431 100644
+--- a/library/alloc/src/lib.rs
++++ b/library/alloc/src/lib.rs
+@@ -131,7 +131,6 @@
+ #![feature(inplace_iteration)]
+ #![feature(iter_advance_by)]
+ #![feature(iter_next_chunk)]
+-#![feature(iter_repeat_n)]
+ #![feature(layout_for_ptr)]
+ #![feature(local_waker)]
+ #![feature(maybe_uninit_slice)]
+diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs
+index 1f2bf49d2b7..5dad9e1a75e 100644
+--- a/library/core/src/iter/mod.rs
++++ b/library/core/src/iter/mod.rs
+@@ -436,7 +436,7 @@ fn $fold<AAA, FFF>(mut self, init: AAA, fold: FFF) -> AAA
+ pub use self::sources::{once_with, OnceWith};
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub use self::sources::{repeat, Repeat};
+-#[unstable(feature = "iter_repeat_n", issue = "104434")]
++#[stable(feature = "iter_repeat_n", since = "CURRENT_RUSTC_VERSION")]
+ pub use self::sources::{repeat_n, RepeatN};
+ #[stable(feature = "iterator_repeat_with", since = "1.28.0")]
+ pub use self::sources::{repeat_with, RepeatWith};
+diff --git a/library/core/src/iter/sources.rs b/library/core/src/iter/sources.rs
+index 6a94051b7c7..55901e1e50b 100644
+--- a/library/core/src/iter/sources.rs
++++ b/library/core/src/iter/sources.rs
+@@ -24,7 +24,7 @@
+ pub use self::once_with::{once_with, OnceWith};
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub use self::repeat::{repeat, Repeat};
+-#[unstable(feature = "iter_repeat_n", issue = "104434")]
++#[stable(feature = "iter_repeat_n", since = "CURRENT_RUSTC_VERSION")]
+ pub use self::repeat_n::{repeat_n, RepeatN};
+ #[stable(feature = "iterator_repeat_with", since = "1.28.0")]
+ pub use self::repeat_with::{repeat_with, RepeatWith};
+diff --git a/library/core/src/iter/sources/repeat_n.rs b/library/core/src/iter/sources/repeat_n.rs
+index 4c4ae39f836..2e247a34075 100644
+--- a/library/core/src/iter/sources/repeat_n.rs
++++ b/library/core/src/iter/sources/repeat_n.rs
+@@ -18,7 +18,6 @@
+ /// Basic usage:
+ ///
+ /// ```
+-/// #![feature(iter_repeat_n)]
+ /// use std::iter;
+ ///
+ /// // four of the number four:
+@@ -36,7 +35,6 @@
+ /// For non-`Copy` types,
+ ///
+ /// ```
+-/// #![feature(iter_repeat_n)]
+ /// use std::iter;
+ ///
+ /// let v: Vec<i32> = Vec::with_capacity(123);
+@@ -58,7 +56,7 @@
+ /// assert_eq!(None, it.next());
+ /// ```
+ #[inline]
+-#[unstable(feature = "iter_repeat_n", issue = "104434")]
++#[stable(feature = "iter_repeat_n", since = "CURRENT_RUSTC_VERSION")]
+ pub fn repeat_n<T: Clone>(element: T, count: usize) -> RepeatN<T> {
+ let mut element = ManuallyDrop::new(element);
+
+@@ -77,7 +75,7 @@ pub fn repeat_n<T: Clone>(element: T, count: usize) -> RepeatN<T> {
+ /// This `struct` is created by the [`repeat_n()`] function.
+ /// See its documentation for more.
+ #[derive(Clone, Debug)]
+-#[unstable(feature = "iter_repeat_n", issue = "104434")]
++#[stable(feature = "iter_repeat_n", since = "CURRENT_RUSTC_VERSION")]
+ pub struct RepeatN<A> {
+ count: usize,
+ // Invariant: has been dropped iff count == 0.
+@@ -101,14 +99,14 @@ fn take_element(&mut self) -> Option<A> {
+ }
+ }
+
+-#[unstable(feature = "iter_repeat_n", issue = "104434")]
++#[stable(feature = "iter_repeat_n", since = "CURRENT_RUSTC_VERSION")]
+ impl<A> Drop for RepeatN<A> {
+ fn drop(&mut self) {
+ self.take_element();
+ }
+ }
+
+-#[unstable(feature = "iter_repeat_n", issue = "104434")]
++#[stable(feature = "iter_repeat_n", since = "CURRENT_RUSTC_VERSION")]
+ impl<A: Clone> Iterator for RepeatN<A> {
+ type Item = A;
+
+@@ -156,14 +154,14 @@ fn count(self) -> usize {
+ }
+ }
+
+-#[unstable(feature = "iter_repeat_n", issue = "104434")]
++#[stable(feature = "iter_repeat_n", since = "CURRENT_RUSTC_VERSION")]
+ impl<A: Clone> ExactSizeIterator for RepeatN<A> {
+ fn len(&self) -> usize {
+ self.count
+ }
+ }
+
+-#[unstable(feature = "iter_repeat_n", issue = "104434")]
++#[stable(feature = "iter_repeat_n", since = "CURRENT_RUSTC_VERSION")]
+ impl<A: Clone> DoubleEndedIterator for RepeatN<A> {
+ #[inline]
+ fn next_back(&mut self) -> Option<A> {
+@@ -181,12 +179,12 @@ fn nth_back(&mut self, n: usize) -> Option<A> {
+ }
+ }
+
+-#[unstable(feature = "iter_repeat_n", issue = "104434")]
++#[stable(feature = "iter_repeat_n", since = "CURRENT_RUSTC_VERSION")]
+ impl<A: Clone> FusedIterator for RepeatN<A> {}
+
+ #[unstable(feature = "trusted_len", issue = "37572")]
+ unsafe impl<A: Clone> TrustedLen for RepeatN<A> {}
+-#[unstable(feature = "trusted_len_next_unchecked", issue = "37572")]
++#[stable(feature = "iter_repeat_n", since = "CURRENT_RUSTC_VERSION")]
+ impl<A: Clone> UncheckedIterator for RepeatN<A> {
+ #[inline]
+ unsafe fn next_unchecked(&mut self) -> Self::Item {
+diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
+index 1e336bf96b8..40d67f707e8 100644
+--- a/library/core/tests/lib.rs
++++ b/library/core/tests/lib.rs
+@@ -73,7 +73,6 @@
+ #![feature(iter_next_chunk)]
+ #![feature(iter_order_by)]
+ #![feature(iter_partition_in_place)]
+-#![feature(iter_repeat_n)]
+ #![feature(iterator_try_collect)]
+ #![feature(iterator_try_reduce)]
+ #![feature(layout_for_ptr)]
diff --git a/build/build-rust/stabilize-option-is-none-or-1.82.patch b/build/build-rust/stabilize-option-is-none-or-1.82.patch
@@ -0,0 +1,75 @@
+Stabilizes `Option::is_none_or` for our not-quite-Rust-1.82 build for sanitizers.
+
+This patch is consolidated from [`rust`#129086](https://github.com/rust-lang/rust/pull/129086).
+
+diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
+index 780404212c..d825a47bfd 100644
+--- a/compiler/rustc_const_eval/src/lib.rs
++++ b/compiler/rustc_const_eval/src/lib.rs
+@@ -6,7 +6,6 @@
+ #![feature(box_patterns)]
+ #![feature(decl_macro)]
+ #![feature(if_let_guard)]
+-#![feature(is_none_or)]
+ #![feature(let_chains)]
+ #![feature(never_type)]
+ #![feature(rustdoc_internals)]
+diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
+index 758a1cefe6..9ec101196a 100644
+--- a/compiler/rustc_hir_typeck/src/lib.rs
++++ b/compiler/rustc_hir_typeck/src/lib.rs
+@@ -5,7 +5,6 @@
+ #![feature(box_patterns)]
+ #![feature(control_flow_enum)]
+ #![feature(if_let_guard)]
+-#![feature(is_none_or)]
+ #![feature(let_chains)]
+ #![feature(never_type)]
+ #![feature(try_blocks)]
+diff --git a/library/core/src/option.rs b/library/core/src/option.rs
+index 6c89c81018..9c6819bc58 100644
+--- a/library/core/src/option.rs
++++ b/library/core/src/option.rs
+@@ -656,8 +656,6 @@
+ /// # Examples
+ ///
+ /// ```
+- /// #![feature(is_none_or)]
+- ///
+ /// let x: Option<u32> = Some(2);
+ /// assert_eq!(x.is_none_or(|x| x > 1), true);
+ ///
+@@ -669,7 +667,7 @@
+ /// ```
+ #[must_use]
+ #[inline]
+- #[unstable(feature = "is_none_or", issue = "126383")]
++ #[stable(feature = "is_none_or", since = "CURRENT_RUSTC_VERSION")]
+ pub fn is_none_or(self, f: impl FnOnce(T) -> bool) -> bool {
+ match self {
+ None => true,
+diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
+index 966d38508f..7a11e353f9 100644
+--- a/src/tools/miri/src/lib.rs
++++ b/src/tools/miri/src/lib.rs
+@@ -12,7 +12,6 @@
+ #![feature(let_chains)]
+ #![feature(trait_upcasting)]
+ #![feature(strict_overflow_ops)]
+-#![feature(is_none_or)]
+ // Configure clippy and other lints
+ #![allow(
+ clippy::collapsible_else_if,
+diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+index a433ecfd77..f6f90faa4e 100644
+--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
++++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+@@ -1462,7 +1462,7 @@
+ // otherwise, if the arg is equal to the param default, hide it (unless the
+ // default is an error which can happen for the trait Self type)
+ #[allow(unstable_name_collisions)]
+- default_parameters.get(i).is_none_or(|default_parameter| {
++ IsNoneOr::is_none_or(default_parameters.get(i), |default_parameter| {
+ // !is_err(default_parameter.skip_binders())
+ // &&
+ arg != &default_parameter.clone().substitute(Interner, ¶meters)
diff --git a/build/build-rust/stabilize-unsafe-attributes.patch b/build/build-rust/stabilize-unsafe-attributes.patch
@@ -0,0 +1,855 @@
+commit de9b5c3ea28
+Author: carbotaniuman <41451839+carbotaniuman@users.noreply.github.com>
+Date: 2024-08-07T01:36:28-0500 (Wednesday)
+
+ Stabilize `unsafe_attributes`
+
+diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
+index a353c79f12d..837cb805700 100644
+--- a/compiler/rustc_ast_passes/src/ast_validation.rs
++++ b/compiler/rustc_ast_passes/src/ast_validation.rs
+@@ -887,7 +887,7 @@ fn validate_generic_param_order(dcx: DiagCtxtHandle<'_>, generics: &[GenericPara
+
+ impl<'a> Visitor<'a> for AstValidator<'a> {
+ fn visit_attribute(&mut self, attr: &Attribute) {
+- validate_attr::check_attr(&self.features, &self.session.psess, attr);
++ validate_attr::check_attr(&self.session.psess, attr);
+ }
+
+ fn visit_ty(&mut self, ty: &'a Ty) {
+diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
+index 3ceb8e0711a..214a37bca03 100644
+--- a/compiler/rustc_ast_passes/src/feature_gate.rs
++++ b/compiler/rustc_ast_passes/src/feature_gate.rs
+@@ -559,7 +559,6 @@ macro_rules! gate_all {
+ gate_all!(mut_ref, "mutable by-reference bindings are experimental");
+ gate_all!(precise_capturing, "precise captures on `impl Trait` are experimental");
+ gate_all!(global_registration, "global registration is experimental");
+- gate_all!(unsafe_attributes, "`#[unsafe()]` markers for attributes are experimental");
+ gate_all!(return_type_notation, "return type notation is experimental");
+
+ if !visitor.features.never_patterns {
+diff --git a/compiler/rustc_builtin_macros/src/cfg_accessible.rs b/compiler/rustc_builtin_macros/src/cfg_accessible.rs
+index 006b6aa823f..3d3bd3aea05 100644
+--- a/compiler/rustc_builtin_macros/src/cfg_accessible.rs
++++ b/compiler/rustc_builtin_macros/src/cfg_accessible.rs
+@@ -47,7 +47,6 @@ fn expand(
+ ) -> ExpandResult<Vec<Annotatable>, Annotatable> {
+ let template = AttributeTemplate { list: Some("path"), ..Default::default() };
+ validate_attr::check_builtin_meta_item(
+- &ecx.ecfg.features,
+ &ecx.sess.psess,
+ meta_item,
+ ast::AttrStyle::Outer,
+diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs
+index 57bddf0ab60..e8704bc2f63 100644
+--- a/compiler/rustc_builtin_macros/src/derive.rs
++++ b/compiler/rustc_builtin_macros/src/derive.rs
+@@ -38,7 +38,6 @@ fn expand(
+ let template =
+ AttributeTemplate { list: Some("Trait1, Trait2, ..."), ..Default::default() };
+ validate_attr::check_builtin_meta_item(
+- features,
+ &sess.psess,
+ meta_item,
+ ast::AttrStyle::Outer,
+diff --git a/compiler/rustc_builtin_macros/src/util.rs b/compiler/rustc_builtin_macros/src/util.rs
+index 73cc8ff547d..0bcd5aef28b 100644
+--- a/compiler/rustc_builtin_macros/src/util.rs
++++ b/compiler/rustc_builtin_macros/src/util.rs
+@@ -17,7 +17,6 @@ pub(crate) fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaI
+ // All the built-in macro attributes are "words" at the moment.
+ let template = AttributeTemplate { word: true, ..Default::default() };
+ validate_attr::check_builtin_meta_item(
+- &ecx.ecfg.features,
+ &ecx.sess.psess,
+ meta_item,
+ AttrStyle::Outer,
+diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
+index f6bf9f5e89f..b0d3fecbb47 100644
+--- a/compiler/rustc_expand/src/config.rs
++++ b/compiler/rustc_expand/src/config.rs
+@@ -265,12 +265,7 @@ fn process_cfg_attr(&self, attr: &Attribute) -> Vec<Attribute> {
+ /// is in the original source file. Gives a compiler error if the syntax of
+ /// the attribute is incorrect.
+ pub(crate) fn expand_cfg_attr(&self, cfg_attr: &Attribute, recursive: bool) -> Vec<Attribute> {
+- validate_attr::check_attribute_safety(
+- self.features.unwrap_or(&Features::default()),
+- &self.sess.psess,
+- AttributeSafety::Normal,
+- &cfg_attr,
+- );
++ validate_attr::check_attribute_safety(&self.sess.psess, AttributeSafety::Normal, &cfg_attr);
+
+ let Some((cfg_predicate, expanded_attrs)) =
+ rustc_parse::parse_cfg_attr(cfg_attr, &self.sess.psess)
+@@ -395,11 +390,7 @@ pub(crate) fn cfg_true(&self, attr: &Attribute) -> (bool, Option<MetaItem>) {
+ }
+ };
+
+- validate_attr::deny_builtin_meta_unsafety(
+- self.features.unwrap_or(&Features::default()),
+- &self.sess.psess,
+- &meta_item,
+- );
++ validate_attr::deny_builtin_meta_unsafety(&self.sess.psess, &meta_item);
+
+ (
+ parse_cfg(&meta_item, self.sess).map_or(true, |meta_item| {
+diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
+index d8cb367e3fa..61b36e15487 100644
+--- a/compiler/rustc_expand/src/expand.rs
++++ b/compiler/rustc_expand/src/expand.rs
+@@ -1883,7 +1883,7 @@ fn check_attributes(&self, attrs: &[ast::Attribute], call: &ast::MacCall) {
+ let mut span: Option<Span> = None;
+ while let Some(attr) = attrs.next() {
+ rustc_ast_passes::feature_gate::check_attribute(attr, self.cx.sess, features);
+- validate_attr::check_attr(features, &self.cx.sess.psess, attr);
++ validate_attr::check_attr(&self.cx.sess.psess, attr);
+
+ let current_span = if let Some(sp) = span { sp.to(attr.span) } else { attr.span };
+ span = Some(current_span);
+diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
+index e42a655531b..689e2d2771e 100644
+--- a/compiler/rustc_feature/src/accepted.rs
++++ b/compiler/rustc_feature/src/accepted.rs
+@@ -388,6 +388,8 @@ macro_rules! declare_features {
+ (accepted, universal_impl_trait, "1.26.0", Some(34511)),
+ /// Allows arbitrary delimited token streams in non-macro attributes.
+ (accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208)),
++ /// Allows unsafe attributes.
++ (accepted, unsafe_attributes, "CURRENT_RUSTC_VERSION", Some(123757)),
+ /// The `unsafe_op_in_unsafe_fn` lint (allowed by default): no longer treat an unsafe function as an unsafe block.
+ (accepted, unsafe_block_in_unsafe_fn, "1.52.0", Some(71668)),
+ /// Allows unsafe on extern declarations and safety qualifiers over internal items.
+diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
+index 88a4b5a8382..a9e9bdd6a41 100644
+--- a/compiler/rustc_feature/src/unstable.rs
++++ b/compiler/rustc_feature/src/unstable.rs
+@@ -627,8 +627,6 @@ pub fn internal(&self, feature: Symbol) -> bool {
+ (unstable, type_changing_struct_update, "1.58.0", Some(86555)),
+ /// Allows unnamed fields of struct and union type
+ (incomplete, unnamed_fields, "1.74.0", Some(49804)),
+- /// Allows unsafe attributes.
+- (unstable, unsafe_attributes, "1.80.0", Some(123757)),
+ /// Allows const generic parameters to be defined with types that
+ /// are not `Sized`, e.g. `fn foo<const N: [u8]>() {`.
+ (incomplete, unsized_const_params, "CURRENT_RUSTC_VERSION", Some(95174)),
+diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
+index ff0bdfcc9d2..aa281a6f67b 100644
+--- a/compiler/rustc_lint_defs/src/builtin.rs
++++ b/compiler/rustc_lint_defs/src/builtin.rs
+@@ -4937,7 +4937,6 @@
+ /// ### Example
+ ///
+ /// ```rust
+- /// #![feature(unsafe_attributes)]
+ /// #![warn(unsafe_attr_outside_unsafe)]
+ ///
+ /// #[no_mangle]
+diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
+index 8fdfbcee385..4fea00edebc 100644
+--- a/compiler/rustc_parse/src/parser/attr.rs
++++ b/compiler/rustc_parse/src/parser/attr.rs
+@@ -4,7 +4,7 @@
+ use rustc_errors::codes::*;
+ use rustc_errors::{Diag, PResult};
+ use rustc_span::symbol::kw;
+-use rustc_span::{sym, BytePos, Span};
++use rustc_span::{BytePos, Span};
+ use thin_vec::ThinVec;
+ use tracing::debug;
+
+@@ -261,7 +261,6 @@ pub fn parse_attr_item(&mut self, force_collect: ForceCollect) -> PResult<'a, as
+ let is_unsafe = this.eat_keyword(kw::Unsafe);
+ let unsafety = if is_unsafe {
+ let unsafe_span = this.prev_token.span;
+- this.psess.gated_spans.gate(sym::unsafe_attributes, unsafe_span);
+ this.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
+ ast::Safety::Unsafe(unsafe_span)
+ } else {
+@@ -400,7 +399,6 @@ pub fn parse_meta_item(
+ };
+ let unsafety = if is_unsafe {
+ let unsafe_span = self.prev_token.span;
+- self.psess.gated_spans.gate(sym::unsafe_attributes, unsafe_span);
+ self.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
+
+ ast::Safety::Unsafe(unsafe_span)
+diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
+index a64c00f3b6c..fce41bd90be 100644
+--- a/compiler/rustc_parse/src/validate_attr.rs
++++ b/compiler/rustc_parse/src/validate_attr.rs
+@@ -7,9 +7,7 @@
+ NestedMetaItem, Safety,
+ };
+ use rustc_errors::{Applicability, FatalError, PResult};
+-use rustc_feature::{
+- AttributeSafety, AttributeTemplate, BuiltinAttribute, Features, BUILTIN_ATTRIBUTE_MAP,
+-};
++use rustc_feature::{AttributeSafety, AttributeTemplate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
+ use rustc_session::errors::report_lit_error;
+ use rustc_session::lint::builtin::{ILL_FORMED_ATTRIBUTE_INPUT, UNSAFE_ATTR_OUTSIDE_UNSAFE};
+ use rustc_session::lint::BuiltinLintDiag;
+@@ -18,7 +16,7 @@
+
+ use crate::{errors, parse_in};
+
+-pub fn check_attr(features: &Features, psess: &ParseSess, attr: &Attribute) {
++pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
+ if attr.is_doc_comment() {
+ return;
+ }
+@@ -28,7 +26,7 @@ pub fn check_attr(features: &Features, psess: &ParseSess, attr: &Attribute) {
+
+ // All non-builtin attributes are considered safe
+ let safety = attr_info.map(|x| x.safety).unwrap_or(AttributeSafety::Normal);
+- check_attribute_safety(features, psess, safety, attr);
++ check_attribute_safety(psess, safety, attr);
+
+ // Check input tokens for built-in and key-value attributes.
+ match attr_info {
+@@ -36,9 +34,9 @@ pub fn check_attr(features: &Features, psess: &ParseSess, attr: &Attribute) {
+ Some(BuiltinAttribute { name, template, .. }) if *name != sym::rustc_dummy => {
+ match parse_meta(psess, attr) {
+ // Don't check safety again, we just did that
+- Ok(meta) => check_builtin_meta_item(
+- features, psess, &meta, attr.style, *name, *template, false,
+- ),
++ Ok(meta) => {
++ check_builtin_meta_item(psess, &meta, attr.style, *name, *template, false)
++ }
+ Err(err) => {
+ err.emit();
+ }
+@@ -157,16 +155,7 @@ fn is_attr_template_compatible(template: &AttributeTemplate, meta: &ast::MetaIte
+ }
+ }
+
+-pub fn check_attribute_safety(
+- features: &Features,
+- psess: &ParseSess,
+- safety: AttributeSafety,
+- attr: &Attribute,
+-) {
+- if !features.unsafe_attributes {
+- return;
+- }
+-
++pub fn check_attribute_safety(psess: &ParseSess, safety: AttributeSafety, attr: &Attribute) {
+ let attr_item = attr.get_normal_item();
+
+ if safety == AttributeSafety::Unsafe {
+@@ -215,21 +204,18 @@ pub fn check_attribute_safety(
+
+ // Called by `check_builtin_meta_item` and code that manually denies
+ // `unsafe(...)` in `cfg`
+-pub fn deny_builtin_meta_unsafety(features: &Features, psess: &ParseSess, meta: &MetaItem) {
++pub fn deny_builtin_meta_unsafety(psess: &ParseSess, meta: &MetaItem) {
+ // This only supports denying unsafety right now - making builtin attributes
+ // support unsafety will requite us to thread the actual `Attribute` through
+ // for the nice diagnostics.
+- if features.unsafe_attributes {
+- if let Safety::Unsafe(unsafe_span) = meta.unsafety {
+- psess
+- .dcx()
+- .emit_err(errors::InvalidAttrUnsafe { span: unsafe_span, name: meta.path.clone() });
+- }
++ if let Safety::Unsafe(unsafe_span) = meta.unsafety {
++ psess
++ .dcx()
++ .emit_err(errors::InvalidAttrUnsafe { span: unsafe_span, name: meta.path.clone() });
+ }
+ }
+
+ pub fn check_builtin_meta_item(
+- features: &Features,
+ psess: &ParseSess,
+ meta: &MetaItem,
+ style: ast::AttrStyle,
+@@ -246,7 +232,7 @@ pub fn check_builtin_meta_item(
+ }
+
+ if deny_unsafety {
+- deny_builtin_meta_unsafety(features, psess, meta);
++ deny_builtin_meta_unsafety(psess, meta);
+ }
+ }
+
+diff --git a/src/tools/rustfmt/tests/target/unsafe_attributes.rs b/src/tools/rustfmt/tests/target/unsafe_attributes.rs
+index a05bedc751a..d79c56f2147 100644
+--- a/src/tools/rustfmt/tests/target/unsafe_attributes.rs
++++ b/src/tools/rustfmt/tests/target/unsafe_attributes.rs
+@@ -1,4 +1,3 @@
+-#![feature(unsafe_attributes)]
+ // https://github.com/rust-lang/rust/issues/123757
+ //
+ #![simple_ident]
+diff --git a/tests/ui/attributes/unsafe/cfg-unsafe-attributes.rs b/tests/ui/attributes/unsafe/cfg-unsafe-attributes.rs
+index ce365d1a8b1..6a9853b2f6f 100644
+--- a/tests/ui/attributes/unsafe/cfg-unsafe-attributes.rs
++++ b/tests/ui/attributes/unsafe/cfg-unsafe-attributes.rs
+@@ -1,5 +1,4 @@
+ //@ build-pass
+-#![feature(unsafe_attributes)]
+
+ #[cfg_attr(all(), unsafe(no_mangle))]
+ fn a() {}
+diff --git a/tests/ui/attributes/unsafe/derive-unsafe-attributes.rs b/tests/ui/attributes/unsafe/derive-unsafe-attributes.rs
+index b8edb4aab90..95fc19f506b 100644
+--- a/tests/ui/attributes/unsafe/derive-unsafe-attributes.rs
++++ b/tests/ui/attributes/unsafe/derive-unsafe-attributes.rs
+@@ -1,5 +1,3 @@
+-#![feature(unsafe_attributes)]
+-
+ #[derive(unsafe(Debug))]
+ //~^ ERROR: expected identifier, found keyword `unsafe`
+ //~| ERROR: traits in `#[derive(...)]` don't accept arguments
+diff --git a/tests/ui/attributes/unsafe/derive-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/derive-unsafe-attributes.stderr
+index c40a5512fd5..4002c930b63 100644
+--- a/tests/ui/attributes/unsafe/derive-unsafe-attributes.stderr
++++ b/tests/ui/attributes/unsafe/derive-unsafe-attributes.stderr
+@@ -1,5 +1,5 @@
+ error: expected identifier, found keyword `unsafe`
+- --> $DIR/derive-unsafe-attributes.rs:3:10
++ --> $DIR/derive-unsafe-attributes.rs:1:10
+ |
+ LL | #[derive(unsafe(Debug))]
+ | ^^^^^^ expected identifier, found keyword
+@@ -10,13 +10,13 @@ LL | #[derive(r#unsafe(Debug))]
+ | ++
+
+ error: traits in `#[derive(...)]` don't accept arguments
+- --> $DIR/derive-unsafe-attributes.rs:3:16
++ --> $DIR/derive-unsafe-attributes.rs:1:16
+ |
+ LL | #[derive(unsafe(Debug))]
+ | ^^^^^^^ help: remove the arguments
+
+ error: `derive` is not an unsafe attribute
+- --> $DIR/derive-unsafe-attributes.rs:12:3
++ --> $DIR/derive-unsafe-attributes.rs:10:3
+ |
+ LL | #[unsafe(derive(Debug))]
+ | ^^^^^^ this is not an unsafe attribute
+@@ -24,7 +24,7 @@ LL | #[unsafe(derive(Debug))]
+ = note: extraneous unsafe is not allowed in attributes
+
+ error: expected identifier, found keyword `unsafe`
+- --> $DIR/derive-unsafe-attributes.rs:3:10
++ --> $DIR/derive-unsafe-attributes.rs:1:10
+ |
+ LL | #[derive(unsafe(Debug))]
+ | ^^^^^^ expected identifier, found keyword
+@@ -36,7 +36,7 @@ LL | #[derive(r#unsafe(Debug))]
+ | ++
+
+ error: expected identifier, found keyword `unsafe`
+- --> $DIR/derive-unsafe-attributes.rs:3:10
++ --> $DIR/derive-unsafe-attributes.rs:1:10
+ |
+ LL | #[derive(unsafe(Debug))]
+ | ^^^^^^ expected identifier, found keyword
+@@ -48,13 +48,13 @@ LL | #[derive(r#unsafe(Debug))]
+ | ++
+
+ error: cannot find derive macro `r#unsafe` in this scope
+- --> $DIR/derive-unsafe-attributes.rs:3:10
++ --> $DIR/derive-unsafe-attributes.rs:1:10
+ |
+ LL | #[derive(unsafe(Debug))]
+ | ^^^^^^
+
+ error: cannot find derive macro `r#unsafe` in this scope
+- --> $DIR/derive-unsafe-attributes.rs:3:10
++ --> $DIR/derive-unsafe-attributes.rs:1:10
+ |
+ LL | #[derive(unsafe(Debug))]
+ | ^^^^^^
+diff --git a/tests/ui/attributes/unsafe/double-unsafe-attributes.rs b/tests/ui/attributes/unsafe/double-unsafe-attributes.rs
+index a6c0ea578f2..894d1327da7 100644
+--- a/tests/ui/attributes/unsafe/double-unsafe-attributes.rs
++++ b/tests/ui/attributes/unsafe/double-unsafe-attributes.rs
+@@ -1,5 +1,3 @@
+-#![feature(unsafe_attributes)]
+-
+ #[unsafe(unsafe(no_mangle))]
+ //~^ ERROR expected identifier, found keyword `unsafe`
+ //~| ERROR cannot find attribute `r#unsafe` in this scope
+diff --git a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr
+index 950b2636993..0825cf79408 100644
+--- a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr
++++ b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr
+@@ -1,5 +1,5 @@
+ error: expected identifier, found keyword `unsafe`
+- --> $DIR/double-unsafe-attributes.rs:3:10
++ --> $DIR/double-unsafe-attributes.rs:1:10
+ |
+ LL | #[unsafe(unsafe(no_mangle))]
+ | ^^^^^^ expected identifier, found keyword
+@@ -10,7 +10,7 @@ LL | #[unsafe(r#unsafe(no_mangle))]
+ | ++
+
+ error: `r#unsafe` is not an unsafe attribute
+- --> $DIR/double-unsafe-attributes.rs:3:3
++ --> $DIR/double-unsafe-attributes.rs:1:3
+ |
+ LL | #[unsafe(unsafe(no_mangle))]
+ | ^^^^^^ this is not an unsafe attribute
+@@ -18,7 +18,7 @@ LL | #[unsafe(unsafe(no_mangle))]
+ = note: extraneous unsafe is not allowed in attributes
+
+ error: cannot find attribute `r#unsafe` in this scope
+- --> $DIR/double-unsafe-attributes.rs:3:10
++ --> $DIR/double-unsafe-attributes.rs:1:10
+ |
+ LL | #[unsafe(unsafe(no_mangle))]
+ | ^^^^^^
+diff --git a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs
+index 0181add843b..b561550c198 100644
+--- a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs
++++ b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs
+@@ -1,6 +1,5 @@
+ //@ edition: 2024
+ //@ compile-flags: -Zunstable-options
+-#![feature(unsafe_attributes)]
+
+ #[unsafe(cfg(any()))] //~ ERROR: is not an unsafe attribute
+ fn a() {}
+diff --git a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr
+index f39074b613d..9fb7f062b91 100644
+--- a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr
++++ b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr
+@@ -1,5 +1,5 @@
+ error: `cfg` is not an unsafe attribute
+- --> $DIR/extraneous-unsafe-attributes.rs:5:3
++ --> $DIR/extraneous-unsafe-attributes.rs:4:3
+ |
+ LL | #[unsafe(cfg(any()))]
+ | ^^^^^^ this is not an unsafe attribute
+@@ -7,7 +7,7 @@ LL | #[unsafe(cfg(any()))]
+ = note: extraneous unsafe is not allowed in attributes
+
+ error: `cfg_attr` is not an unsafe attribute
+- --> $DIR/extraneous-unsafe-attributes.rs:8:3
++ --> $DIR/extraneous-unsafe-attributes.rs:7:3
+ |
+ LL | #[unsafe(cfg_attr(any(), allow(dead_code)))]
+ | ^^^^^^ this is not an unsafe attribute
+@@ -15,7 +15,7 @@ LL | #[unsafe(cfg_attr(any(), allow(dead_code)))]
+ = note: extraneous unsafe is not allowed in attributes
+
+ error: `test` is not an unsafe attribute
+- --> $DIR/extraneous-unsafe-attributes.rs:11:3
++ --> $DIR/extraneous-unsafe-attributes.rs:10:3
+ |
+ LL | #[unsafe(test)]
+ | ^^^^^^ this is not an unsafe attribute
+@@ -23,7 +23,7 @@ LL | #[unsafe(test)]
+ = note: extraneous unsafe is not allowed in attributes
+
+ error: `ignore` is not an unsafe attribute
+- --> $DIR/extraneous-unsafe-attributes.rs:14:3
++ --> $DIR/extraneous-unsafe-attributes.rs:13:3
+ |
+ LL | #[unsafe(ignore = "test")]
+ | ^^^^^^ this is not an unsafe attribute
+@@ -31,7 +31,7 @@ LL | #[unsafe(ignore = "test")]
+ = note: extraneous unsafe is not allowed in attributes
+
+ error: `should_panic` is not an unsafe attribute
+- --> $DIR/extraneous-unsafe-attributes.rs:17:3
++ --> $DIR/extraneous-unsafe-attributes.rs:16:3
+ |
+ LL | #[unsafe(should_panic(expected = "test"))]
+ | ^^^^^^ this is not an unsafe attribute
+@@ -39,7 +39,7 @@ LL | #[unsafe(should_panic(expected = "test"))]
+ = note: extraneous unsafe is not allowed in attributes
+
+ error: `macro_use` is not an unsafe attribute
+- --> $DIR/extraneous-unsafe-attributes.rs:20:3
++ --> $DIR/extraneous-unsafe-attributes.rs:19:3
+ |
+ LL | #[unsafe(macro_use)]
+ | ^^^^^^ this is not an unsafe attribute
+@@ -47,7 +47,7 @@ LL | #[unsafe(macro_use)]
+ = note: extraneous unsafe is not allowed in attributes
+
+ error: `macro_export` is not an unsafe attribute
+- --> $DIR/extraneous-unsafe-attributes.rs:22:7
++ --> $DIR/extraneous-unsafe-attributes.rs:21:7
+ |
+ LL | #[unsafe(macro_export)]
+ | ^^^^^^ this is not an unsafe attribute
+@@ -55,7 +55,7 @@ LL | #[unsafe(macro_export)]
+ = note: extraneous unsafe is not allowed in attributes
+
+ error: `used` is not an unsafe attribute
+- --> $DIR/extraneous-unsafe-attributes.rs:28:3
++ --> $DIR/extraneous-unsafe-attributes.rs:27:3
+ |
+ LL | #[unsafe(used)]
+ | ^^^^^^ this is not an unsafe attribute
+diff --git a/tests/ui/attributes/unsafe/proc-unsafe-attributes.rs b/tests/ui/attributes/unsafe/proc-unsafe-attributes.rs
+index f29a5b3252b..eaf8706369a 100644
+--- a/tests/ui/attributes/unsafe/proc-unsafe-attributes.rs
++++ b/tests/ui/attributes/unsafe/proc-unsafe-attributes.rs
+@@ -1,5 +1,3 @@
+-#![feature(unsafe_attributes)]
+-
+ #[unsafe(proc_macro)]
+ //~^ ERROR: is not an unsafe attribute
+ //~| ERROR attribute is only usable with crates of the `proc-macro` crate type
+diff --git a/tests/ui/attributes/unsafe/proc-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/proc-unsafe-attributes.stderr
+index 79d34d458bd..9c5751c82e4 100644
+--- a/tests/ui/attributes/unsafe/proc-unsafe-attributes.stderr
++++ b/tests/ui/attributes/unsafe/proc-unsafe-attributes.stderr
+@@ -1,11 +1,11 @@
+ error[E0452]: malformed lint attribute input
+- --> $DIR/proc-unsafe-attributes.rs:28:16
++ --> $DIR/proc-unsafe-attributes.rs:26:16
+ |
+ LL | #[unsafe(allow(unsafe(dead_code)))]
+ | ^^^^^^^^^^^^^^^^^ bad attribute argument
+
+ error[E0452]: malformed lint attribute input
+- --> $DIR/proc-unsafe-attributes.rs:28:16
++ --> $DIR/proc-unsafe-attributes.rs:26:16
+ |
+ LL | #[unsafe(allow(unsafe(dead_code)))]
+ | ^^^^^^^^^^^^^^^^^ bad attribute argument
+@@ -13,7 +13,7 @@ LL | #[unsafe(allow(unsafe(dead_code)))]
+ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+ error: `proc_macro` is not an unsafe attribute
+- --> $DIR/proc-unsafe-attributes.rs:3:3
++ --> $DIR/proc-unsafe-attributes.rs:1:3
+ |
+ LL | #[unsafe(proc_macro)]
+ | ^^^^^^ this is not an unsafe attribute
+@@ -21,7 +21,7 @@ LL | #[unsafe(proc_macro)]
+ = note: extraneous unsafe is not allowed in attributes
+
+ error: `proc_macro_derive` is not an unsafe attribute
+- --> $DIR/proc-unsafe-attributes.rs:9:3
++ --> $DIR/proc-unsafe-attributes.rs:7:3
+ |
+ LL | #[unsafe(proc_macro_derive(Foo))]
+ | ^^^^^^ this is not an unsafe attribute
+@@ -29,7 +29,7 @@ LL | #[unsafe(proc_macro_derive(Foo))]
+ = note: extraneous unsafe is not allowed in attributes
+
+ error: expected identifier, found keyword `unsafe`
+- --> $DIR/proc-unsafe-attributes.rs:14:21
++ --> $DIR/proc-unsafe-attributes.rs:12:21
+ |
+ LL | #[proc_macro_derive(unsafe(Foo))]
+ | ^^^^^^ expected identifier, found keyword
+@@ -40,7 +40,7 @@ LL | #[proc_macro_derive(r#unsafe(Foo))]
+ | ++
+
+ error: `proc_macro_attribute` is not an unsafe attribute
+- --> $DIR/proc-unsafe-attributes.rs:19:3
++ --> $DIR/proc-unsafe-attributes.rs:17:3
+ |
+ LL | #[unsafe(proc_macro_attribute)]
+ | ^^^^^^ this is not an unsafe attribute
+@@ -48,7 +48,7 @@ LL | #[unsafe(proc_macro_attribute)]
+ = note: extraneous unsafe is not allowed in attributes
+
+ error: `allow` is not an unsafe attribute
+- --> $DIR/proc-unsafe-attributes.rs:24:3
++ --> $DIR/proc-unsafe-attributes.rs:22:3
+ |
+ LL | #[unsafe(allow(dead_code))]
+ | ^^^^^^ this is not an unsafe attribute
+@@ -56,7 +56,7 @@ LL | #[unsafe(allow(dead_code))]
+ = note: extraneous unsafe is not allowed in attributes
+
+ error: `allow` is not an unsafe attribute
+- --> $DIR/proc-unsafe-attributes.rs:28:3
++ --> $DIR/proc-unsafe-attributes.rs:26:3
+ |
+ LL | #[unsafe(allow(unsafe(dead_code)))]
+ | ^^^^^^ this is not an unsafe attribute
+@@ -64,7 +64,7 @@ LL | #[unsafe(allow(unsafe(dead_code)))]
+ = note: extraneous unsafe is not allowed in attributes
+
+ error: expected identifier, found keyword `unsafe`
+- --> $DIR/proc-unsafe-attributes.rs:28:16
++ --> $DIR/proc-unsafe-attributes.rs:26:16
+ |
+ LL | #[unsafe(allow(unsafe(dead_code)))]
+ | ^^^^^^ expected identifier, found keyword
+@@ -75,31 +75,31 @@ LL | #[unsafe(allow(r#unsafe(dead_code)))]
+ | ++
+
+ error: the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type
+- --> $DIR/proc-unsafe-attributes.rs:3:1
++ --> $DIR/proc-unsafe-attributes.rs:1:1
+ |
+ LL | #[unsafe(proc_macro)]
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+ error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type
+- --> $DIR/proc-unsafe-attributes.rs:9:1
++ --> $DIR/proc-unsafe-attributes.rs:7:1
+ |
+ LL | #[unsafe(proc_macro_derive(Foo))]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type
+- --> $DIR/proc-unsafe-attributes.rs:14:1
++ --> $DIR/proc-unsafe-attributes.rs:12:1
+ |
+ LL | #[proc_macro_derive(unsafe(Foo))]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ error: the `#[proc_macro_attribute]` attribute is only usable with crates of the `proc-macro` crate type
+- --> $DIR/proc-unsafe-attributes.rs:19:1
++ --> $DIR/proc-unsafe-attributes.rs:17:1
+ |
+ LL | #[unsafe(proc_macro_attribute)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ error[E0452]: malformed lint attribute input
+- --> $DIR/proc-unsafe-attributes.rs:28:16
++ --> $DIR/proc-unsafe-attributes.rs:26:16
+ |
+ LL | #[unsafe(allow(unsafe(dead_code)))]
+ | ^^^^^^^^^^^^^^^^^ bad attribute argument
+@@ -107,7 +107,7 @@ LL | #[unsafe(allow(unsafe(dead_code)))]
+ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+ error[E0452]: malformed lint attribute input
+- --> $DIR/proc-unsafe-attributes.rs:28:16
++ --> $DIR/proc-unsafe-attributes.rs:26:16
+ |
+ LL | #[unsafe(allow(unsafe(dead_code)))]
+ | ^^^^^^^^^^^^^^^^^ bad attribute argument
+diff --git a/tests/ui/attributes/unsafe/unsafe-attributes.rs b/tests/ui/attributes/unsafe/unsafe-attributes.rs
+index 33a412add50..5c57767b3b9 100644
+--- a/tests/ui/attributes/unsafe/unsafe-attributes.rs
++++ b/tests/ui/attributes/unsafe/unsafe-attributes.rs
+@@ -1,5 +1,4 @@
+ //@ build-pass
+-#![feature(unsafe_attributes)]
+
+ #[unsafe(no_mangle)]
+ fn a() {}
+diff --git a/tests/ui/attributes/unsafe/unsafe-safe-attribute.rs b/tests/ui/attributes/unsafe/unsafe-safe-attribute.rs
+index 67db36afd2e..5af03a2b8d1 100644
+--- a/tests/ui/attributes/unsafe/unsafe-safe-attribute.rs
++++ b/tests/ui/attributes/unsafe/unsafe-safe-attribute.rs
+@@ -1,5 +1,3 @@
+-#![feature(unsafe_attributes)]
+-
+ #[unsafe(repr(C))] //~ ERROR: is not an unsafe attribute
+ struct Foo {}
+
+diff --git a/tests/ui/attributes/unsafe/unsafe-safe-attribute.stderr b/tests/ui/attributes/unsafe/unsafe-safe-attribute.stderr
+index 584b0ea797d..55172c91aae 100644
+--- a/tests/ui/attributes/unsafe/unsafe-safe-attribute.stderr
++++ b/tests/ui/attributes/unsafe/unsafe-safe-attribute.stderr
+@@ -1,5 +1,5 @@
+ error: `repr` is not an unsafe attribute
+- --> $DIR/unsafe-safe-attribute.rs:3:3
++ --> $DIR/unsafe-safe-attribute.rs:1:3
+ |
+ LL | #[unsafe(repr(C))]
+ | ^^^^^^ this is not an unsafe attribute
+diff --git a/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.rs b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.rs
+index ff2eb61b405..0f241cc439f 100644
+--- a/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.rs
++++ b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.rs
+@@ -1,5 +1,3 @@
+-#![feature(unsafe_attributes)]
+-
+ #[unsafe(diagnostic::on_unimplemented( //~ ERROR: is not an unsafe attribute
+ message = "testing",
+ ))]
+diff --git a/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr
+index 26b5e4e37b9..3bc291db5ac 100644
+--- a/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr
++++ b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr
+@@ -1,5 +1,5 @@
+ error: `diagnostic::on_unimplemented` is not an unsafe attribute
+- --> $DIR/unsafe-safe-attribute_diagnostic.rs:3:3
++ --> $DIR/unsafe-safe-attribute_diagnostic.rs:1:3
+ |
+ LL | #[unsafe(diagnostic::on_unimplemented(
+ | ^^^^^^ this is not an unsafe attribute
+diff --git a/tests/ui/feature-gates/feature-gate-unsafe-attributes.rs b/tests/ui/feature-gates/feature-gate-unsafe-attributes.rs
+deleted file mode 100644
+index 9eba415dda0..00000000000
+--- a/tests/ui/feature-gates/feature-gate-unsafe-attributes.rs
++++ /dev/null
+@@ -1,8 +0,0 @@
+-#[unsafe(no_mangle)] //~ ERROR [E0658]
+-extern "C" fn foo() {
+-
+-}
+-
+-fn main() {
+- foo();
+-}
+diff --git a/tests/ui/feature-gates/feature-gate-unsafe-attributes.stderr b/tests/ui/feature-gates/feature-gate-unsafe-attributes.stderr
+deleted file mode 100644
+index dfcea756b02..00000000000
+--- a/tests/ui/feature-gates/feature-gate-unsafe-attributes.stderr
++++ /dev/null
+@@ -1,13 +0,0 @@
+-error[E0658]: `#[unsafe()]` markers for attributes are experimental
+- --> $DIR/feature-gate-unsafe-attributes.rs:1:3
+- |
+-LL | #[unsafe(no_mangle)]
+- | ^^^^^^
+- |
+- = note: see issue #123757 <https://github.com/rust-lang/rust/issues/123757> for more information
+- = help: add `#![feature(unsafe_attributes)]` to the crate attributes to enable
+- = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+-
+-error: aborting due to 1 previous error
+-
+-For more information about this error, try `rustc --explain E0658`.
+diff --git a/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.rs b/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.rs
+index c6f9115cde7..f3b8645abaf 100644
+--- a/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.rs
++++ b/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.rs
+@@ -1,5 +1,4 @@
+ #![deny(rust_2024_compatibility)]
+-#![feature(unsafe_attributes)]
+
+ #[no_mangle]
+ //~^ ERROR: unsafe attribute used without unsafe
+diff --git a/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.stderr b/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.stderr
+index f0689d9883c..4629a154ac3 100644
+--- a/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.stderr
++++ b/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.stderr
+@@ -1,5 +1,5 @@
+ error: unsafe attribute used without unsafe
+- --> $DIR/in_2024_compatibility.rs:4:3
++ --> $DIR/in_2024_compatibility.rs:3:3
+ |
+ LL | #[no_mangle]
+ | ^^^^^^^^^ usage of unsafe attribute
+diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attribute-marked.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attribute-marked.rs
+index 279ced2525a..7c919fed976 100644
+--- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attribute-marked.rs
++++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attribute-marked.rs
+@@ -4,7 +4,6 @@
+ //@[edition2024] compile-flags: -Zunstable-options
+ //@ check-pass
+
+-#![feature(unsafe_attributes)]
+
+ #[unsafe(no_mangle)]
+ extern "C" fn foo() {}
+diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed
+index 6ebdff0334c..586881d1807 100644
+--- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed
++++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed
+@@ -1,5 +1,4 @@
+ //@ run-rustfix
+-#![feature(unsafe_attributes)]
+ #![deny(unsafe_attr_outside_unsafe)]
+
+ macro_rules! tt {
+diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs
+index c78ff45ea4c..03e122c7d57 100644
+--- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs
++++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs
+@@ -1,5 +1,4 @@
+ //@ run-rustfix
+-#![feature(unsafe_attributes)]
+ #![deny(unsafe_attr_outside_unsafe)]
+
+ macro_rules! tt {
+diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr
+index c95984f58ec..64debc58905 100644
+--- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr
++++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr
+@@ -1,5 +1,5 @@
+ error: unsafe attribute used without unsafe
+- --> $DIR/unsafe-attributes-fix.rs:44:6
++ --> $DIR/unsafe-attributes-fix.rs:43:6
+ |
+ LL | tt!([no_mangle]);
+ | ^^^^^^^^^ usage of unsafe attribute
+@@ -7,7 +7,7 @@ LL | tt!([no_mangle]);
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
+ = note: for more information, see issue #123757 <https://github.com/rust-lang/rust/issues/123757>
+ note: the lint level is defined here
+- --> $DIR/unsafe-attributes-fix.rs:3:9
++ --> $DIR/unsafe-attributes-fix.rs:2:9
+ |
+ LL | #![deny(unsafe_attr_outside_unsafe)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+@@ -17,7 +17,7 @@ LL | tt!([unsafe(no_mangle)]);
+ | +++++++ +
+
+ error: unsafe attribute used without unsafe
+- --> $DIR/unsafe-attributes-fix.rs:14:11
++ --> $DIR/unsafe-attributes-fix.rs:13:11
+ |
+ LL | #[$e]
+ | ^^ usage of unsafe attribute
+@@ -34,7 +34,7 @@ LL | #[unsafe($e)]
+ | +++++++ +
+
+ error: unsafe attribute used without unsafe
+- --> $DIR/unsafe-attributes-fix.rs:48:7
++ --> $DIR/unsafe-attributes-fix.rs:47:7
+ |
+ LL | meta!(no_mangle);
+ | ^^^^^^^^^ usage of unsafe attribute
+@@ -47,7 +47,7 @@ LL | meta!(unsafe(no_mangle));
+ | +++++++ +
+
+ error: unsafe attribute used without unsafe
+- --> $DIR/unsafe-attributes-fix.rs:51:8
++ --> $DIR/unsafe-attributes-fix.rs:50:8
+ |
+ LL | meta2!(export_name = "baw");
+ | ^^^^^^^^^^^ usage of unsafe attribute
+@@ -60,7 +60,7 @@ LL | meta2!(unsafe(export_name = "baw"));
+ | +++++++ +
+
+ error: unsafe attribute used without unsafe
+- --> $DIR/unsafe-attributes-fix.rs:23:11
++ --> $DIR/unsafe-attributes-fix.rs:22:11
+ |
+ LL | #[$e = $l]
+ | ^^ usage of unsafe attribute
+@@ -77,7 +77,7 @@ LL | #[unsafe($e = $l)]
+ | +++++++ +
+
+ error: unsafe attribute used without unsafe
+- --> $DIR/unsafe-attributes-fix.rs:56:3
++ --> $DIR/unsafe-attributes-fix.rs:55:3
+ |
+ LL | #[no_mangle]
+ | ^^^^^^^^^ usage of unsafe attribute
+diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.edition2024.stderr b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.edition2024.stderr
+index 35475d66716..fb697e14ef1 100644
+--- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.edition2024.stderr
++++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.edition2024.stderr
+@@ -1,5 +1,5 @@
+ error: unsafe attribute used without unsafe
+- --> $DIR/unsafe-attributes.rs:9:3
++ --> $DIR/unsafe-attributes.rs:8:3
+ |
+ LL | #[no_mangle]
+ | ^^^^^^^^^ usage of unsafe attribute
+diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.rs
+index 3a6af9dfb2b..f6f2994bb6d 100644
+--- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.rs
++++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.rs
+@@ -4,7 +4,6 @@
+ //@[edition2024] edition:2024
+ //@[edition2024] compile-flags: -Zunstable-options
+
+-#![feature(unsafe_attributes)]
+
+ #[no_mangle] //[edition2024]~ ERROR: unsafe attribute used without unsafe
+ extern "C" fn foo() {}
diff --git a/build/build-rust/stabilize_raw_ref_op.patch b/build/build-rust/stabilize_raw_ref_op.patch
@@ -0,0 +1,118 @@
+From 79503dd742253cdca54f10aec9052ff477ccaf38 Mon Sep 17 00:00:00 2001
+From: Ralf Jung <post@ralfj.de>
+Date: Sat, 13 Jul 2024 13:53:56 +0200
+Subject: [PATCH] stabilize raw_ref_op
+
+diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
+index 214a37bca03e2..5ab99fbac866f 100644
+--- a/compiler/rustc_ast_passes/src/feature_gate.rs
++++ b/compiler/rustc_ast_passes/src/feature_gate.rs
+@@ -539,7 +539,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
+ }
+ }
+ gate_all!(gen_blocks, "gen blocks are experimental");
+- gate_all!(raw_ref_op, "raw address of syntax is experimental");
+ gate_all!(const_trait_impl, "const trait impls are experimental");
+ gate_all!(
+ half_open_range_patterns_in_slices,
+diff --git a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
+index e603ac566f4ec..ccbd5a78485d7 100644
+--- a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
++++ b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
+@@ -6,8 +6,7 @@
+ extern_types,
+ naked_functions,
+ thread_local,
+- repr_simd,
+- raw_ref_op
++ repr_simd
+ )]
+ #![no_core]
+ #![allow(dead_code, non_camel_case_types, internal_features)]
+diff --git a/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs b/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs
+index 9f096e9022012..dcfa34cb729d8 100644
+--- a/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs
++++ b/compiler/rustc_codegen_gcc/example/mini_core_hello_world.rs
+@@ -2,7 +2,7 @@
+
+ #![feature(
+ no_core, unboxed_closures, start, lang_items, never_type, linkage,
+- extern_types, thread_local, raw_ref_op
++ extern_types, thread_local
+ )]
+ #![no_core]
+ #![allow(dead_code, internal_features, non_camel_case_types)]
+diff --git a/compiler/rustc_error_codes/src/error_codes/E0745.md b/compiler/rustc_error_codes/src/error_codes/E0745.md
+index 23ee7af30f418..32b28f3de949f 100644
+--- a/compiler/rustc_error_codes/src/error_codes/E0745.md
++++ b/compiler/rustc_error_codes/src/error_codes/E0745.md
+@@ -3,7 +3,6 @@ The address of temporary value was taken.
+ Erroneous code example:
+
+ ```compile_fail,E0745
+-# #![feature(raw_ref_op)]
+ fn temp_address() {
+ let ptr = &raw const 2; // error!
+ }
+@@ -15,7 +14,6 @@ In this example, `2` is destroyed right after the assignment, which means that
+ To avoid this error, first bind the temporary to a named local variable:
+
+ ```
+-# #![feature(raw_ref_op)]
+ fn temp_address() {
+ let val = 2;
+ let ptr = &raw const val; // ok!
+diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
+index 3d5ecbaae32a2..7838abca9b890 100644
+--- a/compiler/rustc_feature/src/accepted.rs
++++ b/compiler/rustc_feature/src/accepted.rs
+@@ -321,6 +321,8 @@ declare_features! (
+ (accepted, raw_dylib, "1.71.0", Some(58713)),
+ /// Allows keywords to be escaped for use as identifiers.
+ (accepted, raw_identifiers, "1.30.0", Some(48589)),
++ /// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
++ (accepted, raw_ref_op, "CURRENT_RUSTC_VERSION", Some(64490)),
+ /// Allows relaxing the coherence rules such that
+ /// `impl<T> ForeignTrait<LocalType> for ForeignType<T>` is permitted.
+ (accepted, re_rebalance_coherence, "1.41.0", Some(55437)),
+diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
+index 459df9ea1b859..14e353f13ca49 100644
+--- a/compiler/rustc_feature/src/unstable.rs
++++ b/compiler/rustc_feature/src/unstable.rs
+@@ -565,8 +565,6 @@ declare_features! (
+ (unstable, precise_capturing, "1.79.0", Some(123432)),
+ /// Allows macro attributes on expressions, statements and non-inline modules.
+ (unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
+- /// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
+- (unstable, raw_ref_op, "1.41.0", Some(64490)),
+ /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024.
+ (incomplete, ref_pat_eat_one_layer_2024, "1.79.0", Some(123076)),
+ /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024—structural variant
+diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
+index e0917ba43e41c..422206ebbce07 100644
+--- a/compiler/rustc_parse/src/parser/expr.rs
++++ b/compiler/rustc_parse/src/parser/expr.rs
+@@ -851,7 +851,7 @@ impl<'a> Parser<'a> {
+ self.expect_and()?;
+ let has_lifetime = self.token.is_lifetime() && self.look_ahead(1, |t| t != &token::Colon);
+ let lifetime = has_lifetime.then(|| self.expect_lifetime()); // For recovery, see below.
+- let (borrow_kind, mutbl) = self.parse_borrow_modifiers(lo);
++ let (borrow_kind, mutbl) = self.parse_borrow_modifiers();
+ let attrs = self.parse_outer_attributes()?;
+ let expr = if self.token.is_range_separator() {
+ self.parse_expr_prefix_range(attrs)
+@@ -871,13 +871,12 @@ impl<'a> Parser<'a> {
+ }
+
+ /// Parse `mut?` or `raw [ const | mut ]`.
+- fn parse_borrow_modifiers(&mut self, lo: Span) -> (ast::BorrowKind, ast::Mutability) {
++ fn parse_borrow_modifiers(&mut self) -> (ast::BorrowKind, ast::Mutability) {
+ if self.check_keyword(kw::Raw) && self.look_ahead(1, Token::is_mutability) {
+ // `raw [ const | mut ]`.
+ let found_raw = self.eat_keyword(kw::Raw);
+ assert!(found_raw);
+ let mutability = self.parse_const_or_mut().unwrap();
+- self.psess.gated_spans.gate(sym::raw_ref_op, lo.to(self.prev_token.span));
+ (ast::BorrowKind::Raw, mutability)
+ } else {
+ // `mut?`
diff --git a/taskcluster/kinds/fetch/toolchains.yml b/taskcluster/kinds/fetch/toolchains.yml
@@ -410,13 +410,16 @@ clang-trunk:
# We build stable rust from source so the resulting compiler acts as a nightly
# rust compiler, allowing to use unstable features like -Zbuild-std and
# sanitizers.
-rust-1.82.0:
- description: Rust 1.82.0 source code
+rust-1.81.0:
+ description: Rust 1.81.0 source code
fetch:
type: git
include-dot-git: true
repo: https://github.com/rust-lang/rust/
- revision: f6e511eec7342f59a25f7c0534f1dbea00d01b14
+ # NOTE: This is 1.81.0 and then some, to accommodate compiling some 1.82.0 code without
+ # breaking patches we use for sanitizers. See
+ # <https://bugzilla.mozilla.org/show_bug.cgi?id=1915537> for follow-up.
+ revision: ab1527f1d6560168f9fd36fa8cd7ba677c1d36ad
rust-nightly:
description: Rust nightly source code
diff --git a/taskcluster/kinds/toolchain/rust.yml b/taskcluster/kinds/toolchain/rust.yml
@@ -98,7 +98,7 @@ linux64-rust-1.90:
# A patched rust toolchain that allows us to use sanitizers in our vendored
# build environment. See the rust fetch's comments for more details.
-linux64-rust-1.82-dev:
+linux64-rust-1.81-dev:
description: "build rust from source"
worker-type: b-linux-docker-large-amd
treeherder:
@@ -110,20 +110,35 @@ linux64-rust-1.82-dev:
RUSTFLAGS_NOT_BOOTSTRAP: '-Clink-arg=-Wl,--undefined-version'
run:
arguments: [
+ '--patch', 'rust-compiler-intrinsics.patch',
'--patch', 'rust-vendor-std.patch',
+ '--patch', 'src/tools/cargo:cargo-vendor-std-1.79.patch',
+ '--patch', 'stabilize-option-is-none-or-1.82.patch',
+ '--patch', 'stabilize-unsafe-attributes.patch',
+ '--patch', 'stabilize-iter_repeat_n.patch',
+ '--patch', 'stabilize-const_fn_floating_point_arithmetic.patch',
+ '--patch', 'stabilize_raw_ref_op.patch',
+ '--patch', 'soft_deprecate_the_addr_of_macros.patch',
+ '--patch', 'rename_AddressOf_to_RawBorrow_inside_the_compiler.patch',
'--channel', 'dev',
'--host', 'x86_64-unknown-linux-gnu',
'--target', 'x86_64-unknown-linux-gnu',
]
resources:
+ - build/build-rust/rust-compiler-intrinsics.patch
- build/build-rust/rust-vendor-std.patch
+ - build/build-rust/cargo-vendor-std-1.79.patch
+ - build/build-rust/stabilize-option-is-none-or-1.82.patch
+ - build/build-rust/stabilize-unsafe-attributes.patch
+ - build/build-rust/stabilize-iter_repeat_n.patch
+ - build/build-rust/stabilize-const_fn_floating_point_arithmetic.patch
toolchain-alias:
by-project:
toolchains: null
default: linux64-rust-dev
fetches:
fetch:
- - rust-1.82.0
+ - rust-1.81.0
toolchain:
- linux64-clang-toolchain
- linux64-toolchain-sysroot
@@ -328,12 +343,14 @@ linux64-rust-nightly-dev:
run:
arguments: [
'--patch', 'rust-vendor-std.patch',
+ '--patch', 'src/tools/cargo:cargo-vendor-std-1.79.patch',
'--channel', 'dev',
'--host', 'x86_64-unknown-linux-gnu',
'--target', 'x86_64-unknown-linux-gnu',
]
resources:
- build/build-rust/rust-vendor-std.patch
+ - build/build-rust/cargo-vendor-std-1.79.patch
toolchain-alias:
by-project:
toolchains: linux64-rust-dev