Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/lang_item.rs')
| -rw-r--r-- | crates/hir-def/src/lang_item.rs | 55 |
1 files changed, 44 insertions, 11 deletions
diff --git a/crates/hir-def/src/lang_item.rs b/crates/hir-def/src/lang_item.rs index 66e0d2cc34..60c8baf424 100644 --- a/crates/hir-def/src/lang_item.rs +++ b/crates/hir-def/src/lang_item.rs @@ -125,12 +125,8 @@ impl LangItems { } ModuleDefId::AdtId(AdtId::EnumId(e)) => { lang_items.collect_lang_item(db, e, LangItemTarget::EnumId); - db.enum_data(e).variants.iter().for_each(|(local_id, _)| { - lang_items.collect_lang_item( - db, - EnumVariantId { parent: e, local_id }, - LangItemTarget::EnumVariant, - ); + crate_def_map.enum_definitions[&e].iter().for_each(|&id| { + lang_items.collect_lang_item(db, id, LangItemTarget::EnumVariant); }); } ModuleDefId::AdtId(AdtId::StructId(s)) => { @@ -188,15 +184,51 @@ impl LangItems { T: Into<AttrDefId> + Copy, { let _p = profile::span("collect_lang_item"); - if let Some(lang_item) = db.lang_attr(item.into()) { + if let Some(lang_item) = lang_attr(db, item.into()) { self.items.entry(lang_item).or_insert_with(|| constructor(item)); } } } -pub(crate) fn lang_attr_query(db: &dyn DefDatabase, item: AttrDefId) -> Option<LangItem> { +pub(crate) fn lang_attr(db: &dyn DefDatabase, item: AttrDefId) -> Option<LangItem> { let attrs = db.attrs(item); - attrs.by_key("lang").string_value().and_then(|it| LangItem::from_str(&it)) + attrs.by_key("lang").string_value().and_then(|it| LangItem::from_str(it)) +} + +pub(crate) fn notable_traits_in_deps( + db: &dyn DefDatabase, + krate: CrateId, +) -> Arc<[Arc<[TraitId]>]> { + let _p = profile::span("notable_traits_in_deps").detail(|| format!("{krate:?}")); + let crate_graph = db.crate_graph(); + + Arc::from_iter( + crate_graph.transitive_deps(krate).filter_map(|krate| db.crate_notable_traits(krate)), + ) +} + +pub(crate) fn crate_notable_traits(db: &dyn DefDatabase, krate: CrateId) -> Option<Arc<[TraitId]>> { + let _p = profile::span("crate_notable_traits").detail(|| format!("{krate:?}")); + + let mut traits = Vec::new(); + + let crate_def_map = db.crate_def_map(krate); + + for (_, module_data) in crate_def_map.modules() { + for def in module_data.scope.declarations() { + if let ModuleDefId::TraitId(trait_) = def { + if db.attrs(trait_.into()).has_doc_notable_trait() { + traits.push(trait_); + } + } + } + } + + if traits.is_empty() { + None + } else { + Some(traits.into_iter().collect()) + } } pub enum GenericRequirement { @@ -228,6 +260,7 @@ macro_rules! language_item_table { } /// Opposite of [`LangItem::name`] + #[allow(clippy::should_implement_trait)] pub fn from_str(name: &str) -> Option<Self> { match name { $( stringify!($name) => Some(LangItem::$variant), )* @@ -334,8 +367,8 @@ language_item_table! { FnOnceOutput, sym::fn_once_output, fn_once_output, Target::AssocTy, GenericRequirement::None; Future, sym::future_trait, future_trait, Target::Trait, GenericRequirement::Exact(0); - GeneratorState, sym::generator_state, gen_state, Target::Enum, GenericRequirement::None; - Generator, sym::generator, gen_trait, Target::Trait, GenericRequirement::Minimum(1); + CoroutineState, sym::coroutine_state, coroutine_state, Target::Enum, GenericRequirement::None; + Coroutine, sym::coroutine, coroutine_trait, Target::Trait, GenericRequirement::Minimum(1); Unpin, sym::unpin, unpin_trait, Target::Trait, GenericRequirement::None; Pin, sym::pin, pin_type, Target::Struct, GenericRequirement::None; |