diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 81294d4e19ae..7907585d684d 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -714,12 +714,14 @@ pub(crate) fn global_llvm_features( sess.dcx().emit_warn(unknown_feature); } Some((_, stability, _)) => { - if let Err(reason) = stability.compute(&sess.target).allow_toggle() { + if let Err(reason) = + stability.compute_toggleability(&sess.target).allow_toggle() + { sess.dcx().emit_warn(ForbiddenCTargetFeature { feature, reason }); } else if stability.requires_nightly().is_some() { - // An unstable feature. Warn about using it. (It makes little sense + // An unstable feature. Warn about using it. It makes little sense // to hard-error here since we just warn about fully unknown - // features above). + // features above. sess.dcx().emit_warn(UnstableCTargetFeature { feature }); } } diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index b3057325bd62..fa600ec7166a 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -153,14 +153,14 @@ pub(crate) fn provide(providers: &mut Providers) { // rustdoc needs to be able to document functions that use all the features, so // whitelist them all rustc_target::target_features::all_rust_features() - .map(|(a, b)| (a.to_string(), b.compute(target))) + .map(|(a, b)| (a.to_string(), b.compute_toggleability(target))) .collect() } else { tcx.sess .target .rust_target_features() .iter() - .map(|&(a, b, _)| (a.to_string(), b.compute(target))) + .map(|&(a, b, _)| (a.to_string(), b.compute_toggleability(target))) .collect() } }, diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index edb91f87d4ef..8a8723d8512b 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -17,17 +17,17 @@ pub const RUSTC_SPECIFIC_FEATURES: &[&str] = &["crt-static"]; pub const RUSTC_SPECIAL_FEATURES: &[&str] = &["backchain"]; /// Stability information for target features. -/// `AllowToggle` is the type storing whether (un)stable features can be toggled: +/// `Toggleability` is the type storing whether (un)stable features can be toggled: /// this is initially a function since it can depend on `Target`, but for stable hashing /// it needs to be something hashable to we have to make the type generic. #[derive(Debug, Clone, Copy)] -pub enum Stability { +pub enum Stability { /// This target feature is stable, it can be used in `#[target_feature]` and /// `#[cfg(target_feature)]`. Stable { - /// When enabling/dsiabling the feature via `-Ctarget-feature` or `#[target_feature]`, + /// When enabling/disabling the feature via `-Ctarget-feature` or `#[target_feature]`, /// determine if that is allowed. - allow_toggle: AllowToggle, + allow_toggle: Toggleability, }, /// This target feature is unstable. It is only present in `#[cfg(target_feature)]` on /// nightly and using it in `#[target_feature]` requires enabling the given nightly feature. @@ -36,7 +36,7 @@ pub enum Stability { /// feature gate! nightly_feature: Symbol, /// See `Stable::allow_toggle` comment above. - allow_toggle: AllowToggle, + allow_toggle: Toggleability, }, /// This feature can not be set via `-Ctarget-feature` or `#[target_feature]`, it can only be /// set in the basic target definition. It is never set in `cfg(target_feature)`. Used in @@ -50,7 +50,7 @@ pub type StabilityUncomputed = Stability Result<(), &'static str> /// `Stability` where `allow_toggle` has already been computed. pub type StabilityComputed = Stability>; -impl> HashStable for Stability { +impl> HashStable for Stability { #[inline] fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { std::mem::discriminant(self).hash_stable(hcx, hasher); @@ -69,15 +69,22 @@ impl> HashStable for Stability Stability { - /// Returns whether the feature can be queried in `cfg` ever. - /// (It might still be nightly-only even if this returns `true`). +impl Stability { + /// Returns whether the feature can be used in `cfg(target_feature)` ever. + /// (It might still be nightly-only even if this returns `true`, so make sure to also check + /// `requires_nightly`.) pub fn in_cfg(self) -> bool { !matches!(self, Stability::Forbidden { .. }) } - /// Returns the nightly feature that is required to toggle or query this target feature. Ensure - /// to also check `allow_toggle()` before allowing to toggle! + /// Returns the nightly feature that is required to toggle this target feature via + /// `#[target_feature]`/`-Ctarget-feature` or to test it via `cfg(target_feature)`. + /// (For `cfg` we only care whether the feature is nightly or not, we don't require + /// the feature gate to actually be enabled when using a nightly compiler.) + /// + /// Before calling this, ensure the feature is even permitted for this use: + /// - for `#[target_feature]`/`-Ctarget-feature`, check `allow_toggle()` + /// - for `cfg(target_feature)`, check `in_cfg` pub fn requires_nightly(self) -> Option { match self { Stability::Unstable { nightly_feature, .. } => Some(nightly_feature), @@ -88,7 +95,7 @@ impl Stability { } impl StabilityUncomputed { - pub fn compute(self, target: &Target) -> StabilityComputed { + pub fn compute_toggleability(self, target: &Target) -> StabilityComputed { use Stability::*; match self { Stable { allow_toggle } => Stable { allow_toggle: allow_toggle(target) }, @@ -101,6 +108,9 @@ impl StabilityUncomputed { } impl StabilityComputed { + /// Returns whether the feature may be toggled via `#[target_feature]` or `-Ctarget-feature`. + /// (It might still be nightly-only even if this returns `true`, so make sure to also check + /// `requires_nightly`.) pub fn allow_toggle(self) -> Result<(), &'static str> { match self { Stability::Stable { allow_toggle } => allow_toggle,