diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index e34661d5fc6..f73a286e6af 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -50,6 +50,8 @@ macro_rules! declare_features { }),+ ]; + const NUM_FEATURES: usize = UNSTABLE_FEATURES.len(); + /// A set of features to be used by later passes. #[derive(Clone, Default, Debug)] pub struct Features { @@ -82,8 +84,14 @@ macro_rules! declare_features { self.declared_features.insert(symbol); } - pub fn walk_feature_fields(&self, mut f: impl FnMut(&str, bool)) { - $(f(stringify!($feature), self.$feature);)+ + /// This is intended for hashing the set of active features. + /// + /// The expectation is that this produces much smaller code than other alternatives. + /// + /// Note that the total feature count is pretty small, so this is not a huge array. + #[inline] + pub fn all_features(&self) -> [u8; NUM_FEATURES] { + [$(self.$feature as u8),+] } /// Is the given feature explicitly declared, i.e. named in a diff --git a/compiler/rustc_query_system/src/ich/impls_syntax.rs b/compiler/rustc_query_system/src/ich/impls_syntax.rs index 81a7eb604f5..f2387017c82 100644 --- a/compiler/rustc_query_system/src/ich/impls_syntax.rs +++ b/compiler/rustc_query_system/src/ich/impls_syntax.rs @@ -117,9 +117,9 @@ impl<'tcx> HashStable> for rustc_feature::Features { self.declared_lang_features.hash_stable(hcx, hasher); self.declared_lib_features.hash_stable(hcx, hasher); - self.walk_feature_fields(|feature_name, value| { - feature_name.hash_stable(hcx, hasher); - value.hash_stable(hcx, hasher); - }); + self.all_features()[..].hash_stable(hcx, hasher); + for feature in rustc_feature::UNSTABLE_FEATURES.iter() { + feature.feature.name.hash_stable(hcx, hasher); + } } }