diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs index 2f6eed82cb6..54e95cf7c3d 100644 --- a/crates/hir/src/attrs.rs +++ b/crates/hir/src/attrs.rs @@ -137,6 +137,7 @@ fn resolve_doc_path( AttrDefId::TraitId(it) => it.resolver(db.upcast()), AttrDefId::TypeAliasId(it) => it.resolver(db.upcast()), AttrDefId::ImplId(it) => it.resolver(db.upcast()), + AttrDefId::ExternBlockId(it) => it.resolver(db.upcast()), AttrDefId::GenericParamId(it) => match it { GenericParamId::TypeParamId(it) => it.parent, GenericParamId::LifetimeParamId(it) => it.parent, diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index fe8a8018dbe..3e04ea8da9a 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -114,11 +114,11 @@ pub use { type_ref::{Mutability, TypeRef}, visibility::Visibility, AdtId, - AssocContainerId, AssocItemId, AssocItemLoc, DefWithBodyId, ImplId, + ItemContainerId, ItemLoc, Lookup, ModuleDefId, @@ -1550,7 +1550,7 @@ impl Static { pub fn ty(self, db: &dyn HirDatabase) -> Type { let data = db.static_data(self.id); let resolver = self.id.resolver(db.upcast()); - let krate = self.id.lookup(db.upcast()).container.krate(); + let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate(); let ctx = hir_ty::TyLoweringContext::new(db, &resolver); let ty = ctx.lower_ty(&data.type_ref); Type::new_with_resolver_inner(db, krate, &resolver, ty) @@ -1820,8 +1820,8 @@ where AST: ItemTreeNode, { match id.lookup(db.upcast()).container { - AssocContainerId::TraitId(_) | AssocContainerId::ImplId(_) => Some(ctor(DEF::from(id))), - AssocContainerId::ModuleId(_) => None, + ItemContainerId::TraitId(_) | ItemContainerId::ImplId(_) => Some(ctor(DEF::from(id))), + ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => None, } } @@ -1847,9 +1847,11 @@ impl AssocItem { AssocItem::TypeAlias(it) => it.id.lookup(db.upcast()).container, }; match container { - AssocContainerId::TraitId(id) => AssocItemContainer::Trait(id.into()), - AssocContainerId::ImplId(id) => AssocItemContainer::Impl(id.into()), - AssocContainerId::ModuleId(_) => panic!("invalid AssocItem"), + ItemContainerId::TraitId(id) => AssocItemContainer::Trait(id.into()), + ItemContainerId::ImplId(id) => AssocItemContainer::Impl(id.into()), + ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => { + panic!("invalid AssocItem") + } } } diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index 711062c7132..36e46a103c1 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs @@ -362,6 +362,7 @@ impl AttrsWithOwner { RawAttrs::from_attrs_owner(db, src.with_value(&src.value[it.local_id])) } }, + AttrDefId::ExternBlockId(it) => attrs_from_item_tree(it.lookup(db).id, db), }; let attrs = raw_attrs.filter(db, def.krate(db)); @@ -443,6 +444,7 @@ impl AttrsWithOwner { .child_source(db) .map(|source| ast::AnyHasAttrs::new(source[id.local_id].clone())), }, + AttrDefId::ExternBlockId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new), }; AttrSourceMap::new(owner.as_ref().map(|node| node as &dyn HasAttrs)) diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs index f4d0c3af90b..ad1c1f2ce5d 100644 --- a/crates/hir_def/src/data.rs +++ b/crates/hir_def/src/data.rs @@ -13,8 +13,8 @@ use crate::{ item_tree::{self, AssocItem, FnFlags, ItemTreeId, ModItem, Param}, type_ref::{TraitRef, TypeBound, TypeRef}, visibility::RawVisibility, - AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId, - Intern, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc, + AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId, Intern, + ItemContainerId, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc, }; #[derive(Debug, Clone, PartialEq, Eq)] @@ -54,6 +54,10 @@ impl FunctionData { flags.bits |= FnFlags::IS_VARARGS; } + if matches!(loc.container, ItemContainerId::ExternBlockId(_)) { + flags.bits |= FnFlags::IS_IN_EXTERN_BLOCK; + } + Arc::new(FunctionData { name: func.name.clone(), params: enabled_params @@ -130,7 +134,7 @@ impl TypeAliasData { name: typ.name.clone(), type_ref: typ.type_ref.clone(), visibility: item_tree[typ.visibility].clone(), - is_extern: typ.is_extern, + is_extern: matches!(loc.container, ItemContainerId::ExternBlockId(_)), bounds: typ.bounds.to_vec(), }) } @@ -162,7 +166,7 @@ impl TraitData { let is_auto = tr_def.is_auto; let is_unsafe = tr_def.is_unsafe; let module_id = tr_loc.container; - let container = AssocContainerId::TraitId(tr); + let container = ItemContainerId::TraitId(tr); let visibility = item_tree[tr_def.visibility].clone(); let mut expander = Expander::new(db, tr_loc.id.file_id(), module_id); let skip_array_during_method_dispatch = item_tree @@ -231,7 +235,7 @@ impl ImplData { let self_ty = impl_def.self_ty.clone(); let is_negative = impl_def.is_negative; let module_id = impl_loc.container; - let container = AssocContainerId::ImplId(id); + let container = ItemContainerId::ImplId(id); let mut expander = Expander::new(db, impl_loc.id.file_id(), module_id); let items = collect_items( @@ -282,16 +286,16 @@ pub struct StaticData { impl StaticData { pub(crate) fn static_data_query(db: &dyn DefDatabase, konst: StaticId) -> Arc { - let node = konst.lookup(db); - let item_tree = node.id.item_tree(db); - let statik = &item_tree[node.id.value]; + let loc = konst.lookup(db); + let item_tree = loc.id.item_tree(db); + let statik = &item_tree[loc.id.value]; Arc::new(StaticData { name: statik.name.clone(), type_ref: statik.type_ref.clone(), visibility: item_tree[statik.visibility].clone(), mutable: statik.mutable, - is_extern: statik.is_extern, + is_extern: matches!(loc.container, ItemContainerId::ExternBlockId(_)), }) } } @@ -302,7 +306,7 @@ fn collect_items( expander: &mut Expander, assoc_items: impl Iterator, tree_id: item_tree::TreeId, - container: AssocContainerId, + container: ItemContainerId, limit: usize, ) -> Vec<(Name, AssocItemId)> { if limit == 0 { diff --git a/crates/hir_def/src/db.rs b/crates/hir_def/src/db.rs index c977971cd48..7946558311a 100644 --- a/crates/hir_def/src/db.rs +++ b/crates/hir_def/src/db.rs @@ -19,10 +19,10 @@ use crate::{ lang_item::{LangItemTarget, LangItems}, nameres::DefMap, visibility::{self, Visibility}, - AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, - FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalEnumVariantId, LocalFieldId, StaticId, - StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, - UnionLoc, VariantId, + AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, ExternBlockId, + ExternBlockLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalEnumVariantId, + LocalFieldId, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, + TypeAliasLoc, UnionId, UnionLoc, VariantId, }; #[salsa::query_group(InternDatabaseStorage)] @@ -46,6 +46,8 @@ pub trait InternDatabase: SourceDatabase { #[salsa::interned] fn intern_impl(&self, loc: ImplLoc) -> ImplId; #[salsa::interned] + fn intern_extern_block(&self, loc: ExternBlockLoc) -> ExternBlockId; + #[salsa::interned] fn intern_block(&self, loc: BlockLoc) -> BlockId; } diff --git a/crates/hir_def/src/import_map.rs b/crates/hir_def/src/import_map.rs index 404e3e15394..27a05b87c1d 100644 --- a/crates/hir_def/src/import_map.rs +++ b/crates/hir_def/src/import_map.rs @@ -468,7 +468,7 @@ mod tests { use base_db::{fixture::WithFixture, SourceDatabase, Upcast}; use expect_test::{expect, Expect}; - use crate::{test_db::TestDB, AssocContainerId, Lookup}; + use crate::{test_db::TestDB, ItemContainerId, Lookup}; use super::*; @@ -563,7 +563,7 @@ mod tests { }; match container { - AssocContainerId::TraitId(it) => Some(ItemInNs::Types(it.into())), + ItemContainerId::TraitId(it) => Some(ItemInNs::Types(it.into())), _ => None, } } diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index aab3f4b3c84..405cc2d00f8 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs @@ -660,8 +660,6 @@ pub struct Static { pub name: Name, pub visibility: RawVisibilityId, pub mutable: bool, - /// Whether the static is in an `extern` block. - pub is_extern: bool, pub type_ref: Interned, pub ast_id: FileAstId, } @@ -695,7 +693,6 @@ pub struct TypeAlias { pub bounds: Box<[Interned]>, pub generic_params: Interned, pub type_ref: Option>, - pub is_extern: bool, pub ast_id: FileAstId, } diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 32213aac390..e9af991785d 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs @@ -360,7 +360,6 @@ impl<'a> Ctx<'a> { generic_params, type_ref, ast_id, - is_extern: false, }; Some(id(self.data().type_aliases.alloc(res))) } @@ -371,7 +370,7 @@ impl<'a> Ctx<'a> { let visibility = self.lower_visibility(static_); let mutable = static_.mut_token().is_some(); let ast_id = self.source_ast_id_map.ast_id(static_); - let res = Static { name, visibility, mutable, type_ref, ast_id, is_extern: false }; + let res = Static { name, visibility, mutable, type_ref, ast_id }; Some(id(self.data().statics.alloc(res))) } @@ -525,27 +524,23 @@ impl<'a> Ctx<'a> { let children: Box<[_]> = block.extern_item_list().map_or(Box::new([]), |list| { list.extern_items() .filter_map(|item| { + // Note: All items in an `extern` block need to be lowered as if they're outside of one + // (in other words, the knowledge that they're in an extern block must not be used). + // This is because an extern block can contain macros whose ItemTree's top-level items + // should be considered to be in an extern block too. let attrs = RawAttrs::new(self.db, &item, &self.hygiene); let id: ModItem = match item { ast::ExternItem::Fn(ast) => { let func_id = self.lower_function(&ast)?; let func = &mut self.data().functions[func_id.index]; if is_intrinsic_fn_unsafe(&func.name) { + // FIXME: this breaks in macros func.flags.bits |= FnFlags::IS_UNSAFE; } - func.flags.bits |= FnFlags::IS_IN_EXTERN_BLOCK; func_id.into() } - ast::ExternItem::Static(ast) => { - let statik = self.lower_static(&ast)?; - self.data().statics[statik.index].is_extern = true; - statik.into() - } - ast::ExternItem::TypeAlias(ty) => { - let foreign_ty = self.lower_type_alias(&ty)?; - self.data().type_aliases[foreign_ty.index].is_extern = true; - foreign_ty.into() - } + ast::ExternItem::Static(ast) => self.lower_static(&ast)?.into(), + ast::ExternItem::TypeAlias(ty) => self.lower_type_alias(&ty)?.into(), ast::ExternItem::MacroCall(call) => { // FIXME: we need some way of tracking that the macro call is in an // extern block diff --git a/crates/hir_def/src/item_tree/pretty.rs b/crates/hir_def/src/item_tree/pretty.rs index 49dc1eef18b..4b462837436 100644 --- a/crates/hir_def/src/item_tree/pretty.rs +++ b/crates/hir_def/src/item_tree/pretty.rs @@ -328,8 +328,7 @@ impl<'a> Printer<'a> { wln!(self, " = _;"); } ModItem::Static(it) => { - let Static { name, visibility, mutable, is_extern, type_ref, ast_id: _ } = - &self.tree[it]; + let Static { name, visibility, mutable, type_ref, ast_id: _ } = &self.tree[it]; self.print_visibility(*visibility); w!(self, "static "); if *mutable { @@ -338,9 +337,6 @@ impl<'a> Printer<'a> { w!(self, "{}: ", name); self.print_type_ref(type_ref); w!(self, " = _;"); - if *is_extern { - w!(self, " // extern"); - } wln!(self); } ModItem::Trait(it) => { @@ -393,15 +389,8 @@ impl<'a> Printer<'a> { wln!(self, "}}"); } ModItem::TypeAlias(it) => { - let TypeAlias { - name, - visibility, - bounds, - type_ref, - is_extern, - generic_params, - ast_id: _, - } = &self.tree[it]; + let TypeAlias { name, visibility, bounds, type_ref, generic_params, ast_id: _ } = + &self.tree[it]; self.print_visibility(*visibility); w!(self, "type {}", name); self.print_generic_params(generic_params); @@ -415,9 +404,6 @@ impl<'a> Printer<'a> { } self.print_where_clause(generic_params); w!(self, ";"); - if *is_extern { - w!(self, " // extern"); - } wln!(self); } ModItem::Mod(it) => { diff --git a/crates/hir_def/src/item_tree/tests.rs b/crates/hir_def/src/item_tree/tests.rs index 7671ccefd17..1969913bf94 100644 --- a/crates/hir_def/src/item_tree/tests.rs +++ b/crates/hir_def/src/item_tree/tests.rs @@ -70,13 +70,13 @@ extern "C" { #[on_extern_block] // AttrId { is_doc_comment: false, ast_index: 0 } extern "C" { #[on_extern_type] // AttrId { is_doc_comment: false, ast_index: 0 } - pub(self) type ExType; // extern + pub(self) type ExType; #[on_extern_static] // AttrId { is_doc_comment: false, ast_index: 0 } - pub(self) static EX_STATIC: u8 = _; // extern + pub(self) static EX_STATIC: u8 = _; #[on_extern_fn] // AttrId { is_doc_comment: false, ast_index: 0 } - // flags = 0x60 + // flags = 0x20 pub(self) fn ex_fn() -> (); } "##]], diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index b68ede40039..c8e60032dfa 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs @@ -65,6 +65,7 @@ use hir_expand::{ hygiene::Hygiene, AstId, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, }; +use item_tree::ExternBlock; use la_arena::Idx; use nameres::DefMap; use path::ModPath; @@ -153,7 +154,7 @@ impl Hash for ItemLoc { #[derive(Debug)] pub struct AssocItemLoc { - pub container: AssocContainerId, + pub container: ItemContainerId, pub id: ItemTreeId, } @@ -244,7 +245,7 @@ impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct StaticId(salsa::InternId); -pub type StaticLoc = ItemLoc; +pub type StaticLoc = AssocItemLoc; impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -262,6 +263,11 @@ pub struct ImplId(salsa::InternId); type ImplLoc = ItemLoc; impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl); +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] +pub struct ExternBlockId(salsa::InternId); +type ExternBlockLoc = ItemLoc; +impl_intern!(ExternBlockId, ExternBlockLoc, intern_extern_block, lookup_intern_extern_block); + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] pub struct BlockId(salsa::InternId); #[derive(Debug, Hash, PartialEq, Eq, Clone)] @@ -295,12 +301,13 @@ pub struct ConstParamId { pub type LocalConstParamId = Idx; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum AssocContainerId { +pub enum ItemContainerId { + ExternBlockId(ExternBlockId), ModuleId(ModuleId), ImplId(ImplId), TraitId(TraitId), } -impl_from!(ModuleId for AssocContainerId); +impl_from!(ModuleId for ItemContainerId); /// A Data Type #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] @@ -427,6 +434,7 @@ pub enum AttrDefId { MacroDefId(MacroDefId), ImplId(ImplId), GenericParamId(GenericParamId), + ExternBlockId(ExternBlockId), } impl_from!( @@ -445,12 +453,13 @@ impl_from!( for AttrDefId ); -impl From for AttrDefId { - fn from(acid: AssocContainerId) -> Self { +impl From for AttrDefId { + fn from(acid: ItemContainerId) -> Self { match acid { - AssocContainerId::ModuleId(mid) => AttrDefId::ModuleId(mid), - AssocContainerId::ImplId(iid) => AttrDefId::ImplId(iid), - AssocContainerId::TraitId(tid) => AttrDefId::TraitId(tid), + ItemContainerId::ModuleId(mid) => AttrDefId::ModuleId(mid), + ItemContainerId::ImplId(iid) => AttrDefId::ImplId(iid), + ItemContainerId::TraitId(tid) => AttrDefId::TraitId(tid), + ItemContainerId::ExternBlockId(id) => AttrDefId::ExternBlockId(id), } } } @@ -505,12 +514,13 @@ pub trait HasModule { fn module(&self, db: &dyn db::DefDatabase) -> ModuleId; } -impl HasModule for AssocContainerId { +impl HasModule for ItemContainerId { fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { match *self { - AssocContainerId::ModuleId(it) => it, - AssocContainerId::ImplId(it) => it.lookup(db).container, - AssocContainerId::TraitId(it) => it.lookup(db).container, + ItemContainerId::ModuleId(it) => it, + ItemContainerId::ImplId(it) => it.lookup(db).container, + ItemContainerId::TraitId(it) => it.lookup(db).container, + ItemContainerId::ExternBlockId(it) => it.lookup(db).container, } } } @@ -587,12 +597,6 @@ impl HasModule for TraitId { } } -impl HasModule for StaticLoc { - fn module(&self, _db: &dyn db::DefDatabase) -> ModuleId { - self.container - } -} - impl ModuleDefId { /// Returns the module containing `self` (or `self`, if `self` is itself a module). /// @@ -604,7 +608,7 @@ impl ModuleDefId { ModuleDefId::AdtId(id) => id.module(db), ModuleDefId::EnumVariantId(id) => id.parent.lookup(db).container, ModuleDefId::ConstId(id) => id.lookup(db).container.module(db), - ModuleDefId::StaticId(id) => id.lookup(db).container, + ModuleDefId::StaticId(id) => id.lookup(db).module(db), ModuleDefId::TraitId(id) => id.lookup(db).container, ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db), ModuleDefId::BuiltinType(_) => return None, @@ -625,6 +629,7 @@ impl AttrDefId { AttrDefId::TraitId(it) => it.lookup(db).container.krate, AttrDefId::TypeAliasId(it) => it.lookup(db).module(db).krate, AttrDefId::ImplId(it) => it.lookup(db).container.krate, + AttrDefId::ExternBlockId(it) => it.lookup(db).container.krate, AttrDefId::GenericParamId(it) => { match it { GenericParamId::TypeParamId(it) => it.parent, diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index ad4a4aa752b..8c0ba3c0564 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs @@ -44,9 +44,9 @@ use crate::{ path::{ImportAlias, ModPath, PathKind}, per_ns::PerNs, visibility::{RawVisibility, Visibility}, - AdtId, AstId, AstIdWithPath, ConstLoc, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern, - LocalModuleId, ModuleDefId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, - UnresolvedMacro, + AdtId, AstId, AstIdWithPath, ConstLoc, EnumLoc, EnumVariantId, ExternBlockLoc, FunctionLoc, + ImplLoc, Intern, ItemContainerId, LocalModuleId, ModuleDefId, StaticLoc, StructLoc, TraitLoc, + TypeAliasLoc, UnionLoc, UnresolvedMacro, }; static GLOB_RECURSION_LIMIT: Limit = Limit::new(100); @@ -213,6 +213,7 @@ struct MacroDirective { module_id: LocalModuleId, depth: usize, kind: MacroDirectiveKind, + container: ItemContainerId, } #[derive(Clone, Debug, Eq, PartialEq)] @@ -306,7 +307,7 @@ impl DefCollector<'_> { item_tree: &item_tree, mod_dir: ModDir::root(), } - .collect(item_tree.top_level_items()); + .collect_in_top_module(item_tree.top_level_items()); } } @@ -327,7 +328,7 @@ impl DefCollector<'_> { item_tree: &item_tree, mod_dir: ModDir::root(), } - .collect(item_tree.top_level_items()); + .collect_in_top_module(item_tree.top_level_items()); } } @@ -433,7 +434,7 @@ impl DefCollector<'_> { item_tree: &item_tree, mod_dir, } - .collect(&[*mod_item]); + .collect(&[*mod_item], directive.container); true } else { false @@ -1053,7 +1054,12 @@ impl DefCollector<'_> { &mut |_err| (), ); if let Ok(Ok(call_id)) = call_id { - resolved.push((directive.module_id, call_id, directive.depth)); + resolved.push(( + directive.module_id, + call_id, + directive.depth, + directive.container, + )); res = ReachedFixedPoint::No; return false; } @@ -1073,7 +1079,12 @@ impl DefCollector<'_> { *derive_attr, ); - resolved.push((directive.module_id, call_id, directive.depth)); + resolved.push(( + directive.module_id, + call_id, + directive.depth, + directive.container, + )); res = ReachedFixedPoint::No; return false; } @@ -1096,7 +1107,7 @@ impl DefCollector<'_> { item_tree: &item_tree, mod_dir, } - .collect(&[*mod_item]); + .collect(&[*mod_item], directive.container); res = ReachedFixedPoint::No; false }; @@ -1144,6 +1155,7 @@ impl DefCollector<'_> { ast_id, derive_attr: attr.id, }, + container: directive.container, }); } } @@ -1199,7 +1211,12 @@ impl DefCollector<'_> { .scope .add_attr_macro_invoc(ast_id, call_id); - resolved.push((directive.module_id, call_id, directive.depth)); + resolved.push(( + directive.module_id, + call_id, + directive.depth, + directive.container, + )); res = ReachedFixedPoint::No; return false; } @@ -1213,8 +1230,8 @@ impl DefCollector<'_> { // Attribute resolution can add unresolved macro invocations, so concatenate the lists. self.unresolved_macros.extend(macros); - for (module_id, macro_call_id, depth) in resolved { - self.collect_macro_expansion(module_id, macro_call_id, depth); + for (module_id, macro_call_id, depth, container) in resolved { + self.collect_macro_expansion(module_id, macro_call_id, depth, container); } res @@ -1225,6 +1242,7 @@ impl DefCollector<'_> { module_id: LocalModuleId, macro_call_id: MacroCallId, depth: usize, + container: ItemContainerId, ) { if EXPANSION_DEPTH_LIMIT.check(depth).is_err() { cov_mark::hit!(macro_expansion_overflow); @@ -1276,7 +1294,7 @@ impl DefCollector<'_> { item_tree: &item_tree, mod_dir, } - .collect(item_tree.top_level_items()); + .collect(item_tree.top_level_items(), container); } fn finish(mut self) -> DefMap { @@ -1372,7 +1390,12 @@ struct ModCollector<'a, 'b> { } impl ModCollector<'_, '_> { - fn collect(&mut self, items: &[ModItem]) { + fn collect_in_top_module(&mut self, items: &[ModItem]) { + let module = self.def_collector.def_map.module_id(self.module_id); + self.collect(items, module.into()) + } + + fn collect(&mut self, items: &[ModItem], container: ItemContainerId) { struct DefData<'a> { id: ModuleDefId, name: &'a Name, @@ -1423,7 +1446,7 @@ impl ModCollector<'_, '_> { } } - if let Err(()) = self.resolve_attributes(&attrs, item) { + if let Err(()) = self.resolve_attributes(&attrs, item, container) { // Do not process the item. It has at least one non-builtin attribute, so the // fixed-point algorithm is required to resolve the rest of them. continue; @@ -1462,8 +1485,17 @@ impl ModCollector<'_, '_> { status: PartialResolvedImport::Unresolved, }) } - ModItem::ExternBlock(block) => self.collect(&self.item_tree[block].children), - ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac]), + ModItem::ExternBlock(block) => self.collect( + &self.item_tree[block].children, + ItemContainerId::ExternBlockId( + ExternBlockLoc { + container: module, + id: ItemTreeId::new(self.tree_id, block), + } + .intern(self.def_collector.db), + ), + ), + ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac], container), ModItem::MacroRules(id) => self.collect_macro_rules(id), ModItem::MacroDef(id) => self.collect_macro_def(id), ModItem::Impl(imp) => { @@ -1480,12 +1512,9 @@ impl ModCollector<'_, '_> { self.collect_proc_macro_def(&func.name, ast_id, &attrs); def = Some(DefData { - id: FunctionLoc { - container: module.into(), - id: ItemTreeId::new(self.tree_id, id), - } - .intern(self.def_collector.db) - .into(), + id: FunctionLoc { container, id: ItemTreeId::new(self.tree_id, id) } + .intern(self.def_collector.db) + .into(), name: &func.name, visibility: &self.item_tree[func.visibility], has_constructor: false, @@ -1529,11 +1558,8 @@ impl ModCollector<'_, '_> { } ModItem::Const(id) => { let it = &self.item_tree[id]; - let const_id = ConstLoc { - container: module.into(), - id: ItemTreeId::new(self.tree_id, id), - } - .intern(self.def_collector.db); + let const_id = ConstLoc { container, id: ItemTreeId::new(self.tree_id, id) } + .intern(self.def_collector.db); match &it.name { Some(name) => { @@ -1556,7 +1582,7 @@ impl ModCollector<'_, '_> { let it = &self.item_tree[id]; def = Some(DefData { - id: StaticLoc { container: module, id: ItemTreeId::new(self.tree_id, id) } + id: StaticLoc { container, id: ItemTreeId::new(self.tree_id, id) } .intern(self.def_collector.db) .into(), name: &it.name, @@ -1580,12 +1606,9 @@ impl ModCollector<'_, '_> { let it = &self.item_tree[id]; def = Some(DefData { - id: TypeAliasLoc { - container: module.into(), - id: ItemTreeId::new(self.tree_id, id), - } - .intern(self.def_collector.db) - .into(), + id: TypeAliasLoc { container, id: ItemTreeId::new(self.tree_id, id) } + .intern(self.def_collector.db) + .into(), name: &it.name, visibility: &self.item_tree[it.visibility], has_constructor: false, @@ -1633,7 +1656,7 @@ impl ModCollector<'_, '_> { item_tree: self.item_tree, mod_dir, } - .collect(&*items); + .collect_in_top_module(&*items); if is_macro_use { self.import_all_legacy_macros(module_id); } @@ -1666,7 +1689,7 @@ impl ModCollector<'_, '_> { item_tree: &item_tree, mod_dir, } - .collect(item_tree.top_level_items()); + .collect_in_top_module(item_tree.top_level_items()); let is_macro_use = is_macro_use || item_tree .top_level_attrs(db, self.def_collector.def_map.krate) @@ -1734,7 +1757,12 @@ impl ModCollector<'_, '_> { /// /// If `ignore_up_to` is `Some`, attributes preceding and including that attribute will be /// assumed to be resolved already. - fn resolve_attributes(&mut self, attrs: &Attrs, mod_item: ModItem) -> Result<(), ()> { + fn resolve_attributes( + &mut self, + attrs: &Attrs, + mod_item: ModItem, + container: ItemContainerId, + ) -> Result<(), ()> { let mut ignore_up_to = self.def_collector.skip_attrs.get(&InFile::new(self.file_id(), mod_item)).copied(); let iter = attrs @@ -1777,6 +1805,7 @@ impl ModCollector<'_, '_> { mod_item, tree: self.tree_id, }, + container, }); return Err(()); @@ -1951,7 +1980,7 @@ impl ModCollector<'_, '_> { ); } - fn collect_macro_call(&mut self, mac: &MacroCall) { + fn collect_macro_call(&mut self, mac: &MacroCall, container: ItemContainerId) { let ast_id = AstIdWithPath::new(self.file_id(), mac.ast_id, ModPath::clone(&mac.path)); // Case 1: try to resolve in legacy scope and expand macro_rules @@ -1981,6 +2010,7 @@ impl ModCollector<'_, '_> { self.module_id, macro_call_id, self.macro_depth + 1, + container, ); if let Some(err) = error { @@ -2011,6 +2041,7 @@ impl ModCollector<'_, '_> { module_id: self.module_id, depth: self.macro_depth + 1, kind: MacroDirectiveKind::FnLike { ast_id, expand_to: mac.expand_to }, + container, }); } diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs index 0cf28acf7ff..8b2eea9d586 100644 --- a/crates/hir_def/src/resolver.rs +++ b/crates/hir_def/src/resolver.rs @@ -22,8 +22,8 @@ use crate::{ path::{ModPath, PathKind}, per_ns::PerNs, visibility::{RawVisibility, Visibility}, - AdtId, AssocContainerId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, EnumId, - EnumVariantId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, LifetimeParamId, + AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, + FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, VariantId, }; @@ -802,6 +802,13 @@ impl HasResolver for ImplId { } } +impl HasResolver for ExternBlockId { + fn resolver(self, db: &dyn DefDatabase) -> Resolver { + // Same as parent's + self.lookup(db).container.resolver(db) + } +} + impl HasResolver for DefWithBodyId { fn resolver(self, db: &dyn DefDatabase) -> Resolver { match self { @@ -812,12 +819,13 @@ impl HasResolver for DefWithBodyId { } } -impl HasResolver for AssocContainerId { +impl HasResolver for ItemContainerId { fn resolver(self, db: &dyn DefDatabase) -> Resolver { match self { - AssocContainerId::ModuleId(it) => it.resolver(db), - AssocContainerId::TraitId(it) => it.resolver(db), - AssocContainerId::ImplId(it) => it.resolver(db), + ItemContainerId::ModuleId(it) => it.resolver(db), + ItemContainerId::TraitId(it) => it.resolver(db), + ItemContainerId::ImplId(it) => it.resolver(db), + ItemContainerId::ExternBlockId(it) => it.resolver(db), } } } diff --git a/crates/hir_ty/src/chalk_db.rs b/crates/hir_ty/src/chalk_db.rs index f58339286f4..dc5dcd163c3 100644 --- a/crates/hir_ty/src/chalk_db.rs +++ b/crates/hir_ty/src/chalk_db.rs @@ -11,7 +11,7 @@ use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; use base_db::CrateId; use hir_def::{ lang_item::{lang_attr, LangItemTarget}, - AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, ModuleId, TypeAliasId, + AssocItemId, GenericDefId, HasModule, ItemContainerId, Lookup, ModuleId, TypeAliasId, }; use hir_expand::name::name; @@ -396,7 +396,7 @@ pub(crate) fn associated_ty_data_query( debug!("associated_ty_data {:?}", id); let type_alias: TypeAliasId = from_assoc_type_id(id); let trait_ = match type_alias.lookup(db.upcast()).container { - AssocContainerId::TraitId(t) => t, + ItemContainerId::TraitId(t) => t, _ => panic!("associated type not in trait"), }; @@ -634,7 +634,7 @@ fn type_alias_associated_ty_value( ) -> Arc { let type_alias_data = db.type_alias_data(type_alias); let impl_id = match type_alias.lookup(db.upcast()).container { - AssocContainerId::ImplId(it) => it, + ItemContainerId::ImplId(it) => it, _ => panic!("assoc ty value should be in impl"), }; diff --git a/crates/hir_ty/src/chalk_ext.rs b/crates/hir_ty/src/chalk_ext.rs index 36c56820eb6..653c4d5ec84 100644 --- a/crates/hir_ty/src/chalk_ext.rs +++ b/crates/hir_ty/src/chalk_ext.rs @@ -4,7 +4,7 @@ use chalk_ir::{FloatTy, IntTy, Mutability, Scalar, UintTy}; use hir_def::{ builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType, BuiltinUint}, type_ref::Rawness, - AssocContainerId, FunctionId, GenericDefId, HasModule, Lookup, TraitId, + FunctionId, GenericDefId, HasModule, ItemContainerId, Lookup, TraitId, }; use crate::{ @@ -268,7 +268,7 @@ impl TyExt for Ty { match self.kind(&Interner) { TyKind::AssociatedType(id, ..) => { match from_assoc_type_id(*id).lookup(db.upcast()).container { - AssocContainerId::TraitId(trait_id) => Some(trait_id), + ItemContainerId::TraitId(trait_id) => Some(trait_id), _ => None, } } @@ -277,7 +277,7 @@ impl TyExt for Ty { .lookup(db.upcast()) .container { - AssocContainerId::TraitId(trait_id) => Some(trait_id), + ItemContainerId::TraitId(trait_id) => Some(trait_id), _ => None, } } @@ -331,7 +331,7 @@ impl ProjectionTyExt for ProjectionTy { fn trait_(&self, db: &dyn HirDatabase) -> TraitId { match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container { - AssocContainerId::TraitId(it) => it, + ItemContainerId::TraitId(it) => it, _ => panic!("projection ty without parent trait"), } } diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs index 6a3588dc741..a1e7198bc2c 100644 --- a/crates/hir_ty/src/diagnostics/decl_check.rs +++ b/crates/hir_ty/src/diagnostics/decl_check.rs @@ -178,6 +178,7 @@ impl<'a> DeclValidator<'a> { AttrDefId::ConstId(cid) => Some(cid.lookup(self.db.upcast()).container.into()), AttrDefId::TraitId(tid) => Some(tid.lookup(self.db.upcast()).container.into()), AttrDefId::ImplId(iid) => Some(iid.lookup(self.db.upcast()).container.into()), + AttrDefId::ExternBlockId(id) => Some(id.lookup(self.db.upcast()).container.into()), // These warnings should not explore macro definitions at all AttrDefId::MacroDefId(_) => None, // Will never occur under an enum/struct/union/type alias diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index e2b4e925752..307323690a5 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs @@ -16,7 +16,7 @@ use hir_def::{ path::{Path, PathKind}, type_ref::{TraitBoundModifier, TypeBound, TypeRef}, visibility::Visibility, - AssocContainerId, HasModule, Lookup, ModuleId, TraitId, + HasModule, ItemContainerId, Lookup, ModuleId, TraitId, }; use hir_expand::{hygiene::Hygiene, name::Name}; use itertools::Itertools; @@ -576,7 +576,7 @@ impl HirDisplay for Ty { TyKind::AssociatedType(assoc_type_id, parameters) => { let type_alias = from_assoc_type_id(*assoc_type_id); let trait_ = match type_alias.lookup(f.db.upcast()).container { - AssocContainerId::TraitId(it) => it, + ItemContainerId::TraitId(it) => it, _ => panic!("not an associated type"), }; let trait_ = f.db.trait_data(trait_); diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index d07a9395839..56e554736e2 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs @@ -521,7 +521,7 @@ impl<'a> InferenceContext<'a> { match assoc_ty { Some(res_assoc_ty) => { let trait_ = match res_assoc_ty.lookup(self.db.upcast()).container { - hir_def::AssocContainerId::TraitId(trait_) => trait_, + hir_def::ItemContainerId::TraitId(trait_) => trait_, _ => panic!("resolve_associated_type called with non-associated type"), }; let ty = self.table.new_type_var(); diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 5fb227c0e49..90c68c9d3f7 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs @@ -14,7 +14,7 @@ use hir_def::{ }, path::{GenericArg, GenericArgs}, resolver::resolver_for_expr, - AssocContainerId, FieldId, FunctionId, Lookup, + FieldId, FunctionId, ItemContainerId, Lookup, }; use hir_expand::name::{name, Name}; use stdx::always; @@ -1167,8 +1167,7 @@ impl<'a> InferenceContext<'a> { // add obligation for trait implementation, if this is a trait method match def { CallableDefId::FunctionId(f) => { - if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container - { + if let ItemContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container { // construct a TraitRef let substs = crate::subst_prefix( &*parameters, diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs index 056cdb5d5ba..a84501fa54d 100644 --- a/crates/hir_ty/src/infer/path.rs +++ b/crates/hir_ty/src/infer/path.rs @@ -6,7 +6,7 @@ use chalk_ir::cast::Cast; use hir_def::{ path::{Path, PathSegment}, resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs}, - AdtId, AssocContainerId, AssocItemId, EnumVariantId, Lookup, + AdtId, AssocItemId, EnumVariantId, ItemContainerId, Lookup, }; use hir_expand::name::Name; @@ -241,7 +241,7 @@ impl<'a> InferenceContext<'a> { AssocItemId::TypeAliasId(_) => unreachable!(), }; let substs = match container { - AssocContainerId::ImplId(impl_id) => { + ItemContainerId::ImplId(impl_id) => { let impl_substs = TyBuilder::subst_for_def(self.db, impl_id) .fill(iter::repeat_with(|| self.table.new_type_var())) .build(); @@ -250,7 +250,7 @@ impl<'a> InferenceContext<'a> { self.unify(&impl_self_ty, &ty); Some(impl_substs) } - AssocContainerId::TraitId(trait_) => { + ItemContainerId::TraitId(trait_) => { // we're picking this method let trait_ref = TyBuilder::trait_ref(self.db, trait_) .push(ty.clone()) @@ -259,7 +259,7 @@ impl<'a> InferenceContext<'a> { self.push_obligation(trait_ref.clone().cast(&Interner)); Some(trait_ref.substitution) } - AssocContainerId::ModuleId(_) => None, + ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => None, }; self.write_assoc_resolution(id, item); diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index af1d5fdb6a7..99267e085fa 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs @@ -19,8 +19,8 @@ use hir_def::{ path::{GenericArg, Path, PathSegment, PathSegments}, resolver::{HasResolver, Resolver, TypeNs}, type_ref::{TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef}, - AdtId, AssocContainerId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, - GenericDefId, HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId, + AdtId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId, + HasModule, ImplId, ItemContainerId, LocalFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId, VariantId, }; use hir_expand::{name::Name, ExpandResult}; @@ -1125,7 +1125,7 @@ pub(crate) fn trait_environment_query( } } - let container: Option = match def { + let container: Option = match def { // FIXME: is there a function for this? GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container), GenericDefId::AdtId(_) => None, @@ -1135,7 +1135,7 @@ pub(crate) fn trait_environment_query( GenericDefId::EnumVariantId(_) => None, GenericDefId::ConstId(c) => Some(c.lookup(db.upcast()).container), }; - if let Some(AssocContainerId::TraitId(trait_id)) = container { + if let Some(ItemContainerId::TraitId(trait_id)) = container { // add `Self: Trait` to the environment in trait // function default implementations (and speculative code // inside consts or type aliases) diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index 8e19928746c..6b3f48b1945 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs @@ -8,8 +8,8 @@ use arrayvec::ArrayVec; use base_db::{CrateId, Edition}; use chalk_ir::{cast::Cast, Mutability, UniverseIndex}; use hir_def::{ - lang_item::LangItemTarget, nameres::DefMap, AssocContainerId, AssocItemId, BlockId, FunctionId, - GenericDefId, HasModule, ImplId, Lookup, ModuleId, TraitId, + lang_item::LangItemTarget, nameres::DefMap, AssocItemId, BlockId, FunctionId, GenericDefId, + HasModule, ImplId, ItemContainerId, Lookup, ModuleId, TraitId, }; use hir_expand::name::Name; use rustc_hash::{FxHashMap, FxHashSet}; @@ -979,18 +979,19 @@ fn transform_receiver_ty( self_ty: &Canonical, ) -> Option { let substs = match function_id.lookup(db.upcast()).container { - AssocContainerId::TraitId(_) => TyBuilder::subst_for_def(db, function_id) + ItemContainerId::TraitId(_) => TyBuilder::subst_for_def(db, function_id) .push(self_ty.value.clone()) .fill_with_unknown() .build(), - AssocContainerId::ImplId(impl_id) => { + ItemContainerId::ImplId(impl_id) => { let impl_substs = inherent_impl_substs(db, env, impl_id, self_ty)?; TyBuilder::subst_for_def(db, function_id) .use_parent_substs(&impl_substs) .fill_with_unknown() .build() } - AssocContainerId::ModuleId(_) => unreachable!(), + // No receiver + ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => unreachable!(), }; let sig = db.callable_item_signature(function_id.into()); Some(sig.map(|s| s.params()[0].clone()).substitute(&Interner, &substs)) diff --git a/crates/hir_ty/src/tls.rs b/crates/hir_ty/src/tls.rs index 6a662dcf7bd..18a07f2c640 100644 --- a/crates/hir_ty/src/tls.rs +++ b/crates/hir_ty/src/tls.rs @@ -7,7 +7,7 @@ use crate::{ chalk_db, db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, mapping::from_chalk, CallableDefId, Interner, }; -use hir_def::{AdtId, AssocContainerId, Lookup, TypeAliasId}; +use hir_def::{AdtId, ItemContainerId, Lookup, TypeAliasId}; pub(crate) use unsafe_tls::{set_current_program, with_current_program}; @@ -45,7 +45,7 @@ impl DebugContext<'_> { let type_alias: TypeAliasId = from_assoc_type_id(id); let type_alias_data = self.0.type_alias_data(type_alias); let trait_ = match type_alias.lookup(self.0.upcast()).container { - AssocContainerId::TraitId(t) => t, + ItemContainerId::TraitId(t) => t, _ => panic!("associated type not in trait"), }; let trait_data = self.0.trait_data(trait_); @@ -60,7 +60,7 @@ impl DebugContext<'_> { let type_alias = from_assoc_type_id(projection_ty.associated_ty_id); let type_alias_data = self.0.type_alias_data(type_alias); let trait_ = match type_alias.lookup(self.0.upcast()).container { - AssocContainerId::TraitId(t) => t, + ItemContainerId::TraitId(t) => t, _ => panic!("associated type not in trait"), }; let trait_data = self.0.trait_data(trait_); diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs index 0037849d1ca..a0837377c6e 100644 --- a/crates/hir_ty/src/utils.rs +++ b/crates/hir_ty/src/utils.rs @@ -14,7 +14,7 @@ use hir_def::{ path::Path, resolver::{HasResolver, TypeNs}, type_ref::{TraitBoundModifier, TypeRef}, - AssocContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, TypeParamId, + GenericDefId, ItemContainerId, Lookup, TraitId, TypeAliasId, TypeParamId, }; use hir_expand::name::{name, Name}; use rustc_hash::FxHashSet; @@ -296,8 +296,8 @@ fn parent_generic_def(db: &dyn DefDatabase, def: GenericDefId) -> Option Some(it.into()), - AssocContainerId::TraitId(it) => Some(it.into()), - AssocContainerId::ModuleId(_) => None, + ItemContainerId::ImplId(it) => Some(it.into()), + ItemContainerId::TraitId(it) => Some(it.into()), + ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => None, } } diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index e8c6ec3e0ee..62f4a819107 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -36,8 +36,8 @@ use either::Either; use fst::{self, Streamer}; use hir::{ db::{DefDatabase, HirDatabase}, - AdtId, AssocContainerId, AssocItemId, AssocItemLoc, DefHasSource, DefWithBodyId, HasSource, - HirFileId, ImplId, InFile, ItemLoc, ItemTreeNode, Lookup, MacroDef, Module, ModuleDefId, + AdtId, AssocItemId, AssocItemLoc, DefHasSource, DefWithBodyId, HasSource, HirFileId, ImplId, + InFile, ItemContainerId, ItemLoc, ItemTreeNode, Lookup, MacroDef, Module, ModuleDefId, ModuleId, Semantics, TraitId, }; use rayon::prelude::*; @@ -508,7 +508,7 @@ impl<'a> SymbolCollector<'a> { self.collect_from_body(id); } ModuleDefId::StaticId(id) => { - self.push_decl(id, FileSymbolKind::Static); + self.push_decl_assoc(id, FileSymbolKind::Static); self.collect_from_body(id); } ModuleDefId::TraitId(id) => { @@ -610,17 +610,17 @@ impl<'a> SymbolCollector<'a> { T: ItemTreeNode, ::Source: HasName, { - fn container_name(db: &dyn HirDatabase, container: AssocContainerId) -> Option { + fn container_name(db: &dyn HirDatabase, container: ItemContainerId) -> Option { match container { - AssocContainerId::ModuleId(module_id) => { + ItemContainerId::ModuleId(module_id) => { let module = Module::from(module_id); module.name(db).and_then(|name| name.as_text()) } - AssocContainerId::TraitId(trait_id) => { + ItemContainerId::TraitId(trait_id) => { let trait_data = db.trait_data(trait_id); trait_data.name.as_text() } - AssocContainerId::ImplId(_) => None, + ItemContainerId::ImplId(_) | ItemContainerId::ExternBlockId(_) => None, } } diff --git a/crates/ide_diagnostics/src/handlers/incorrect_case.rs b/crates/ide_diagnostics/src/handlers/incorrect_case.rs index 6990b19cf3a..3206a63a902 100644 --- a/crates/ide_diagnostics/src/handlers/incorrect_case.rs +++ b/crates/ide_diagnostics/src/handlers/incorrect_case.rs @@ -397,6 +397,24 @@ extern { ); } + #[test] + fn ignores_extern_items_from_macro() { + check_diagnostics( + r#" +macro_rules! m { + () => { + fn NonSnakeCaseName(SOME_VAR: u8) -> u8; + pub static SomeStatic: u8 = 10; + } +} + +extern { + m!(); +} + "#, + ); + } + #[test] fn bug_traits_arent_checked() { // FIXME: Traits and functions in traits aren't currently checked by