Treat extern blocks as item containers

This commit is contained in:
Jonas Schievink 2021-12-07 17:31:26 +01:00
parent b7afb6fc6c
commit b365b6119c
26 changed files with 216 additions and 164 deletions

View file

@ -137,6 +137,7 @@ fn resolve_doc_path(
AttrDefId::TraitId(it) => it.resolver(db.upcast()), AttrDefId::TraitId(it) => it.resolver(db.upcast()),
AttrDefId::TypeAliasId(it) => it.resolver(db.upcast()), AttrDefId::TypeAliasId(it) => it.resolver(db.upcast()),
AttrDefId::ImplId(it) => it.resolver(db.upcast()), AttrDefId::ImplId(it) => it.resolver(db.upcast()),
AttrDefId::ExternBlockId(it) => it.resolver(db.upcast()),
AttrDefId::GenericParamId(it) => match it { AttrDefId::GenericParamId(it) => match it {
GenericParamId::TypeParamId(it) => it.parent, GenericParamId::TypeParamId(it) => it.parent,
GenericParamId::LifetimeParamId(it) => it.parent, GenericParamId::LifetimeParamId(it) => it.parent,

View file

@ -114,11 +114,11 @@ pub use {
type_ref::{Mutability, TypeRef}, type_ref::{Mutability, TypeRef},
visibility::Visibility, visibility::Visibility,
AdtId, AdtId,
AssocContainerId,
AssocItemId, AssocItemId,
AssocItemLoc, AssocItemLoc,
DefWithBodyId, DefWithBodyId,
ImplId, ImplId,
ItemContainerId,
ItemLoc, ItemLoc,
Lookup, Lookup,
ModuleDefId, ModuleDefId,
@ -1550,7 +1550,7 @@ impl Static {
pub fn ty(self, db: &dyn HirDatabase) -> Type { pub fn ty(self, db: &dyn HirDatabase) -> Type {
let data = db.static_data(self.id); let data = db.static_data(self.id);
let resolver = self.id.resolver(db.upcast()); 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 ctx = hir_ty::TyLoweringContext::new(db, &resolver);
let ty = ctx.lower_ty(&data.type_ref); let ty = ctx.lower_ty(&data.type_ref);
Type::new_with_resolver_inner(db, krate, &resolver, ty) Type::new_with_resolver_inner(db, krate, &resolver, ty)
@ -1820,8 +1820,8 @@ where
AST: ItemTreeNode, AST: ItemTreeNode,
{ {
match id.lookup(db.upcast()).container { match id.lookup(db.upcast()).container {
AssocContainerId::TraitId(_) | AssocContainerId::ImplId(_) => Some(ctor(DEF::from(id))), ItemContainerId::TraitId(_) | ItemContainerId::ImplId(_) => Some(ctor(DEF::from(id))),
AssocContainerId::ModuleId(_) => None, ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => None,
} }
} }
@ -1847,9 +1847,11 @@ impl AssocItem {
AssocItem::TypeAlias(it) => it.id.lookup(db.upcast()).container, AssocItem::TypeAlias(it) => it.id.lookup(db.upcast()).container,
}; };
match container { match container {
AssocContainerId::TraitId(id) => AssocItemContainer::Trait(id.into()), ItemContainerId::TraitId(id) => AssocItemContainer::Trait(id.into()),
AssocContainerId::ImplId(id) => AssocItemContainer::Impl(id.into()), ItemContainerId::ImplId(id) => AssocItemContainer::Impl(id.into()),
AssocContainerId::ModuleId(_) => panic!("invalid AssocItem"), ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => {
panic!("invalid AssocItem")
}
} }
} }

View file

@ -362,6 +362,7 @@ impl AttrsWithOwner {
RawAttrs::from_attrs_owner(db, src.with_value(&src.value[it.local_id])) 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)); let attrs = raw_attrs.filter(db, def.krate(db));
@ -443,6 +444,7 @@ impl AttrsWithOwner {
.child_source(db) .child_source(db)
.map(|source| ast::AnyHasAttrs::new(source[id.local_id].clone())), .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)) AttrSourceMap::new(owner.as_ref().map(|node| node as &dyn HasAttrs))

View file

@ -13,8 +13,8 @@ use crate::{
item_tree::{self, AssocItem, FnFlags, ItemTreeId, ModItem, Param}, item_tree::{self, AssocItem, FnFlags, ItemTreeId, ModItem, Param},
type_ref::{TraitRef, TypeBound, TypeRef}, type_ref::{TraitRef, TypeBound, TypeRef},
visibility::RawVisibility, visibility::RawVisibility,
AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId, Intern,
Intern, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc, ItemContainerId, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc,
}; };
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
@ -54,6 +54,10 @@ impl FunctionData {
flags.bits |= FnFlags::IS_VARARGS; flags.bits |= FnFlags::IS_VARARGS;
} }
if matches!(loc.container, ItemContainerId::ExternBlockId(_)) {
flags.bits |= FnFlags::IS_IN_EXTERN_BLOCK;
}
Arc::new(FunctionData { Arc::new(FunctionData {
name: func.name.clone(), name: func.name.clone(),
params: enabled_params params: enabled_params
@ -130,7 +134,7 @@ impl TypeAliasData {
name: typ.name.clone(), name: typ.name.clone(),
type_ref: typ.type_ref.clone(), type_ref: typ.type_ref.clone(),
visibility: item_tree[typ.visibility].clone(), visibility: item_tree[typ.visibility].clone(),
is_extern: typ.is_extern, is_extern: matches!(loc.container, ItemContainerId::ExternBlockId(_)),
bounds: typ.bounds.to_vec(), bounds: typ.bounds.to_vec(),
}) })
} }
@ -162,7 +166,7 @@ impl TraitData {
let is_auto = tr_def.is_auto; let is_auto = tr_def.is_auto;
let is_unsafe = tr_def.is_unsafe; let is_unsafe = tr_def.is_unsafe;
let module_id = tr_loc.container; 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 visibility = item_tree[tr_def.visibility].clone();
let mut expander = Expander::new(db, tr_loc.id.file_id(), module_id); let mut expander = Expander::new(db, tr_loc.id.file_id(), module_id);
let skip_array_during_method_dispatch = item_tree let skip_array_during_method_dispatch = item_tree
@ -231,7 +235,7 @@ impl ImplData {
let self_ty = impl_def.self_ty.clone(); let self_ty = impl_def.self_ty.clone();
let is_negative = impl_def.is_negative; let is_negative = impl_def.is_negative;
let module_id = impl_loc.container; 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 mut expander = Expander::new(db, impl_loc.id.file_id(), module_id);
let items = collect_items( let items = collect_items(
@ -282,16 +286,16 @@ pub struct StaticData {
impl StaticData { impl StaticData {
pub(crate) fn static_data_query(db: &dyn DefDatabase, konst: StaticId) -> Arc<StaticData> { pub(crate) fn static_data_query(db: &dyn DefDatabase, konst: StaticId) -> Arc<StaticData> {
let node = konst.lookup(db); let loc = konst.lookup(db);
let item_tree = node.id.item_tree(db); let item_tree = loc.id.item_tree(db);
let statik = &item_tree[node.id.value]; let statik = &item_tree[loc.id.value];
Arc::new(StaticData { Arc::new(StaticData {
name: statik.name.clone(), name: statik.name.clone(),
type_ref: statik.type_ref.clone(), type_ref: statik.type_ref.clone(),
visibility: item_tree[statik.visibility].clone(), visibility: item_tree[statik.visibility].clone(),
mutable: statik.mutable, 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, expander: &mut Expander,
assoc_items: impl Iterator<Item = AssocItem>, assoc_items: impl Iterator<Item = AssocItem>,
tree_id: item_tree::TreeId, tree_id: item_tree::TreeId,
container: AssocContainerId, container: ItemContainerId,
limit: usize, limit: usize,
) -> Vec<(Name, AssocItemId)> { ) -> Vec<(Name, AssocItemId)> {
if limit == 0 { if limit == 0 {

View file

@ -19,10 +19,10 @@ use crate::{
lang_item::{LangItemTarget, LangItems}, lang_item::{LangItemTarget, LangItems},
nameres::DefMap, nameres::DefMap,
visibility::{self, Visibility}, visibility::{self, Visibility},
AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, ExternBlockId,
FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalEnumVariantId, LocalFieldId, StaticId, ExternBlockLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalEnumVariantId,
StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, LocalFieldId, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId,
UnionLoc, VariantId, TypeAliasLoc, UnionId, UnionLoc, VariantId,
}; };
#[salsa::query_group(InternDatabaseStorage)] #[salsa::query_group(InternDatabaseStorage)]
@ -46,6 +46,8 @@ pub trait InternDatabase: SourceDatabase {
#[salsa::interned] #[salsa::interned]
fn intern_impl(&self, loc: ImplLoc) -> ImplId; fn intern_impl(&self, loc: ImplLoc) -> ImplId;
#[salsa::interned] #[salsa::interned]
fn intern_extern_block(&self, loc: ExternBlockLoc) -> ExternBlockId;
#[salsa::interned]
fn intern_block(&self, loc: BlockLoc) -> BlockId; fn intern_block(&self, loc: BlockLoc) -> BlockId;
} }

View file

@ -468,7 +468,7 @@ mod tests {
use base_db::{fixture::WithFixture, SourceDatabase, Upcast}; use base_db::{fixture::WithFixture, SourceDatabase, Upcast};
use expect_test::{expect, Expect}; use expect_test::{expect, Expect};
use crate::{test_db::TestDB, AssocContainerId, Lookup}; use crate::{test_db::TestDB, ItemContainerId, Lookup};
use super::*; use super::*;
@ -563,7 +563,7 @@ mod tests {
}; };
match container { match container {
AssocContainerId::TraitId(it) => Some(ItemInNs::Types(it.into())), ItemContainerId::TraitId(it) => Some(ItemInNs::Types(it.into())),
_ => None, _ => None,
} }
} }

View file

@ -660,8 +660,6 @@ pub struct Static {
pub name: Name, pub name: Name,
pub visibility: RawVisibilityId, pub visibility: RawVisibilityId,
pub mutable: bool, pub mutable: bool,
/// Whether the static is in an `extern` block.
pub is_extern: bool,
pub type_ref: Interned<TypeRef>, pub type_ref: Interned<TypeRef>,
pub ast_id: FileAstId<ast::Static>, pub ast_id: FileAstId<ast::Static>,
} }
@ -695,7 +693,6 @@ pub struct TypeAlias {
pub bounds: Box<[Interned<TypeBound>]>, pub bounds: Box<[Interned<TypeBound>]>,
pub generic_params: Interned<GenericParams>, pub generic_params: Interned<GenericParams>,
pub type_ref: Option<Interned<TypeRef>>, pub type_ref: Option<Interned<TypeRef>>,
pub is_extern: bool,
pub ast_id: FileAstId<ast::TypeAlias>, pub ast_id: FileAstId<ast::TypeAlias>,
} }

View file

@ -360,7 +360,6 @@ impl<'a> Ctx<'a> {
generic_params, generic_params,
type_ref, type_ref,
ast_id, ast_id,
is_extern: false,
}; };
Some(id(self.data().type_aliases.alloc(res))) Some(id(self.data().type_aliases.alloc(res)))
} }
@ -371,7 +370,7 @@ impl<'a> Ctx<'a> {
let visibility = self.lower_visibility(static_); let visibility = self.lower_visibility(static_);
let mutable = static_.mut_token().is_some(); let mutable = static_.mut_token().is_some();
let ast_id = self.source_ast_id_map.ast_id(static_); 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))) 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| { let children: Box<[_]> = block.extern_item_list().map_or(Box::new([]), |list| {
list.extern_items() list.extern_items()
.filter_map(|item| { .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 attrs = RawAttrs::new(self.db, &item, &self.hygiene);
let id: ModItem = match item { let id: ModItem = match item {
ast::ExternItem::Fn(ast) => { ast::ExternItem::Fn(ast) => {
let func_id = self.lower_function(&ast)?; let func_id = self.lower_function(&ast)?;
let func = &mut self.data().functions[func_id.index]; let func = &mut self.data().functions[func_id.index];
if is_intrinsic_fn_unsafe(&func.name) { if is_intrinsic_fn_unsafe(&func.name) {
// FIXME: this breaks in macros
func.flags.bits |= FnFlags::IS_UNSAFE; func.flags.bits |= FnFlags::IS_UNSAFE;
} }
func.flags.bits |= FnFlags::IS_IN_EXTERN_BLOCK;
func_id.into() func_id.into()
} }
ast::ExternItem::Static(ast) => { ast::ExternItem::Static(ast) => self.lower_static(&ast)?.into(),
let statik = self.lower_static(&ast)?; ast::ExternItem::TypeAlias(ty) => self.lower_type_alias(&ty)?.into(),
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::MacroCall(call) => { ast::ExternItem::MacroCall(call) => {
// FIXME: we need some way of tracking that the macro call is in an // FIXME: we need some way of tracking that the macro call is in an
// extern block // extern block

View file

@ -328,8 +328,7 @@ impl<'a> Printer<'a> {
wln!(self, " = _;"); wln!(self, " = _;");
} }
ModItem::Static(it) => { ModItem::Static(it) => {
let Static { name, visibility, mutable, is_extern, type_ref, ast_id: _ } = let Static { name, visibility, mutable, type_ref, ast_id: _ } = &self.tree[it];
&self.tree[it];
self.print_visibility(*visibility); self.print_visibility(*visibility);
w!(self, "static "); w!(self, "static ");
if *mutable { if *mutable {
@ -338,9 +337,6 @@ impl<'a> Printer<'a> {
w!(self, "{}: ", name); w!(self, "{}: ", name);
self.print_type_ref(type_ref); self.print_type_ref(type_ref);
w!(self, " = _;"); w!(self, " = _;");
if *is_extern {
w!(self, " // extern");
}
wln!(self); wln!(self);
} }
ModItem::Trait(it) => { ModItem::Trait(it) => {
@ -393,15 +389,8 @@ impl<'a> Printer<'a> {
wln!(self, "}}"); wln!(self, "}}");
} }
ModItem::TypeAlias(it) => { ModItem::TypeAlias(it) => {
let TypeAlias { let TypeAlias { name, visibility, bounds, type_ref, generic_params, ast_id: _ } =
name, &self.tree[it];
visibility,
bounds,
type_ref,
is_extern,
generic_params,
ast_id: _,
} = &self.tree[it];
self.print_visibility(*visibility); self.print_visibility(*visibility);
w!(self, "type {}", name); w!(self, "type {}", name);
self.print_generic_params(generic_params); self.print_generic_params(generic_params);
@ -415,9 +404,6 @@ impl<'a> Printer<'a> {
} }
self.print_where_clause(generic_params); self.print_where_clause(generic_params);
w!(self, ";"); w!(self, ";");
if *is_extern {
w!(self, " // extern");
}
wln!(self); wln!(self);
} }
ModItem::Mod(it) => { ModItem::Mod(it) => {

View file

@ -70,13 +70,13 @@ extern "C" {
#[on_extern_block] // AttrId { is_doc_comment: false, ast_index: 0 } #[on_extern_block] // AttrId { is_doc_comment: false, ast_index: 0 }
extern "C" { extern "C" {
#[on_extern_type] // AttrId { is_doc_comment: false, ast_index: 0 } #[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 } #[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 } #[on_extern_fn] // AttrId { is_doc_comment: false, ast_index: 0 }
// flags = 0x60 // flags = 0x20
pub(self) fn ex_fn() -> (); pub(self) fn ex_fn() -> ();
} }
"##]], "##]],

View file

@ -65,6 +65,7 @@ use hir_expand::{
hygiene::Hygiene, hygiene::Hygiene,
AstId, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, AstId, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
}; };
use item_tree::ExternBlock;
use la_arena::Idx; use la_arena::Idx;
use nameres::DefMap; use nameres::DefMap;
use path::ModPath; use path::ModPath;
@ -153,7 +154,7 @@ impl<N: ItemTreeNode> Hash for ItemLoc<N> {
#[derive(Debug)] #[derive(Debug)]
pub struct AssocItemLoc<N: ItemTreeNode> { pub struct AssocItemLoc<N: ItemTreeNode> {
pub container: AssocContainerId, pub container: ItemContainerId,
pub id: ItemTreeId<N>, pub id: ItemTreeId<N>,
} }
@ -244,7 +245,7 @@ impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct StaticId(salsa::InternId); pub struct StaticId(salsa::InternId);
pub type StaticLoc = ItemLoc<Static>; pub type StaticLoc = AssocItemLoc<Static>;
impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static); impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -262,6 +263,11 @@ pub struct ImplId(salsa::InternId);
type ImplLoc = ItemLoc<Impl>; type ImplLoc = ItemLoc<Impl>;
impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_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)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub struct BlockId(salsa::InternId); pub struct BlockId(salsa::InternId);
#[derive(Debug, Hash, PartialEq, Eq, Clone)] #[derive(Debug, Hash, PartialEq, Eq, Clone)]
@ -295,12 +301,13 @@ pub struct ConstParamId {
pub type LocalConstParamId = Idx<generics::ConstParamData>; pub type LocalConstParamId = Idx<generics::ConstParamData>;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum AssocContainerId { pub enum ItemContainerId {
ExternBlockId(ExternBlockId),
ModuleId(ModuleId), ModuleId(ModuleId),
ImplId(ImplId), ImplId(ImplId),
TraitId(TraitId), TraitId(TraitId),
} }
impl_from!(ModuleId for AssocContainerId); impl_from!(ModuleId for ItemContainerId);
/// A Data Type /// A Data Type
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
@ -427,6 +434,7 @@ pub enum AttrDefId {
MacroDefId(MacroDefId), MacroDefId(MacroDefId),
ImplId(ImplId), ImplId(ImplId),
GenericParamId(GenericParamId), GenericParamId(GenericParamId),
ExternBlockId(ExternBlockId),
} }
impl_from!( impl_from!(
@ -445,12 +453,13 @@ impl_from!(
for AttrDefId for AttrDefId
); );
impl From<AssocContainerId> for AttrDefId { impl From<ItemContainerId> for AttrDefId {
fn from(acid: AssocContainerId) -> Self { fn from(acid: ItemContainerId) -> Self {
match acid { match acid {
AssocContainerId::ModuleId(mid) => AttrDefId::ModuleId(mid), ItemContainerId::ModuleId(mid) => AttrDefId::ModuleId(mid),
AssocContainerId::ImplId(iid) => AttrDefId::ImplId(iid), ItemContainerId::ImplId(iid) => AttrDefId::ImplId(iid),
AssocContainerId::TraitId(tid) => AttrDefId::TraitId(tid), 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; fn module(&self, db: &dyn db::DefDatabase) -> ModuleId;
} }
impl HasModule for AssocContainerId { impl HasModule for ItemContainerId {
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
match *self { match *self {
AssocContainerId::ModuleId(it) => it, ItemContainerId::ModuleId(it) => it,
AssocContainerId::ImplId(it) => it.lookup(db).container, ItemContainerId::ImplId(it) => it.lookup(db).container,
AssocContainerId::TraitId(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 { impl ModuleDefId {
/// Returns the module containing `self` (or `self`, if `self` is itself a module). /// 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::AdtId(id) => id.module(db),
ModuleDefId::EnumVariantId(id) => id.parent.lookup(db).container, ModuleDefId::EnumVariantId(id) => id.parent.lookup(db).container,
ModuleDefId::ConstId(id) => id.lookup(db).container.module(db), 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::TraitId(id) => id.lookup(db).container,
ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db), ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db),
ModuleDefId::BuiltinType(_) => return None, ModuleDefId::BuiltinType(_) => return None,
@ -625,6 +629,7 @@ impl AttrDefId {
AttrDefId::TraitId(it) => it.lookup(db).container.krate, AttrDefId::TraitId(it) => it.lookup(db).container.krate,
AttrDefId::TypeAliasId(it) => it.lookup(db).module(db).krate, AttrDefId::TypeAliasId(it) => it.lookup(db).module(db).krate,
AttrDefId::ImplId(it) => it.lookup(db).container.krate, AttrDefId::ImplId(it) => it.lookup(db).container.krate,
AttrDefId::ExternBlockId(it) => it.lookup(db).container.krate,
AttrDefId::GenericParamId(it) => { AttrDefId::GenericParamId(it) => {
match it { match it {
GenericParamId::TypeParamId(it) => it.parent, GenericParamId::TypeParamId(it) => it.parent,

View file

@ -44,9 +44,9 @@ use crate::{
path::{ImportAlias, ModPath, PathKind}, path::{ImportAlias, ModPath, PathKind},
per_ns::PerNs, per_ns::PerNs,
visibility::{RawVisibility, Visibility}, visibility::{RawVisibility, Visibility},
AdtId, AstId, AstIdWithPath, ConstLoc, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern, AdtId, AstId, AstIdWithPath, ConstLoc, EnumLoc, EnumVariantId, ExternBlockLoc, FunctionLoc,
LocalModuleId, ModuleDefId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, ImplLoc, Intern, ItemContainerId, LocalModuleId, ModuleDefId, StaticLoc, StructLoc, TraitLoc,
UnresolvedMacro, TypeAliasLoc, UnionLoc, UnresolvedMacro,
}; };
static GLOB_RECURSION_LIMIT: Limit = Limit::new(100); static GLOB_RECURSION_LIMIT: Limit = Limit::new(100);
@ -213,6 +213,7 @@ struct MacroDirective {
module_id: LocalModuleId, module_id: LocalModuleId,
depth: usize, depth: usize,
kind: MacroDirectiveKind, kind: MacroDirectiveKind,
container: ItemContainerId,
} }
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq)]
@ -306,7 +307,7 @@ impl DefCollector<'_> {
item_tree: &item_tree, item_tree: &item_tree,
mod_dir: ModDir::root(), 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, item_tree: &item_tree,
mod_dir: ModDir::root(), 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, item_tree: &item_tree,
mod_dir, mod_dir,
} }
.collect(&[*mod_item]); .collect(&[*mod_item], directive.container);
true true
} else { } else {
false false
@ -1053,7 +1054,12 @@ impl DefCollector<'_> {
&mut |_err| (), &mut |_err| (),
); );
if let Ok(Ok(call_id)) = call_id { 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; res = ReachedFixedPoint::No;
return false; return false;
} }
@ -1073,7 +1079,12 @@ impl DefCollector<'_> {
*derive_attr, *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; res = ReachedFixedPoint::No;
return false; return false;
} }
@ -1096,7 +1107,7 @@ impl DefCollector<'_> {
item_tree: &item_tree, item_tree: &item_tree,
mod_dir, mod_dir,
} }
.collect(&[*mod_item]); .collect(&[*mod_item], directive.container);
res = ReachedFixedPoint::No; res = ReachedFixedPoint::No;
false false
}; };
@ -1144,6 +1155,7 @@ impl DefCollector<'_> {
ast_id, ast_id,
derive_attr: attr.id, derive_attr: attr.id,
}, },
container: directive.container,
}); });
} }
} }
@ -1199,7 +1211,12 @@ impl DefCollector<'_> {
.scope .scope
.add_attr_macro_invoc(ast_id, call_id); .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; res = ReachedFixedPoint::No;
return false; return false;
} }
@ -1213,8 +1230,8 @@ impl DefCollector<'_> {
// Attribute resolution can add unresolved macro invocations, so concatenate the lists. // Attribute resolution can add unresolved macro invocations, so concatenate the lists.
self.unresolved_macros.extend(macros); self.unresolved_macros.extend(macros);
for (module_id, macro_call_id, depth) in resolved { for (module_id, macro_call_id, depth, container) in resolved {
self.collect_macro_expansion(module_id, macro_call_id, depth); self.collect_macro_expansion(module_id, macro_call_id, depth, container);
} }
res res
@ -1225,6 +1242,7 @@ impl DefCollector<'_> {
module_id: LocalModuleId, module_id: LocalModuleId,
macro_call_id: MacroCallId, macro_call_id: MacroCallId,
depth: usize, depth: usize,
container: ItemContainerId,
) { ) {
if EXPANSION_DEPTH_LIMIT.check(depth).is_err() { if EXPANSION_DEPTH_LIMIT.check(depth).is_err() {
cov_mark::hit!(macro_expansion_overflow); cov_mark::hit!(macro_expansion_overflow);
@ -1276,7 +1294,7 @@ impl DefCollector<'_> {
item_tree: &item_tree, item_tree: &item_tree,
mod_dir, mod_dir,
} }
.collect(item_tree.top_level_items()); .collect(item_tree.top_level_items(), container);
} }
fn finish(mut self) -> DefMap { fn finish(mut self) -> DefMap {
@ -1372,7 +1390,12 @@ struct ModCollector<'a, 'b> {
} }
impl ModCollector<'_, '_> { 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> { struct DefData<'a> {
id: ModuleDefId, id: ModuleDefId,
name: &'a Name, 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 // 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. // fixed-point algorithm is required to resolve the rest of them.
continue; continue;
@ -1462,8 +1485,17 @@ impl ModCollector<'_, '_> {
status: PartialResolvedImport::Unresolved, status: PartialResolvedImport::Unresolved,
}) })
} }
ModItem::ExternBlock(block) => self.collect(&self.item_tree[block].children), ModItem::ExternBlock(block) => self.collect(
ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac]), &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::MacroRules(id) => self.collect_macro_rules(id),
ModItem::MacroDef(id) => self.collect_macro_def(id), ModItem::MacroDef(id) => self.collect_macro_def(id),
ModItem::Impl(imp) => { ModItem::Impl(imp) => {
@ -1480,12 +1512,9 @@ impl ModCollector<'_, '_> {
self.collect_proc_macro_def(&func.name, ast_id, &attrs); self.collect_proc_macro_def(&func.name, ast_id, &attrs);
def = Some(DefData { def = Some(DefData {
id: FunctionLoc { id: FunctionLoc { container, id: ItemTreeId::new(self.tree_id, id) }
container: module.into(), .intern(self.def_collector.db)
id: ItemTreeId::new(self.tree_id, id), .into(),
}
.intern(self.def_collector.db)
.into(),
name: &func.name, name: &func.name,
visibility: &self.item_tree[func.visibility], visibility: &self.item_tree[func.visibility],
has_constructor: false, has_constructor: false,
@ -1529,11 +1558,8 @@ impl ModCollector<'_, '_> {
} }
ModItem::Const(id) => { ModItem::Const(id) => {
let it = &self.item_tree[id]; let it = &self.item_tree[id];
let const_id = ConstLoc { let const_id = ConstLoc { container, id: ItemTreeId::new(self.tree_id, id) }
container: module.into(), .intern(self.def_collector.db);
id: ItemTreeId::new(self.tree_id, id),
}
.intern(self.def_collector.db);
match &it.name { match &it.name {
Some(name) => { Some(name) => {
@ -1556,7 +1582,7 @@ impl ModCollector<'_, '_> {
let it = &self.item_tree[id]; let it = &self.item_tree[id];
def = Some(DefData { 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) .intern(self.def_collector.db)
.into(), .into(),
name: &it.name, name: &it.name,
@ -1580,12 +1606,9 @@ impl ModCollector<'_, '_> {
let it = &self.item_tree[id]; let it = &self.item_tree[id];
def = Some(DefData { def = Some(DefData {
id: TypeAliasLoc { id: TypeAliasLoc { container, id: ItemTreeId::new(self.tree_id, id) }
container: module.into(), .intern(self.def_collector.db)
id: ItemTreeId::new(self.tree_id, id), .into(),
}
.intern(self.def_collector.db)
.into(),
name: &it.name, name: &it.name,
visibility: &self.item_tree[it.visibility], visibility: &self.item_tree[it.visibility],
has_constructor: false, has_constructor: false,
@ -1633,7 +1656,7 @@ impl ModCollector<'_, '_> {
item_tree: self.item_tree, item_tree: self.item_tree,
mod_dir, mod_dir,
} }
.collect(&*items); .collect_in_top_module(&*items);
if is_macro_use { if is_macro_use {
self.import_all_legacy_macros(module_id); self.import_all_legacy_macros(module_id);
} }
@ -1666,7 +1689,7 @@ impl ModCollector<'_, '_> {
item_tree: &item_tree, item_tree: &item_tree,
mod_dir, mod_dir,
} }
.collect(item_tree.top_level_items()); .collect_in_top_module(item_tree.top_level_items());
let is_macro_use = is_macro_use let is_macro_use = is_macro_use
|| item_tree || item_tree
.top_level_attrs(db, self.def_collector.def_map.krate) .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 /// If `ignore_up_to` is `Some`, attributes preceding and including that attribute will be
/// assumed to be resolved already. /// 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 = let mut ignore_up_to =
self.def_collector.skip_attrs.get(&InFile::new(self.file_id(), mod_item)).copied(); self.def_collector.skip_attrs.get(&InFile::new(self.file_id(), mod_item)).copied();
let iter = attrs let iter = attrs
@ -1777,6 +1805,7 @@ impl ModCollector<'_, '_> {
mod_item, mod_item,
tree: self.tree_id, tree: self.tree_id,
}, },
container,
}); });
return Err(()); 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)); 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 // Case 1: try to resolve in legacy scope and expand macro_rules
@ -1981,6 +2010,7 @@ impl ModCollector<'_, '_> {
self.module_id, self.module_id,
macro_call_id, macro_call_id,
self.macro_depth + 1, self.macro_depth + 1,
container,
); );
if let Some(err) = error { if let Some(err) = error {
@ -2011,6 +2041,7 @@ impl ModCollector<'_, '_> {
module_id: self.module_id, module_id: self.module_id,
depth: self.macro_depth + 1, depth: self.macro_depth + 1,
kind: MacroDirectiveKind::FnLike { ast_id, expand_to: mac.expand_to }, kind: MacroDirectiveKind::FnLike { ast_id, expand_to: mac.expand_to },
container,
}); });
} }

View file

@ -22,8 +22,8 @@ use crate::{
path::{ModPath, PathKind}, path::{ModPath, PathKind},
per_ns::PerNs, per_ns::PerNs,
visibility::{RawVisibility, Visibility}, visibility::{RawVisibility, Visibility},
AdtId, AssocContainerId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, EnumId, AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId,
EnumVariantId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, LifetimeParamId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId,
TypeParamId, VariantId, 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 { impl HasResolver for DefWithBodyId {
fn resolver(self, db: &dyn DefDatabase) -> Resolver { fn resolver(self, db: &dyn DefDatabase) -> Resolver {
match self { 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 { fn resolver(self, db: &dyn DefDatabase) -> Resolver {
match self { match self {
AssocContainerId::ModuleId(it) => it.resolver(db), ItemContainerId::ModuleId(it) => it.resolver(db),
AssocContainerId::TraitId(it) => it.resolver(db), ItemContainerId::TraitId(it) => it.resolver(db),
AssocContainerId::ImplId(it) => it.resolver(db), ItemContainerId::ImplId(it) => it.resolver(db),
ItemContainerId::ExternBlockId(it) => it.resolver(db),
} }
} }
} }

View file

@ -11,7 +11,7 @@ use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
use base_db::CrateId; use base_db::CrateId;
use hir_def::{ use hir_def::{
lang_item::{lang_attr, LangItemTarget}, lang_item::{lang_attr, LangItemTarget},
AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, ModuleId, TypeAliasId, AssocItemId, GenericDefId, HasModule, ItemContainerId, Lookup, ModuleId, TypeAliasId,
}; };
use hir_expand::name::name; use hir_expand::name::name;
@ -396,7 +396,7 @@ pub(crate) fn associated_ty_data_query(
debug!("associated_ty_data {:?}", id); debug!("associated_ty_data {:?}", id);
let type_alias: TypeAliasId = from_assoc_type_id(id); let type_alias: TypeAliasId = from_assoc_type_id(id);
let trait_ = match type_alias.lookup(db.upcast()).container { let trait_ = match type_alias.lookup(db.upcast()).container {
AssocContainerId::TraitId(t) => t, ItemContainerId::TraitId(t) => t,
_ => panic!("associated type not in trait"), _ => panic!("associated type not in trait"),
}; };
@ -634,7 +634,7 @@ fn type_alias_associated_ty_value(
) -> Arc<AssociatedTyValue> { ) -> Arc<AssociatedTyValue> {
let type_alias_data = db.type_alias_data(type_alias); let type_alias_data = db.type_alias_data(type_alias);
let impl_id = match type_alias.lookup(db.upcast()).container { 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"), _ => panic!("assoc ty value should be in impl"),
}; };

View file

@ -4,7 +4,7 @@ use chalk_ir::{FloatTy, IntTy, Mutability, Scalar, UintTy};
use hir_def::{ use hir_def::{
builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType, BuiltinUint}, builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType, BuiltinUint},
type_ref::Rawness, type_ref::Rawness,
AssocContainerId, FunctionId, GenericDefId, HasModule, Lookup, TraitId, FunctionId, GenericDefId, HasModule, ItemContainerId, Lookup, TraitId,
}; };
use crate::{ use crate::{
@ -268,7 +268,7 @@ impl TyExt for Ty {
match self.kind(&Interner) { match self.kind(&Interner) {
TyKind::AssociatedType(id, ..) => { TyKind::AssociatedType(id, ..) => {
match from_assoc_type_id(*id).lookup(db.upcast()).container { 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, _ => None,
} }
} }
@ -277,7 +277,7 @@ impl TyExt for Ty {
.lookup(db.upcast()) .lookup(db.upcast())
.container .container
{ {
AssocContainerId::TraitId(trait_id) => Some(trait_id), ItemContainerId::TraitId(trait_id) => Some(trait_id),
_ => None, _ => None,
} }
} }
@ -331,7 +331,7 @@ impl ProjectionTyExt for ProjectionTy {
fn trait_(&self, db: &dyn HirDatabase) -> TraitId { fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container { 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"), _ => panic!("projection ty without parent trait"),
} }
} }

View file

@ -178,6 +178,7 @@ impl<'a> DeclValidator<'a> {
AttrDefId::ConstId(cid) => Some(cid.lookup(self.db.upcast()).container.into()), AttrDefId::ConstId(cid) => Some(cid.lookup(self.db.upcast()).container.into()),
AttrDefId::TraitId(tid) => Some(tid.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::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 // These warnings should not explore macro definitions at all
AttrDefId::MacroDefId(_) => None, AttrDefId::MacroDefId(_) => None,
// Will never occur under an enum/struct/union/type alias // Will never occur under an enum/struct/union/type alias

View file

@ -16,7 +16,7 @@ use hir_def::{
path::{Path, PathKind}, path::{Path, PathKind},
type_ref::{TraitBoundModifier, TypeBound, TypeRef}, type_ref::{TraitBoundModifier, TypeBound, TypeRef},
visibility::Visibility, visibility::Visibility,
AssocContainerId, HasModule, Lookup, ModuleId, TraitId, HasModule, ItemContainerId, Lookup, ModuleId, TraitId,
}; };
use hir_expand::{hygiene::Hygiene, name::Name}; use hir_expand::{hygiene::Hygiene, name::Name};
use itertools::Itertools; use itertools::Itertools;
@ -576,7 +576,7 @@ impl HirDisplay for Ty {
TyKind::AssociatedType(assoc_type_id, parameters) => { TyKind::AssociatedType(assoc_type_id, parameters) => {
let type_alias = from_assoc_type_id(*assoc_type_id); let type_alias = from_assoc_type_id(*assoc_type_id);
let trait_ = match type_alias.lookup(f.db.upcast()).container { let trait_ = match type_alias.lookup(f.db.upcast()).container {
AssocContainerId::TraitId(it) => it, ItemContainerId::TraitId(it) => it,
_ => panic!("not an associated type"), _ => panic!("not an associated type"),
}; };
let trait_ = f.db.trait_data(trait_); let trait_ = f.db.trait_data(trait_);

View file

@ -521,7 +521,7 @@ impl<'a> InferenceContext<'a> {
match assoc_ty { match assoc_ty {
Some(res_assoc_ty) => { Some(res_assoc_ty) => {
let trait_ = match res_assoc_ty.lookup(self.db.upcast()).container { 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"), _ => panic!("resolve_associated_type called with non-associated type"),
}; };
let ty = self.table.new_type_var(); let ty = self.table.new_type_var();

View file

@ -14,7 +14,7 @@ use hir_def::{
}, },
path::{GenericArg, GenericArgs}, path::{GenericArg, GenericArgs},
resolver::resolver_for_expr, resolver::resolver_for_expr,
AssocContainerId, FieldId, FunctionId, Lookup, FieldId, FunctionId, ItemContainerId, Lookup,
}; };
use hir_expand::name::{name, Name}; use hir_expand::name::{name, Name};
use stdx::always; use stdx::always;
@ -1167,8 +1167,7 @@ impl<'a> InferenceContext<'a> {
// add obligation for trait implementation, if this is a trait method // add obligation for trait implementation, if this is a trait method
match def { match def {
CallableDefId::FunctionId(f) => { 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 // construct a TraitRef
let substs = crate::subst_prefix( let substs = crate::subst_prefix(
&*parameters, &*parameters,

View file

@ -6,7 +6,7 @@ use chalk_ir::cast::Cast;
use hir_def::{ use hir_def::{
path::{Path, PathSegment}, path::{Path, PathSegment},
resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs}, resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs},
AdtId, AssocContainerId, AssocItemId, EnumVariantId, Lookup, AdtId, AssocItemId, EnumVariantId, ItemContainerId, Lookup,
}; };
use hir_expand::name::Name; use hir_expand::name::Name;
@ -241,7 +241,7 @@ impl<'a> InferenceContext<'a> {
AssocItemId::TypeAliasId(_) => unreachable!(), AssocItemId::TypeAliasId(_) => unreachable!(),
}; };
let substs = match container { let substs = match container {
AssocContainerId::ImplId(impl_id) => { ItemContainerId::ImplId(impl_id) => {
let impl_substs = TyBuilder::subst_for_def(self.db, impl_id) let impl_substs = TyBuilder::subst_for_def(self.db, impl_id)
.fill(iter::repeat_with(|| self.table.new_type_var())) .fill(iter::repeat_with(|| self.table.new_type_var()))
.build(); .build();
@ -250,7 +250,7 @@ impl<'a> InferenceContext<'a> {
self.unify(&impl_self_ty, &ty); self.unify(&impl_self_ty, &ty);
Some(impl_substs) Some(impl_substs)
} }
AssocContainerId::TraitId(trait_) => { ItemContainerId::TraitId(trait_) => {
// we're picking this method // we're picking this method
let trait_ref = TyBuilder::trait_ref(self.db, trait_) let trait_ref = TyBuilder::trait_ref(self.db, trait_)
.push(ty.clone()) .push(ty.clone())
@ -259,7 +259,7 @@ impl<'a> InferenceContext<'a> {
self.push_obligation(trait_ref.clone().cast(&Interner)); self.push_obligation(trait_ref.clone().cast(&Interner));
Some(trait_ref.substitution) Some(trait_ref.substitution)
} }
AssocContainerId::ModuleId(_) => None, ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => None,
}; };
self.write_assoc_resolution(id, item); self.write_assoc_resolution(id, item);

View file

@ -19,8 +19,8 @@ use hir_def::{
path::{GenericArg, Path, PathSegment, PathSegments}, path::{GenericArg, Path, PathSegment, PathSegments},
resolver::{HasResolver, Resolver, TypeNs}, resolver::{HasResolver, Resolver, TypeNs},
type_ref::{TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef}, type_ref::{TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef},
AdtId, AssocContainerId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, AdtId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId,
GenericDefId, HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId, HasModule, ImplId, ItemContainerId, LocalFieldId, Lookup, StaticId, StructId, TraitId,
TypeAliasId, TypeParamId, UnionId, VariantId, TypeAliasId, TypeParamId, UnionId, VariantId,
}; };
use hir_expand::{name::Name, ExpandResult}; 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? // FIXME: is there a function for this?
GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container), GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container),
GenericDefId::AdtId(_) => None, GenericDefId::AdtId(_) => None,
@ -1135,7 +1135,7 @@ pub(crate) fn trait_environment_query(
GenericDefId::EnumVariantId(_) => None, GenericDefId::EnumVariantId(_) => None,
GenericDefId::ConstId(c) => Some(c.lookup(db.upcast()).container), 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 // add `Self: Trait<T1, T2, ...>` to the environment in trait
// function default implementations (and speculative code // function default implementations (and speculative code
// inside consts or type aliases) // inside consts or type aliases)

View file

@ -8,8 +8,8 @@ use arrayvec::ArrayVec;
use base_db::{CrateId, Edition}; use base_db::{CrateId, Edition};
use chalk_ir::{cast::Cast, Mutability, UniverseIndex}; use chalk_ir::{cast::Cast, Mutability, UniverseIndex};
use hir_def::{ use hir_def::{
lang_item::LangItemTarget, nameres::DefMap, AssocContainerId, AssocItemId, BlockId, FunctionId, lang_item::LangItemTarget, nameres::DefMap, AssocItemId, BlockId, FunctionId, GenericDefId,
GenericDefId, HasModule, ImplId, Lookup, ModuleId, TraitId, HasModule, ImplId, ItemContainerId, Lookup, ModuleId, TraitId,
}; };
use hir_expand::name::Name; use hir_expand::name::Name;
use rustc_hash::{FxHashMap, FxHashSet}; use rustc_hash::{FxHashMap, FxHashSet};
@ -979,18 +979,19 @@ fn transform_receiver_ty(
self_ty: &Canonical<Ty>, self_ty: &Canonical<Ty>,
) -> Option<Ty> { ) -> Option<Ty> {
let substs = match function_id.lookup(db.upcast()).container { 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()) .push(self_ty.value.clone())
.fill_with_unknown() .fill_with_unknown()
.build(), .build(),
AssocContainerId::ImplId(impl_id) => { ItemContainerId::ImplId(impl_id) => {
let impl_substs = inherent_impl_substs(db, env, impl_id, self_ty)?; let impl_substs = inherent_impl_substs(db, env, impl_id, self_ty)?;
TyBuilder::subst_for_def(db, function_id) TyBuilder::subst_for_def(db, function_id)
.use_parent_substs(&impl_substs) .use_parent_substs(&impl_substs)
.fill_with_unknown() .fill_with_unknown()
.build() .build()
} }
AssocContainerId::ModuleId(_) => unreachable!(), // No receiver
ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => unreachable!(),
}; };
let sig = db.callable_item_signature(function_id.into()); let sig = db.callable_item_signature(function_id.into());
Some(sig.map(|s| s.params()[0].clone()).substitute(&Interner, &substs)) Some(sig.map(|s| s.params()[0].clone()).substitute(&Interner, &substs))

View file

@ -7,7 +7,7 @@ use crate::{
chalk_db, db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, mapping::from_chalk, chalk_db, db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, mapping::from_chalk,
CallableDefId, Interner, 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}; 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: TypeAliasId = from_assoc_type_id(id);
let type_alias_data = self.0.type_alias_data(type_alias); let type_alias_data = self.0.type_alias_data(type_alias);
let trait_ = match type_alias.lookup(self.0.upcast()).container { let trait_ = match type_alias.lookup(self.0.upcast()).container {
AssocContainerId::TraitId(t) => t, ItemContainerId::TraitId(t) => t,
_ => panic!("associated type not in trait"), _ => panic!("associated type not in trait"),
}; };
let trait_data = self.0.trait_data(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 = from_assoc_type_id(projection_ty.associated_ty_id);
let type_alias_data = self.0.type_alias_data(type_alias); let type_alias_data = self.0.type_alias_data(type_alias);
let trait_ = match type_alias.lookup(self.0.upcast()).container { let trait_ = match type_alias.lookup(self.0.upcast()).container {
AssocContainerId::TraitId(t) => t, ItemContainerId::TraitId(t) => t,
_ => panic!("associated type not in trait"), _ => panic!("associated type not in trait"),
}; };
let trait_data = self.0.trait_data(trait_); let trait_data = self.0.trait_data(trait_);

View file

@ -14,7 +14,7 @@ use hir_def::{
path::Path, path::Path,
resolver::{HasResolver, TypeNs}, resolver::{HasResolver, TypeNs},
type_ref::{TraitBoundModifier, TypeRef}, type_ref::{TraitBoundModifier, TypeRef},
AssocContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, TypeParamId, GenericDefId, ItemContainerId, Lookup, TraitId, TypeAliasId, TypeParamId,
}; };
use hir_expand::name::{name, Name}; use hir_expand::name::{name, Name};
use rustc_hash::FxHashSet; use rustc_hash::FxHashSet;
@ -296,8 +296,8 @@ fn parent_generic_def(db: &dyn DefDatabase, def: GenericDefId) -> Option<Generic
}; };
match container { match container {
AssocContainerId::ImplId(it) => Some(it.into()), ItemContainerId::ImplId(it) => Some(it.into()),
AssocContainerId::TraitId(it) => Some(it.into()), ItemContainerId::TraitId(it) => Some(it.into()),
AssocContainerId::ModuleId(_) => None, ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => None,
} }
} }

View file

@ -36,8 +36,8 @@ use either::Either;
use fst::{self, Streamer}; use fst::{self, Streamer};
use hir::{ use hir::{
db::{DefDatabase, HirDatabase}, db::{DefDatabase, HirDatabase},
AdtId, AssocContainerId, AssocItemId, AssocItemLoc, DefHasSource, DefWithBodyId, HasSource, AdtId, AssocItemId, AssocItemLoc, DefHasSource, DefWithBodyId, HasSource, HirFileId, ImplId,
HirFileId, ImplId, InFile, ItemLoc, ItemTreeNode, Lookup, MacroDef, Module, ModuleDefId, InFile, ItemContainerId, ItemLoc, ItemTreeNode, Lookup, MacroDef, Module, ModuleDefId,
ModuleId, Semantics, TraitId, ModuleId, Semantics, TraitId,
}; };
use rayon::prelude::*; use rayon::prelude::*;
@ -508,7 +508,7 @@ impl<'a> SymbolCollector<'a> {
self.collect_from_body(id); self.collect_from_body(id);
} }
ModuleDefId::StaticId(id) => { ModuleDefId::StaticId(id) => {
self.push_decl(id, FileSymbolKind::Static); self.push_decl_assoc(id, FileSymbolKind::Static);
self.collect_from_body(id); self.collect_from_body(id);
} }
ModuleDefId::TraitId(id) => { ModuleDefId::TraitId(id) => {
@ -610,17 +610,17 @@ impl<'a> SymbolCollector<'a> {
T: ItemTreeNode, T: ItemTreeNode,
<T as ItemTreeNode>::Source: HasName, <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 { match container {
AssocContainerId::ModuleId(module_id) => { ItemContainerId::ModuleId(module_id) => {
let module = Module::from(module_id); let module = Module::from(module_id);
module.name(db).and_then(|name| name.as_text()) 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); let trait_data = db.trait_data(trait_id);
trait_data.name.as_text() trait_data.name.as_text()
} }
AssocContainerId::ImplId(_) => None, ItemContainerId::ImplId(_) | ItemContainerId::ExternBlockId(_) => None,
} }
} }

View file

@ -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] #[test]
fn bug_traits_arent_checked() { fn bug_traits_arent_checked() {
// FIXME: Traits and functions in traits aren't currently checked by // FIXME: Traits and functions in traits aren't currently checked by