also fix potential issues with mixed stable/unstable target features in rustdoc
This commit is contained in:
parent
b6f2240000
commit
039af88e09
1 changed files with 33 additions and 12 deletions
|
@ -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;
|
||||
|
||||
|
@ -87,10 +87,7 @@ pub(crate) fn from_target_feature_attr(
|
|||
// But ensure the ABI does not forbid enabling this.
|
||||
// Here we do assume that LLVM doesn't add even more implied features
|
||||
// we don't know about, at least no features that would have ABI effects!
|
||||
// We skip this check in rustdoc, like we skip all target feature related checks.
|
||||
if !tcx.sess.opts.actually_rustdoc
|
||||
&& abi_feature_constraints.incompatible.contains(&name.as_str())
|
||||
{
|
||||
if abi_feature_constraints.incompatible.contains(&name.as_str()) {
|
||||
tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr {
|
||||
span: item.span(),
|
||||
feature: name.as_str(),
|
||||
|
@ -146,13 +143,37 @@ pub(crate) fn provide(providers: &mut Providers) {
|
|||
assert_eq!(cnum, LOCAL_CRATE);
|
||||
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))
|
||||
.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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result
|
||||
} else {
|
||||
tcx.sess
|
||||
.target
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue