Unnamed repository; edit this file 'description' to name the repository.
Merge #10960
10960: fix: fix handling of macros in `extern` blocks r=jonas-schievink a=jonas-schievink - Removes knowledge of what's in an extern block from `ItemTree`. - Treats extern blocks as `AssocContainerId` and renames the latter to `ItemContainerId`. - Threads the container through name resolution (which is a bit messy). - Considers statics to be associated items, since they can be in an extern block. (it might be better to further distinguish potentially-associated-items from potentially-in-an-extern-block-items, but currently I don't expect much of a benefit) - Adds a test for the incorrect-case diagnostic demonstrating the impact of this change. Fixes https://github.com/rust-analyzer/rust-analyzer/issues/8913 bors r+ Co-authored-by: Jonas Schievink <[email protected]>
bors[bot] 2021-12-07
parent b7afb6f · parent b365b61 · commit 755b668
-rw-r--r--crates/hir/src/attrs.rs1
-rw-r--r--crates/hir/src/lib.rs16
-rw-r--r--crates/hir_def/src/attr.rs2
-rw-r--r--crates/hir_def/src/data.rs24
-rw-r--r--crates/hir_def/src/db.rs10
-rw-r--r--crates/hir_def/src/import_map.rs4
-rw-r--r--crates/hir_def/src/item_tree.rs3
-rw-r--r--crates/hir_def/src/item_tree/lower.rs21
-rw-r--r--crates/hir_def/src/item_tree/pretty.rs20
-rw-r--r--crates/hir_def/src/item_tree/tests.rs6
-rw-r--r--crates/hir_def/src/lib.rs45
-rw-r--r--crates/hir_def/src/nameres/collector.rs109
-rw-r--r--crates/hir_def/src/resolver.rs20
-rw-r--r--crates/hir_ty/src/chalk_db.rs6
-rw-r--r--crates/hir_ty/src/chalk_ext.rs8
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check.rs1
-rw-r--r--crates/hir_ty/src/display.rs4
-rw-r--r--crates/hir_ty/src/infer.rs2
-rw-r--r--crates/hir_ty/src/infer/expr.rs5
-rw-r--r--crates/hir_ty/src/infer/path.rs8
-rw-r--r--crates/hir_ty/src/lower.rs8
-rw-r--r--crates/hir_ty/src/method_resolution.rs11
-rw-r--r--crates/hir_ty/src/tls.rs6
-rw-r--r--crates/hir_ty/src/utils.rs8
-rw-r--r--crates/ide_db/src/symbol_index.rs14
-rw-r--r--crates/ide_diagnostics/src/handlers/incorrect_case.rs18
26 files changed, 216 insertions, 164 deletions
diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs
index 2f6eed82cb..54e95cf7c3 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 fe8a8018db..3e04ea8da9 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 711062c713..36e46a103c 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 f4d0c3af90..ad1c1f2ce5 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<StaticData> {
- 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<Item = AssocItem>,
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 c977971cd4..7946558311 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 404e3e1539..27a05b87c1 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 aab3f4b3c8..405cc2d00f 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<TypeRef>,
pub ast_id: FileAstId<ast::Static>,
}
@@ -695,7 +693,6 @@ pub struct TypeAlias {
pub bounds: Box<[Interned<TypeBound>]>,
pub generic_params: Interned<GenericParams>,
pub type_ref: Option<Interned<TypeRef>>,
- pub is_extern: bool,
pub ast_id: FileAstId<ast::TypeAlias>,
}
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index 32213aac39..e9af991785 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 49dc1eef18..4b46283743 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 7671ccefd1..1969913bf9 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 b68ede4003..c8e60032df 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<N: ItemTreeNode> Hash for ItemLoc<N> {
#[derive(Debug)]
pub struct AssocItemLoc<N: ItemTreeNode> {
- pub container: AssocContainerId,
+ pub container: ItemContainerId,
pub id: ItemTreeId<N>,
}
@@ -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<Static>;
+pub type StaticLoc = AssocItemLoc<Static>;
impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -263,6 +264,11 @@ type ImplLoc = ItemLoc<Impl>;
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<ExternBlock>;
+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)]
pub struct BlockLoc {
@@ -295,12 +301,13 @@ pub struct ConstParamId {
pub type LocalConstParamId = Idx<generics::ConstParamData>;
#[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<AssocContainerId> for AttrDefId {
- fn from(acid: AssocContainerId) -> Self {
+impl From<ItemContainerId> 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 ad4a4aa752..8c0ba3c056 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 0cf28acf7f..8b2eea9d58 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 f58339286f..dc5dcd163c 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<AssociatedTyValue> {
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 36c56820eb..653c4d5ec8 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 6a3588dc74..a1e7198bc2 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 e2b4e92575..307323690a 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 d07a939583..56e554736e 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 5fb227c0e4..90c68c9d3f 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 056cdb5d5b..a84501fa54 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 af1d5fdb6a..99267e085f 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<AssocContainerId> = match def {
+ let container: Option<ItemContainerId> = 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<T1, T2, ...>` 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 8e19928746..6b3f48b194 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<Ty>,
) -> Option<Ty> {
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 6a662dcf7b..18a07f2c64 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 0037849d1c..a0837377c6 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<Generic
};
match container {
- AssocContainerId::ImplId(it) => 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 e8c6ec3e0e..62f4a81910 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,
<T as ItemTreeNode>::Source: HasName,
{
- fn container_name(db: &dyn HirDatabase, container: AssocContainerId) -> Option<SmolStr> {
+ fn container_name(db: &dyn HirDatabase, container: ItemContainerId) -> Option<SmolStr> {
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 6990b19cf3..3206a63a90 100644
--- a/crates/ide_diagnostics/src/handlers/incorrect_case.rs
+++ b/crates/ide_diagnostics/src/handlers/incorrect_case.rs
@@ -398,6 +398,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
// r-a, even though rustc will complain about them.