target_features: explain what exacty 'implied' means here

This commit is contained in:
Ralf Jung 2024-11-10 22:51:38 +01:00
parent f5b62577f7
commit 2c7f3badcf
2 changed files with 16 additions and 3 deletions

View File

@ -344,15 +344,23 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
})
{
if enabled {
// Also add all transitively implied features.
features.extend(sess.target.implied_target_features(std::iter::once(feature)));
} else {
// Remove transitively reverse-implied features.
// We don't care about the order in `features` since the only thing we use it for is the
// `features.contains` below.
#[allow(rustc::potential_query_instability)]
features.retain(|f| {
// Keep a feature if it does not imply `feature`. Or, equivalently,
// remove the reverse-dependencies of `feature`.
!sess.target.implied_target_features(std::iter::once(*f)).contains(&feature)
if sess.target.implied_target_features(std::iter::once(*f)).contains(&feature) {
// If `f` if implies `feature`, then `!feature` implies `!f`, so we have to
// remove `f`. (This is the standard logical contraposition principle.)
false
} else {
// We can keep `f`.
true
}
});
}
}

View File

@ -92,6 +92,11 @@ pub fn is_supported(self) -> bool {
//
// Stabilizing a target feature requires t-lang approval.
// If feature A "implies" feature B, then:
// - when A gets enabled (via `-Ctarget-feature` or `#[target_feature]`), we also enable B
// - when B gets disabled (via `-Ctarget-feature`), we also disable A
//
// Both of these are also applied transitively.
type ImpliedFeatures = &'static [&'static str];
const ARM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[