Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_ssa/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ pub(crate) fn from_target_feature_attr(
feature: feature_str,
reason,
});
} else if let Some(nightly_feature) = stability.requires_nightly()
} else if let Some(nightly_feature) = stability.requires_nightly(false)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
} else if let Some(nightly_feature) = stability.requires_nightly(false)
} else if let Some(nightly_feature) = stability.requires_nightly(/* in_cfg */ false)

&& !rust_features.enabled(nightly_feature)
{
feature_err(
Expand Down Expand Up @@ -315,7 +315,7 @@ pub fn cfg_target_feature<'a, const N: usize>(
enabled: if enable { "enabled" } else { "disabled" },
reason,
});
} else if stability.requires_nightly().is_some() {
} else if stability.requires_nightly(true).is_some() {
Copy link
Copy Markdown
Member

@RalfJung RalfJung Apr 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
} else if stability.requires_nightly(true).is_some() {
} else if stability.requires_nightly(/* in_cfg */ false).is_some() {

This is where we emit warnings for unstable things in -Ctarget-feature. Yes it's pretty hacky to do that as a side-effect of constructing the cfg data... codegen backend initialization is a terrible spaghetti mess and someone decided this was the place to put that check. 🤷 (It's probably here to avoid emitting the warnings multiple times, or something like that.)

// An unstable feature. Warn about using it. It makes little sense
// to hard-error here since we just warn about fully unknown
// features above.
Expand Down Expand Up @@ -346,7 +346,7 @@ pub fn cfg_target_feature<'a, const N: usize>(
// "forbidden" features.
if allow_unstable
|| (gate.in_cfg()
&& (sess.is_nightly_build() || gate.requires_nightly().is_none()))
&& (sess.is_nightly_build() || gate.requires_nightly(true).is_none()))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
&& (sess.is_nightly_build() || gate.requires_nightly(true).is_none()))
&& (sess.is_nightly_build() || gate.requires_nightly(/* in_cfg */ true).is_none()))

{
Some(Symbol::intern(feature))
} else {
Expand Down
28 changes: 25 additions & 3 deletions compiler/rustc_target/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ pub enum Stability {
/// This target feature is stable, it can be used in `#[target_feature]` and
/// `#[cfg(target_feature)]`.
Stable,
/// This target feature is cfg-stable. It can be used for `#[cfg(target_feature)]` on stable,
/// but using it in `#[target_feature]` requires the given nightly feature.
CfgOnlyStable(
/// This must be a *language* feature, or else rustc will ICE when reporting a missing
/// feature gate!
Symbol,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CfgOnlyStable(feature_name) will look odd.

Maybe CfgStableToggleUnstable?

),
/// 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.
Unstable(
Expand All @@ -37,7 +44,10 @@ impl Stability {
/// (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::Stable | Stability::Unstable { .. })
matches!(
self,
Stability::Stable | Stability::CfgOnlyStable { .. } | Stability::Unstable { .. }
)
}

/// Returns the nightly feature that is required to toggle this target feature via
Expand All @@ -48,9 +58,19 @@ impl Stability {
/// Before calling this, ensure the feature is even permitted for this use:
/// - for `#[target_feature]`/`-Ctarget-feature`, check `toggle_allowed()`
/// - for `cfg(target_feature)`, check `in_cfg()`
pub fn requires_nightly(&self) -> Option<Symbol> {
///
/// The `is_cfg` parameter is used to determine whether it will be used in
/// `cfg(target_feature)` (true) or `#[target_feature]`/`-Ctarget-feature` (false)
pub fn requires_nightly(&self, is_cfg: bool) -> Option<Symbol> {
match *self {
Stability::Unstable(nightly_feature) => Some(nightly_feature),
Stability::CfgOnlyStable(nightly_feature) => {
if is_cfg {
None
} else {
Some(nightly_feature)
}
}
Stability::Stable { .. } => None,
Stability::Forbidden { .. } => panic!("forbidden features should not reach this far"),
}
Expand All @@ -61,7 +81,9 @@ impl Stability {
/// `requires_nightly`.)
pub fn toggle_allowed(&self) -> Result<(), &'static str> {
match self {
Stability::Unstable(_) | Stability::Stable { .. } => Ok(()),
Stability::Unstable(_) | Stability::CfgOnlyStable(_) | Stability::Stable { .. } => {
Ok(())
}
Stability::Forbidden { reason } => Err(reason),
}
}
Expand Down
Loading