Support multiple `enable` in `#[target_feature]`
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs
index f4a1a31..1428529 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/attrs.rs
@@ -1051,17 +1051,25 @@ fn target_features(db: &dyn DefDatabase, owner: FunctionId) -> FxHashSet<Symbol>
collect_attrs::<Infallible>(db, owner.into(), |attr| {
if let Meta::TokenTree { path, tt } = attr
&& path.is1("target_feature")
- && let mut tt = TokenTreeChildren::new(&tt)
- && let Some(NodeOrToken::Token(enable_ident)) = tt.next()
- && enable_ident.text() == "enable"
- && let Some(NodeOrToken::Token(eq_token)) = tt.next()
- && eq_token.kind() == T![=]
- && let Some(NodeOrToken::Token(features)) = tt.next()
- && let Some(features) = ast::String::cast(features)
- && let Ok(features) = features.value()
- && tt.next().is_none()
{
- result.extend(features.split(',').map(Symbol::intern));
+ let mut tt = TokenTreeChildren::new(&tt);
+ while let Some(NodeOrToken::Token(enable_ident)) = tt.next()
+ && enable_ident.text() == "enable"
+ && let Some(NodeOrToken::Token(eq_token)) = tt.next()
+ && eq_token.kind() == T![=]
+ && let Some(NodeOrToken::Token(features)) = tt.next()
+ && let Some(features) = ast::String::cast(features)
+ && let Ok(features) = features.value()
+ {
+ result.extend(features.split(',').map(Symbol::intern));
+ if tt
+ .next()
+ .and_then(NodeOrToken::into_token)
+ .is_none_or(|it| it.kind() != T![,])
+ {
+ break;
+ }
+ }
}
ControlFlow::Continue(())
});
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
index df1cd76..59215f3 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
@@ -1094,4 +1094,19 @@ fn main() {
"#,
);
}
+
+ #[test]
+ fn multiple_target_feature_enable() {
+ check_diagnostics(
+ r#"
+#[target_feature(enable = "avx2,fma")]
+fn foo() {}
+
+#[target_feature(enable = "avx2", enable = "fma")]
+fn bar() {
+ foo();
+}
+ "#,
+ );
+ }
}