--- /dev/null
+From: Ralf Jung <post@ralfj.de>
+Date: Fri, 28 Feb 2025 16:51:53 +0100
+X-Dgit-Generated: 1.85.0+dfsg2-2+rpi1 3e8d878c40118510cfb639f6b0488321eaab4792
+Subject: add test
+
+(cherry picked from commit dc04c0ca48c7285d74a0489354ed7d013dc25799)
+
+---
+
+diff --git a/tests/rustdoc-ui/target-feature-stability.rs b/tests/rustdoc-ui/target-feature-stability.rs
+new file mode 100644
+index 00000000000..4ade9690310
+--- /dev/null
++++ b/tests/rustdoc-ui/target-feature-stability.rs
+@@ -0,0 +1,18 @@
++//! This is a regression test for <https://github.com/rust-lang/rust/issues/137366>, ensuring
++//! that we can use the `neon` target feature on ARM-32 targets in rustdoc despite there
++//! being a "forbidden" feature of the same name for aarch64, and rustdoc merging the
++//! target features of all targets.
++//@ check-pass
++//@ compile-flags: --target armv7-unknown-linux-gnueabihf
++
++#![crate_type = "lib"]
++#![feature(no_core, lang_items)]
++#![feature(arm_target_feature)]
++#![no_core]
++
++#[lang = "sized"]
++pub trait Sized {}
++
++// `fp-armv8` is "forbidden" on aarch64 as we tie it to `neon`.
++#[target_feature(enable = "fp-armv8")]
++pub fn fun() {}
--- /dev/null
+From: Ralf Jung <post@ralfj.de>
+Date: Tue, 25 Feb 2025 20:38:13 +0100
+X-Dgit-Generated: 1.85.0+dfsg2-2+rpi1 07905b9e498fc346755ca65d32fd821034373268
+Subject: also fix potential issues with mixed stable/unstable target features in rustdoc
+
+(cherry picked from commit 039af88e09f4f4beb47406f4771bffc2e61d800a)
+
+---
+
+diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
+index d673cd6e6b4..bffcdca299b 100644
+--- a/compiler/rustc_codegen_ssa/src/target_features.rs
++++ b/compiler/rustc_codegen_ssa/src/target_features.rs
+@@ -10,7 +10,7 @@ use rustc_middle::query::Providers;
+ use rustc_middle::ty::TyCtxt;
+ use rustc_session::parse::feature_err;
+ use rustc_span::{Span, Symbol, sym};
+-use rustc_target::target_features;
++use rustc_target::target_features::{self, Stability};
+
+ use crate::errors;
+
+@@ -150,13 +150,37 @@ pub(crate) fn provide(providers: &mut Providers) {
+ let target = &tcx.sess.target;
+ if tcx.sess.opts.actually_rustdoc {
+ // HACK: rustdoc would like to pretend that we have all the target features, so we
+- // have to merge all the lists into one. The result has a "random" stability
+- // (depending on the order in which we consider features); all places that check
+- // target stability are expected to check `actually_rustdoc` and do nothing when
+- // that is set.
+- rustc_target::target_features::all_rust_features()
+- .map(|(a, b)| (a.to_string(), b.compute_toggleability(target)))
+- .collect()
++ // have to merge all the lists into one. To ensure an unstable target never prevents
++ // a stable one from working, we merge the stability info of all instances of the
++ // same target feature name, with the "most stable" taking precedence. And then we
++ // hope that this doesn't cause issues anywhere else in the compiler...
++ let mut result: UnordMap<String, Stability<_>> = Default::default();
++ for (name, stability) in rustc_target::target_features::all_rust_features() {
++ use std::collections::hash_map::Entry;
++ match result.entry(name.to_owned()) {
++ Entry::Vacant(vacant_entry) => {
++ vacant_entry.insert(stability.compute_toggleability(target));
++ }
++ Entry::Occupied(mut occupied_entry) => {
++ // Merge the two stabilities, "more stable" taking precedence.
++ match (occupied_entry.get(), &stability) {
++ (Stability::Stable { .. }, _)
++ | (
++ Stability::Unstable { .. },
++ Stability::Unstable { .. } | Stability::Forbidden { .. },
++ )
++ | (Stability::Forbidden { .. }, Stability::Forbidden { .. }) => {
++ // The stability in the entry is at least as good as the new one, just keep it.
++ }
++ _ => {
++ // Overwrite stabilite.
++ occupied_entry.insert(stability.compute_toggleability(target));
++ }
++ }
++ }
++ }
++ }
++ result
+ } else {
+ tcx.sess
+ .target
--- /dev/null
+From: Ralf Jung <post@ralfj.de>
+Date: Fri, 28 Feb 2025 16:56:36 +0100
+X-Dgit-Generated: 1.85.0+dfsg2-2+rpi1 2bc8c4ff9c13b267a3b874a43ecf54c970203eb3
+Subject: also skip abi_required_features check in rustdoc
+
+(cherry picked from commit 4c939db0e775df21a0b409b7603eaaf0056e8f86)
+
+---
+
+diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
+index bffcdca299b..0c53a731221 100644
+--- a/compiler/rustc_codegen_ssa/src/target_features.rs
++++ b/compiler/rustc_codegen_ssa/src/target_features.rs
+@@ -65,11 +65,16 @@ pub(crate) fn from_target_feature_attr(
+ // Only allow target features whose feature gates have been enabled
+ // and which are permitted to be toggled.
+ if let Err(reason) = stability.toggle_allowed(/*enable*/ true) {
+- tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr {
+- span: item.span(),
+- feature,
+- reason,
+- });
++ // We skip this error in rustdoc, where we want to allow all target features of
++ // all targets, so we can't check their ABI compatibility and anyway we are not
++ // generating code so "it's fine".
++ if !tcx.sess.opts.actually_rustdoc {
++ tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr {
++ span: item.span(),
++ feature,
++ reason,
++ });
++ }
+ } else if let Some(nightly_feature) = stability.requires_nightly()
+ && !rust_features.enabled(nightly_feature)
+ {
+diff --git a/tests/rustdoc-ui/target-feature-stability.rs b/tests/rustdoc-ui/target-feature-stability.rs
+index 4ade9690310..17fa3ccfe3e 100644
+--- a/tests/rustdoc-ui/target-feature-stability.rs
++++ b/tests/rustdoc-ui/target-feature-stability.rs
+@@ -1,9 +1,13 @@
+ //! This is a regression test for <https://github.com/rust-lang/rust/issues/137366>, ensuring
+-//! that we can use the `neon` target feature on ARM-32 targets in rustdoc despite there
++//! that we can use the `neon` target feature on ARM32 targets in rustdoc despite there
+ //! being a "forbidden" feature of the same name for aarch64, and rustdoc merging the
+ //! target features of all targets.
+ //@ check-pass
+-//@ compile-flags: --target armv7-unknown-linux-gnueabihf
++//@ revisions: arm aarch64
++//@[arm] compile-flags: --target armv7-unknown-linux-gnueabihf
++//@[arm] needs-llvm-components: arm
++//@[aarch64] compile-flags: --target aarch64-unknown-none-softfloat
++//@[aarch64] needs-llvm-components: aarch64
+
+ #![crate_type = "lib"]
+ #![feature(no_core, lang_items)]
+@@ -15,4 +19,10 @@ pub trait Sized {}
+
+ // `fp-armv8` is "forbidden" on aarch64 as we tie it to `neon`.
+ #[target_feature(enable = "fp-armv8")]
+-pub fn fun() {}
++pub fn fun1() {}
++
++// This would usually be rejected as it changes the ABI.
++// But we disable that check in rustdoc since we are building "for all targets" and the
++// check can't really handle that.
++#[target_feature(enable = "soft-float")]
++pub fn fun2() {}
--- /dev/null
+From: Ralf Jung <post@ralfj.de>
+Date: Tue, 25 Feb 2025 20:26:12 +0100
+X-Dgit-Generated: 1.85.0+dfsg2-2+rpi1 f5bd6c66b8a09b2cf24e888744d842ec0de69e48
+Subject: rustdoc: disable forbidden #[target_feature] check
+
+(cherry picked from commit b6f22400002f7921feed13e35852e3041cf2b145)
+
+---
+
+diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
+index 7e80d014ea2..d673cd6e6b4 100644
+--- a/compiler/rustc_codegen_ssa/src/target_features.rs
++++ b/compiler/rustc_codegen_ssa/src/target_features.rs
+@@ -149,8 +149,11 @@ pub(crate) fn provide(providers: &mut Providers) {
+ assert_eq!(cnum, LOCAL_CRATE);
+ let target = &tcx.sess.target;
+ if tcx.sess.opts.actually_rustdoc {
+- // rustdoc needs to be able to document functions that use all the features, so
+- // whitelist them all
++ // HACK: rustdoc would like to pretend that we have all the target features, so we
++ // have to merge all the lists into one. The result has a "random" stability
++ // (depending on the order in which we consider features); all places that check
++ // target stability are expected to check `actually_rustdoc` and do nothing when
++ // that is set.
+ rustc_target::target_features::all_rust_features()
+ .map(|(a, b)| (a.to_string(), b.compute_toggleability(target)))
+ .collect()
behaviour/proc-macro-srv-make-usage-of-RTLD_DEEPBIND-portable.patch
bootstrap/bootstrap-revert-cross-build-breaking-change.patch
vendor/cargo-update-git2-bindings.patch
+rustdoc-disable-forbidden-target_feature.patch
+also-fix-potential-issues-with-mixed-sta.patch
+add-test.patch
+also-skip-abi_required_features-check-in.patch