mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 12:29:21 +00:00
Merge commit 'ddf105b646
' into sync-from-ra
This commit is contained in:
parent
0816d49d83
commit
e41ab350d6
378 changed files with 14720 additions and 3111 deletions
|
@ -24,11 +24,11 @@ use triomphe::Arc;
|
|||
|
||||
use crate::{
|
||||
db::DefDatabase,
|
||||
item_tree::{AttrOwner, Fields, ItemTreeId, ItemTreeModItemNode},
|
||||
item_tree::{AttrOwner, Fields, ItemTreeNode},
|
||||
lang_item::LangItem,
|
||||
nameres::{ModuleOrigin, ModuleSource},
|
||||
src::{HasChildSource, HasSource},
|
||||
AdtId, AssocItemLoc, AttrDefId, GenericParamId, ItemLoc, LocalFieldId, Lookup, MacroId,
|
||||
AdtId, AttrDefId, GenericParamId, HasModule, ItemTreeLoc, LocalFieldId, Lookup, MacroId,
|
||||
VariantId,
|
||||
};
|
||||
|
||||
|
@ -317,7 +317,7 @@ fn parse_comma_sep<S>(subtree: &tt::Subtree<S>) -> Vec<SmolStr> {
|
|||
}
|
||||
|
||||
impl AttrsWithOwner {
|
||||
pub fn attrs_with_owner(db: &dyn DefDatabase, owner: AttrDefId) -> Self {
|
||||
pub fn new(db: &dyn DefDatabase, owner: AttrDefId) -> Self {
|
||||
Self { attrs: db.attrs(owner), owner }
|
||||
}
|
||||
|
||||
|
@ -356,12 +356,7 @@ impl AttrsWithOwner {
|
|||
AttrDefId::FieldId(it) => {
|
||||
return db.fields_attrs(it.parent)[it.local_id].clone();
|
||||
}
|
||||
// FIXME: DRY this up
|
||||
AttrDefId::EnumVariantId(it) => {
|
||||
let id = it.lookup(db).id;
|
||||
let tree = id.item_tree(db);
|
||||
tree.raw_attrs(id.value.into()).clone()
|
||||
}
|
||||
AttrDefId::EnumVariantId(it) => attrs_from_item_tree_loc(db, it),
|
||||
AttrDefId::AdtId(it) => match it {
|
||||
AdtId::StructId(it) => attrs_from_item_tree_loc(db, it),
|
||||
AdtId::EnumId(it) => attrs_from_item_tree_loc(db, it),
|
||||
|
@ -370,15 +365,15 @@ impl AttrsWithOwner {
|
|||
AttrDefId::TraitId(it) => attrs_from_item_tree_loc(db, it),
|
||||
AttrDefId::TraitAliasId(it) => attrs_from_item_tree_loc(db, it),
|
||||
AttrDefId::MacroId(it) => match it {
|
||||
MacroId::Macro2Id(it) => attrs_from_item_tree(db, it.lookup(db).id),
|
||||
MacroId::MacroRulesId(it) => attrs_from_item_tree(db, it.lookup(db).id),
|
||||
MacroId::ProcMacroId(it) => attrs_from_item_tree(db, it.lookup(db).id),
|
||||
MacroId::Macro2Id(it) => attrs_from_item_tree_loc(db, it),
|
||||
MacroId::MacroRulesId(it) => attrs_from_item_tree_loc(db, it),
|
||||
MacroId::ProcMacroId(it) => attrs_from_item_tree_loc(db, it),
|
||||
},
|
||||
AttrDefId::ImplId(it) => attrs_from_item_tree_loc(db, it),
|
||||
AttrDefId::ConstId(it) => attrs_from_item_tree_assoc(db, it),
|
||||
AttrDefId::StaticId(it) => attrs_from_item_tree_assoc(db, it),
|
||||
AttrDefId::FunctionId(it) => attrs_from_item_tree_assoc(db, it),
|
||||
AttrDefId::TypeAliasId(it) => attrs_from_item_tree_assoc(db, it),
|
||||
AttrDefId::ConstId(it) => attrs_from_item_tree_loc(db, it),
|
||||
AttrDefId::StaticId(it) => attrs_from_item_tree_loc(db, it),
|
||||
AttrDefId::FunctionId(it) => attrs_from_item_tree_loc(db, it),
|
||||
AttrDefId::TypeAliasId(it) => attrs_from_item_tree_loc(db, it),
|
||||
AttrDefId::GenericParamId(it) => match it {
|
||||
GenericParamId::ConstParamId(it) => {
|
||||
let src = it.parent().child_source(db);
|
||||
|
@ -603,29 +598,14 @@ fn any_has_attrs<'db>(
|
|||
id.lookup(db).source(db).map(ast::AnyHasAttrs::new)
|
||||
}
|
||||
|
||||
fn attrs_from_item_tree<N: ItemTreeModItemNode>(
|
||||
db: &dyn DefDatabase,
|
||||
id: ItemTreeId<N>,
|
||||
fn attrs_from_item_tree_loc<'db, N: ItemTreeNode>(
|
||||
db: &(dyn DefDatabase + 'db),
|
||||
lookup: impl Lookup<Database<'db> = dyn DefDatabase + 'db, Data = impl ItemTreeLoc<Id = N>>,
|
||||
) -> RawAttrs {
|
||||
let id = lookup.lookup(db).item_tree_id();
|
||||
let tree = id.item_tree(db);
|
||||
let mod_item = N::id_to_mod_item(id.value);
|
||||
tree.raw_attrs(mod_item.into()).clone()
|
||||
}
|
||||
|
||||
fn attrs_from_item_tree_loc<'db, N: ItemTreeModItemNode>(
|
||||
db: &(dyn DefDatabase + 'db),
|
||||
lookup: impl Lookup<Database<'db> = dyn DefDatabase + 'db, Data = ItemLoc<N>>,
|
||||
) -> RawAttrs {
|
||||
let id = lookup.lookup(db).id;
|
||||
attrs_from_item_tree(db, id)
|
||||
}
|
||||
|
||||
fn attrs_from_item_tree_assoc<'db, N: ItemTreeModItemNode>(
|
||||
db: &(dyn DefDatabase + 'db),
|
||||
lookup: impl Lookup<Database<'db> = dyn DefDatabase + 'db, Data = AssocItemLoc<N>>,
|
||||
) -> RawAttrs {
|
||||
let id = lookup.lookup(db).id;
|
||||
attrs_from_item_tree(db, id)
|
||||
let attr_owner = N::attr_owner(id.value);
|
||||
tree.raw_attrs(attr_owner).clone()
|
||||
}
|
||||
|
||||
pub(crate) fn fields_attrs_source_map(
|
||||
|
|
|
@ -283,9 +283,6 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||
experimental!(optimize),
|
||||
),
|
||||
|
||||
gated!(
|
||||
ffi_returns_twice, Normal, template!(Word), WarnFollowing, experimental!(ffi_returns_twice)
|
||||
),
|
||||
gated!(ffi_pure, Normal, template!(Word), WarnFollowing, experimental!(ffi_pure)),
|
||||
gated!(ffi_const, Normal, template!(Word), WarnFollowing, experimental!(ffi_const)),
|
||||
gated!(
|
||||
|
|
|
@ -1980,10 +1980,7 @@ fn pat_literal_to_hir(lit: &ast::LiteralPat) -> Option<(Literal, ast::Literal)>
|
|||
let ast_lit = lit.literal()?;
|
||||
let mut hir_lit: Literal = ast_lit.kind().into();
|
||||
if lit.minus_token().is_some() {
|
||||
let Some(h) = hir_lit.negate() else {
|
||||
return None;
|
||||
};
|
||||
hir_lit = h;
|
||||
hir_lit = hir_lit.negate()?;
|
||||
}
|
||||
Some((hir_lit, ast_lit))
|
||||
}
|
||||
|
|
|
@ -29,11 +29,11 @@ pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBo
|
|||
"const {} = ",
|
||||
match &it.name {
|
||||
Some(name) => name.display(db.upcast()).to_string(),
|
||||
None => "_".to_string(),
|
||||
None => "_".to_owned(),
|
||||
}
|
||||
)
|
||||
}),
|
||||
DefWithBodyId::InTypeConstId(_) => "In type const = ".to_string(),
|
||||
DefWithBodyId::InTypeConstId(_) => "In type const = ".to_owned(),
|
||||
DefWithBodyId::VariantId(it) => {
|
||||
let loc = it.lookup(db);
|
||||
let enum_loc = loc.parent.lookup(db);
|
||||
|
@ -123,7 +123,7 @@ impl Printer<'_> {
|
|||
wln!(self);
|
||||
f(self);
|
||||
self.indent_level -= 1;
|
||||
self.buf = self.buf.trim_end_matches('\n').to_string();
|
||||
self.buf = self.buf.trim_end_matches('\n').to_owned();
|
||||
}
|
||||
|
||||
fn whitespace(&mut self) {
|
||||
|
|
|
@ -6,15 +6,21 @@
|
|||
|
||||
use either::Either;
|
||||
use hir_expand::{attrs::collect_attrs, HirFileId};
|
||||
use syntax::ast;
|
||||
|
||||
use crate::{
|
||||
db::DefDatabase,
|
||||
dyn_map::{keys, DynMap},
|
||||
dyn_map::{
|
||||
keys::{self, Key},
|
||||
DynMap,
|
||||
},
|
||||
item_scope::ItemScope,
|
||||
item_tree::ItemTreeNode,
|
||||
nameres::DefMap,
|
||||
src::{HasChildSource, HasSource},
|
||||
AdtId, AssocItemId, DefWithBodyId, EnumId, ExternCrateId, FieldId, ImplId, Lookup, MacroId,
|
||||
ModuleDefId, ModuleId, TraitId, UseId, VariantId,
|
||||
AdtId, AssocItemId, DefWithBodyId, EnumId, FieldId, GenericDefId, ImplId, ItemTreeLoc,
|
||||
LifetimeParamId, Lookup, MacroId, ModuleDefId, ModuleId, TraitId, TypeOrConstParamId,
|
||||
VariantId,
|
||||
};
|
||||
|
||||
pub trait ChildBySource {
|
||||
|
@ -55,29 +61,6 @@ impl ChildBySource for ImplId {
|
|||
}
|
||||
}
|
||||
|
||||
fn add_assoc_item(db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId, item: AssocItemId) {
|
||||
match item {
|
||||
AssocItemId::FunctionId(func) => {
|
||||
let loc = func.lookup(db);
|
||||
if loc.id.file_id() == file_id {
|
||||
res[keys::FUNCTION].insert(loc.source(db).value, func)
|
||||
}
|
||||
}
|
||||
AssocItemId::ConstId(konst) => {
|
||||
let loc = konst.lookup(db);
|
||||
if loc.id.file_id() == file_id {
|
||||
res[keys::CONST].insert(loc.source(db).value, konst)
|
||||
}
|
||||
}
|
||||
AssocItemId::TypeAliasId(ty) => {
|
||||
let loc = ty.lookup(db);
|
||||
if loc.id.file_id() == file_id {
|
||||
res[keys::TYPE_ALIAS].insert(loc.source(db).value, ty)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ChildBySource for ModuleId {
|
||||
fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
|
||||
let def_map = self.def_map(db);
|
||||
|
@ -89,15 +72,12 @@ impl ChildBySource for ModuleId {
|
|||
impl ChildBySource for ItemScope {
|
||||
fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
|
||||
self.declarations().for_each(|item| add_module_def(db, res, file_id, item));
|
||||
self.impls().for_each(|imp| add_impl(db, res, file_id, imp));
|
||||
self.extern_crate_decls().for_each(|ext| add_extern_crate(db, res, file_id, ext));
|
||||
self.use_decls().for_each(|ext| add_use(db, res, file_id, ext));
|
||||
self.unnamed_consts(db).for_each(|konst| {
|
||||
let loc = konst.lookup(db);
|
||||
if loc.id.file_id() == file_id {
|
||||
res[keys::CONST].insert(loc.source(db).value, konst);
|
||||
}
|
||||
});
|
||||
self.impls().for_each(|imp| insert_item_loc(db, res, file_id, imp, keys::IMPL));
|
||||
self.extern_crate_decls()
|
||||
.for_each(|ext| insert_item_loc(db, res, file_id, ext, keys::EXTERN_CRATE));
|
||||
self.use_decls().for_each(|ext| insert_item_loc(db, res, file_id, ext, keys::USE));
|
||||
self.unnamed_consts(db)
|
||||
.for_each(|konst| insert_item_loc(db, res, file_id, konst, keys::CONST));
|
||||
self.attr_macro_invocs().filter(|(id, _)| id.file_id == file_id).for_each(
|
||||
|(ast_id, call_id)| {
|
||||
res[keys::ATTR_MACRO_CALL].insert(ast_id.to_node(db.upcast()), call_id);
|
||||
|
@ -132,59 +112,38 @@ impl ChildBySource for ItemScope {
|
|||
file_id: HirFileId,
|
||||
item: ModuleDefId,
|
||||
) {
|
||||
macro_rules! insert {
|
||||
($map:ident[$key:path].$insert:ident($id:ident)) => {{
|
||||
let loc = $id.lookup(db);
|
||||
if loc.id.file_id() == file_id {
|
||||
$map[$key].$insert(loc.source(db).value, $id)
|
||||
}
|
||||
}};
|
||||
}
|
||||
match item {
|
||||
ModuleDefId::FunctionId(id) => insert!(map[keys::FUNCTION].insert(id)),
|
||||
ModuleDefId::ConstId(id) => insert!(map[keys::CONST].insert(id)),
|
||||
ModuleDefId::StaticId(id) => insert!(map[keys::STATIC].insert(id)),
|
||||
ModuleDefId::TypeAliasId(id) => insert!(map[keys::TYPE_ALIAS].insert(id)),
|
||||
ModuleDefId::TraitId(id) => insert!(map[keys::TRAIT].insert(id)),
|
||||
ModuleDefId::TraitAliasId(id) => insert!(map[keys::TRAIT_ALIAS].insert(id)),
|
||||
ModuleDefId::FunctionId(id) => {
|
||||
insert_item_loc(db, map, file_id, id, keys::FUNCTION)
|
||||
}
|
||||
ModuleDefId::ConstId(id) => insert_item_loc(db, map, file_id, id, keys::CONST),
|
||||
ModuleDefId::TypeAliasId(id) => {
|
||||
insert_item_loc(db, map, file_id, id, keys::TYPE_ALIAS)
|
||||
}
|
||||
ModuleDefId::StaticId(id) => insert_item_loc(db, map, file_id, id, keys::STATIC),
|
||||
ModuleDefId::TraitId(id) => insert_item_loc(db, map, file_id, id, keys::TRAIT),
|
||||
ModuleDefId::TraitAliasId(id) => {
|
||||
insert_item_loc(db, map, file_id, id, keys::TRAIT_ALIAS)
|
||||
}
|
||||
ModuleDefId::AdtId(adt) => match adt {
|
||||
AdtId::StructId(id) => insert!(map[keys::STRUCT].insert(id)),
|
||||
AdtId::UnionId(id) => insert!(map[keys::UNION].insert(id)),
|
||||
AdtId::EnumId(id) => insert!(map[keys::ENUM].insert(id)),
|
||||
AdtId::StructId(id) => insert_item_loc(db, map, file_id, id, keys::STRUCT),
|
||||
AdtId::UnionId(id) => insert_item_loc(db, map, file_id, id, keys::UNION),
|
||||
AdtId::EnumId(id) => insert_item_loc(db, map, file_id, id, keys::ENUM),
|
||||
},
|
||||
ModuleDefId::MacroId(id) => match id {
|
||||
MacroId::Macro2Id(id) => insert!(map[keys::MACRO2].insert(id)),
|
||||
MacroId::MacroRulesId(id) => insert!(map[keys::MACRO_RULES].insert(id)),
|
||||
MacroId::ProcMacroId(id) => insert!(map[keys::PROC_MACRO].insert(id)),
|
||||
MacroId::Macro2Id(id) => insert_item_loc(db, map, file_id, id, keys::MACRO2),
|
||||
MacroId::MacroRulesId(id) => {
|
||||
insert_item_loc(db, map, file_id, id, keys::MACRO_RULES)
|
||||
}
|
||||
MacroId::ProcMacroId(id) => {
|
||||
insert_item_loc(db, map, file_id, id, keys::PROC_MACRO)
|
||||
}
|
||||
},
|
||||
ModuleDefId::ModuleId(_)
|
||||
| ModuleDefId::EnumVariantId(_)
|
||||
| ModuleDefId::BuiltinType(_) => (),
|
||||
}
|
||||
}
|
||||
fn add_impl(db: &dyn DefDatabase, map: &mut DynMap, file_id: HirFileId, imp: ImplId) {
|
||||
let loc = imp.lookup(db);
|
||||
if loc.id.file_id() == file_id {
|
||||
map[keys::IMPL].insert(loc.source(db).value, imp)
|
||||
}
|
||||
}
|
||||
fn add_extern_crate(
|
||||
db: &dyn DefDatabase,
|
||||
map: &mut DynMap,
|
||||
file_id: HirFileId,
|
||||
ext: ExternCrateId,
|
||||
) {
|
||||
let loc = ext.lookup(db);
|
||||
if loc.id.file_id() == file_id {
|
||||
map[keys::EXTERN_CRATE].insert(loc.source(db).value, ext)
|
||||
}
|
||||
}
|
||||
fn add_use(db: &dyn DefDatabase, map: &mut DynMap, file_id: HirFileId, ext: UseId) {
|
||||
let loc = ext.lookup(db);
|
||||
if loc.id.file_id() == file_id {
|
||||
map[keys::USE].insert(loc.source(db).value, ext)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -237,3 +196,63 @@ impl ChildBySource for DefWithBodyId {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ChildBySource for GenericDefId {
|
||||
fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
|
||||
let (gfile_id, generic_params_list) = self.file_id_and_params_of(db);
|
||||
if gfile_id != file_id {
|
||||
return;
|
||||
}
|
||||
|
||||
let generic_params = db.generic_params(*self);
|
||||
let mut toc_idx_iter = generic_params.type_or_consts.iter().map(|(idx, _)| idx);
|
||||
let lts_idx_iter = generic_params.lifetimes.iter().map(|(idx, _)| idx);
|
||||
|
||||
// For traits the first type index is `Self`, skip it.
|
||||
if let GenericDefId::TraitId(_) = *self {
|
||||
toc_idx_iter.next().unwrap(); // advance_by(1);
|
||||
}
|
||||
|
||||
if let Some(generic_params_list) = generic_params_list {
|
||||
for (local_id, ast_param) in
|
||||
toc_idx_iter.zip(generic_params_list.type_or_const_params())
|
||||
{
|
||||
let id = TypeOrConstParamId { parent: *self, local_id };
|
||||
match ast_param {
|
||||
ast::TypeOrConstParam::Type(a) => res[keys::TYPE_PARAM].insert(a, id),
|
||||
ast::TypeOrConstParam::Const(a) => res[keys::CONST_PARAM].insert(a, id),
|
||||
}
|
||||
}
|
||||
for (local_id, ast_param) in lts_idx_iter.zip(generic_params_list.lifetime_params()) {
|
||||
let id = LifetimeParamId { parent: *self, local_id };
|
||||
res[keys::LIFETIME_PARAM].insert(ast_param, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn insert_item_loc<ID, N, Data>(
|
||||
db: &dyn DefDatabase,
|
||||
res: &mut DynMap,
|
||||
file_id: HirFileId,
|
||||
id: ID,
|
||||
key: Key<N::Source, ID>,
|
||||
) where
|
||||
ID: for<'db> Lookup<Database<'db> = dyn DefDatabase + 'db, Data = Data> + 'static,
|
||||
Data: ItemTreeLoc<Id = N>,
|
||||
N: ItemTreeNode,
|
||||
N::Source: 'static,
|
||||
{
|
||||
let loc = id.lookup(db);
|
||||
if loc.item_tree_id().file_id() == file_id {
|
||||
res[key].insert(loc.source(db).value, id)
|
||||
}
|
||||
}
|
||||
|
||||
fn add_assoc_item(db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId, item: AssocItemId) {
|
||||
match item {
|
||||
AssocItemId::FunctionId(func) => insert_item_loc(db, res, file_id, func, keys::FUNCTION),
|
||||
AssocItemId::ConstId(konst) => insert_item_loc(db, res, file_id, konst, keys::CONST),
|
||||
AssocItemId::TypeAliasId(ty) => insert_item_loc(db, res, file_id, ty, keys::TYPE_ALIAS),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use hir_expand::{
|
|||
HirFileId, InFile,
|
||||
};
|
||||
use intern::Interned;
|
||||
use la_arena::{Arena, ArenaMap};
|
||||
use la_arena::Arena;
|
||||
use rustc_abi::{Align, Integer, IntegerType, ReprFlags, ReprOptions};
|
||||
use syntax::ast::{self, HasName, HasVisibility};
|
||||
use triomphe::Arc;
|
||||
|
@ -22,13 +22,11 @@ use crate::{
|
|||
lang_item::LangItem,
|
||||
lower::LowerCtx,
|
||||
nameres::diagnostics::{DefDiagnostic, DefDiagnostics},
|
||||
src::HasChildSource,
|
||||
src::HasSource,
|
||||
trace::Trace,
|
||||
tt::{Delimiter, DelimiterKind, Leaf, Subtree, TokenTree},
|
||||
type_ref::TypeRef,
|
||||
visibility::RawVisibility,
|
||||
EnumId, EnumVariantId, LocalFieldId, LocalModuleId, Lookup, StructId, UnionId, VariantId,
|
||||
EnumId, EnumVariantId, LocalFieldId, LocalModuleId, Lookup, StructId, UnionId,
|
||||
};
|
||||
|
||||
/// Note that we use `StructData` for unions as well!
|
||||
|
@ -387,46 +385,6 @@ impl VariantData {
|
|||
}
|
||||
}
|
||||
|
||||
impl HasChildSource<LocalFieldId> for VariantId {
|
||||
type Value = Either<ast::TupleField, ast::RecordField>;
|
||||
|
||||
fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<LocalFieldId, Self::Value>> {
|
||||
let item_tree;
|
||||
let (src, fields, container) = match *self {
|
||||
VariantId::EnumVariantId(it) => {
|
||||
let lookup = it.lookup(db);
|
||||
item_tree = lookup.id.item_tree(db);
|
||||
(
|
||||
lookup.source(db).map(|it| it.kind()),
|
||||
&item_tree[lookup.id.value].fields,
|
||||
lookup.parent.lookup(db).container,
|
||||
)
|
||||
}
|
||||
VariantId::StructId(it) => {
|
||||
let lookup = it.lookup(db);
|
||||
item_tree = lookup.id.item_tree(db);
|
||||
(
|
||||
lookup.source(db).map(|it| it.kind()),
|
||||
&item_tree[lookup.id.value].fields,
|
||||
lookup.container,
|
||||
)
|
||||
}
|
||||
VariantId::UnionId(it) => {
|
||||
let lookup = it.lookup(db);
|
||||
item_tree = lookup.id.item_tree(db);
|
||||
(
|
||||
lookup.source(db).map(|it| it.kind()),
|
||||
&item_tree[lookup.id.value].fields,
|
||||
lookup.container,
|
||||
)
|
||||
}
|
||||
};
|
||||
let mut trace = Trace::new_for_map();
|
||||
lower_struct(db, &mut trace, &src, container.krate, &item_tree, fields);
|
||||
src.with_value(trace.into_map())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum StructKind {
|
||||
Tuple,
|
||||
|
@ -434,7 +392,7 @@ pub enum StructKind {
|
|||
Unit,
|
||||
}
|
||||
|
||||
fn lower_struct(
|
||||
pub(crate) fn lower_struct(
|
||||
db: &dyn DefDatabase,
|
||||
trace: &mut Trace<FieldData, Either<ast::TupleField, ast::RecordField>>,
|
||||
ast: &InFile<ast::StructKind>,
|
||||
|
|
|
@ -171,6 +171,7 @@ fn find_path_inner(ctx: FindPathCtx<'_>, item: ItemInNs, from: ModuleId) -> Opti
|
|||
.map(|(item, _)| item)
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
fn find_path_for_module(
|
||||
ctx: FindPathCtx<'_>,
|
||||
def_map: &DefMap,
|
||||
|
@ -312,6 +313,7 @@ fn find_self_super(def_map: &DefMap, item: ModuleId, from: ModuleId) -> Option<M
|
|||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
fn calculate_best_path(
|
||||
ctx: FindPathCtx<'_>,
|
||||
def_map: &DefMap,
|
||||
|
|
|
@ -3,31 +3,27 @@
|
|||
//! generic parameters. See also the `Generics` type and the `generics_of` query
|
||||
//! in rustc.
|
||||
|
||||
use base_db::FileId;
|
||||
use either::Either;
|
||||
use hir_expand::{
|
||||
name::{AsName, Name},
|
||||
ExpandResult, HirFileId, InFile,
|
||||
ExpandResult,
|
||||
};
|
||||
use intern::Interned;
|
||||
use la_arena::{Arena, ArenaMap, Idx};
|
||||
use la_arena::{Arena, Idx};
|
||||
use once_cell::unsync::Lazy;
|
||||
use stdx::impl_from;
|
||||
use syntax::ast::{self, HasGenericParams, HasName, HasTypeBounds};
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
child_by_source::ChildBySource,
|
||||
db::DefDatabase,
|
||||
dyn_map::{keys, DynMap},
|
||||
expander::Expander,
|
||||
item_tree::ItemTree,
|
||||
item_tree::{GenericsItemTreeNode, ItemTree},
|
||||
lower::LowerCtx,
|
||||
nameres::{DefMap, MacroSubNs},
|
||||
src::{HasChildSource, HasSource},
|
||||
type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRef},
|
||||
AdtId, ConstParamId, GenericDefId, HasModule, LifetimeParamId, LocalLifetimeParamId,
|
||||
LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId,
|
||||
AdtId, ConstParamId, GenericDefId, HasModule, ItemTreeLoc, LocalTypeOrConstParamId, Lookup,
|
||||
TypeOrConstParamId, TypeParamId,
|
||||
};
|
||||
|
||||
/// Data about a generic type parameter (to a function, struct, impl, ...).
|
||||
|
@ -264,7 +260,7 @@ impl GenericParamsCollector {
|
|||
self.add_where_predicate_from_bound(
|
||||
lower_ctx,
|
||||
bound,
|
||||
lifetimes.as_ref(),
|
||||
lifetimes.as_deref(),
|
||||
target.clone(),
|
||||
);
|
||||
}
|
||||
|
@ -275,14 +271,14 @@ impl GenericParamsCollector {
|
|||
&mut self,
|
||||
lower_ctx: &LowerCtx<'_>,
|
||||
bound: ast::TypeBound,
|
||||
hrtb_lifetimes: Option<&Box<[Name]>>,
|
||||
hrtb_lifetimes: Option<&[Name]>,
|
||||
target: Either<TypeRef, LifetimeRef>,
|
||||
) {
|
||||
let bound = TypeBound::from_ast(lower_ctx, bound);
|
||||
let predicate = match (target, bound) {
|
||||
(Either::Left(type_ref), bound) => match hrtb_lifetimes {
|
||||
Some(hrtb_lifetimes) => WherePredicate::ForLifetime {
|
||||
lifetimes: hrtb_lifetimes.clone(),
|
||||
lifetimes: hrtb_lifetimes.to_vec().into_boxed_slice(),
|
||||
target: WherePredicateTypeTarget::TypeRef(Interned::new(type_ref)),
|
||||
bound: Interned::new(bound),
|
||||
},
|
||||
|
@ -418,13 +414,18 @@ impl GenericParams {
|
|||
})
|
||||
}
|
||||
};
|
||||
macro_rules! id_to_generics {
|
||||
($id:ident) => {{
|
||||
let id = $id.lookup(db).id;
|
||||
let tree = id.item_tree(db);
|
||||
let item = &tree[id.value];
|
||||
enabled_params(&item.generic_params, &tree)
|
||||
}};
|
||||
fn id_to_generics<Id: GenericsItemTreeNode>(
|
||||
db: &dyn DefDatabase,
|
||||
id: impl for<'db> Lookup<
|
||||
Database<'db> = dyn DefDatabase + 'db,
|
||||
Data = impl ItemTreeLoc<Id = Id>,
|
||||
>,
|
||||
enabled_params: impl Fn(&Interned<GenericParams>, &ItemTree) -> Interned<GenericParams>,
|
||||
) -> Interned<GenericParams> {
|
||||
let id = id.lookup(db).item_tree_id();
|
||||
let tree = id.item_tree(db);
|
||||
let item = &tree[id.value];
|
||||
enabled_params(item.generic_params(), &tree)
|
||||
}
|
||||
|
||||
match def {
|
||||
|
@ -457,13 +458,13 @@ impl GenericParams {
|
|||
Interned::new(generic_params.finish())
|
||||
}
|
||||
}
|
||||
GenericDefId::AdtId(AdtId::StructId(id)) => id_to_generics!(id),
|
||||
GenericDefId::AdtId(AdtId::EnumId(id)) => id_to_generics!(id),
|
||||
GenericDefId::AdtId(AdtId::UnionId(id)) => id_to_generics!(id),
|
||||
GenericDefId::TraitId(id) => id_to_generics!(id),
|
||||
GenericDefId::TraitAliasId(id) => id_to_generics!(id),
|
||||
GenericDefId::TypeAliasId(id) => id_to_generics!(id),
|
||||
GenericDefId::ImplId(id) => id_to_generics!(id),
|
||||
GenericDefId::AdtId(AdtId::StructId(id)) => id_to_generics(db, id, enabled_params),
|
||||
GenericDefId::AdtId(AdtId::EnumId(id)) => id_to_generics(db, id, enabled_params),
|
||||
GenericDefId::AdtId(AdtId::UnionId(id)) => id_to_generics(db, id, enabled_params),
|
||||
GenericDefId::TraitId(id) => id_to_generics(db, id, enabled_params),
|
||||
GenericDefId::TraitAliasId(id) => id_to_generics(db, id, enabled_params),
|
||||
GenericDefId::TypeAliasId(id) => id_to_generics(db, id, enabled_params),
|
||||
GenericDefId::ImplId(id) => id_to_generics(db, id, enabled_params),
|
||||
GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => {
|
||||
Interned::new(GenericParams {
|
||||
type_or_consts: Default::default(),
|
||||
|
@ -507,141 +508,3 @@ impl GenericParams {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn file_id_and_params_of(
|
||||
def: GenericDefId,
|
||||
db: &dyn DefDatabase,
|
||||
) -> (HirFileId, Option<ast::GenericParamList>) {
|
||||
match def {
|
||||
GenericDefId::FunctionId(it) => {
|
||||
let src = it.lookup(db).source(db);
|
||||
(src.file_id, src.value.generic_param_list())
|
||||
}
|
||||
GenericDefId::AdtId(AdtId::StructId(it)) => {
|
||||
let src = it.lookup(db).source(db);
|
||||
(src.file_id, src.value.generic_param_list())
|
||||
}
|
||||
GenericDefId::AdtId(AdtId::UnionId(it)) => {
|
||||
let src = it.lookup(db).source(db);
|
||||
(src.file_id, src.value.generic_param_list())
|
||||
}
|
||||
GenericDefId::AdtId(AdtId::EnumId(it)) => {
|
||||
let src = it.lookup(db).source(db);
|
||||
(src.file_id, src.value.generic_param_list())
|
||||
}
|
||||
GenericDefId::TraitId(it) => {
|
||||
let src = it.lookup(db).source(db);
|
||||
(src.file_id, src.value.generic_param_list())
|
||||
}
|
||||
GenericDefId::TraitAliasId(it) => {
|
||||
let src = it.lookup(db).source(db);
|
||||
(src.file_id, src.value.generic_param_list())
|
||||
}
|
||||
GenericDefId::TypeAliasId(it) => {
|
||||
let src = it.lookup(db).source(db);
|
||||
(src.file_id, src.value.generic_param_list())
|
||||
}
|
||||
GenericDefId::ImplId(it) => {
|
||||
let src = it.lookup(db).source(db);
|
||||
(src.file_id, src.value.generic_param_list())
|
||||
}
|
||||
// We won't be using this ID anyway
|
||||
GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => (FileId::BOGUS.into(), None),
|
||||
}
|
||||
}
|
||||
|
||||
impl HasChildSource<LocalTypeOrConstParamId> for GenericDefId {
|
||||
type Value = Either<ast::TypeOrConstParam, ast::TraitOrAlias>;
|
||||
fn child_source(
|
||||
&self,
|
||||
db: &dyn DefDatabase,
|
||||
) -> InFile<ArenaMap<LocalTypeOrConstParamId, Self::Value>> {
|
||||
let generic_params = db.generic_params(*self);
|
||||
let mut idx_iter = generic_params.type_or_consts.iter().map(|(idx, _)| idx);
|
||||
|
||||
let (file_id, generic_params_list) = file_id_and_params_of(*self, db);
|
||||
|
||||
let mut params = ArenaMap::default();
|
||||
|
||||
// For traits and trait aliases the first type index is `Self`, we need to add it before
|
||||
// the other params.
|
||||
match *self {
|
||||
GenericDefId::TraitId(id) => {
|
||||
let trait_ref = id.lookup(db).source(db).value;
|
||||
let idx = idx_iter.next().unwrap();
|
||||
params.insert(idx, Either::Right(ast::TraitOrAlias::Trait(trait_ref)));
|
||||
}
|
||||
GenericDefId::TraitAliasId(id) => {
|
||||
let alias = id.lookup(db).source(db).value;
|
||||
let idx = idx_iter.next().unwrap();
|
||||
params.insert(idx, Either::Right(ast::TraitOrAlias::TraitAlias(alias)));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if let Some(generic_params_list) = generic_params_list {
|
||||
for (idx, ast_param) in idx_iter.zip(generic_params_list.type_or_const_params()) {
|
||||
params.insert(idx, Either::Left(ast_param));
|
||||
}
|
||||
}
|
||||
|
||||
InFile::new(file_id, params)
|
||||
}
|
||||
}
|
||||
|
||||
impl HasChildSource<LocalLifetimeParamId> for GenericDefId {
|
||||
type Value = ast::LifetimeParam;
|
||||
fn child_source(
|
||||
&self,
|
||||
db: &dyn DefDatabase,
|
||||
) -> InFile<ArenaMap<LocalLifetimeParamId, Self::Value>> {
|
||||
let generic_params = db.generic_params(*self);
|
||||
let idx_iter = generic_params.lifetimes.iter().map(|(idx, _)| idx);
|
||||
|
||||
let (file_id, generic_params_list) = file_id_and_params_of(*self, db);
|
||||
|
||||
let mut params = ArenaMap::default();
|
||||
|
||||
if let Some(generic_params_list) = generic_params_list {
|
||||
for (idx, ast_param) in idx_iter.zip(generic_params_list.lifetime_params()) {
|
||||
params.insert(idx, ast_param);
|
||||
}
|
||||
}
|
||||
|
||||
InFile::new(file_id, params)
|
||||
}
|
||||
}
|
||||
|
||||
impl ChildBySource for GenericDefId {
|
||||
fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
|
||||
let (gfile_id, generic_params_list) = file_id_and_params_of(*self, db);
|
||||
if gfile_id != file_id {
|
||||
return;
|
||||
}
|
||||
|
||||
let generic_params = db.generic_params(*self);
|
||||
let mut toc_idx_iter = generic_params.type_or_consts.iter().map(|(idx, _)| idx);
|
||||
let lts_idx_iter = generic_params.lifetimes.iter().map(|(idx, _)| idx);
|
||||
|
||||
// For traits the first type index is `Self`, skip it.
|
||||
if let GenericDefId::TraitId(_) = *self {
|
||||
toc_idx_iter.next().unwrap(); // advance_by(1);
|
||||
}
|
||||
|
||||
if let Some(generic_params_list) = generic_params_list {
|
||||
for (local_id, ast_param) in
|
||||
toc_idx_iter.zip(generic_params_list.type_or_const_params())
|
||||
{
|
||||
let id = TypeOrConstParamId { parent: *self, local_id };
|
||||
match ast_param {
|
||||
ast::TypeOrConstParam::Type(a) => res[keys::TYPE_PARAM].insert(a, id),
|
||||
ast::TypeOrConstParam::Const(a) => res[keys::CONST_PARAM].insert(a, id),
|
||||
}
|
||||
}
|
||||
for (local_id, ast_param) in lts_idx_iter.zip(generic_params_list.lifetime_params()) {
|
||||
let id = LifetimeParamId { parent: *self, local_id };
|
||||
res[keys::LIFETIME_PARAM].insert(ast_param, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -859,7 +859,7 @@ mod tests {
|
|||
check_search(
|
||||
ra_fixture,
|
||||
"main",
|
||||
Query::new("fmt".to_string()).fuzzy(),
|
||||
Query::new("fmt".to_owned()).fuzzy(),
|
||||
expect![[r#"
|
||||
dep::fmt (t)
|
||||
dep::fmt::Display::FMT_CONST (a)
|
||||
|
@ -888,9 +888,7 @@ mod tests {
|
|||
check_search(
|
||||
ra_fixture,
|
||||
"main",
|
||||
Query::new("fmt".to_string())
|
||||
.fuzzy()
|
||||
.assoc_search_mode(AssocSearchMode::AssocItemsOnly),
|
||||
Query::new("fmt".to_owned()).fuzzy().assoc_search_mode(AssocSearchMode::AssocItemsOnly),
|
||||
expect![[r#"
|
||||
dep::fmt::Display::FMT_CONST (a)
|
||||
dep::fmt::Display::format_function (a)
|
||||
|
@ -901,7 +899,7 @@ mod tests {
|
|||
check_search(
|
||||
ra_fixture,
|
||||
"main",
|
||||
Query::new("fmt".to_string()).fuzzy().assoc_search_mode(AssocSearchMode::Exclude),
|
||||
Query::new("fmt".to_owned()).fuzzy().assoc_search_mode(AssocSearchMode::Exclude),
|
||||
expect![[r#"
|
||||
dep::fmt (t)
|
||||
"#]],
|
||||
|
@ -937,7 +935,7 @@ pub mod fmt {
|
|||
check_search(
|
||||
ra_fixture,
|
||||
"main",
|
||||
Query::new("fmt".to_string()).fuzzy(),
|
||||
Query::new("fmt".to_owned()).fuzzy(),
|
||||
expect![[r#"
|
||||
dep::Fmt (m)
|
||||
dep::Fmt (t)
|
||||
|
@ -951,7 +949,7 @@ pub mod fmt {
|
|||
check_search(
|
||||
ra_fixture,
|
||||
"main",
|
||||
Query::new("fmt".to_string()),
|
||||
Query::new("fmt".to_owned()),
|
||||
expect![[r#"
|
||||
dep::Fmt (m)
|
||||
dep::Fmt (t)
|
||||
|
@ -991,7 +989,7 @@ pub mod fmt {
|
|||
check_search(
|
||||
ra_fixture,
|
||||
"main",
|
||||
Query::new("fmt".to_string()),
|
||||
Query::new("fmt".to_owned()),
|
||||
expect![[r#"
|
||||
dep::Fmt (m)
|
||||
dep::Fmt (t)
|
||||
|
@ -1015,7 +1013,7 @@ pub mod fmt {
|
|||
check_search(
|
||||
ra_fixture,
|
||||
"main",
|
||||
Query::new("FMT".to_string()),
|
||||
Query::new("FMT".to_owned()),
|
||||
expect![[r#"
|
||||
dep::FMT (t)
|
||||
dep::FMT (v)
|
||||
|
@ -1027,7 +1025,7 @@ pub mod fmt {
|
|||
check_search(
|
||||
ra_fixture,
|
||||
"main",
|
||||
Query::new("FMT".to_string()).case_sensitive(),
|
||||
Query::new("FMT".to_owned()).case_sensitive(),
|
||||
expect![[r#"
|
||||
dep::FMT (t)
|
||||
dep::FMT (v)
|
||||
|
|
|
@ -222,17 +222,15 @@ impl ItemScope {
|
|||
self.declarations.iter().copied()
|
||||
}
|
||||
|
||||
pub fn extern_crate_decls(
|
||||
&self,
|
||||
) -> impl Iterator<Item = ExternCrateId> + ExactSizeIterator + '_ {
|
||||
pub fn extern_crate_decls(&self) -> impl ExactSizeIterator<Item = ExternCrateId> + '_ {
|
||||
self.extern_crate_decls.iter().copied()
|
||||
}
|
||||
|
||||
pub fn use_decls(&self) -> impl Iterator<Item = UseId> + ExactSizeIterator + '_ {
|
||||
pub fn use_decls(&self) -> impl ExactSizeIterator<Item = UseId> + '_ {
|
||||
self.use_decls.iter().copied()
|
||||
}
|
||||
|
||||
pub fn impls(&self) -> impl Iterator<Item = ImplId> + ExactSizeIterator + '_ {
|
||||
pub fn impls(&self) -> impl ExactSizeIterator<Item = ImplId> + '_ {
|
||||
self.impls.iter().copied()
|
||||
}
|
||||
|
||||
|
@ -674,7 +672,7 @@ impl ItemScope {
|
|||
format_to!(
|
||||
buf,
|
||||
"{}:",
|
||||
name.map_or("_".to_string(), |name| name.display(db).to_string())
|
||||
name.map_or("_".to_owned(), |name| name.display(db).to_string())
|
||||
);
|
||||
|
||||
if let Some((.., i)) = def.types {
|
||||
|
|
|
@ -337,20 +337,18 @@ from_attrs!(
|
|||
LifetimeParamData(Idx<LifetimeParamData>),
|
||||
);
|
||||
|
||||
/// Trait implemented by all item nodes in the item tree.
|
||||
pub trait ItemTreeModItemNode: Clone {
|
||||
type Source: AstIdNode + Into<ast::Item>;
|
||||
/// Trait implemented by all nodes in the item tree.
|
||||
pub trait ItemTreeNode: Clone {
|
||||
type Source: AstIdNode;
|
||||
|
||||
fn ast_id(&self) -> FileAstId<Self::Source>;
|
||||
|
||||
/// Looks up an instance of `Self` in an item tree.
|
||||
fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self;
|
||||
|
||||
/// Downcasts a `ModItem` to a `FileItemTreeId` specific to this type.
|
||||
fn id_from_mod_item(mod_item: ModItem) -> Option<FileItemTreeId<Self>>;
|
||||
|
||||
/// Upcasts a `FileItemTreeId` to a generic `ModItem`.
|
||||
fn id_to_mod_item(id: FileItemTreeId<Self>) -> ModItem;
|
||||
fn attr_owner(id: FileItemTreeId<Self>) -> AttrOwner;
|
||||
}
|
||||
pub trait GenericsItemTreeNode: ItemTreeNode {
|
||||
fn generic_params(&self) -> &Interned<GenericParams>;
|
||||
}
|
||||
|
||||
pub struct FileItemTreeId<N>(Idx<N>);
|
||||
|
@ -372,7 +370,7 @@ impl<N> FileItemTreeId<N> {
|
|||
|
||||
impl<N> Clone for FileItemTreeId<N> {
|
||||
fn clone(&self) -> Self {
|
||||
Self(self.0)
|
||||
*self
|
||||
}
|
||||
}
|
||||
impl<N> Copy for FileItemTreeId<N> {}
|
||||
|
@ -478,7 +476,7 @@ impl<N> Hash for ItemTreeId<N> {
|
|||
}
|
||||
|
||||
macro_rules! mod_items {
|
||||
( $( $typ:ident in $fld:ident -> $ast:ty ),+ $(,)? ) => {
|
||||
( $( $typ:ident $(<$generic_params:ident>)? in $fld:ident -> $ast:ty ),+ $(,)? ) => {
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub enum ModItem {
|
||||
$(
|
||||
|
@ -495,7 +493,7 @@ macro_rules! mod_items {
|
|||
)+
|
||||
|
||||
$(
|
||||
impl ItemTreeModItemNode for $typ {
|
||||
impl ItemTreeNode for $typ {
|
||||
type Source = $ast;
|
||||
|
||||
fn ast_id(&self) -> FileAstId<Self::Source> {
|
||||
|
@ -506,15 +504,8 @@ macro_rules! mod_items {
|
|||
&tree.data().$fld[index]
|
||||
}
|
||||
|
||||
fn id_from_mod_item(mod_item: ModItem) -> Option<FileItemTreeId<Self>> {
|
||||
match mod_item {
|
||||
ModItem::$typ(id) => Some(id),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn id_to_mod_item(id: FileItemTreeId<Self>) -> ModItem {
|
||||
ModItem::$typ(id)
|
||||
fn attr_owner(id: FileItemTreeId<Self>) -> AttrOwner {
|
||||
AttrOwner::ModItem(ModItem::$typ(id))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -525,6 +516,14 @@ macro_rules! mod_items {
|
|||
&self.data().$fld[index]
|
||||
}
|
||||
}
|
||||
|
||||
$(
|
||||
impl GenericsItemTreeNode for $typ {
|
||||
fn generic_params(&self) -> &Interned<GenericParams> {
|
||||
&self.$generic_params
|
||||
}
|
||||
}
|
||||
)?
|
||||
)+
|
||||
};
|
||||
}
|
||||
|
@ -533,16 +532,16 @@ mod_items! {
|
|||
Use in uses -> ast::Use,
|
||||
ExternCrate in extern_crates -> ast::ExternCrate,
|
||||
ExternBlock in extern_blocks -> ast::ExternBlock,
|
||||
Function in functions -> ast::Fn,
|
||||
Struct in structs -> ast::Struct,
|
||||
Union in unions -> ast::Union,
|
||||
Enum in enums -> ast::Enum,
|
||||
Function<explicit_generic_params> in functions -> ast::Fn,
|
||||
Struct<generic_params> in structs -> ast::Struct,
|
||||
Union<generic_params> in unions -> ast::Union,
|
||||
Enum<generic_params> in enums -> ast::Enum,
|
||||
Const in consts -> ast::Const,
|
||||
Static in statics -> ast::Static,
|
||||
Trait in traits -> ast::Trait,
|
||||
TraitAlias in trait_aliases -> ast::TraitAlias,
|
||||
Impl in impls -> ast::Impl,
|
||||
TypeAlias in type_aliases -> ast::TypeAlias,
|
||||
Trait<generic_params> in traits -> ast::Trait,
|
||||
TraitAlias<generic_params> in trait_aliases -> ast::TraitAlias,
|
||||
Impl<generic_params> in impls -> ast::Impl,
|
||||
TypeAlias<generic_params> in type_aliases -> ast::TypeAlias,
|
||||
Mod in mods -> ast::Module,
|
||||
MacroCall in macro_calls -> ast::MacroCall,
|
||||
MacroRules in macro_rules -> ast::MacroRules,
|
||||
|
@ -578,17 +577,26 @@ impl Index<RawVisibilityId> for ItemTree {
|
|||
}
|
||||
}
|
||||
|
||||
impl<N: ItemTreeModItemNode> Index<FileItemTreeId<N>> for ItemTree {
|
||||
impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree {
|
||||
type Output = N;
|
||||
fn index(&self, id: FileItemTreeId<N>) -> &N {
|
||||
N::lookup(self, id.index())
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<FileItemTreeId<Variant>> for ItemTree {
|
||||
type Output = Variant;
|
||||
fn index(&self, id: FileItemTreeId<Variant>) -> &Variant {
|
||||
&self[id.index()]
|
||||
impl ItemTreeNode for Variant {
|
||||
type Source = ast::Variant;
|
||||
|
||||
fn ast_id(&self) -> FileAstId<Self::Source> {
|
||||
self.ast_id
|
||||
}
|
||||
|
||||
fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self {
|
||||
&tree.data().variants[index]
|
||||
}
|
||||
|
||||
fn attr_owner(id: FileItemTreeId<Self>) -> AttrOwner {
|
||||
AttrOwner::Variant(id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1027,7 +1035,7 @@ impl AssocItem {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Variant {
|
||||
pub name: Name,
|
||||
pub fields: Fields,
|
||||
|
|
|
@ -13,7 +13,7 @@ use crate::{
|
|||
|
||||
use super::*;
|
||||
|
||||
fn id<N: ItemTreeModItemNode>(index: Idx<N>) -> FileItemTreeId<N> {
|
||||
fn id<N: ItemTreeNode>(index: Idx<N>) -> FileItemTreeId<N> {
|
||||
FileItemTreeId(index)
|
||||
}
|
||||
|
||||
|
@ -267,7 +267,7 @@ impl<'a> Ctx<'a> {
|
|||
if let Some(data) = self.lower_variant(&variant) {
|
||||
let idx = self.data().variants.alloc(data);
|
||||
self.add_attrs(
|
||||
FileItemTreeId(idx).into(),
|
||||
id(idx).into(),
|
||||
RawAttrs::new(self.db.upcast(), &variant, self.span_map()),
|
||||
);
|
||||
}
|
||||
|
@ -658,7 +658,7 @@ impl<'a> Ctx<'a> {
|
|||
|
||||
fn lower_visibility(&mut self, item: &dyn ast::HasVisibility) -> RawVisibilityId {
|
||||
let vis =
|
||||
RawVisibility::from_ast_with_span_map(self.db, item.visibility(), self.span_map());
|
||||
RawVisibility::from_opt_ast_with_span_map(self.db, item.visibility(), self.span_map());
|
||||
self.data().vis.alloc(vis)
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ pub(super) fn print_item_tree(db: &dyn DefDatabase, tree: &ItemTree) -> String {
|
|||
p.print_mod_item(*item);
|
||||
}
|
||||
|
||||
let mut s = p.buf.trim_end_matches('\n').to_string();
|
||||
let mut s = p.buf.trim_end_matches('\n').to_owned();
|
||||
s.push('\n');
|
||||
s
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ impl Printer<'_> {
|
|||
wln!(self);
|
||||
f(self);
|
||||
self.indent_level -= 1;
|
||||
self.buf = self.buf.trim_end_matches('\n').to_string();
|
||||
self.buf = self.buf.trim_end_matches('\n').to_owned();
|
||||
}
|
||||
|
||||
/// Ensures that a blank line is output before the next text.
|
||||
|
|
|
@ -70,7 +70,11 @@ use std::{
|
|||
panic::{RefUnwindSafe, UnwindSafe},
|
||||
};
|
||||
|
||||
use base_db::{impl_intern_key, salsa, CrateId, Edition};
|
||||
use base_db::{
|
||||
impl_intern_key,
|
||||
salsa::{self, impl_intern_value_trivial},
|
||||
CrateId, Edition,
|
||||
};
|
||||
use hir_expand::{
|
||||
ast_id_map::{AstIdNode, FileAstId},
|
||||
builtin_attr_macro::BuiltinAttrExpander,
|
||||
|
@ -87,7 +91,7 @@ use hir_expand::{
|
|||
use item_tree::ExternBlock;
|
||||
use la_arena::Idx;
|
||||
use nameres::DefMap;
|
||||
use span::Span;
|
||||
use span::{FileId, Span};
|
||||
use stdx::impl_from;
|
||||
use syntax::{ast, AstNode};
|
||||
|
||||
|
@ -98,11 +102,268 @@ use crate::{
|
|||
data::adt::VariantData,
|
||||
db::DefDatabase,
|
||||
item_tree::{
|
||||
Const, Enum, ExternCrate, Function, Impl, ItemTreeId, ItemTreeModItemNode, Macro2,
|
||||
MacroRules, Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use, Variant,
|
||||
Const, Enum, ExternCrate, Function, Impl, ItemTreeId, ItemTreeNode, Macro2, MacroRules,
|
||||
Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use, Variant,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ItemLoc<N: ItemTreeNode> {
|
||||
pub container: ModuleId,
|
||||
pub id: ItemTreeId<N>,
|
||||
}
|
||||
|
||||
impl<N: ItemTreeNode> Clone for ItemLoc<N> {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ItemTreeNode> Copy for ItemLoc<N> {}
|
||||
|
||||
impl<N: ItemTreeNode> PartialEq for ItemLoc<N> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.container == other.container && self.id == other.id
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ItemTreeNode> Eq for ItemLoc<N> {}
|
||||
|
||||
impl<N: ItemTreeNode> Hash for ItemLoc<N> {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.container.hash(state);
|
||||
self.id.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AssocItemLoc<N: ItemTreeNode> {
|
||||
pub container: ItemContainerId,
|
||||
pub id: ItemTreeId<N>,
|
||||
}
|
||||
|
||||
impl<N: ItemTreeNode> Clone for AssocItemLoc<N> {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ItemTreeNode> Copy for AssocItemLoc<N> {}
|
||||
|
||||
impl<N: ItemTreeNode> PartialEq for AssocItemLoc<N> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.container == other.container && self.id == other.id
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ItemTreeNode> Eq for AssocItemLoc<N> {}
|
||||
|
||||
impl<N: ItemTreeNode> Hash for AssocItemLoc<N> {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.container.hash(state);
|
||||
self.id.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ItemTreeLoc {
|
||||
type Container;
|
||||
type Id;
|
||||
fn item_tree_id(&self) -> ItemTreeId<Self::Id>;
|
||||
fn container(&self) -> Self::Container;
|
||||
}
|
||||
|
||||
macro_rules! impl_intern {
|
||||
($id:ident, $loc:ident, $intern:ident, $lookup:ident) => {
|
||||
impl_intern_key!($id);
|
||||
impl_intern_value_trivial!($loc);
|
||||
impl_intern_lookup!(DefDatabase, $id, $loc, $intern, $lookup);
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_loc {
|
||||
($loc:ident, $id:ident: $id_ty:ident, $container:ident: $container_type:ident) => {
|
||||
impl ItemTreeLoc for $loc {
|
||||
type Container = $container_type;
|
||||
type Id = $id_ty;
|
||||
fn item_tree_id(&self) -> ItemTreeId<Self::Id> {
|
||||
self.$id
|
||||
}
|
||||
fn container(&self) -> Self::Container {
|
||||
self.$container
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct FunctionId(salsa::InternId);
|
||||
type FunctionLoc = AssocItemLoc<Function>;
|
||||
impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function);
|
||||
impl_loc!(FunctionLoc, id: Function, container: ItemContainerId);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct StructId(salsa::InternId);
|
||||
type StructLoc = ItemLoc<Struct>;
|
||||
impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct);
|
||||
impl_loc!(StructLoc, id: Struct, container: ModuleId);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct UnionId(salsa::InternId);
|
||||
pub type UnionLoc = ItemLoc<Union>;
|
||||
impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union);
|
||||
impl_loc!(UnionLoc, id: Union, container: ModuleId);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct EnumId(salsa::InternId);
|
||||
pub type EnumLoc = ItemLoc<Enum>;
|
||||
impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum);
|
||||
impl_loc!(EnumLoc, id: Enum, container: ModuleId);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct ConstId(salsa::InternId);
|
||||
type ConstLoc = AssocItemLoc<Const>;
|
||||
impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const);
|
||||
impl_loc!(ConstLoc, id: Const, container: ItemContainerId);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct StaticId(salsa::InternId);
|
||||
pub type StaticLoc = AssocItemLoc<Static>;
|
||||
impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static);
|
||||
impl_loc!(StaticLoc, id: Static, container: ItemContainerId);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct TraitId(salsa::InternId);
|
||||
pub type TraitLoc = ItemLoc<Trait>;
|
||||
impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait);
|
||||
impl_loc!(TraitLoc, id: Trait, container: ModuleId);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct TraitAliasId(salsa::InternId);
|
||||
pub type TraitAliasLoc = ItemLoc<TraitAlias>;
|
||||
impl_intern!(TraitAliasId, TraitAliasLoc, intern_trait_alias, lookup_intern_trait_alias);
|
||||
impl_loc!(TraitAliasLoc, id: TraitAlias, container: ModuleId);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct TypeAliasId(salsa::InternId);
|
||||
type TypeAliasLoc = AssocItemLoc<TypeAlias>;
|
||||
impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias);
|
||||
impl_loc!(TypeAliasLoc, id: TypeAlias, container: ItemContainerId);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
pub struct ImplId(salsa::InternId);
|
||||
type ImplLoc = ItemLoc<Impl>;
|
||||
impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl);
|
||||
impl_loc!(ImplLoc, id: Impl, container: ModuleId);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
pub struct UseId(salsa::InternId);
|
||||
type UseLoc = ItemLoc<Use>;
|
||||
impl_intern!(UseId, UseLoc, intern_use, lookup_intern_use);
|
||||
impl_loc!(UseLoc, id: Use, container: ModuleId);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
pub struct ExternCrateId(salsa::InternId);
|
||||
type ExternCrateLoc = ItemLoc<ExternCrate>;
|
||||
impl_intern!(ExternCrateId, ExternCrateLoc, intern_extern_crate, lookup_intern_extern_crate);
|
||||
impl_loc!(ExternCrateLoc, id: ExternCrate, container: ModuleId);
|
||||
|
||||
#[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);
|
||||
impl_loc!(ExternBlockLoc, id: ExternBlock, container: ModuleId);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct EnumVariantId(salsa::InternId);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct EnumVariantLoc {
|
||||
pub id: ItemTreeId<Variant>,
|
||||
pub parent: EnumId,
|
||||
pub index: u32,
|
||||
}
|
||||
impl_intern!(EnumVariantId, EnumVariantLoc, intern_enum_variant, lookup_intern_enum_variant);
|
||||
impl_loc!(EnumVariantLoc, id: Variant, parent: EnumId);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
pub struct Macro2Id(salsa::InternId);
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct Macro2Loc {
|
||||
pub container: ModuleId,
|
||||
pub id: ItemTreeId<Macro2>,
|
||||
pub expander: MacroExpander,
|
||||
pub allow_internal_unsafe: bool,
|
||||
pub edition: Edition,
|
||||
}
|
||||
impl_intern!(Macro2Id, Macro2Loc, intern_macro2, lookup_intern_macro2);
|
||||
impl_loc!(Macro2Loc, id: Macro2, container: ModuleId);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
pub struct MacroRulesId(salsa::InternId);
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct MacroRulesLoc {
|
||||
pub container: ModuleId,
|
||||
pub id: ItemTreeId<MacroRules>,
|
||||
pub expander: MacroExpander,
|
||||
pub flags: MacroRulesLocFlags,
|
||||
pub edition: Edition,
|
||||
}
|
||||
impl_intern!(MacroRulesId, MacroRulesLoc, intern_macro_rules, lookup_intern_macro_rules);
|
||||
impl_loc!(MacroRulesLoc, id: MacroRules, container: ModuleId);
|
||||
|
||||
bitflags::bitflags! {
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct MacroRulesLocFlags: u8 {
|
||||
const ALLOW_INTERNAL_UNSAFE = 1 << 0;
|
||||
const LOCAL_INNER = 1 << 1;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum MacroExpander {
|
||||
Declarative,
|
||||
BuiltIn(BuiltinFnLikeExpander),
|
||||
BuiltInAttr(BuiltinAttrExpander),
|
||||
BuiltInDerive(BuiltinDeriveExpander),
|
||||
BuiltInEager(EagerExpander),
|
||||
}
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
pub struct ProcMacroId(salsa::InternId);
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct ProcMacroLoc {
|
||||
pub container: CrateRootModuleId,
|
||||
pub id: ItemTreeId<Function>,
|
||||
pub expander: CustomProcMacroExpander,
|
||||
pub kind: ProcMacroKind,
|
||||
pub edition: Edition,
|
||||
}
|
||||
impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro);
|
||||
impl_loc!(ProcMacroLoc, id: Function, container: CrateRootModuleId);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
pub struct BlockId(salsa::InternId);
|
||||
#[derive(Debug, Hash, PartialEq, Eq, Clone)]
|
||||
pub struct BlockLoc {
|
||||
ast_id: AstId<ast::BlockExpr>,
|
||||
/// The containing module.
|
||||
module: ModuleId,
|
||||
}
|
||||
impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block);
|
||||
|
||||
/// Id of the anonymous const block expression and patterns. This is very similar to `ClosureId` and
|
||||
/// shouldn't be a `DefWithBodyId` since its type inference is dependent on its parent.
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||
pub struct ConstBlockId(salsa::InternId);
|
||||
impl_intern!(ConstBlockId, ConstBlockLoc, intern_anonymous_const, lookup_intern_anonymous_const);
|
||||
|
||||
#[derive(Debug, Hash, PartialEq, Eq, Clone)]
|
||||
pub struct ConstBlockLoc {
|
||||
/// The parent of the anonymous const block.
|
||||
pub parent: DefWithBodyId,
|
||||
/// The root expression of this const block in the parent body.
|
||||
pub root: hir::ExprId,
|
||||
}
|
||||
|
||||
/// A `ModuleId` that is always a crate's root module.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct CrateRootModuleId {
|
||||
|
@ -124,23 +385,6 @@ impl PartialEq<ModuleId> for CrateRootModuleId {
|
|||
other.block.is_none() && other.local_id == DefMap::ROOT && self.krate == other.krate
|
||||
}
|
||||
}
|
||||
impl PartialEq<CrateRootModuleId> for ModuleId {
|
||||
fn eq(&self, other: &CrateRootModuleId) -> bool {
|
||||
other == self
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CrateRootModuleId> for ModuleId {
|
||||
fn from(CrateRootModuleId { krate }: CrateRootModuleId) -> Self {
|
||||
ModuleId { krate, block: None, local_id: DefMap::ROOT }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CrateRootModuleId> for ModuleDefId {
|
||||
fn from(value: CrateRootModuleId) -> Self {
|
||||
ModuleDefId::ModuleId(value.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CrateId> for CrateRootModuleId {
|
||||
fn from(krate: CrateId) -> Self {
|
||||
|
@ -208,105 +452,27 @@ impl ModuleId {
|
|||
}
|
||||
}
|
||||
|
||||
impl PartialEq<CrateRootModuleId> for ModuleId {
|
||||
fn eq(&self, other: &CrateRootModuleId) -> bool {
|
||||
other == self
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CrateRootModuleId> for ModuleId {
|
||||
fn from(CrateRootModuleId { krate }: CrateRootModuleId) -> Self {
|
||||
ModuleId { krate, block: None, local_id: DefMap::ROOT }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CrateRootModuleId> for ModuleDefId {
|
||||
fn from(value: CrateRootModuleId) -> Self {
|
||||
ModuleDefId::ModuleId(value.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// An ID of a module, **local** to a `DefMap`.
|
||||
pub type LocalModuleId = Idx<nameres::ModuleData>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ItemLoc<N: ItemTreeModItemNode> {
|
||||
pub container: ModuleId,
|
||||
pub id: ItemTreeId<N>,
|
||||
}
|
||||
|
||||
impl<N: ItemTreeModItemNode> Clone for ItemLoc<N> {
|
||||
fn clone(&self) -> Self {
|
||||
Self { container: self.container, id: self.id }
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ItemTreeModItemNode> Copy for ItemLoc<N> {}
|
||||
|
||||
impl<N: ItemTreeModItemNode> PartialEq for ItemLoc<N> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.container == other.container && self.id == other.id
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ItemTreeModItemNode> Eq for ItemLoc<N> {}
|
||||
|
||||
impl<N: ItemTreeModItemNode> Hash for ItemLoc<N> {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.container.hash(state);
|
||||
self.id.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AssocItemLoc<N: ItemTreeModItemNode> {
|
||||
pub container: ItemContainerId,
|
||||
pub id: ItemTreeId<N>,
|
||||
}
|
||||
|
||||
impl<N: ItemTreeModItemNode> Clone for AssocItemLoc<N> {
|
||||
fn clone(&self) -> Self {
|
||||
Self { container: self.container, id: self.id }
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ItemTreeModItemNode> Copy for AssocItemLoc<N> {}
|
||||
|
||||
impl<N: ItemTreeModItemNode> PartialEq for AssocItemLoc<N> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.container == other.container && self.id == other.id
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ItemTreeModItemNode> Eq for AssocItemLoc<N> {}
|
||||
|
||||
impl<N: ItemTreeModItemNode> Hash for AssocItemLoc<N> {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.container.hash(state);
|
||||
self.id.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_intern {
|
||||
($id:ident, $loc:ident, $intern:ident, $lookup:ident) => {
|
||||
impl_intern_key!($id);
|
||||
impl_intern_lookup!(DefDatabase, $id, $loc, $intern, $lookup);
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct FunctionId(salsa::InternId);
|
||||
type FunctionLoc = AssocItemLoc<Function>;
|
||||
impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct StructId(salsa::InternId);
|
||||
type StructLoc = ItemLoc<Struct>;
|
||||
impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct UnionId(salsa::InternId);
|
||||
pub type UnionLoc = ItemLoc<Union>;
|
||||
impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct EnumId(salsa::InternId);
|
||||
pub type EnumLoc = ItemLoc<Enum>;
|
||||
impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct EnumVariantId(salsa::InternId);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct EnumVariantLoc {
|
||||
pub id: ItemTreeId<Variant>,
|
||||
pub parent: EnumId,
|
||||
pub index: u32,
|
||||
}
|
||||
impl_intern!(EnumVariantId, EnumVariantLoc, intern_enum_variant, lookup_intern_enum_variant);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct FieldId {
|
||||
pub parent: VariantId,
|
||||
|
@ -324,119 +490,12 @@ pub struct TupleFieldId {
|
|||
pub index: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct ConstId(salsa::InternId);
|
||||
type ConstLoc = AssocItemLoc<Const>;
|
||||
impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct StaticId(salsa::InternId);
|
||||
pub type StaticLoc = AssocItemLoc<Static>;
|
||||
impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct TraitId(salsa::InternId);
|
||||
pub type TraitLoc = ItemLoc<Trait>;
|
||||
impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct TraitAliasId(salsa::InternId);
|
||||
pub type TraitAliasLoc = ItemLoc<TraitAlias>;
|
||||
impl_intern!(TraitAliasId, TraitAliasLoc, intern_trait_alias, lookup_intern_trait_alias);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct TypeAliasId(salsa::InternId);
|
||||
type TypeAliasLoc = AssocItemLoc<TypeAlias>;
|
||||
impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
pub struct ImplId(salsa::InternId);
|
||||
type ImplLoc = ItemLoc<Impl>;
|
||||
impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
pub struct UseId(salsa::InternId);
|
||||
type UseLoc = ItemLoc<Use>;
|
||||
impl_intern!(UseId, UseLoc, intern_use, lookup_intern_use);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
pub struct ExternCrateId(salsa::InternId);
|
||||
type ExternCrateLoc = ItemLoc<ExternCrate>;
|
||||
impl_intern!(ExternCrateId, ExternCrateLoc, intern_extern_crate, lookup_intern_extern_crate);
|
||||
|
||||
#[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)]
|
||||
pub enum MacroExpander {
|
||||
Declarative,
|
||||
BuiltIn(BuiltinFnLikeExpander),
|
||||
BuiltInAttr(BuiltinAttrExpander),
|
||||
BuiltInDerive(BuiltinDeriveExpander),
|
||||
BuiltInEager(EagerExpander),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
pub struct Macro2Id(salsa::InternId);
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct Macro2Loc {
|
||||
pub container: ModuleId,
|
||||
pub id: ItemTreeId<Macro2>,
|
||||
pub expander: MacroExpander,
|
||||
pub allow_internal_unsafe: bool,
|
||||
pub edition: Edition,
|
||||
}
|
||||
impl_intern!(Macro2Id, Macro2Loc, intern_macro2, lookup_intern_macro2);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
pub struct MacroRulesId(salsa::InternId);
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct MacroRulesLoc {
|
||||
pub container: ModuleId,
|
||||
pub id: ItemTreeId<MacroRules>,
|
||||
pub expander: MacroExpander,
|
||||
pub flags: MacroRulesLocFlags,
|
||||
pub edition: Edition,
|
||||
}
|
||||
impl_intern!(MacroRulesId, MacroRulesLoc, intern_macro_rules, lookup_intern_macro_rules);
|
||||
|
||||
bitflags::bitflags! {
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct MacroRulesLocFlags: u8 {
|
||||
const ALLOW_INTERNAL_UNSAFE = 1 << 0;
|
||||
const LOCAL_INNER = 1 << 1;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
pub struct ProcMacroId(salsa::InternId);
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct ProcMacroLoc {
|
||||
pub container: CrateRootModuleId,
|
||||
pub id: ItemTreeId<Function>,
|
||||
pub expander: CustomProcMacroExpander,
|
||||
pub kind: ProcMacroKind,
|
||||
pub edition: Edition,
|
||||
}
|
||||
impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
pub struct BlockId(salsa::InternId);
|
||||
#[derive(Debug, Hash, PartialEq, Eq, Clone)]
|
||||
pub struct BlockLoc {
|
||||
ast_id: AstId<ast::BlockExpr>,
|
||||
/// The containing module.
|
||||
module: ModuleId,
|
||||
}
|
||||
impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct TypeOrConstParamId {
|
||||
pub parent: GenericDefId,
|
||||
pub local_id: LocalTypeOrConstParamId,
|
||||
}
|
||||
impl_intern_value_trivial!(TypeOrConstParamId);
|
||||
|
||||
/// A TypeOrConstParamId with an invariant that it actually belongs to a type
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
|
@ -498,6 +557,7 @@ pub struct LifetimeParamId {
|
|||
pub local_id: LocalLifetimeParamId,
|
||||
}
|
||||
pub type LocalLifetimeParamId = Idx<generics::LifetimeParamData>;
|
||||
impl_intern_value_trivial!(LifetimeParamId);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum ItemContainerId {
|
||||
|
@ -572,20 +632,6 @@ impl_from!(
|
|||
for ModuleDefId
|
||||
);
|
||||
|
||||
/// Id of the anonymous const block expression and patterns. This is very similar to `ClosureId` and
|
||||
/// shouldn't be a `DefWithBodyId` since its type inference is dependent on its parent.
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||
pub struct ConstBlockId(salsa::InternId);
|
||||
impl_intern!(ConstBlockId, ConstBlockLoc, intern_anonymous_const, lookup_intern_anonymous_const);
|
||||
|
||||
#[derive(Debug, Hash, PartialEq, Eq, Clone)]
|
||||
pub struct ConstBlockLoc {
|
||||
/// The parent of the anonymous const block.
|
||||
pub parent: DefWithBodyId,
|
||||
/// The root expression of this const block in the parent body.
|
||||
pub root: hir::ExprId,
|
||||
}
|
||||
|
||||
/// Something that holds types, required for the current const arg lowering implementation as they
|
||||
/// need to be able to query where they are defined.
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||
|
@ -721,6 +767,9 @@ impl Clone for Box<dyn OpaqueInternableThing> {
|
|||
pub struct InTypeConstId(salsa::InternId);
|
||||
impl_intern!(InTypeConstId, InTypeConstLoc, intern_in_type_const, lookup_intern_in_type_const);
|
||||
|
||||
// We would like to set `derive(PartialEq)`
|
||||
// but the compiler complains about that `.expected_ty` does not implement the `Copy` trait.
|
||||
#[allow(clippy::derived_hash_with_manual_eq)]
|
||||
#[derive(Debug, Hash, Eq, Clone)]
|
||||
pub struct InTypeConstLoc {
|
||||
pub id: AstId<ast::ConstArg>,
|
||||
|
@ -850,6 +899,39 @@ impl_from!(
|
|||
for GenericDefId
|
||||
);
|
||||
|
||||
impl GenericDefId {
|
||||
fn file_id_and_params_of(
|
||||
self,
|
||||
db: &dyn DefDatabase,
|
||||
) -> (HirFileId, Option<ast::GenericParamList>) {
|
||||
fn file_id_and_params_of_item_loc<Loc>(
|
||||
db: &dyn DefDatabase,
|
||||
def: impl for<'db> Lookup<Database<'db> = dyn DefDatabase + 'db, Data = Loc>,
|
||||
) -> (HirFileId, Option<ast::GenericParamList>)
|
||||
where
|
||||
Loc: src::HasSource,
|
||||
Loc::Value: ast::HasGenericParams,
|
||||
{
|
||||
let src = def.lookup(db).source(db);
|
||||
(src.file_id, ast::HasGenericParams::generic_param_list(&src.value))
|
||||
}
|
||||
|
||||
match self {
|
||||
GenericDefId::FunctionId(it) => file_id_and_params_of_item_loc(db, it),
|
||||
GenericDefId::TypeAliasId(it) => file_id_and_params_of_item_loc(db, it),
|
||||
GenericDefId::ConstId(_) => (FileId::BOGUS.into(), None),
|
||||
GenericDefId::AdtId(AdtId::StructId(it)) => file_id_and_params_of_item_loc(db, it),
|
||||
GenericDefId::AdtId(AdtId::UnionId(it)) => file_id_and_params_of_item_loc(db, it),
|
||||
GenericDefId::AdtId(AdtId::EnumId(it)) => file_id_and_params_of_item_loc(db, it),
|
||||
GenericDefId::TraitId(it) => file_id_and_params_of_item_loc(db, it),
|
||||
GenericDefId::TraitAliasId(it) => file_id_and_params_of_item_loc(db, it),
|
||||
GenericDefId::ImplId(it) => file_id_and_params_of_item_loc(db, it),
|
||||
// We won't be using this ID anyway
|
||||
GenericDefId::EnumVariantId(_) => (FileId::BOGUS.into(), None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AssocItemId> for GenericDefId {
|
||||
fn from(item: AssocItemId) -> Self {
|
||||
match item {
|
||||
|
@ -983,44 +1065,92 @@ impl VariantId {
|
|||
}
|
||||
|
||||
pub trait HasModule {
|
||||
/// Returns the enclosing module this thing is defined within.
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId;
|
||||
}
|
||||
|
||||
impl HasModule for ItemContainerId {
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
match *self {
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ItemTreeModItemNode> HasModule for AssocItemLoc<N> {
|
||||
/// Returns the crate this thing is defined within.
|
||||
#[inline]
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
self.container.module(db)
|
||||
#[doc(alias = "crate")]
|
||||
fn krate(&self, db: &dyn DefDatabase) -> CrateId {
|
||||
self.module(db).krate
|
||||
}
|
||||
}
|
||||
|
||||
impl HasModule for AdtId {
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
match self {
|
||||
AdtId::StructId(it) => it.lookup(db).container,
|
||||
AdtId::UnionId(it) => it.lookup(db).container,
|
||||
AdtId::EnumId(it) => it.lookup(db).container,
|
||||
}
|
||||
}
|
||||
}
|
||||
// In theory this impl should work out for us, but rustc thinks it collides with all the other
|
||||
// manual impls that do not have a ModuleId container...
|
||||
// impl<N, ItemId, Data> HasModule for ItemId
|
||||
// where
|
||||
// N: ItemTreeNode,
|
||||
// ItemId: for<'db> Lookup<Database<'db> = dyn DefDatabase + 'db, Data = Data> + Copy,
|
||||
// Data: ItemTreeLoc<Id = N, Container = ModuleId>,
|
||||
// {
|
||||
// #[inline]
|
||||
// fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
// self.lookup(db).container()
|
||||
// }
|
||||
// }
|
||||
|
||||
impl HasModule for EnumId {
|
||||
impl<N, ItemId> HasModule for ItemId
|
||||
where
|
||||
N: ItemTreeNode,
|
||||
ItemId: for<'db> Lookup<Database<'db> = dyn DefDatabase + 'db, Data = ItemLoc<N>> + Copy,
|
||||
{
|
||||
#[inline]
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
self.lookup(db).container
|
||||
}
|
||||
}
|
||||
|
||||
// Technically this does not overlap with the above, but rustc currently forbids this, hence why we
|
||||
// need to write the 3 impls manually instead
|
||||
// impl<N, ItemId> HasModule for ItemId
|
||||
// where
|
||||
// N: ItemTreeModItemNode,
|
||||
// ItemId: for<'db> Lookup<Database<'db> = dyn DefDatabase + 'db, Data = AssocItemLoc<N>> + Copy,
|
||||
// {
|
||||
// #[inline]
|
||||
// fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
// self.lookup(db).container.module(db)
|
||||
// }
|
||||
// }
|
||||
|
||||
// region: manual-assoc-has-module-impls
|
||||
#[inline]
|
||||
fn module_for_assoc_item_loc<'db>(
|
||||
db: &(dyn 'db + DefDatabase),
|
||||
id: impl Lookup<Database<'db> = dyn DefDatabase + 'db, Data = AssocItemLoc<impl ItemTreeNode>>,
|
||||
) -> ModuleId {
|
||||
id.lookup(db).container.module(db)
|
||||
}
|
||||
|
||||
impl HasModule for FunctionId {
|
||||
#[inline]
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
module_for_assoc_item_loc(db, *self)
|
||||
}
|
||||
}
|
||||
|
||||
impl HasModule for ConstId {
|
||||
#[inline]
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
module_for_assoc_item_loc(db, *self)
|
||||
}
|
||||
}
|
||||
|
||||
impl HasModule for StaticId {
|
||||
#[inline]
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
module_for_assoc_item_loc(db, *self)
|
||||
}
|
||||
}
|
||||
|
||||
impl HasModule for TypeAliasId {
|
||||
#[inline]
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
module_for_assoc_item_loc(db, *self)
|
||||
}
|
||||
}
|
||||
// endregion: manual-assoc-has-module-impls
|
||||
|
||||
impl HasModule for EnumVariantId {
|
||||
#[inline]
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
|
@ -1028,46 +1158,81 @@ impl HasModule for EnumVariantId {
|
|||
}
|
||||
}
|
||||
|
||||
impl HasModule for ExternCrateId {
|
||||
impl HasModule for MacroRulesId {
|
||||
#[inline]
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
self.lookup(db).container
|
||||
}
|
||||
}
|
||||
|
||||
impl HasModule for Macro2Id {
|
||||
#[inline]
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
self.lookup(db).container
|
||||
}
|
||||
}
|
||||
|
||||
impl HasModule for ProcMacroId {
|
||||
#[inline]
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
self.lookup(db).container.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl HasModule for ItemContainerId {
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
match *self {
|
||||
ItemContainerId::ModuleId(it) => it,
|
||||
ItemContainerId::ImplId(it) => it.module(db),
|
||||
ItemContainerId::TraitId(it) => it.module(db),
|
||||
ItemContainerId::ExternBlockId(it) => it.module(db),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HasModule for AdtId {
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
match *self {
|
||||
AdtId::StructId(it) => it.module(db),
|
||||
AdtId::UnionId(it) => it.module(db),
|
||||
AdtId::EnumId(it) => it.module(db),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HasModule for VariantId {
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
match self {
|
||||
VariantId::EnumVariantId(it) => it.lookup(db).parent.module(db),
|
||||
VariantId::StructId(it) => it.lookup(db).container,
|
||||
VariantId::UnionId(it) => it.lookup(db).container,
|
||||
match *self {
|
||||
VariantId::EnumVariantId(it) => it.module(db),
|
||||
VariantId::StructId(it) => it.module(db),
|
||||
VariantId::UnionId(it) => it.module(db),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HasModule for MacroId {
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
match self {
|
||||
MacroId::MacroRulesId(it) => it.lookup(db).container,
|
||||
MacroId::Macro2Id(it) => it.lookup(db).container,
|
||||
MacroId::ProcMacroId(it) => it.lookup(db).container.into(),
|
||||
match *self {
|
||||
MacroId::MacroRulesId(it) => it.module(db),
|
||||
MacroId::Macro2Id(it) => it.module(db),
|
||||
MacroId::ProcMacroId(it) => it.module(db),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HasModule for TypeOwnerId {
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
match self {
|
||||
TypeOwnerId::FunctionId(it) => it.lookup(db).module(db),
|
||||
TypeOwnerId::StaticId(it) => it.lookup(db).module(db),
|
||||
TypeOwnerId::ConstId(it) => it.lookup(db).module(db),
|
||||
TypeOwnerId::InTypeConstId(it) => it.lookup(db).owner.module(db),
|
||||
match *self {
|
||||
TypeOwnerId::FunctionId(it) => it.module(db),
|
||||
TypeOwnerId::StaticId(it) => it.module(db),
|
||||
TypeOwnerId::ConstId(it) => it.module(db),
|
||||
TypeOwnerId::AdtId(it) => it.module(db),
|
||||
TypeOwnerId::TraitId(it) => it.lookup(db).container,
|
||||
TypeOwnerId::TraitAliasId(it) => it.lookup(db).container,
|
||||
TypeOwnerId::TypeAliasId(it) => it.lookup(db).module(db),
|
||||
TypeOwnerId::ImplId(it) => it.lookup(db).container,
|
||||
TypeOwnerId::EnumVariantId(it) => it.lookup(db).parent.module(db),
|
||||
TypeOwnerId::TraitId(it) => it.module(db),
|
||||
TypeOwnerId::TraitAliasId(it) => it.module(db),
|
||||
TypeOwnerId::TypeAliasId(it) => it.module(db),
|
||||
TypeOwnerId::ImplId(it) => it.module(db),
|
||||
TypeOwnerId::EnumVariantId(it) => it.module(db),
|
||||
TypeOwnerId::InTypeConstId(it) => it.lookup(db).owner.module(db),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1075,10 +1240,10 @@ impl HasModule for TypeOwnerId {
|
|||
impl HasModule for DefWithBodyId {
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
match self {
|
||||
DefWithBodyId::FunctionId(it) => it.lookup(db).module(db),
|
||||
DefWithBodyId::StaticId(it) => it.lookup(db).module(db),
|
||||
DefWithBodyId::ConstId(it) => it.lookup(db).module(db),
|
||||
DefWithBodyId::VariantId(it) => it.lookup(db).parent.module(db),
|
||||
DefWithBodyId::FunctionId(it) => it.module(db),
|
||||
DefWithBodyId::StaticId(it) => it.module(db),
|
||||
DefWithBodyId::ConstId(it) => it.module(db),
|
||||
DefWithBodyId::VariantId(it) => it.module(db),
|
||||
DefWithBodyId::InTypeConstId(it) => it.lookup(db).owner.module(db),
|
||||
}
|
||||
}
|
||||
|
@ -1087,29 +1252,43 @@ impl HasModule for DefWithBodyId {
|
|||
impl HasModule for GenericDefId {
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
match self {
|
||||
GenericDefId::FunctionId(it) => it.lookup(db).module(db),
|
||||
GenericDefId::FunctionId(it) => it.module(db),
|
||||
GenericDefId::AdtId(it) => it.module(db),
|
||||
GenericDefId::TraitId(it) => it.lookup(db).container,
|
||||
GenericDefId::TraitAliasId(it) => it.lookup(db).container,
|
||||
GenericDefId::TypeAliasId(it) => it.lookup(db).module(db),
|
||||
GenericDefId::ImplId(it) => it.lookup(db).container,
|
||||
GenericDefId::EnumVariantId(it) => it.lookup(db).parent.lookup(db).container,
|
||||
GenericDefId::ConstId(it) => it.lookup(db).module(db),
|
||||
GenericDefId::TraitId(it) => it.module(db),
|
||||
GenericDefId::TraitAliasId(it) => it.module(db),
|
||||
GenericDefId::TypeAliasId(it) => it.module(db),
|
||||
GenericDefId::ImplId(it) => it.module(db),
|
||||
GenericDefId::EnumVariantId(it) => it.module(db),
|
||||
GenericDefId::ConstId(it) => it.module(db),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HasModule for TypeAliasId {
|
||||
#[inline]
|
||||
impl HasModule for AttrDefId {
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
self.lookup(db).module(db)
|
||||
}
|
||||
}
|
||||
|
||||
impl HasModule for TraitId {
|
||||
#[inline]
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
self.lookup(db).container
|
||||
match self {
|
||||
AttrDefId::ModuleId(it) => *it,
|
||||
AttrDefId::FieldId(it) => it.parent.module(db),
|
||||
AttrDefId::AdtId(it) => it.module(db),
|
||||
AttrDefId::FunctionId(it) => it.module(db),
|
||||
AttrDefId::EnumVariantId(it) => it.module(db),
|
||||
AttrDefId::StaticId(it) => it.module(db),
|
||||
AttrDefId::ConstId(it) => it.module(db),
|
||||
AttrDefId::TraitId(it) => it.module(db),
|
||||
AttrDefId::TraitAliasId(it) => it.module(db),
|
||||
AttrDefId::TypeAliasId(it) => it.module(db),
|
||||
AttrDefId::ImplId(it) => it.module(db),
|
||||
AttrDefId::ExternBlockId(it) => it.module(db),
|
||||
AttrDefId::GenericParamId(it) => match it {
|
||||
GenericParamId::TypeParamId(it) => it.parent(),
|
||||
GenericParamId::ConstParamId(it) => it.parent(),
|
||||
GenericParamId::LifetimeParamId(it) => it.parent,
|
||||
}
|
||||
.module(db),
|
||||
AttrDefId::MacroId(it) => it.module(db),
|
||||
AttrDefId::ExternCrateId(it) => it.module(db),
|
||||
AttrDefId::UseId(it) => it.module(db),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1120,51 +1299,20 @@ impl ModuleDefId {
|
|||
pub fn module(&self, db: &dyn DefDatabase) -> Option<ModuleId> {
|
||||
Some(match self {
|
||||
ModuleDefId::ModuleId(id) => *id,
|
||||
ModuleDefId::FunctionId(id) => id.lookup(db).module(db),
|
||||
ModuleDefId::FunctionId(id) => id.module(db),
|
||||
ModuleDefId::AdtId(id) => id.module(db),
|
||||
ModuleDefId::EnumVariantId(id) => id.lookup(db).parent.module(db),
|
||||
ModuleDefId::ConstId(id) => id.lookup(db).container.module(db),
|
||||
ModuleDefId::StaticId(id) => id.lookup(db).module(db),
|
||||
ModuleDefId::TraitId(id) => id.lookup(db).container,
|
||||
ModuleDefId::TraitAliasId(id) => id.lookup(db).container,
|
||||
ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db),
|
||||
ModuleDefId::EnumVariantId(id) => id.module(db),
|
||||
ModuleDefId::ConstId(id) => id.module(db),
|
||||
ModuleDefId::StaticId(id) => id.module(db),
|
||||
ModuleDefId::TraitId(id) => id.module(db),
|
||||
ModuleDefId::TraitAliasId(id) => id.module(db),
|
||||
ModuleDefId::TypeAliasId(id) => id.module(db),
|
||||
ModuleDefId::MacroId(id) => id.module(db),
|
||||
ModuleDefId::BuiltinType(_) => return None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl AttrDefId {
|
||||
pub fn krate(&self, db: &dyn DefDatabase) -> CrateId {
|
||||
match self {
|
||||
AttrDefId::ModuleId(it) => it.krate,
|
||||
AttrDefId::FieldId(it) => it.parent.module(db).krate,
|
||||
AttrDefId::AdtId(it) => it.module(db).krate,
|
||||
AttrDefId::FunctionId(it) => it.lookup(db).module(db).krate,
|
||||
AttrDefId::EnumVariantId(it) => it.lookup(db).parent.module(db).krate,
|
||||
AttrDefId::StaticId(it) => it.lookup(db).module(db).krate,
|
||||
AttrDefId::ConstId(it) => it.lookup(db).module(db).krate,
|
||||
AttrDefId::TraitId(it) => it.lookup(db).container.krate,
|
||||
AttrDefId::TraitAliasId(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(),
|
||||
GenericParamId::ConstParamId(it) => it.parent(),
|
||||
GenericParamId::LifetimeParamId(it) => it.parent,
|
||||
}
|
||||
.module(db)
|
||||
.krate
|
||||
}
|
||||
AttrDefId::MacroId(it) => it.module(db).krate,
|
||||
AttrDefId::ExternCrateId(it) => it.lookup(db).container.krate,
|
||||
AttrDefId::UseId(it) => it.lookup(db).container.krate,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A helper trait for converting to MacroCallId
|
||||
pub trait AsMacroCall {
|
||||
fn as_call_id(
|
||||
|
|
|
@ -157,7 +157,7 @@ where
|
|||
generic: Vec<T::InGenericArg>,
|
||||
}
|
||||
|
||||
impl <T: $crate::clone::Clone, > $crate::clone::Clone for Foo<T, > where T: Trait, T::InFieldShorthand: $crate::clone::Clone, T::InGenericArg: $crate::clone::Clone, {
|
||||
impl <T: $crate::clone::Clone, > $crate::clone::Clone for Foo<T, > where <T as Trait>::InWc: Marker, T: Trait, T::InFieldShorthand: $crate::clone::Clone, T::InGenericArg: $crate::clone::Clone, {
|
||||
fn clone(&self ) -> Self {
|
||||
match self {
|
||||
Foo {
|
||||
|
|
|
@ -35,9 +35,9 @@ macro_rules! f {
|
|||
};
|
||||
}
|
||||
|
||||
struct#0:1@58..64#2# MyTraitMap2#0:2@31..42#0# {#0:1@72..73#2#
|
||||
map#0:1@86..89#2#:#0:1@89..90#2# #0:1@89..90#2#::#0:1@91..92#2#std#0:1@93..96#2#::#0:1@96..97#2#collections#0:1@98..109#2#::#0:1@109..110#2#HashSet#0:1@111..118#2#<#0:1@118..119#2#(#0:1@119..120#2#)#0:1@120..121#2#>#0:1@121..122#2#,#0:1@122..123#2#
|
||||
}#0:1@132..133#2#
|
||||
struct#0:1@58..64#1# MyTraitMap2#0:2@31..42#0# {#0:1@72..73#1#
|
||||
map#0:1@86..89#1#:#0:1@89..90#1# #0:1@89..90#1#::#0:1@91..92#1#std#0:1@93..96#1#::#0:1@96..97#1#collections#0:1@98..109#1#::#0:1@109..110#1#HashSet#0:1@111..118#1#<#0:1@118..119#1#(#0:1@119..120#1#)#0:1@120..121#1#>#0:1@121..122#1#,#0:1@122..123#1#
|
||||
}#0:1@132..133#1#
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ fn main(foo: ()) {
|
|||
}
|
||||
|
||||
fn main(foo: ()) {
|
||||
/* error: unresolved macro unresolved */"helloworld!"#0:3@207..323#6#;
|
||||
/* error: unresolved macro unresolved */"helloworld!"#0:3@207..323#2#;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,7 +197,7 @@ macro_rules! mk_struct {
|
|||
#[macro_use]
|
||||
mod foo;
|
||||
|
||||
struct#1:1@59..65#2# Foo#0:2@32..35#0#(#1:1@70..71#2#u32#0:2@41..44#0#)#1:1@74..75#2#;#1:1@75..76#2#
|
||||
struct#1:1@59..65#1# Foo#0:2@32..35#0#(#1:1@70..71#1#u32#0:2@41..44#0#)#1:1@74..75#1#;#1:1@75..76#1#
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -224,7 +224,7 @@ fn reindent(indent: IndentLevel, pp: String) -> String {
|
|||
return pp;
|
||||
}
|
||||
let mut lines = pp.split_inclusive('\n');
|
||||
let mut res = lines.next().unwrap().to_string();
|
||||
let mut res = lines.next().unwrap().to_owned();
|
||||
for line in lines {
|
||||
if line.trim().is_empty() {
|
||||
res.push_str(line)
|
||||
|
|
|
@ -33,8 +33,8 @@ use crate::{
|
|||
db::DefDatabase,
|
||||
item_scope::{ImportId, ImportOrExternCrate, ImportType, PerNsGlobImports},
|
||||
item_tree::{
|
||||
self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId,
|
||||
ItemTreeModItemNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId,
|
||||
self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, ItemTreeNode,
|
||||
Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId,
|
||||
},
|
||||
macro_call_as_call_id, macro_call_as_call_id_with_eager,
|
||||
nameres::{
|
||||
|
@ -2125,7 +2125,7 @@ impl ModCollector<'_, '_> {
|
|||
|
||||
let is_export = export_attr.exists();
|
||||
let local_inner = if is_export {
|
||||
export_attr.tt_values().flat_map(|it| &it.token_trees).any(|it| match it {
|
||||
export_attr.tt_values().flat_map(|it| it.token_trees.iter()).any(|it| match it {
|
||||
tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
|
||||
ident.text.contains("local_inner_macros")
|
||||
}
|
||||
|
|
|
@ -27,9 +27,9 @@ use crate::{
|
|||
visibility::{RawVisibility, Visibility},
|
||||
AdtId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId,
|
||||
ExternBlockId, ExternCrateId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId,
|
||||
ItemContainerId, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, MacroId, MacroRulesId,
|
||||
ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId, TypeAliasId,
|
||||
TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId, VariantId,
|
||||
ItemContainerId, ItemTreeLoc, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, MacroId,
|
||||
MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId,
|
||||
TypeAliasId, TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId, VariantId,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -248,6 +248,7 @@ impl Resolver {
|
|||
RawVisibility::Public => Some(Visibility::Public),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_path_in_value_ns(
|
||||
&self,
|
||||
db: &dyn DefDatabase,
|
||||
|
@ -1014,13 +1015,13 @@ impl HasResolver for CrateRootModuleId {
|
|||
|
||||
impl HasResolver for TraitId {
|
||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||
self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
|
||||
lookup_resolver(db, self).push_generic_params_scope(db, self.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl HasResolver for TraitAliasId {
|
||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||
self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
|
||||
lookup_resolver(db, self).push_generic_params_scope(db, self.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1036,25 +1037,25 @@ impl<T: Into<AdtId> + Copy> HasResolver for T {
|
|||
|
||||
impl HasResolver for FunctionId {
|
||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||
self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
|
||||
lookup_resolver(db, self).push_generic_params_scope(db, self.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl HasResolver for ConstId {
|
||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||
self.lookup(db).container.resolver(db)
|
||||
lookup_resolver(db, self)
|
||||
}
|
||||
}
|
||||
|
||||
impl HasResolver for StaticId {
|
||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||
self.lookup(db).container.resolver(db)
|
||||
lookup_resolver(db, self)
|
||||
}
|
||||
}
|
||||
|
||||
impl HasResolver for TypeAliasId {
|
||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||
self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
|
||||
lookup_resolver(db, self).push_generic_params_scope(db, self.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1071,19 +1072,19 @@ 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)
|
||||
lookup_resolver(db, self)
|
||||
}
|
||||
}
|
||||
|
||||
impl HasResolver for ExternCrateId {
|
||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||
self.lookup(db).container.resolver(db)
|
||||
lookup_resolver(db, self)
|
||||
}
|
||||
}
|
||||
|
||||
impl HasResolver for UseId {
|
||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||
self.lookup(db).container.resolver(db)
|
||||
lookup_resolver(db, self)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1170,18 +1171,28 @@ impl HasResolver for MacroId {
|
|||
|
||||
impl HasResolver for Macro2Id {
|
||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||
self.lookup(db).container.resolver(db)
|
||||
lookup_resolver(db, self)
|
||||
}
|
||||
}
|
||||
|
||||
impl HasResolver for ProcMacroId {
|
||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||
self.lookup(db).container.resolver(db)
|
||||
lookup_resolver(db, self)
|
||||
}
|
||||
}
|
||||
|
||||
impl HasResolver for MacroRulesId {
|
||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||
self.lookup(db).container.resolver(db)
|
||||
lookup_resolver(db, self)
|
||||
}
|
||||
}
|
||||
|
||||
fn lookup_resolver<'db>(
|
||||
db: &(dyn DefDatabase + 'db),
|
||||
lookup: impl Lookup<
|
||||
Database<'db> = dyn DefDatabase + 'db,
|
||||
Data = impl ItemTreeLoc<Container = impl HasResolver>,
|
||||
>,
|
||||
) -> Resolver {
|
||||
lookup.lookup(db).container().resolver(db)
|
||||
}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
//! Utilities for mapping between hir IDs and the surface syntax.
|
||||
|
||||
use either::Either;
|
||||
use hir_expand::InFile;
|
||||
use la_arena::ArenaMap;
|
||||
use syntax::ast;
|
||||
|
||||
use crate::{
|
||||
db::DefDatabase, item_tree::ItemTreeModItemNode, AssocItemLoc, EnumVariantLoc, ItemLoc, Lookup,
|
||||
Macro2Loc, MacroRulesLoc, ProcMacroLoc, UseId,
|
||||
data::adt::lower_struct, db::DefDatabase, item_tree::ItemTreeNode, trace::Trace, GenericDefId,
|
||||
ItemTreeLoc, LocalFieldId, LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, UseId,
|
||||
VariantId,
|
||||
};
|
||||
|
||||
pub trait HasSource {
|
||||
|
@ -14,81 +16,22 @@ pub trait HasSource {
|
|||
fn source(&self, db: &dyn DefDatabase) -> InFile<Self::Value>;
|
||||
}
|
||||
|
||||
impl<N: ItemTreeModItemNode> HasSource for AssocItemLoc<N> {
|
||||
type Value = N::Source;
|
||||
|
||||
fn source(&self, db: &dyn DefDatabase) -> InFile<N::Source> {
|
||||
let tree = self.id.item_tree(db);
|
||||
let ast_id_map = db.ast_id_map(self.id.file_id());
|
||||
let root = db.parse_or_expand(self.id.file_id());
|
||||
let node = &tree[self.id.value];
|
||||
|
||||
InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root))
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: ItemTreeModItemNode> HasSource for ItemLoc<N> {
|
||||
type Value = N::Source;
|
||||
|
||||
fn source(&self, db: &dyn DefDatabase) -> InFile<N::Source> {
|
||||
let tree = self.id.item_tree(db);
|
||||
let ast_id_map = db.ast_id_map(self.id.file_id());
|
||||
let root = db.parse_or_expand(self.id.file_id());
|
||||
let node = &tree[self.id.value];
|
||||
|
||||
InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root))
|
||||
}
|
||||
}
|
||||
|
||||
impl HasSource for EnumVariantLoc {
|
||||
type Value = ast::Variant;
|
||||
|
||||
fn source(&self, db: &dyn DefDatabase) -> InFile<ast::Variant> {
|
||||
let tree = self.id.item_tree(db);
|
||||
let ast_id_map = db.ast_id_map(self.id.file_id());
|
||||
let root = db.parse_or_expand(self.id.file_id());
|
||||
let node = &tree[self.id.value];
|
||||
|
||||
InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id).to_node(&root))
|
||||
}
|
||||
}
|
||||
|
||||
impl HasSource for Macro2Loc {
|
||||
type Value = ast::MacroDef;
|
||||
impl<T> HasSource for T
|
||||
where
|
||||
T: ItemTreeLoc,
|
||||
T::Id: ItemTreeNode,
|
||||
{
|
||||
type Value = <T::Id as ItemTreeNode>::Source;
|
||||
|
||||
fn source(&self, db: &dyn DefDatabase) -> InFile<Self::Value> {
|
||||
let tree = self.id.item_tree(db);
|
||||
let ast_id_map = db.ast_id_map(self.id.file_id());
|
||||
let root = db.parse_or_expand(self.id.file_id());
|
||||
let node = &tree[self.id.value];
|
||||
let id = self.item_tree_id();
|
||||
let file_id = id.file_id();
|
||||
let tree = id.item_tree(db);
|
||||
let ast_id_map = db.ast_id_map(file_id);
|
||||
let root = db.parse_or_expand(file_id);
|
||||
let node = &tree[id.value];
|
||||
|
||||
InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root))
|
||||
}
|
||||
}
|
||||
|
||||
impl HasSource for MacroRulesLoc {
|
||||
type Value = ast::MacroRules;
|
||||
|
||||
fn source(&self, db: &dyn DefDatabase) -> InFile<Self::Value> {
|
||||
let tree = self.id.item_tree(db);
|
||||
let ast_id_map = db.ast_id_map(self.id.file_id());
|
||||
let root = db.parse_or_expand(self.id.file_id());
|
||||
let node = &tree[self.id.value];
|
||||
|
||||
InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root))
|
||||
}
|
||||
}
|
||||
|
||||
impl HasSource for ProcMacroLoc {
|
||||
type Value = ast::Fn;
|
||||
|
||||
fn source(&self, db: &dyn DefDatabase) -> InFile<Self::Value> {
|
||||
let tree = self.id.item_tree(db);
|
||||
let ast_id_map = db.ast_id_map(self.id.file_id());
|
||||
let root = db.parse_or_expand(self.id.file_id());
|
||||
let node = &tree[self.id.value];
|
||||
|
||||
InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root))
|
||||
InFile::new(file_id, ast_id_map.get(node.ast_id()).to_node(&root))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,3 +54,105 @@ impl HasChildSource<la_arena::Idx<ast::UseTree>> for UseId {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl HasChildSource<LocalTypeOrConstParamId> for GenericDefId {
|
||||
type Value = Either<ast::TypeOrConstParam, ast::TraitOrAlias>;
|
||||
fn child_source(
|
||||
&self,
|
||||
db: &dyn DefDatabase,
|
||||
) -> InFile<ArenaMap<LocalTypeOrConstParamId, Self::Value>> {
|
||||
let generic_params = db.generic_params(*self);
|
||||
let mut idx_iter = generic_params.type_or_consts.iter().map(|(idx, _)| idx);
|
||||
|
||||
let (file_id, generic_params_list) = self.file_id_and_params_of(db);
|
||||
|
||||
let mut params = ArenaMap::default();
|
||||
|
||||
// For traits and trait aliases the first type index is `Self`, we need to add it before
|
||||
// the other params.
|
||||
match *self {
|
||||
GenericDefId::TraitId(id) => {
|
||||
let trait_ref = id.lookup(db).source(db).value;
|
||||
let idx = idx_iter.next().unwrap();
|
||||
params.insert(idx, Either::Right(ast::TraitOrAlias::Trait(trait_ref)));
|
||||
}
|
||||
GenericDefId::TraitAliasId(id) => {
|
||||
let alias = id.lookup(db).source(db).value;
|
||||
let idx = idx_iter.next().unwrap();
|
||||
params.insert(idx, Either::Right(ast::TraitOrAlias::TraitAlias(alias)));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if let Some(generic_params_list) = generic_params_list {
|
||||
for (idx, ast_param) in idx_iter.zip(generic_params_list.type_or_const_params()) {
|
||||
params.insert(idx, Either::Left(ast_param));
|
||||
}
|
||||
}
|
||||
|
||||
InFile::new(file_id, params)
|
||||
}
|
||||
}
|
||||
|
||||
impl HasChildSource<LocalLifetimeParamId> for GenericDefId {
|
||||
type Value = ast::LifetimeParam;
|
||||
fn child_source(
|
||||
&self,
|
||||
db: &dyn DefDatabase,
|
||||
) -> InFile<ArenaMap<LocalLifetimeParamId, Self::Value>> {
|
||||
let generic_params = db.generic_params(*self);
|
||||
let idx_iter = generic_params.lifetimes.iter().map(|(idx, _)| idx);
|
||||
|
||||
let (file_id, generic_params_list) = self.file_id_and_params_of(db);
|
||||
|
||||
let mut params = ArenaMap::default();
|
||||
|
||||
if let Some(generic_params_list) = generic_params_list {
|
||||
for (idx, ast_param) in idx_iter.zip(generic_params_list.lifetime_params()) {
|
||||
params.insert(idx, ast_param);
|
||||
}
|
||||
}
|
||||
|
||||
InFile::new(file_id, params)
|
||||
}
|
||||
}
|
||||
|
||||
impl HasChildSource<LocalFieldId> for VariantId {
|
||||
type Value = Either<ast::TupleField, ast::RecordField>;
|
||||
|
||||
fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<LocalFieldId, Self::Value>> {
|
||||
let item_tree;
|
||||
let (src, fields, container) = match *self {
|
||||
VariantId::EnumVariantId(it) => {
|
||||
let lookup = it.lookup(db);
|
||||
item_tree = lookup.id.item_tree(db);
|
||||
(
|
||||
lookup.source(db).map(|it| it.kind()),
|
||||
&item_tree[lookup.id.value].fields,
|
||||
lookup.parent.lookup(db).container,
|
||||
)
|
||||
}
|
||||
VariantId::StructId(it) => {
|
||||
let lookup = it.lookup(db);
|
||||
item_tree = lookup.id.item_tree(db);
|
||||
(
|
||||
lookup.source(db).map(|it| it.kind()),
|
||||
&item_tree[lookup.id.value].fields,
|
||||
lookup.container,
|
||||
)
|
||||
}
|
||||
VariantId::UnionId(it) => {
|
||||
let lookup = it.lookup(db);
|
||||
item_tree = lookup.id.item_tree(db);
|
||||
(
|
||||
lookup.source(db).map(|it| it.kind()),
|
||||
&item_tree[lookup.id.value].fields,
|
||||
lookup.container,
|
||||
)
|
||||
}
|
||||
};
|
||||
let mut trace = Trace::new_for_map();
|
||||
lower_struct(db, &mut trace, &src, container.krate, &item_tree, fields);
|
||||
src.with_value(trace.into_map())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
//! projections.
|
||||
use la_arena::{Arena, ArenaMap, Idx, RawIdx};
|
||||
|
||||
// FIXME: This isn't really used anymore, at least not in a way where it does anything useful.
|
||||
// Check if we should get rid of this or make proper use of it instead.
|
||||
pub(crate) struct Trace<T, V> {
|
||||
arena: Option<Arena<T>>,
|
||||
map: Option<ArenaMap<Idx<T>, V>>,
|
||||
|
|
|
@ -37,10 +37,14 @@ impl RawVisibility {
|
|||
db: &dyn DefDatabase,
|
||||
node: InFile<Option<ast::Visibility>>,
|
||||
) -> RawVisibility {
|
||||
let node = match node.transpose() {
|
||||
None => return RawVisibility::private(),
|
||||
Some(node) => node,
|
||||
};
|
||||
Self::from_ast_with_span_map(db, node.value, db.span_map(node.file_id).as_ref())
|
||||
}
|
||||
|
||||
pub(crate) fn from_ast_with_span_map(
|
||||
pub(crate) fn from_opt_ast_with_span_map(
|
||||
db: &dyn DefDatabase,
|
||||
node: Option<ast::Visibility>,
|
||||
span_map: SpanMapRef<'_>,
|
||||
|
@ -49,29 +53,28 @@ impl RawVisibility {
|
|||
None => return RawVisibility::private(),
|
||||
Some(node) => node,
|
||||
};
|
||||
match node.kind() {
|
||||
Self::from_ast_with_span_map(db, node, span_map)
|
||||
}
|
||||
|
||||
fn from_ast_with_span_map(
|
||||
db: &dyn DefDatabase,
|
||||
node: ast::Visibility,
|
||||
span_map: SpanMapRef<'_>,
|
||||
) -> RawVisibility {
|
||||
let path = match node.kind() {
|
||||
ast::VisibilityKind::In(path) => {
|
||||
let path = ModPath::from_src(db.upcast(), path, span_map);
|
||||
let path = match path {
|
||||
match path {
|
||||
None => return RawVisibility::private(),
|
||||
Some(path) => path,
|
||||
};
|
||||
RawVisibility::Module(path, VisibilityExplicitness::Explicit)
|
||||
}
|
||||
}
|
||||
ast::VisibilityKind::PubCrate => {
|
||||
let path = ModPath::from_kind(PathKind::Crate);
|
||||
RawVisibility::Module(path, VisibilityExplicitness::Explicit)
|
||||
}
|
||||
ast::VisibilityKind::PubSuper => {
|
||||
let path = ModPath::from_kind(PathKind::Super(1));
|
||||
RawVisibility::Module(path, VisibilityExplicitness::Explicit)
|
||||
}
|
||||
ast::VisibilityKind::PubSelf => {
|
||||
let path = ModPath::from_kind(PathKind::Super(0));
|
||||
RawVisibility::Module(path, VisibilityExplicitness::Explicit)
|
||||
}
|
||||
ast::VisibilityKind::Pub => RawVisibility::Public,
|
||||
}
|
||||
ast::VisibilityKind::PubCrate => ModPath::from_kind(PathKind::Crate),
|
||||
ast::VisibilityKind::PubSuper => ModPath::from_kind(PathKind::Super(1)),
|
||||
ast::VisibilityKind::PubSelf => ModPath::from_kind(PathKind::Super(0)),
|
||||
ast::VisibilityKind::Pub => return RawVisibility::Public,
|
||||
};
|
||||
RawVisibility::Module(path, VisibilityExplicitness::Explicit)
|
||||
}
|
||||
|
||||
pub fn resolve(
|
||||
|
@ -94,6 +97,11 @@ pub enum Visibility {
|
|||
}
|
||||
|
||||
impl Visibility {
|
||||
pub(crate) fn is_visible_from_other_crate(self) -> bool {
|
||||
matches!(self, Visibility::Public)
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub fn is_visible_from(self, db: &dyn DefDatabase, from_module: ModuleId) -> bool {
|
||||
let to_module = match self {
|
||||
Visibility::Module(m, _) => m,
|
||||
|
@ -104,24 +112,33 @@ impl Visibility {
|
|||
return false;
|
||||
}
|
||||
let def_map = from_module.def_map(db);
|
||||
self.is_visible_from_def_map(db, &def_map, from_module.local_id)
|
||||
}
|
||||
|
||||
pub(crate) fn is_visible_from_other_crate(self) -> bool {
|
||||
matches!(self, Visibility::Public)
|
||||
Self::is_visible_from_def_map_(db, &def_map, to_module, from_module.local_id)
|
||||
}
|
||||
|
||||
pub(crate) fn is_visible_from_def_map(
|
||||
self,
|
||||
db: &dyn DefDatabase,
|
||||
def_map: &DefMap,
|
||||
mut from_module: LocalModuleId,
|
||||
from_module: LocalModuleId,
|
||||
) -> bool {
|
||||
let mut to_module = match self {
|
||||
let to_module = match self {
|
||||
Visibility::Module(m, _) => m,
|
||||
Visibility::Public => return true,
|
||||
};
|
||||
// if they're not in the same crate, it can't be visible
|
||||
if def_map.krate() != to_module.krate {
|
||||
return false;
|
||||
}
|
||||
Self::is_visible_from_def_map_(db, def_map, to_module, from_module)
|
||||
}
|
||||
|
||||
fn is_visible_from_def_map_(
|
||||
db: &dyn DefDatabase,
|
||||
def_map: &DefMap,
|
||||
mut to_module: ModuleId,
|
||||
mut from_module: LocalModuleId,
|
||||
) -> bool {
|
||||
debug_assert_eq!(to_module.krate, def_map.krate());
|
||||
// `to_module` might be the root module of a block expression. Those have the same
|
||||
// visibility as the containing module (even though no items are directly nameable from
|
||||
// there, getting this right is important for method resolution).
|
||||
|
@ -129,20 +146,25 @@ impl Visibility {
|
|||
|
||||
// Additional complication: `to_module` might be in `from_module`'s `DefMap`, which we're
|
||||
// currently computing, so we must not call the `def_map` query for it.
|
||||
let mut arc;
|
||||
let def_map_block = def_map.block_id();
|
||||
loop {
|
||||
let to_module_def_map =
|
||||
if to_module.krate == def_map.krate() && to_module.block == def_map.block_id() {
|
||||
match (to_module.block, def_map_block) {
|
||||
// to_module is not a block, so there is no parent def map to use
|
||||
(None, _) => (),
|
||||
(Some(a), Some(b)) if a == b => {
|
||||
cov_mark::hit!(is_visible_from_same_block_def_map);
|
||||
def_map
|
||||
} else {
|
||||
arc = to_module.def_map(db);
|
||||
&arc
|
||||
};
|
||||
match to_module_def_map.parent() {
|
||||
Some(parent) => to_module = parent,
|
||||
None => break,
|
||||
if let Some(parent) = def_map.parent() {
|
||||
to_module = parent;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if let Some(parent) = to_module.def_map(db).parent() {
|
||||
to_module = parent;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// from_module needs to be a descendant of to_module
|
||||
|
@ -175,30 +197,25 @@ impl Visibility {
|
|||
/// visible in unrelated modules).
|
||||
pub(crate) fn max(self, other: Visibility, def_map: &DefMap) -> Option<Visibility> {
|
||||
match (self, other) {
|
||||
(Visibility::Module(_, _) | Visibility::Public, Visibility::Public)
|
||||
| (Visibility::Public, Visibility::Module(_, _)) => Some(Visibility::Public),
|
||||
(Visibility::Module(mod_a, vis_a), Visibility::Module(mod_b, vis_b)) => {
|
||||
(_, Visibility::Public) | (Visibility::Public, _) => Some(Visibility::Public),
|
||||
(Visibility::Module(mod_a, expl_a), Visibility::Module(mod_b, expl_b)) => {
|
||||
if mod_a.krate != mod_b.krate {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut a_ancestors = iter::successors(Some(mod_a.local_id), |&m| {
|
||||
let parent_id = def_map[m].parent?;
|
||||
Some(parent_id)
|
||||
});
|
||||
let mut b_ancestors = iter::successors(Some(mod_b.local_id), |&m| {
|
||||
let parent_id = def_map[m].parent?;
|
||||
Some(parent_id)
|
||||
});
|
||||
let mut a_ancestors =
|
||||
iter::successors(Some(mod_a.local_id), |&m| def_map[m].parent);
|
||||
let mut b_ancestors =
|
||||
iter::successors(Some(mod_b.local_id), |&m| def_map[m].parent);
|
||||
|
||||
if a_ancestors.any(|m| m == mod_b.local_id) {
|
||||
// B is above A
|
||||
return Some(Visibility::Module(mod_b, vis_b));
|
||||
return Some(Visibility::Module(mod_b, expl_b));
|
||||
}
|
||||
|
||||
if b_ancestors.any(|m| m == mod_a.local_id) {
|
||||
// A is above B
|
||||
return Some(Visibility::Module(mod_a, vis_a));
|
||||
return Some(Visibility::Module(mod_a, expl_a));
|
||||
}
|
||||
|
||||
None
|
||||
|
@ -207,7 +224,8 @@ impl Visibility {
|
|||
}
|
||||
}
|
||||
|
||||
/// Whether the item was imported through `pub(crate) use` or just `use`.
|
||||
/// Whether the item was imported through an explicit `pub(crate) use` or just a `use` without
|
||||
/// visibility.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum VisibilityExplicitness {
|
||||
Explicit,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue