diff options
| author | Ralf Jung <post@ralfj.de> | 2025-02-25 20:38:13 +0100 |
|---|---|---|
| committer | Josh Stone <jistone@redhat.com> | 2025-03-14 14:12:37 -0700 |
| commit | c13521b739511d4a0cb7d6941e93eadd9e59aaf9 (patch) | |
| tree | f0e77950e91bd400c37ab842cc1d88e47462304a | |
| parent | d4de520fc458f67758ad7d7fb024e065f840f61e (diff) | |
| download | rust-c13521b739511d4a0cb7d6941e93eadd9e59aaf9.tar.gz rust-c13521b739511d4a0cb7d6941e93eadd9e59aaf9.zip | |
also fix potential issues with mixed stable/unstable target features in rustdoc
(cherry picked from commit 039af88e09f4f4beb47406f4771bffc2e61d800a)
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/target_features.rs | 40 |
1 files changed, 32 insertions, 8 deletions
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 |
