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();
+}
+        "#,
+        );
+    }
 }