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 <jonas.schievink@ferrous-systems.com>
This commit is contained in:
commit
755b668ae4
@ -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,
|
||||
|
@ -114,11 +114,11 @@
|
||||
type_ref::{Mutability, TypeRef},
|
||||
visibility::Visibility,
|
||||
AdtId,
|
||||
AssocContainerId,
|
||||
AssocItemId,
|
||||
AssocItemLoc,
|
||||
DefWithBodyId,
|
||||
ImplId,
|
||||
ItemContainerId,
|
||||
ItemLoc,
|
||||
Lookup,
|
||||
ModuleDefId,
|
||||
@ -1550,7 +1550,7 @@ pub fn value(self, db: &dyn HirDatabase) -> Option<ast::Expr> {
|
||||
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 @@ fn as_assoc_item<ID, DEF, CTOR, AST>(db: &dyn HirDatabase, ctor: CTOR, id: ID) -
|
||||
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 @@ pub fn container(self, db: &dyn HirDatabase) -> AssocItemContainer {
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -362,6 +362,7 @@ pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Self {
|
||||
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 @@ pub fn source_map(&self, db: &dyn DefDatabase) -> AttrSourceMap {
|
||||
.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))
|
||||
|
@ -13,8 +13,8 @@
|
||||
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 @@ pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc<Funct
|
||||
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 @@ pub(crate) fn type_alias_data_query(
|
||||
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 @@ pub(crate) fn trait_data_query(db: &dyn DefDatabase, tr: TraitId) -> Arc<TraitDa
|
||||
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 @@ pub(crate) fn impl_data_query(db: &dyn DefDatabase, id: ImplId) -> Arc<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 {
|
||||
|
@ -19,10 +19,10 @@
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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 @@ fn assoc_to_trait(db: &dyn DefDatabase, item: ItemInNs) -> Option<ItemInNs> {
|
||||
};
|
||||
|
||||
match container {
|
||||
AssocContainerId::TraitId(it) => Some(ItemInNs::Types(it.into())),
|
||||
ItemContainerId::TraitId(it) => Some(ItemInNs::Types(it.into())),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -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>,
|
||||
}
|
||||
|
||||
|
@ -360,7 +360,6 @@ fn lower_type_alias(
|
||||
generic_params,
|
||||
type_ref,
|
||||
ast_id,
|
||||
is_extern: false,
|
||||
};
|
||||
Some(id(self.data().type_aliases.alloc(res)))
|
||||
}
|
||||
@ -371,7 +370,7 @@ fn lower_static(&mut self, static_: &ast::Static) -> Option<FileItemTreeId<Stati
|
||||
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 @@ fn lower_extern_block(&mut self, block: &ast::ExternBlock) -> FileItemTreeId<Ext
|
||||
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
|
||||
|
@ -328,8 +328,7 @@ fn print_mod_item(&mut self, item: ModItem) {
|
||||
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 @@ fn print_mod_item(&mut self, item: ModItem) {
|
||||
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 @@ fn print_mod_item(&mut self, item: ModItem) {
|
||||
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 @@ fn print_mod_item(&mut self, item: ModItem) {
|
||||
}
|
||||
self.print_where_clause(generic_params);
|
||||
w!(self, ";");
|
||||
if *is_extern {
|
||||
w!(self, " // extern");
|
||||
}
|
||||
wln!(self);
|
||||
}
|
||||
ModItem::Mod(it) => {
|
||||
|
@ -70,13 +70,13 @@ fn extern_blocks() {
|
||||
#[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() -> ();
|
||||
}
|
||||
"##]],
|
||||
|
@ -65,6 +65,7 @@ macro_rules! eprintln {
|
||||
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 @@ fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AssocItemLoc<N: ItemTreeNode> {
|
||||
pub container: AssocContainerId,
|
||||
pub container: ItemContainerId,
|
||||
pub id: ItemTreeId<N>,
|
||||
}
|
||||
|
||||
@ -244,7 +245,7 @@ pub struct FieldId {
|
||||
|
||||
#[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)]
|
||||
@ -262,6 +263,11 @@ pub struct FieldId {
|
||||
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)]
|
||||
@ -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 @@ pub enum AttrDefId {
|
||||
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 @@ fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ pub fn module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId> {
|
||||
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 @@ pub fn krate(&self, db: &dyn db::DefDatabase) -> CrateId {
|
||||
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,
|
||||
|
@ -44,9 +44,9 @@
|
||||
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 @@ fn seed_with_top_level(&mut self) {
|
||||
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 @@ fn seed_with_inner(&mut self, tree_id: TreeId) {
|
||||
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 @@ fn reseed_with_unresolved_attribute(&mut self) -> ReachedFixedPoint {
|
||||
item_tree: &item_tree,
|
||||
mod_dir,
|
||||
}
|
||||
.collect(&[*mod_item]);
|
||||
.collect(&[*mod_item], directive.container);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
@ -1053,7 +1054,12 @@ fn resolve_macros(&mut self) -> ReachedFixedPoint {
|
||||
&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 @@ fn resolve_macros(&mut self) -> ReachedFixedPoint {
|
||||
*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 @@ fn resolve_macros(&mut self) -> ReachedFixedPoint {
|
||||
item_tree: &item_tree,
|
||||
mod_dir,
|
||||
}
|
||||
.collect(&[*mod_item]);
|
||||
.collect(&[*mod_item], directive.container);
|
||||
res = ReachedFixedPoint::No;
|
||||
false
|
||||
};
|
||||
@ -1144,6 +1155,7 @@ fn resolve_macros(&mut self) -> ReachedFixedPoint {
|
||||
ast_id,
|
||||
derive_attr: attr.id,
|
||||
},
|
||||
container: directive.container,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1199,7 +1211,12 @@ fn resolve_macros(&mut self) -> ReachedFixedPoint {
|
||||
.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 @@ fn resolve_macros(&mut self) -> ReachedFixedPoint {
|
||||
// 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 @@ fn collect_macro_expansion(
|
||||
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 @@ fn collect_macro_expansion(
|
||||
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 @@ struct DefData<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ struct DefData<'a> {
|
||||
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 @@ struct DefData<'a> {
|
||||
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 @@ struct DefData<'a> {
|
||||
}
|
||||
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 @@ struct DefData<'a> {
|
||||
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 @@ struct DefData<'a> {
|
||||
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 @@ fn collect_module(&mut self, module: &Mod, attrs: &Attrs) {
|
||||
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 @@ fn collect_module(&mut self, module: &Mod, attrs: &Attrs) {
|
||||
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 @@ fn push_child_module(
|
||||
///
|
||||
/// 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 @@ fn resolve_attributes(&mut self, attrs: &Attrs, mod_item: ModItem) -> Result<(),
|
||||
mod_item,
|
||||
tree: self.tree_id,
|
||||
},
|
||||
container,
|
||||
});
|
||||
|
||||
return Err(());
|
||||
@ -1951,7 +1980,7 @@ fn collect_macro_def(&mut self, id: FileItemTreeId<MacroDef>) {
|
||||
);
|
||||
}
|
||||
|
||||
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 @@ fn collect_macro_call(&mut self, mac: &MacroCall) {
|
||||
self.module_id,
|
||||
macro_call_id,
|
||||
self.macro_depth + 1,
|
||||
container,
|
||||
);
|
||||
|
||||
if let Some(err) = error {
|
||||
@ -2011,6 +2041,7 @@ fn collect_macro_call(&mut self, mac: &MacroCall) {
|
||||
module_id: self.module_id,
|
||||
depth: self.macro_depth + 1,
|
||||
kind: MacroDirectiveKind::FnLike { ast_id, expand_to: mac.expand_to },
|
||||
container,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -22,8 +22,8 @@
|
||||
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 @@ fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||
}
|
||||
}
|
||||
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
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"),
|
||||
};
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
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 @@ fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId>
|
||||
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 @@ fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId>
|
||||
.lookup(db.upcast())
|
||||
.container
|
||||
{
|
||||
AssocContainerId::TraitId(trait_id) => Some(trait_id),
|
||||
ItemContainerId::TraitId(trait_id) => Some(trait_id),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -331,7 +331,7 @@ fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef {
|
||||
|
||||
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"),
|
||||
}
|
||||
}
|
||||
|
@ -178,6 +178,7 @@ fn allowed(&self, id: AttrDefId, allow_name: &str, recursing: bool) -> bool {
|
||||
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
|
||||
|
@ -16,7 +16,7 @@
|
||||
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 @@ fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
|
||||
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_);
|
||||
|
@ -521,7 +521,7 @@ fn resolve_associated_type_with_params(
|
||||
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();
|
||||
|
@ -14,7 +14,7 @@
|
||||
},
|
||||
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 @@ fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
|
||||
// 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,
|
||||
|
@ -6,7 +6,7 @@
|
||||
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 @@ fn resolve_ty_assoc_item(
|
||||
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 @@ fn resolve_ty_assoc_item(
|
||||
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 @@ fn resolve_ty_assoc_item(
|
||||
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);
|
||||
|
@ -19,8 +19,8 @@
|
||||
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)
|
||||
|
@ -8,8 +8,8 @@
|
||||
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))
|
||||
|
@ -7,7 +7,7 @@
|
||||
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 @@ pub(crate) fn debug_assoc_type_id(
|
||||
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 @@ pub(crate) fn debug_projection_ty(
|
||||
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_);
|
||||
|
@ -14,7 +14,7 @@
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
@ -36,8 +36,8 @@
|
||||
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 @@ fn collect_from_module(&mut self, module_id: ModuleId) {
|
||||
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 @@ fn push_decl_assoc<L, T>(&mut self, id: L, kind: FileSymbolKind)
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -397,6 +397,24 @@ fn ignores_extern_items() {
|
||||
);
|
||||
}
|
||||
|
||||
#[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
|
||||
|
Loading…
Reference in New Issue
Block a user