mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 12:54:58 +00:00
Treat extern blocks as item containers
This commit is contained in:
parent
b7afb6fc6c
commit
b365b6119c
26 changed files with 216 additions and 164 deletions
|
@ -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,
|
||||||
|
|
|
@ -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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) => {
|
||||||
|
|
|
@ -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() -> ();
|
||||||
}
|
}
|
||||||
"##]],
|
"##]],
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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_);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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_);
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue