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.rs46
1 files changed, 29 insertions, 17 deletions
diff --git a/crates/hir-ty/src/target_feature.rs b/crates/hir-ty/src/target_feature.rs
index 2bd675ba12..0a8ed2cf0c 100644
--- a/crates/hir-ty/src/target_feature.rs
+++ b/crates/hir-ty/src/target_feature.rs
@@ -1,35 +1,31 @@
//! Stuff for handling `#[target_feature]` (needed for unsafe check).
-use std::borrow::Cow;
use std::sync::LazyLock;
-use hir_def::FunctionId;
-use hir_def::attrs::AttrFlags;
-use intern::Symbol;
+use hir_def::attr::Attrs;
+use hir_def::tt;
+use intern::{Symbol, sym};
use rustc_hash::{FxHashMap, FxHashSet};
-use crate::db::HirDatabase;
-
#[derive(Debug, Default, Clone)]
-pub struct TargetFeatures<'db> {
- pub(crate) enabled: Cow<'db, FxHashSet<Symbol>>,
+pub struct TargetFeatures {
+ pub(crate) enabled: FxHashSet<Symbol>,
}
-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);
+impl TargetFeatures {
+ pub fn from_attrs(attrs: &Attrs) -> Self {
+ let mut result = TargetFeatures::from_attrs_no_implications(attrs);
result.expand_implications();
result
}
fn expand_implications(&mut self) {
let all_implications = LazyLock::force(&TARGET_FEATURE_IMPLICATIONS);
- let enabled = self.enabled.to_mut();
- let mut queue = enabled.iter().cloned().collect::<Vec<_>>();
+ let mut queue = self.enabled.iter().cloned().collect::<Vec<_>>();
while let Some(feature) = queue.pop() {
if let Some(implications) = all_implications.get(&feature) {
for implication in implications {
- if enabled.insert(implication.clone()) {
+ if self.enabled.insert(implication.clone()) {
queue.push(implication.clone());
}
}
@@ -38,9 +34,25 @@ impl<'db> TargetFeatures<'db> {
}
/// Retrieves the target features from the attributes, and does not expand the target features implied by them.
- 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) }
+ 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 }
}
}