Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/target_feature.rs')
| -rw-r--r-- | crates/hir-ty/src/target_feature.rs | 46 |
1 files changed, 17 insertions, 29 deletions
diff --git a/crates/hir-ty/src/target_feature.rs b/crates/hir-ty/src/target_feature.rs index 0a8ed2cf0c..2bd675ba12 100644 --- a/crates/hir-ty/src/target_feature.rs +++ b/crates/hir-ty/src/target_feature.rs @@ -1,31 +1,35 @@ //! Stuff for handling `#[target_feature]` (needed for unsafe check). +use std::borrow::Cow; use std::sync::LazyLock; -use hir_def::attr::Attrs; -use hir_def::tt; -use intern::{Symbol, sym}; +use hir_def::FunctionId; +use hir_def::attrs::AttrFlags; +use intern::Symbol; use rustc_hash::{FxHashMap, FxHashSet}; +use crate::db::HirDatabase; + #[derive(Debug, Default, Clone)] -pub struct TargetFeatures { - pub(crate) enabled: FxHashSet<Symbol>, +pub struct TargetFeatures<'db> { + pub(crate) enabled: Cow<'db, FxHashSet<Symbol>>, } -impl TargetFeatures { - pub fn from_attrs(attrs: &Attrs) -> Self { - let mut result = TargetFeatures::from_attrs_no_implications(attrs); +impl<'db> TargetFeatures<'db> { + pub fn from_fn(db: &'db dyn HirDatabase, owner: FunctionId) -> Self { + let mut result = TargetFeatures::from_fn_no_implications(db, owner); result.expand_implications(); result } fn expand_implications(&mut self) { let all_implications = LazyLock::force(&TARGET_FEATURE_IMPLICATIONS); - let mut queue = self.enabled.iter().cloned().collect::<Vec<_>>(); + let enabled = self.enabled.to_mut(); + let mut queue = enabled.iter().cloned().collect::<Vec<_>>(); while let Some(feature) = queue.pop() { if let Some(implications) = all_implications.get(&feature) { for implication in implications { - if self.enabled.insert(implication.clone()) { + if enabled.insert(implication.clone()) { queue.push(implication.clone()); } } @@ -34,25 +38,9 @@ impl TargetFeatures { } /// Retrieves the target features from the attributes, and does not expand the target features implied by them. - pub(crate) fn from_attrs_no_implications(attrs: &Attrs) -> Self { - let enabled = attrs - .by_key(sym::target_feature) - .tt_values() - .filter_map(|tt| match tt.token_trees().flat_tokens() { - [ - tt::TokenTree::Leaf(tt::Leaf::Ident(enable_ident)), - tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '=', .. })), - tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { - kind: tt::LitKind::Str, - symbol: features, - .. - })), - ] if enable_ident.sym == sym::enable => Some(features), - _ => None, - }) - .flat_map(|features| features.as_str().split(',').map(Symbol::intern)) - .collect(); - Self { enabled } + pub(crate) fn from_fn_no_implications(db: &'db dyn HirDatabase, owner: FunctionId) -> Self { + let enabled = AttrFlags::target_features(db, owner); + Self { enabled: Cow::Borrowed(enabled) } } } |