void-packages/srcpkgs/rust/patches/0016-fix-rustdoc-on-arm-targets.patch
2025-03-10 19:22:34 +00:00

97 lines
5.1 KiB
Diff

Ported from https://github.com/rust-lang/rust/pull/137632
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index 7e80d014e..4d1c10bbc 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -62,24 +62,26 @@ pub(crate) fn from_target_feature_attr(
return None;
};
- // 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,
- });
- } else if let Some(nightly_feature) = stability.requires_nightly()
- && !rust_features.enabled(nightly_feature)
- {
- feature_err(
- &tcx.sess,
- nightly_feature,
- item.span(),
- format!("the target feature `{feature}` is currently unstable"),
- )
- .emit();
+ if !tcx.sess.opts.actually_rustdoc {
+ // 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,
+ });
+ } else if let Some(nightly_feature) = stability.requires_nightly()
+ && !rust_features.enabled(nightly_feature)
+ {
+ feature_err(
+ &tcx.sess,
+ nightly_feature,
+ item.span(),
+ format!("the target feature `{feature}` is currently unstable"),
+ )
+ .emit();
+ }
}
Some(Symbol::intern(feature))
}));
@@ -149,9 +151,42 @@ 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
- rustc_target::target_features::all_rust_features()
+ // HACK: rustdoc would like to pretend that we have all the target features, so we
+ // 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...
+ use target_features::StabilityUncomputed;
+ use rustc_data_structures::fx::FxHashMap;
+ let mut result: FxHashMap<String, StabilityUncomputed> = 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);
+ }
+ Entry::Occupied(mut occupied_entry) => {
+ // Merge the two stabilities, "more stable" taking precedence.
+ match (occupied_entry.get(), &stability) {
+ (StabilityUncomputed::Stable { .. }, _)
+ | (
+ StabilityUncomputed::Unstable { .. },
+ StabilityUncomputed::Unstable { .. } | StabilityUncomputed::Forbidden { .. },
+ )
+ | (StabilityUncomputed::Forbidden { .. }, StabilityUncomputed::Forbidden { .. }) => {
+ // The stability in the entry is at least as good as the new one, just keep it.
+ }
+ _ => {
+ // Overwrite stabilite.
+ occupied_entry.insert(stability.clone());
+ }
+ }
+ }
+ }
+ }
+ #[allow(rustc::potential_query_instability)]
+ result
+ .iter()
.map(|(a, b)| (a.to_string(), b.compute_toggleability(target)))
.collect()
} else {