Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/attrs.rs')
-rw-r--r--crates/hir-def/src/attrs.rs23
1 files changed, 23 insertions, 0 deletions
diff --git a/crates/hir-def/src/attrs.rs b/crates/hir-def/src/attrs.rs
index 27f9763f08..d55509e2f0 100644
--- a/crates/hir-def/src/attrs.rs
+++ b/crates/hir-def/src/attrs.rs
@@ -380,6 +380,29 @@ pub fn parse_extra_crate_attrs(db: &dyn SourceDatabase, krate: Crate) -> Option<
Some(p.tree())
}
+/// Whether the crate root declares `#![no_std]`, looking through `cfg_attr` gating.
+#[salsa::tracked(returns(copy))]
+pub(crate) fn crate_supports_no_std(db: &dyn SourceDatabase, krate: Crate) -> bool {
+ fn contains_no_std(meta: ast::Meta) -> bool {
+ match meta {
+ ast::Meta::PathMeta(meta) => meta.path().is1("no_std"),
+ ast::Meta::CfgAttrMeta(meta) => meta.metas().any(contains_no_std),
+ ast::Meta::UnsafeMeta(meta) => meta.meta().is_some_and(contains_no_std),
+ ast::Meta::CfgMeta(_) | ast::Meta::KeyValueMeta(_) | ast::Meta::TokenTreeMeta(_) => {
+ false
+ }
+ }
+ }
+
+ let root_file = krate.root_file_id(db).parse(db).tree();
+ parse_extra_crate_attrs(db, krate)
+ .into_iter()
+ .flat_map(|extra| extra.attrs())
+ .chain(root_file.attrs())
+ .filter_map(|attr| attr.meta())
+ .any(contains_no_std)
+}
+
fn attrs_source(
db: &dyn SourceDatabase,
owner: AttrDefId,