diff --git a/messages.ftl b/messages.ftl index 26ddc5732dd..85fa17a6ba5 100644 --- a/messages.ftl +++ b/messages.ftl @@ -9,7 +9,7 @@ codegen_gcc_lto_not_supported = LTO is not supported. You may get a linker error. codegen_gcc_forbidden_ctarget_feature = - target feature `{$feature}` cannot be toggled with `-Ctarget-feature` + target feature `{$feature}` cannot be toggled with `-Ctarget-feature`: {$reason} codegen_gcc_unwinding_inline_asm = GCC backend does not support unwinding from inline asm diff --git a/src/errors.rs b/src/errors.rs index 7a586b5b04c..56849cc8610 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -28,6 +28,7 @@ pub(crate) struct UnstableCTargetFeature<'a> { #[diag(codegen_gcc_forbidden_ctarget_feature)] pub(crate) struct ForbiddenCTargetFeature<'a> { pub feature: &'a str, + pub reason: &'a str, } #[derive(Subdiagnostic)] diff --git a/src/gcc_util.rs b/src/gcc_util.rs index 65279c9495a..3717e12020f 100644 --- a/src/gcc_util.rs +++ b/src/gcc_util.rs @@ -5,7 +5,7 @@ use rustc_codegen_ssa::errors::TargetFeatureDisableOrEnable; use rustc_data_structures::fx::FxHashMap; use rustc_middle::bug; use rustc_session::Session; -use rustc_target::target_features::{RUSTC_SPECIFIC_FEATURES, Stability}; +use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES; use smallvec::{SmallVec, smallvec}; use crate::errors::{ @@ -94,13 +94,15 @@ pub(crate) fn global_gcc_features(sess: &Session, diagnostics: bool) -> Vec {} - Some((_, Stability::Unstable(_), _)) => { - // An unstable feature. Warn about using it. - sess.dcx().emit_warn(UnstableCTargetFeature { feature }); - } - Some((_, Stability::Forbidden { .. }, _)) => { - sess.dcx().emit_err(ForbiddenCTargetFeature { feature }); + Some((_, stability, _)) => { + if let Err(reason) = stability.compute(&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 + // to hard-error here since we just warn about fully unknown + // features above). + sess.dcx().emit_warn(UnstableCTargetFeature { feature }); + } } } diff --git a/src/lib.rs b/src/lib.rs index 452e92bffa2..764e84be1fe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -260,8 +260,8 @@ impl CodegenBackend for GccCodegenBackend { .join(sess) } - fn target_features(&self, sess: &Session, allow_unstable: bool) -> Vec { - target_features(sess, allow_unstable, &self.target_info) + fn target_features_cfg(&self, sess: &Session, allow_unstable: bool) -> Vec { + target_features_cfg(sess, allow_unstable, &self.target_info) } } @@ -472,7 +472,8 @@ fn to_gcc_opt_level(optlevel: Option) -> OptimizationLevel { } } -pub fn target_features( +/// Returns the features that should be set in `cfg(target_feature)`. +fn target_features_cfg( sess: &Session, allow_unstable: bool, target_info: &LockedTargetInfo, @@ -481,9 +482,9 @@ pub fn target_features( sess.target .rust_target_features() .iter() - .filter(|(_, gate, _)| gate.is_supported()) + .filter(|(_, gate, _)| gate.in_cfg()) .filter_map(|&(feature, gate, _)| { - if sess.is_nightly_build() || allow_unstable || gate.is_stable() { + if sess.is_nightly_build() || allow_unstable || gate.requires_nightly().is_none() { Some(feature) } else { None