2019-10-30 10:10:38 +00:00
|
|
|
//! `hir_def` crate contains everything between macro expansion and type
|
|
|
|
//! inference.
|
|
|
|
//!
|
|
|
|
//! It defines various items (structs, enums, traits) which comprises Rust code,
|
|
|
|
//! as well as an algorithm for resolving paths to such entities.
|
|
|
|
//!
|
|
|
|
//! Note that `hir_def` is a work in progress, so not all of the above is
|
|
|
|
//! actually true.
|
|
|
|
|
2022-07-20 12:59:42 +00:00
|
|
|
#![warn(rust_2018_idioms, unused_lifetimes, semicolon_in_expressions_from_macros)]
|
|
|
|
|
2020-04-06 14:58:16 +00:00
|
|
|
#[allow(unused)]
|
|
|
|
macro_rules! eprintln {
|
|
|
|
($($tt:tt)*) => { stdx::eprintln!($($tt)*) };
|
|
|
|
}
|
|
|
|
|
2019-10-30 10:10:38 +00:00
|
|
|
pub mod db;
|
2019-11-24 14:00:10 +00:00
|
|
|
|
2019-10-30 13:12:55 +00:00
|
|
|
pub mod attr;
|
|
|
|
pub mod path;
|
|
|
|
pub mod type_ref;
|
2019-10-31 07:51:54 +00:00
|
|
|
pub mod builtin_type;
|
2020-12-11 13:04:33 +00:00
|
|
|
pub mod builtin_attr;
|
2019-11-24 14:00:10 +00:00
|
|
|
pub mod per_ns;
|
2019-12-20 14:38:17 +00:00
|
|
|
pub mod item_scope;
|
2019-11-24 14:00:10 +00:00
|
|
|
|
2019-12-05 22:34:12 +00:00
|
|
|
pub mod dyn_map;
|
|
|
|
pub mod keys;
|
|
|
|
|
2020-03-25 14:33:01 +00:00
|
|
|
pub mod item_tree;
|
2021-04-05 01:50:10 +00:00
|
|
|
pub mod intern;
|
2020-03-25 14:33:01 +00:00
|
|
|
|
2019-11-24 14:00:10 +00:00
|
|
|
pub mod adt;
|
2019-11-22 14:32:10 +00:00
|
|
|
pub mod data;
|
2019-11-24 14:00:10 +00:00
|
|
|
pub mod generics;
|
2019-11-23 09:58:01 +00:00
|
|
|
pub mod lang_item;
|
2019-11-24 14:00:10 +00:00
|
|
|
|
|
|
|
pub mod expr;
|
|
|
|
pub mod body;
|
|
|
|
pub mod resolver;
|
2019-10-30 13:12:55 +00:00
|
|
|
|
2019-11-22 18:43:36 +00:00
|
|
|
mod trace;
|
2019-11-27 14:46:02 +00:00
|
|
|
pub mod nameres;
|
2019-11-22 18:43:36 +00:00
|
|
|
|
2019-11-28 15:05:28 +00:00
|
|
|
pub mod src;
|
2019-12-05 22:34:12 +00:00
|
|
|
pub mod child_by_source;
|
2019-11-28 15:05:28 +00:00
|
|
|
|
2019-12-24 19:32:42 +00:00
|
|
|
pub mod visibility;
|
2019-12-30 13:25:19 +00:00
|
|
|
pub mod find_path;
|
2020-05-20 21:51:20 +00:00
|
|
|
pub mod import_map;
|
2019-12-24 19:32:42 +00:00
|
|
|
|
2019-11-03 17:53:17 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
mod test_db;
|
2021-10-09 10:42:32 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
mod macro_expansion_tests;
|
2019-11-03 17:53:17 +00:00
|
|
|
|
2021-01-22 15:31:40 +00:00
|
|
|
use std::{
|
|
|
|
hash::{Hash, Hasher},
|
|
|
|
sync::Arc,
|
|
|
|
};
|
2019-10-30 10:10:38 +00:00
|
|
|
|
2021-05-31 11:37:11 +00:00
|
|
|
use attr::Attr;
|
2022-03-08 20:41:19 +00:00
|
|
|
use base_db::{impl_intern_key, salsa, CrateId, ProcMacroKind};
|
2020-02-17 04:57:24 +00:00
|
|
|
use hir_expand::{
|
2021-02-28 11:12:11 +00:00
|
|
|
ast_id_map::FileAstId,
|
2022-03-08 20:41:19 +00:00
|
|
|
builtin_attr_macro::BuiltinAttrExpander,
|
|
|
|
builtin_derive_macro::BuiltinDeriveExpander,
|
|
|
|
builtin_fn_macro::{BuiltinFnLikeExpander, EagerExpander},
|
2021-03-17 06:31:14 +00:00
|
|
|
eager::{expand_eager_macro, ErrorEmitted, ErrorSink},
|
2021-02-28 11:12:11 +00:00
|
|
|
hygiene::Hygiene,
|
2022-03-08 20:41:19 +00:00
|
|
|
proc_macro::ProcMacroExpander,
|
2022-02-21 18:14:06 +00:00
|
|
|
AstId, ExpandError, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId,
|
|
|
|
MacroDefKind, UnresolvedMacro,
|
2020-02-17 04:57:24 +00:00
|
|
|
};
|
2021-12-07 16:31:26 +00:00
|
|
|
use item_tree::ExternBlock;
|
2021-01-14 15:47:42 +00:00
|
|
|
use la_arena::Idx;
|
2021-01-22 15:31:40 +00:00
|
|
|
use nameres::DefMap;
|
internal: move diagnostics to hir
The idea here is to eventually get rid of `dyn Diagnostic` and
`DiagnosticSink` infrastructure altogether, and just have a `enum
hir::Diagnostic` instead.
The problem with `dyn Diagnostic` is that it is defined in the lowest
level of the stack (hir_expand), but is used by the highest level (ide).
As a first step, we free hir_expand and hir_def from `dyn Diagnostic`
and kick the can up to `hir_ty`, as an intermediate state. The plan is
then to move DiagnosticSink similarly to the hir crate, and, as final
third step, remove its usage from the ide.
One currently unsolved problem is testing. You can notice that the test
which checks precise diagnostic ranges, unresolved_import_in_use_tree,
was moved to the ide layer. Logically, only IDE should have the infra to
render a specific range.
At the same time, the range is determined with the data produced in
hir_def and hir crates, so this layering is rather unfortunate. Working
on hir_def shouldn't require compiling `ide` for testing.
2021-05-23 20:31:59 +00:00
|
|
|
use stdx::impl_from;
|
2020-08-12 16:26:51 +00:00
|
|
|
use syntax::ast;
|
2019-10-30 10:10:38 +00:00
|
|
|
|
internal: move diagnostics to hir
The idea here is to eventually get rid of `dyn Diagnostic` and
`DiagnosticSink` infrastructure altogether, and just have a `enum
hir::Diagnostic` instead.
The problem with `dyn Diagnostic` is that it is defined in the lowest
level of the stack (hir_expand), but is used by the highest level (ide).
As a first step, we free hir_expand and hir_def from `dyn Diagnostic`
and kick the can up to `hir_ty`, as an intermediate state. The plan is
then to move DiagnosticSink similarly to the hir crate, and, as final
third step, remove its usage from the ide.
One currently unsolved problem is testing. You can notice that the test
which checks precise diagnostic ranges, unresolved_import_in_use_tree,
was moved to the ide layer. Logically, only IDE should have the infra to
render a specific range.
At the same time, the range is determined with the data produced in
hir_def and hir crates, so this layering is rather unfortunate. Working
on hir_def shouldn't require compiling `ide` for testing.
2021-05-23 20:31:59 +00:00
|
|
|
use crate::{
|
|
|
|
adt::VariantData,
|
|
|
|
attr::AttrId,
|
|
|
|
builtin_type::BuiltinType,
|
|
|
|
item_tree::{
|
2022-03-08 20:41:19 +00:00
|
|
|
Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, MacroDef, MacroRules, ModItem,
|
|
|
|
Static, Struct, Trait, TypeAlias, Union,
|
internal: move diagnostics to hir
The idea here is to eventually get rid of `dyn Diagnostic` and
`DiagnosticSink` infrastructure altogether, and just have a `enum
hir::Diagnostic` instead.
The problem with `dyn Diagnostic` is that it is defined in the lowest
level of the stack (hir_expand), but is used by the highest level (ide).
As a first step, we free hir_expand and hir_def from `dyn Diagnostic`
and kick the can up to `hir_ty`, as an intermediate state. The plan is
then to move DiagnosticSink similarly to the hir crate, and, as final
third step, remove its usage from the ide.
One currently unsolved problem is testing. You can notice that the test
which checks precise diagnostic ranges, unresolved_import_in_use_tree,
was moved to the ide layer. Logically, only IDE should have the infra to
render a specific range.
At the same time, the range is determined with the data produced in
hir_def and hir crates, so this layering is rather unfortunate. Working
on hir_def shouldn't require compiling `ide` for testing.
2021-05-23 20:31:59 +00:00
|
|
|
},
|
2020-06-22 13:07:06 +00:00
|
|
|
};
|
2019-10-30 10:10:38 +00:00
|
|
|
|
2019-11-23 13:49:05 +00:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
2019-10-30 09:27:54 +00:00
|
|
|
pub struct ModuleId {
|
2021-01-22 17:09:55 +00:00
|
|
|
krate: CrateId,
|
2021-03-18 23:06:35 +00:00
|
|
|
/// If this `ModuleId` was derived from a `DefMap` for a block expression, this stores the
|
|
|
|
/// `BlockId` of that block expression. If `None`, this module is part of the crate-level
|
|
|
|
/// `DefMap` of `krate`.
|
2021-01-25 18:02:05 +00:00
|
|
|
block: Option<BlockId>,
|
2021-03-18 23:06:35 +00:00
|
|
|
/// The module's ID in its originating `DefMap`.
|
2019-11-27 18:31:51 +00:00
|
|
|
pub local_id: LocalModuleId,
|
2019-10-30 09:27:54 +00:00
|
|
|
}
|
|
|
|
|
2021-01-22 15:31:40 +00:00
|
|
|
impl ModuleId {
|
|
|
|
pub fn def_map(&self, db: &dyn db::DefDatabase) -> Arc<DefMap> {
|
2021-01-25 18:02:05 +00:00
|
|
|
match self.block {
|
2021-02-01 12:32:43 +00:00
|
|
|
Some(block) => {
|
|
|
|
db.block_def_map(block).unwrap_or_else(|| {
|
|
|
|
// NOTE: This should be unreachable - all `ModuleId`s come from their `DefMap`s,
|
|
|
|
// so the `DefMap` here must exist.
|
2021-03-18 23:06:35 +00:00
|
|
|
unreachable!("no `block_def_map` for `ModuleId` {:?}", self);
|
2021-02-01 12:32:43 +00:00
|
|
|
})
|
|
|
|
}
|
2021-01-25 18:02:05 +00:00
|
|
|
None => db.crate_def_map(self.krate),
|
|
|
|
}
|
2021-01-22 15:31:40 +00:00
|
|
|
}
|
2021-01-22 17:09:55 +00:00
|
|
|
|
|
|
|
pub fn krate(&self) -> CrateId {
|
|
|
|
self.krate
|
|
|
|
}
|
2021-03-01 18:36:34 +00:00
|
|
|
|
|
|
|
pub fn containing_module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId> {
|
|
|
|
self.def_map(db).containing_module(self.local_id)
|
|
|
|
}
|
2021-04-18 23:06:04 +00:00
|
|
|
|
2021-06-13 11:00:34 +00:00
|
|
|
pub fn containing_block(&self) -> Option<BlockId> {
|
|
|
|
self.block
|
|
|
|
}
|
2021-01-22 15:31:40 +00:00
|
|
|
}
|
|
|
|
|
2019-10-30 09:27:54 +00:00
|
|
|
/// An ID of a module, **local** to a specific crate
|
2020-03-19 15:00:11 +00:00
|
|
|
pub type LocalModuleId = Idx<nameres::ModuleData>;
|
2019-10-30 10:10:38 +00:00
|
|
|
|
2020-06-22 13:07:06 +00:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct ItemLoc<N: ItemTreeNode> {
|
2021-03-09 18:09:02 +00:00
|
|
|
pub container: ModuleId,
|
2020-06-22 13:07:06 +00:00
|
|
|
pub id: ItemTreeId<N>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N: ItemTreeNode> Clone for ItemLoc<N> {
|
|
|
|
fn clone(&self) -> Self {
|
|
|
|
Self { container: self.container, id: self.id }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
2019-12-20 12:11:01 +00:00
|
|
|
}
|
2019-10-30 10:10:38 +00:00
|
|
|
|
2020-06-22 13:07:06 +00:00
|
|
|
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> {
|
2021-12-07 16:31:26 +00:00
|
|
|
pub container: ItemContainerId,
|
2020-06-22 13:07:06 +00:00
|
|
|
pub id: ItemTreeId<N>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N: ItemTreeNode> Clone for AssocItemLoc<N> {
|
|
|
|
fn clone(&self) -> Self {
|
|
|
|
Self { container: self.container, id: self.id }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2019-11-20 13:03:59 +00:00
|
|
|
}
|
|
|
|
|
2019-12-20 12:19:41 +00:00
|
|
|
macro_rules! impl_intern {
|
|
|
|
($id:ident, $loc:ident, $intern:ident, $lookup:ident) => {
|
|
|
|
impl_intern_key!($id);
|
|
|
|
|
|
|
|
impl Intern for $loc {
|
|
|
|
type ID = $id;
|
2020-03-13 15:05:46 +00:00
|
|
|
fn intern(self, db: &dyn db::DefDatabase) -> $id {
|
2019-12-20 12:19:41 +00:00
|
|
|
db.$intern(self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Lookup for $id {
|
|
|
|
type Data = $loc;
|
2020-03-13 15:05:46 +00:00
|
|
|
fn lookup(&self, db: &dyn db::DefDatabase) -> $loc {
|
2019-12-20 12:19:41 +00:00
|
|
|
db.$lookup(*self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-12-20 12:11:01 +00:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct FunctionId(salsa::InternId);
|
2020-06-22 13:07:06 +00:00
|
|
|
type FunctionLoc = AssocItemLoc<Function>;
|
2019-12-20 12:19:41 +00:00
|
|
|
impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function);
|
2019-10-30 10:10:38 +00:00
|
|
|
|
2020-07-15 19:47:45 +00:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
2019-11-25 14:30:50 +00:00
|
|
|
pub struct StructId(salsa::InternId);
|
2020-06-22 13:07:06 +00:00
|
|
|
type StructLoc = ItemLoc<Struct>;
|
2019-12-20 12:19:41 +00:00
|
|
|
impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct);
|
2019-10-30 10:10:38 +00:00
|
|
|
|
2020-07-15 19:47:45 +00:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
2019-11-25 14:30:50 +00:00
|
|
|
pub struct UnionId(salsa::InternId);
|
2020-06-22 13:07:06 +00:00
|
|
|
pub type UnionLoc = ItemLoc<Union>;
|
2019-12-20 12:19:41 +00:00
|
|
|
impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union);
|
2019-10-30 13:12:55 +00:00
|
|
|
|
2020-07-15 19:47:45 +00:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
2019-10-30 10:10:38 +00:00
|
|
|
pub struct EnumId(salsa::InternId);
|
2020-06-22 13:07:06 +00:00
|
|
|
pub type EnumLoc = ItemLoc<Enum>;
|
2019-12-20 12:19:41 +00:00
|
|
|
impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum);
|
2019-10-30 10:10:38 +00:00
|
|
|
|
2019-10-30 13:12:55 +00:00
|
|
|
// FIXME: rename to `VariantId`, only enums can ave variants
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct EnumVariantId {
|
2019-10-31 15:45:10 +00:00
|
|
|
pub parent: EnumId,
|
|
|
|
pub local_id: LocalEnumVariantId,
|
2019-10-30 13:12:55 +00:00
|
|
|
}
|
|
|
|
|
2020-03-19 15:00:11 +00:00
|
|
|
pub type LocalEnumVariantId = Idx<adt::EnumVariantData>;
|
2019-10-30 13:12:55 +00:00
|
|
|
|
2019-10-31 13:40:36 +00:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
2020-04-25 12:23:34 +00:00
|
|
|
pub struct FieldId {
|
2019-11-23 08:14:10 +00:00
|
|
|
pub parent: VariantId,
|
2020-04-25 12:23:34 +00:00
|
|
|
pub local_id: LocalFieldId,
|
2019-10-31 13:40:36 +00:00
|
|
|
}
|
|
|
|
|
2020-04-25 12:23:34 +00:00
|
|
|
pub type LocalFieldId = Idx<adt::FieldData>;
|
2019-10-31 13:40:36 +00:00
|
|
|
|
2019-10-30 10:10:38 +00:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct ConstId(salsa::InternId);
|
2020-06-22 13:07:06 +00:00
|
|
|
type ConstLoc = AssocItemLoc<Const>;
|
2019-12-20 12:19:41 +00:00
|
|
|
impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const);
|
2019-10-30 10:10:38 +00:00
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct StaticId(salsa::InternId);
|
2021-12-07 16:31:26 +00:00
|
|
|
pub type StaticLoc = AssocItemLoc<Static>;
|
2019-12-20 12:19:41 +00:00
|
|
|
impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static);
|
2019-10-30 10:10:38 +00:00
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct TraitId(salsa::InternId);
|
2020-06-22 13:07:06 +00:00
|
|
|
pub type TraitLoc = ItemLoc<Trait>;
|
2019-12-20 12:19:41 +00:00
|
|
|
impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait);
|
2019-10-30 10:10:38 +00:00
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct TypeAliasId(salsa::InternId);
|
2020-06-22 13:07:06 +00:00
|
|
|
type TypeAliasLoc = AssocItemLoc<TypeAlias>;
|
2019-12-20 12:19:41 +00:00
|
|
|
impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias);
|
2019-10-31 08:23:30 +00:00
|
|
|
|
2020-06-18 23:29:34 +00:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
2019-11-15 16:14:50 +00:00
|
|
|
pub struct ImplId(salsa::InternId);
|
2020-06-22 13:07:06 +00:00
|
|
|
type ImplLoc = ItemLoc<Impl>;
|
2019-12-20 12:47:44 +00:00
|
|
|
impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl);
|
2019-11-15 16:14:50 +00:00
|
|
|
|
2021-12-07 16:31:26 +00:00
|
|
|
#[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);
|
|
|
|
|
2022-03-08 20:41:19 +00:00
|
|
|
#[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<MacroDef>,
|
|
|
|
pub expander: MacroExpander,
|
|
|
|
}
|
|
|
|
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 local_inner: bool,
|
|
|
|
pub expander: MacroExpander,
|
|
|
|
}
|
|
|
|
impl_intern!(MacroRulesId, MacroRulesLoc, intern_macro_rules, lookup_intern_macro_rules);
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
|
|
|
pub struct ProcMacroId(salsa::InternId);
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct ProcMacroLoc {
|
|
|
|
// FIXME: this should be a crate? or just a crate-root module
|
|
|
|
pub container: ModuleId,
|
|
|
|
pub id: ItemTreeId<Function>,
|
|
|
|
pub expander: ProcMacroExpander,
|
|
|
|
pub kind: ProcMacroKind,
|
|
|
|
}
|
|
|
|
impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro);
|
|
|
|
|
2021-01-25 18:02:05 +00:00
|
|
|
#[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>,
|
2021-02-01 12:32:43 +00:00
|
|
|
/// The containing module.
|
2021-01-25 18:02:05 +00:00
|
|
|
module: ModuleId,
|
|
|
|
}
|
|
|
|
impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block);
|
|
|
|
|
2019-12-20 12:11:01 +00:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
2021-12-29 13:35:59 +00:00
|
|
|
pub struct TypeOrConstParamId {
|
2019-12-20 12:11:01 +00:00
|
|
|
pub parent: GenericDefId,
|
2021-12-29 13:35:59 +00:00
|
|
|
pub local_id: LocalTypeOrConstParamId,
|
2019-12-20 12:11:01 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 13:35:59 +00:00
|
|
|
/// A TypeOrConstParamId with an invariant that it actually belongs to a type
|
2022-03-08 20:41:19 +00:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
2021-12-29 13:35:59 +00:00
|
|
|
pub struct TypeParamId(TypeOrConstParamId);
|
|
|
|
|
|
|
|
impl TypeParamId {
|
|
|
|
pub fn parent(&self) -> GenericDefId {
|
|
|
|
self.0.parent
|
|
|
|
}
|
|
|
|
pub fn local_id(&self) -> LocalTypeOrConstParamId {
|
|
|
|
self.0.local_id
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-09 18:50:24 +00:00
|
|
|
impl TypeParamId {
|
|
|
|
/// Caller should check if this toc id really belongs to a type
|
|
|
|
pub fn from_unchecked(x: TypeOrConstParamId) -> Self {
|
2021-12-29 13:35:59 +00:00
|
|
|
Self(x)
|
|
|
|
}
|
|
|
|
}
|
2022-03-09 18:50:24 +00:00
|
|
|
|
2021-12-29 13:35:59 +00:00
|
|
|
impl From<TypeParamId> for TypeOrConstParamId {
|
|
|
|
fn from(x: TypeParamId) -> Self {
|
|
|
|
x.0
|
|
|
|
}
|
|
|
|
}
|
2019-12-20 12:11:01 +00:00
|
|
|
|
2021-12-29 13:35:59 +00:00
|
|
|
/// A TypeOrConstParamId with an invariant that it actually belongs to a const
|
2022-06-12 14:07:08 +00:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
2021-12-29 13:35:59 +00:00
|
|
|
pub struct ConstParamId(TypeOrConstParamId);
|
|
|
|
|
|
|
|
impl ConstParamId {
|
|
|
|
pub fn parent(&self) -> GenericDefId {
|
|
|
|
self.0.parent
|
|
|
|
}
|
|
|
|
pub fn local_id(&self) -> LocalTypeOrConstParamId {
|
|
|
|
self.0.local_id
|
|
|
|
}
|
2020-12-11 12:49:32 +00:00
|
|
|
}
|
2021-12-29 13:35:59 +00:00
|
|
|
|
2022-03-09 18:50:24 +00:00
|
|
|
impl ConstParamId {
|
|
|
|
/// Caller should check if this toc id really belongs to a const
|
|
|
|
pub fn from_unchecked(x: TypeOrConstParamId) -> Self {
|
2021-12-29 13:35:59 +00:00
|
|
|
Self(x)
|
|
|
|
}
|
|
|
|
}
|
2022-03-09 18:50:24 +00:00
|
|
|
|
2021-12-29 13:35:59 +00:00
|
|
|
impl From<ConstParamId> for TypeOrConstParamId {
|
|
|
|
fn from(x: ConstParamId) -> Self {
|
|
|
|
x.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub type LocalTypeOrConstParamId = Idx<generics::TypeOrConstParamData>;
|
2020-12-11 12:49:32 +00:00
|
|
|
|
2021-01-01 09:06:42 +00:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
2021-12-29 13:35:59 +00:00
|
|
|
pub struct LifetimeParamId {
|
2021-01-01 09:06:42 +00:00
|
|
|
pub parent: GenericDefId,
|
2021-12-29 13:35:59 +00:00
|
|
|
pub local_id: LocalLifetimeParamId,
|
2021-01-01 09:06:42 +00:00
|
|
|
}
|
2021-12-29 13:35:59 +00:00
|
|
|
pub type LocalLifetimeParamId = Idx<generics::LifetimeParamData>;
|
2021-01-01 09:06:42 +00:00
|
|
|
|
2019-12-20 11:07:23 +00:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
2021-12-07 16:31:26 +00:00
|
|
|
pub enum ItemContainerId {
|
|
|
|
ExternBlockId(ExternBlockId),
|
2021-03-09 17:27:16 +00:00
|
|
|
ModuleId(ModuleId),
|
2019-11-20 14:49:57 +00:00
|
|
|
ImplId(ImplId),
|
|
|
|
TraitId(TraitId),
|
|
|
|
}
|
2021-12-07 16:31:26 +00:00
|
|
|
impl_from!(ModuleId for ItemContainerId);
|
2019-11-20 14:49:57 +00:00
|
|
|
|
2019-10-31 08:23:30 +00:00
|
|
|
/// A Data Type
|
2020-07-15 19:47:45 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
2019-10-31 08:23:30 +00:00
|
|
|
pub enum AdtId {
|
|
|
|
StructId(StructId),
|
|
|
|
UnionId(UnionId),
|
|
|
|
EnumId(EnumId),
|
|
|
|
}
|
2020-07-13 14:16:53 +00:00
|
|
|
impl_from!(StructId, UnionId, EnumId for AdtId);
|
2019-10-31 08:23:30 +00:00
|
|
|
|
2022-03-08 20:41:19 +00:00
|
|
|
/// A macro
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
|
|
|
pub enum MacroId {
|
|
|
|
Macro2Id(Macro2Id),
|
|
|
|
MacroRulesId(MacroRulesId),
|
|
|
|
ProcMacroId(ProcMacroId),
|
|
|
|
}
|
|
|
|
impl_from!(Macro2Id, MacroRulesId, ProcMacroId for MacroId);
|
|
|
|
|
|
|
|
impl MacroId {
|
|
|
|
pub fn is_attribute(self, db: &dyn db::DefDatabase) -> bool {
|
|
|
|
match self {
|
|
|
|
MacroId::ProcMacroId(it) => it.lookup(db).kind == ProcMacroKind::Attr,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-01 23:42:07 +00:00
|
|
|
/// A generic param
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
|
|
|
pub enum GenericParamId {
|
|
|
|
TypeParamId(TypeParamId),
|
|
|
|
ConstParamId(ConstParamId),
|
2021-12-29 13:35:59 +00:00
|
|
|
LifetimeParamId(LifetimeParamId),
|
2021-01-01 23:42:07 +00:00
|
|
|
}
|
|
|
|
impl_from!(TypeParamId, LifetimeParamId, ConstParamId for GenericParamId);
|
|
|
|
|
2019-10-31 08:23:30 +00:00
|
|
|
/// The defs which can be visible in the module.
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub enum ModuleDefId {
|
|
|
|
ModuleId(ModuleId),
|
|
|
|
FunctionId(FunctionId),
|
|
|
|
AdtId(AdtId),
|
|
|
|
// Can't be directly declared, but can be imported.
|
|
|
|
EnumVariantId(EnumVariantId),
|
|
|
|
ConstId(ConstId),
|
|
|
|
StaticId(StaticId),
|
|
|
|
TraitId(TraitId),
|
|
|
|
TypeAliasId(TypeAliasId),
|
|
|
|
BuiltinType(BuiltinType),
|
2022-03-08 20:41:19 +00:00
|
|
|
MacroId(MacroId),
|
2019-10-31 08:23:30 +00:00
|
|
|
}
|
2020-07-13 14:16:53 +00:00
|
|
|
impl_from!(
|
2022-03-08 23:19:53 +00:00
|
|
|
MacroId(Macro2Id, MacroRulesId, ProcMacroId),
|
2020-07-13 14:16:53 +00:00
|
|
|
ModuleId,
|
2019-10-31 08:23:30 +00:00
|
|
|
FunctionId,
|
|
|
|
AdtId(StructId, EnumId, UnionId),
|
|
|
|
EnumVariantId,
|
|
|
|
ConstId,
|
|
|
|
StaticId,
|
|
|
|
TraitId,
|
|
|
|
TypeAliasId,
|
|
|
|
BuiltinType
|
2020-07-13 14:16:53 +00:00
|
|
|
for ModuleDefId
|
2019-10-31 08:23:30 +00:00
|
|
|
);
|
2019-11-14 14:37:22 +00:00
|
|
|
|
|
|
|
/// The defs which have a body.
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub enum DefWithBodyId {
|
|
|
|
FunctionId(FunctionId),
|
|
|
|
StaticId(StaticId),
|
|
|
|
ConstId(ConstId),
|
|
|
|
}
|
|
|
|
|
2020-07-13 14:16:53 +00:00
|
|
|
impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId);
|
2019-11-15 18:28:00 +00:00
|
|
|
|
2021-03-13 19:38:11 +00:00
|
|
|
impl DefWithBodyId {
|
|
|
|
pub fn as_generic_def_id(self) -> Option<GenericDefId> {
|
|
|
|
match self {
|
|
|
|
DefWithBodyId::FunctionId(f) => Some(f.into()),
|
|
|
|
DefWithBodyId::StaticId(_) => None,
|
|
|
|
DefWithBodyId::ConstId(c) => Some(c.into()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-15 18:28:00 +00:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
|
|
|
pub enum AssocItemId {
|
|
|
|
FunctionId(FunctionId),
|
|
|
|
ConstId(ConstId),
|
|
|
|
TypeAliasId(TypeAliasId),
|
|
|
|
}
|
|
|
|
// FIXME: not every function, ... is actually an assoc item. maybe we should make
|
|
|
|
// sure that you can only turn actual assoc items into AssocItemIds. This would
|
|
|
|
// require not implementing From, and instead having some checked way of
|
|
|
|
// casting them, and somehow making the constructors private, which would be annoying.
|
2020-07-13 14:16:53 +00:00
|
|
|
impl_from!(FunctionId, ConstId, TypeAliasId for AssocItemId);
|
2019-11-20 09:25:02 +00:00
|
|
|
|
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
|
|
|
pub enum GenericDefId {
|
|
|
|
FunctionId(FunctionId),
|
|
|
|
AdtId(AdtId),
|
|
|
|
TraitId(TraitId),
|
|
|
|
TypeAliasId(TypeAliasId),
|
|
|
|
ImplId(ImplId),
|
|
|
|
// enum variants cannot have generics themselves, but their parent enums
|
|
|
|
// can, and this makes some code easier to write
|
|
|
|
EnumVariantId(EnumVariantId),
|
|
|
|
// consts can have type parameters from their parents (i.e. associated consts of traits)
|
|
|
|
ConstId(ConstId),
|
|
|
|
}
|
2020-07-13 14:16:53 +00:00
|
|
|
impl_from!(
|
|
|
|
FunctionId,
|
2019-11-20 09:25:02 +00:00
|
|
|
AdtId(StructId, EnumId, UnionId),
|
|
|
|
TraitId,
|
|
|
|
TypeAliasId,
|
|
|
|
ImplId,
|
|
|
|
EnumVariantId,
|
|
|
|
ConstId
|
2020-07-13 14:16:53 +00:00
|
|
|
for GenericDefId
|
2019-11-20 09:25:02 +00:00
|
|
|
);
|
2019-11-20 13:03:59 +00:00
|
|
|
|
2019-11-27 09:31:40 +00:00
|
|
|
impl From<AssocItemId> for GenericDefId {
|
|
|
|
fn from(item: AssocItemId) -> Self {
|
|
|
|
match item {
|
|
|
|
AssocItemId::FunctionId(f) => f.into(),
|
|
|
|
AssocItemId::ConstId(c) => c.into(),
|
|
|
|
AssocItemId::TypeAliasId(t) => t.into(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-23 08:14:10 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
|
|
|
pub enum AttrDefId {
|
|
|
|
ModuleId(ModuleId),
|
2020-04-25 12:23:34 +00:00
|
|
|
FieldId(FieldId),
|
2019-11-23 08:14:10 +00:00
|
|
|
AdtId(AdtId),
|
|
|
|
FunctionId(FunctionId),
|
|
|
|
EnumVariantId(EnumVariantId),
|
|
|
|
StaticId(StaticId),
|
|
|
|
ConstId(ConstId),
|
|
|
|
TraitId(TraitId),
|
|
|
|
TypeAliasId(TypeAliasId),
|
2022-03-08 22:51:19 +00:00
|
|
|
MacroId(MacroId),
|
2019-11-23 09:01:56 +00:00
|
|
|
ImplId(ImplId),
|
2021-01-01 23:42:07 +00:00
|
|
|
GenericParamId(GenericParamId),
|
2021-12-07 16:31:26 +00:00
|
|
|
ExternBlockId(ExternBlockId),
|
2019-11-23 08:14:10 +00:00
|
|
|
}
|
|
|
|
|
2020-07-13 14:16:53 +00:00
|
|
|
impl_from!(
|
|
|
|
ModuleId,
|
2020-04-25 12:23:34 +00:00
|
|
|
FieldId,
|
2019-11-23 08:14:10 +00:00
|
|
|
AdtId(StructId, EnumId, UnionId),
|
|
|
|
EnumVariantId,
|
|
|
|
StaticId,
|
|
|
|
ConstId,
|
|
|
|
FunctionId,
|
|
|
|
TraitId,
|
|
|
|
TypeAliasId,
|
2022-03-09 10:26:06 +00:00
|
|
|
MacroId(Macro2Id, MacroRulesId, ProcMacroId),
|
2021-01-01 23:42:07 +00:00
|
|
|
ImplId,
|
|
|
|
GenericParamId
|
2020-07-13 14:16:53 +00:00
|
|
|
for AttrDefId
|
2019-11-23 08:14:10 +00:00
|
|
|
);
|
|
|
|
|
2021-12-07 16:31:26 +00:00
|
|
|
impl From<ItemContainerId> for AttrDefId {
|
|
|
|
fn from(acid: ItemContainerId) -> Self {
|
2021-04-08 11:37:34 +00:00
|
|
|
match acid {
|
2021-12-07 16:31:26 +00:00
|
|
|
ItemContainerId::ModuleId(mid) => AttrDefId::ModuleId(mid),
|
|
|
|
ItemContainerId::ImplId(iid) => AttrDefId::ImplId(iid),
|
|
|
|
ItemContainerId::TraitId(tid) => AttrDefId::TraitId(tid),
|
|
|
|
ItemContainerId::ExternBlockId(id) => AttrDefId::ExternBlockId(id),
|
2021-04-08 11:37:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-24 20:48:39 +00:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub enum VariantId {
|
|
|
|
EnumVariantId(EnumVariantId),
|
|
|
|
StructId(StructId),
|
2019-11-25 14:34:15 +00:00
|
|
|
UnionId(UnionId),
|
2019-11-24 20:48:39 +00:00
|
|
|
}
|
2020-07-13 14:16:53 +00:00
|
|
|
impl_from!(EnumVariantId, StructId, UnionId for VariantId);
|
2019-11-24 20:48:39 +00:00
|
|
|
|
2021-04-06 15:59:18 +00:00
|
|
|
impl VariantId {
|
|
|
|
pub fn variant_data(self, db: &dyn db::DefDatabase) -> Arc<VariantData> {
|
|
|
|
match self {
|
|
|
|
VariantId::StructId(it) => db.struct_data(it).variant_data.clone(),
|
|
|
|
VariantId::UnionId(it) => db.union_data(it).variant_data.clone(),
|
|
|
|
VariantId::EnumVariantId(it) => {
|
|
|
|
db.enum_data(it.parent).variants[it.local_id].variant_data.clone()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-04-06 20:25:44 +00:00
|
|
|
|
|
|
|
pub fn file_id(self, db: &dyn db::DefDatabase) -> HirFileId {
|
|
|
|
match self {
|
|
|
|
VariantId::EnumVariantId(it) => it.parent.lookup(db).id.file_id(),
|
|
|
|
VariantId::StructId(it) => it.lookup(db).id.file_id(),
|
|
|
|
VariantId::UnionId(it) => it.lookup(db).id.file_id(),
|
|
|
|
}
|
|
|
|
}
|
2021-05-23 16:10:40 +00:00
|
|
|
|
|
|
|
pub fn adt_id(self) -> AdtId {
|
|
|
|
match self {
|
|
|
|
VariantId::EnumVariantId(it) => it.parent.into(),
|
|
|
|
VariantId::StructId(it) => it.into(),
|
|
|
|
VariantId::UnionId(it) => it.into(),
|
|
|
|
}
|
|
|
|
}
|
2021-04-06 15:59:18 +00:00
|
|
|
}
|
|
|
|
|
2019-11-20 13:03:59 +00:00
|
|
|
trait Intern {
|
|
|
|
type ID;
|
2020-03-13 15:05:46 +00:00
|
|
|
fn intern(self, db: &dyn db::DefDatabase) -> Self::ID;
|
2019-11-20 13:03:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub trait Lookup {
|
|
|
|
type Data;
|
2020-03-13 15:05:46 +00:00
|
|
|
fn lookup(&self, db: &dyn db::DefDatabase) -> Self::Data;
|
2019-11-20 13:03:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub trait HasModule {
|
2020-03-13 15:05:46 +00:00
|
|
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId;
|
2019-11-20 13:03:59 +00:00
|
|
|
}
|
|
|
|
|
2021-12-07 16:31:26 +00:00
|
|
|
impl HasModule for ItemContainerId {
|
2020-03-13 15:05:46 +00:00
|
|
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
2019-12-19 17:12:46 +00:00
|
|
|
match *self {
|
2021-12-07 16:31:26 +00:00
|
|
|
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,
|
2019-11-20 13:03:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-22 13:07:06 +00:00
|
|
|
impl<N: ItemTreeNode> HasModule for AssocItemLoc<N> {
|
2020-03-13 15:05:46 +00:00
|
|
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
2019-12-19 17:12:46 +00:00
|
|
|
self.container.module(db)
|
2019-11-20 15:00:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-24 19:47:58 +00:00
|
|
|
impl HasModule for AdtId {
|
2020-03-13 15:05:46 +00:00
|
|
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
2019-11-24 19:47:58 +00:00
|
|
|
match self {
|
2019-12-12 13:58:04 +00:00
|
|
|
AdtId::StructId(it) => it.lookup(db).container,
|
2019-12-12 14:11:57 +00:00
|
|
|
AdtId::UnionId(it) => it.lookup(db).container,
|
|
|
|
AdtId::EnumId(it) => it.lookup(db).container,
|
2019-11-24 19:47:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-17 13:29:29 +00:00
|
|
|
impl HasModule for VariantId {
|
|
|
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
|
|
|
match self {
|
2021-03-09 18:09:02 +00:00
|
|
|
VariantId::EnumVariantId(it) => it.parent.lookup(db).container,
|
|
|
|
VariantId::StructId(it) => it.lookup(db).container,
|
|
|
|
VariantId::UnionId(it) => it.lookup(db).container,
|
2020-12-17 13:29:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-08 20:41:19 +00:00
|
|
|
impl HasModule for MacroId {
|
|
|
|
fn module(&self, db: &dyn db::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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-26 11:02:57 +00:00
|
|
|
impl HasModule for DefWithBodyId {
|
2020-03-13 15:05:46 +00:00
|
|
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
2019-11-26 11:02:57 +00:00
|
|
|
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),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-22 13:07:06 +00:00
|
|
|
impl DefWithBodyId {
|
|
|
|
pub fn as_mod_item(self, db: &dyn db::DefDatabase) -> ModItem {
|
|
|
|
match self {
|
|
|
|
DefWithBodyId::FunctionId(it) => it.lookup(db).id.value.into(),
|
|
|
|
DefWithBodyId::StaticId(it) => it.lookup(db).id.value.into(),
|
|
|
|
DefWithBodyId::ConstId(it) => it.lookup(db).id.value.into(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-07 18:52:09 +00:00
|
|
|
impl HasModule for GenericDefId {
|
2020-03-13 15:05:46 +00:00
|
|
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
2019-12-07 18:52:09 +00:00
|
|
|
match self {
|
|
|
|
GenericDefId::FunctionId(it) => it.lookup(db).module(db),
|
|
|
|
GenericDefId::AdtId(it) => it.module(db),
|
2021-03-09 18:09:02 +00:00
|
|
|
GenericDefId::TraitId(it) => it.lookup(db).container,
|
2019-12-07 18:52:09 +00:00
|
|
|
GenericDefId::TypeAliasId(it) => it.lookup(db).module(db),
|
2021-03-09 18:09:02 +00:00
|
|
|
GenericDefId::ImplId(it) => it.lookup(db).container,
|
|
|
|
GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container,
|
2019-12-07 18:52:09 +00:00
|
|
|
GenericDefId::ConstId(it) => it.lookup(db).module(db),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-13 11:00:34 +00:00
|
|
|
impl HasModule for TypeAliasId {
|
|
|
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
|
|
|
self.lookup(db).module(db)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl HasModule for TraitId {
|
|
|
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
|
|
|
self.lookup(db).container
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-01 18:36:34 +00:00
|
|
|
impl ModuleDefId {
|
|
|
|
/// Returns the module containing `self` (or `self`, if `self` is itself a module).
|
|
|
|
///
|
|
|
|
/// Returns `None` if `self` refers to a primitive type.
|
|
|
|
pub fn module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId> {
|
|
|
|
Some(match self {
|
|
|
|
ModuleDefId::ModuleId(id) => *id,
|
|
|
|
ModuleDefId::FunctionId(id) => id.lookup(db).module(db),
|
|
|
|
ModuleDefId::AdtId(id) => id.module(db),
|
2021-03-09 18:09:02 +00:00
|
|
|
ModuleDefId::EnumVariantId(id) => id.parent.lookup(db).container,
|
2021-03-01 18:36:34 +00:00
|
|
|
ModuleDefId::ConstId(id) => id.lookup(db).container.module(db),
|
2021-12-07 16:31:26 +00:00
|
|
|
ModuleDefId::StaticId(id) => id.lookup(db).module(db),
|
2021-03-09 18:09:02 +00:00
|
|
|
ModuleDefId::TraitId(id) => id.lookup(db).container,
|
2021-03-01 18:36:34 +00:00
|
|
|
ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db),
|
2022-03-08 20:41:19 +00:00
|
|
|
ModuleDefId::MacroId(id) => id.module(db),
|
2021-03-01 18:36:34 +00:00
|
|
|
ModuleDefId::BuiltinType(_) => return None,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-17 13:29:29 +00:00
|
|
|
impl AttrDefId {
|
|
|
|
pub fn krate(&self, db: &dyn db::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,
|
2021-03-09 18:09:02 +00:00
|
|
|
AttrDefId::EnumVariantId(it) => it.parent.lookup(db).container.krate,
|
2020-12-17 13:29:29 +00:00
|
|
|
AttrDefId::StaticId(it) => it.lookup(db).module(db).krate,
|
|
|
|
AttrDefId::ConstId(it) => it.lookup(db).module(db).krate,
|
2021-03-09 18:09:02 +00:00
|
|
|
AttrDefId::TraitId(it) => it.lookup(db).container.krate,
|
2020-12-17 13:29:29 +00:00
|
|
|
AttrDefId::TypeAliasId(it) => it.lookup(db).module(db).krate,
|
2021-03-09 18:09:02 +00:00
|
|
|
AttrDefId::ImplId(it) => it.lookup(db).container.krate,
|
2021-12-07 16:31:26 +00:00
|
|
|
AttrDefId::ExternBlockId(it) => it.lookup(db).container.krate,
|
2021-01-01 23:42:07 +00:00
|
|
|
AttrDefId::GenericParamId(it) => {
|
|
|
|
match it {
|
2021-12-29 13:35:59 +00:00
|
|
|
GenericParamId::TypeParamId(it) => it.parent(),
|
|
|
|
GenericParamId::ConstParamId(it) => it.parent(),
|
2021-01-01 23:42:07 +00:00
|
|
|
GenericParamId::LifetimeParamId(it) => it.parent,
|
|
|
|
}
|
|
|
|
.module(db)
|
|
|
|
.krate
|
|
|
|
}
|
2022-03-08 22:51:19 +00:00
|
|
|
AttrDefId::MacroId(it) => it.module(db).krate,
|
2020-12-17 13:29:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-17 04:57:24 +00:00
|
|
|
/// A helper trait for converting to MacroCallId
|
|
|
|
pub trait AsMacroCall {
|
|
|
|
fn as_call_id(
|
|
|
|
&self,
|
2020-03-13 15:05:46 +00:00
|
|
|
db: &dyn db::DefDatabase,
|
2020-06-11 10:08:24 +00:00
|
|
|
krate: CrateId,
|
2020-02-17 04:57:24 +00:00
|
|
|
resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
|
2020-12-02 15:52:14 +00:00
|
|
|
) -> Option<MacroCallId> {
|
2021-03-17 06:31:14 +00:00
|
|
|
self.as_call_id_with_errors(db, krate, resolver, &mut |_| ()).ok()?.ok()
|
2020-12-02 15:52:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn as_call_id_with_errors(
|
|
|
|
&self,
|
|
|
|
db: &dyn db::DefDatabase,
|
|
|
|
krate: CrateId,
|
|
|
|
resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
|
2022-02-21 18:14:06 +00:00
|
|
|
error_sink: &mut dyn FnMut(ExpandError),
|
2021-03-17 06:31:14 +00:00
|
|
|
) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro>;
|
2020-02-17 04:57:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl AsMacroCall for InFile<&ast::MacroCall> {
|
2020-12-02 15:52:14 +00:00
|
|
|
fn as_call_id_with_errors(
|
2020-02-17 04:57:24 +00:00
|
|
|
&self,
|
2020-03-13 15:05:46 +00:00
|
|
|
db: &dyn db::DefDatabase,
|
2020-06-11 10:08:24 +00:00
|
|
|
krate: CrateId,
|
2020-02-17 04:57:24 +00:00
|
|
|
resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
|
2022-02-21 18:14:06 +00:00
|
|
|
mut error_sink: &mut dyn FnMut(ExpandError),
|
2021-03-17 06:31:14 +00:00
|
|
|
) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
|
2021-09-05 19:30:06 +00:00
|
|
|
let expands_to = hir_expand::ExpandTo::from_call_site(self.value);
|
2020-02-17 04:57:24 +00:00
|
|
|
let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value));
|
2020-03-13 15:05:46 +00:00
|
|
|
let h = Hygiene::new(db.upcast(), self.file_id);
|
2022-01-26 17:31:07 +00:00
|
|
|
let path =
|
|
|
|
self.value.path().and_then(|path| path::ModPath::from_src(db.upcast(), path, &h));
|
2020-12-02 15:52:14 +00:00
|
|
|
|
2021-03-17 06:31:14 +00:00
|
|
|
let path = match error_sink
|
2022-02-21 18:14:06 +00:00
|
|
|
.option(path, || ExpandError::Other("malformed macro invocation".into()))
|
2021-03-17 06:31:14 +00:00
|
|
|
{
|
|
|
|
Ok(path) => path,
|
|
|
|
Err(error) => {
|
|
|
|
return Ok(Err(error));
|
2021-03-16 07:46:57 +00:00
|
|
|
}
|
|
|
|
};
|
2020-02-17 04:57:24 +00:00
|
|
|
|
2021-02-28 11:12:11 +00:00
|
|
|
macro_call_as_call_id(
|
2022-02-21 01:42:58 +00:00
|
|
|
db,
|
2021-03-16 07:46:57 +00:00
|
|
|
&AstIdWithPath::new(ast_id.file_id, ast_id.value, path),
|
2021-09-05 19:30:06 +00:00
|
|
|
expands_to,
|
2021-02-28 11:12:11 +00:00
|
|
|
krate,
|
|
|
|
resolver,
|
|
|
|
error_sink,
|
|
|
|
)
|
2020-02-17 04:57:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Helper wrapper for `AstId` with `ModPath`
|
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
|
|
struct AstIdWithPath<T: ast::AstNode> {
|
2020-11-02 12:13:32 +00:00
|
|
|
ast_id: AstId<T>,
|
|
|
|
path: path::ModPath,
|
2020-02-17 04:57:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: ast::AstNode> AstIdWithPath<T> {
|
2020-11-02 12:13:32 +00:00
|
|
|
fn new(file_id: HirFileId, ast_id: FileAstId<T>, path: path::ModPath) -> AstIdWithPath<T> {
|
2020-02-17 04:57:24 +00:00
|
|
|
AstIdWithPath { ast_id: AstId::new(file_id, ast_id), path }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-28 11:12:11 +00:00
|
|
|
fn macro_call_as_call_id(
|
2022-02-21 01:42:58 +00:00
|
|
|
db: &dyn db::DefDatabase,
|
2021-02-28 11:12:11 +00:00
|
|
|
call: &AstIdWithPath<ast::MacroCall>,
|
2021-09-05 19:30:06 +00:00
|
|
|
expand_to: ExpandTo,
|
2021-02-28 11:12:11 +00:00
|
|
|
krate: CrateId,
|
|
|
|
resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
|
2022-02-21 18:14:06 +00:00
|
|
|
error_sink: &mut dyn FnMut(ExpandError),
|
2021-02-28 11:12:11 +00:00
|
|
|
) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
|
2022-03-08 20:41:19 +00:00
|
|
|
let def =
|
2021-04-16 13:48:03 +00:00
|
|
|
resolver(call.path.clone()).ok_or_else(|| UnresolvedMacro { path: call.path.clone() })?;
|
2021-02-28 11:12:11 +00:00
|
|
|
|
2021-03-18 14:37:14 +00:00
|
|
|
let res = if let MacroDefKind::BuiltInEager(..) = def.kind {
|
2021-02-28 11:12:11 +00:00
|
|
|
let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db.upcast()));
|
|
|
|
|
2022-01-26 17:31:07 +00:00
|
|
|
expand_eager_macro(db.upcast(), krate, macro_call, def, &resolver, error_sink)?
|
2021-02-28 11:12:11 +00:00
|
|
|
} else {
|
2021-06-13 04:18:15 +00:00
|
|
|
Ok(def.as_lazy_macro(
|
|
|
|
db.upcast(),
|
|
|
|
krate,
|
2021-09-05 19:30:06 +00:00
|
|
|
MacroCallKind::FnLike { ast_id: call.ast_id, expand_to },
|
2021-06-13 04:18:15 +00:00
|
|
|
))
|
2021-02-28 11:12:11 +00:00
|
|
|
};
|
|
|
|
Ok(res)
|
2020-02-17 04:57:24 +00:00
|
|
|
}
|
|
|
|
|
2022-03-08 22:51:19 +00:00
|
|
|
pub fn macro_id_to_def_id(db: &dyn db::DefDatabase, id: MacroId) -> MacroDefId {
|
2022-03-08 20:41:19 +00:00
|
|
|
match id {
|
|
|
|
MacroId::Macro2Id(it) => {
|
|
|
|
let loc = it.lookup(db);
|
|
|
|
|
|
|
|
let item_tree = loc.id.item_tree(db);
|
|
|
|
let makro = &item_tree[loc.id.value];
|
|
|
|
let in_file = |m: FileAstId<ast::MacroDef>| InFile::new(loc.id.file_id(), m.upcast());
|
|
|
|
MacroDefId {
|
|
|
|
krate: loc.container.krate,
|
|
|
|
kind: match loc.expander {
|
|
|
|
MacroExpander::Declarative => MacroDefKind::Declarative(in_file(makro.ast_id)),
|
|
|
|
MacroExpander::BuiltIn(it) => MacroDefKind::BuiltIn(it, in_file(makro.ast_id)),
|
|
|
|
MacroExpander::BuiltInAttr(it) => {
|
|
|
|
MacroDefKind::BuiltInAttr(it, in_file(makro.ast_id))
|
|
|
|
}
|
|
|
|
MacroExpander::BuiltInDerive(it) => {
|
|
|
|
MacroDefKind::BuiltInDerive(it, in_file(makro.ast_id))
|
|
|
|
}
|
|
|
|
MacroExpander::BuiltInEager(it) => {
|
|
|
|
MacroDefKind::BuiltInEager(it, in_file(makro.ast_id))
|
|
|
|
}
|
|
|
|
},
|
|
|
|
local_inner: false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
MacroId::MacroRulesId(it) => {
|
|
|
|
let loc = it.lookup(db);
|
|
|
|
|
|
|
|
let item_tree = loc.id.item_tree(db);
|
|
|
|
let makro = &item_tree[loc.id.value];
|
|
|
|
let in_file = |m: FileAstId<ast::MacroRules>| InFile::new(loc.id.file_id(), m.upcast());
|
|
|
|
MacroDefId {
|
|
|
|
krate: loc.container.krate,
|
|
|
|
kind: match loc.expander {
|
|
|
|
MacroExpander::Declarative => MacroDefKind::Declarative(in_file(makro.ast_id)),
|
|
|
|
MacroExpander::BuiltIn(it) => MacroDefKind::BuiltIn(it, in_file(makro.ast_id)),
|
|
|
|
MacroExpander::BuiltInAttr(it) => {
|
|
|
|
MacroDefKind::BuiltInAttr(it, in_file(makro.ast_id))
|
|
|
|
}
|
|
|
|
MacroExpander::BuiltInDerive(it) => {
|
|
|
|
MacroDefKind::BuiltInDerive(it, in_file(makro.ast_id))
|
|
|
|
}
|
|
|
|
MacroExpander::BuiltInEager(it) => {
|
|
|
|
MacroDefKind::BuiltInEager(it, in_file(makro.ast_id))
|
|
|
|
}
|
|
|
|
},
|
|
|
|
local_inner: loc.local_inner,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
MacroId::ProcMacroId(it) => {
|
|
|
|
let loc = it.lookup(db);
|
|
|
|
|
|
|
|
let item_tree = loc.id.item_tree(db);
|
|
|
|
let makro = &item_tree[loc.id.value];
|
|
|
|
MacroDefId {
|
|
|
|
krate: loc.container.krate,
|
|
|
|
kind: MacroDefKind::ProcMacro(
|
|
|
|
loc.expander,
|
|
|
|
loc.kind,
|
|
|
|
InFile::new(loc.id.file_id(), makro.ast_id),
|
|
|
|
),
|
|
|
|
local_inner: false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-19 13:23:13 +00:00
|
|
|
fn derive_macro_as_call_id(
|
2022-02-21 01:42:58 +00:00
|
|
|
db: &dyn db::DefDatabase,
|
2022-01-07 13:19:11 +00:00
|
|
|
item_attr: &AstIdWithPath<ast::Adt>,
|
2021-04-09 11:38:01 +00:00
|
|
|
derive_attr: AttrId,
|
2022-02-20 23:02:10 +00:00
|
|
|
derive_pos: u32,
|
2021-02-28 11:12:11 +00:00
|
|
|
krate: CrateId,
|
2022-07-24 12:05:37 +00:00
|
|
|
resolver: impl Fn(path::ModPath) -> Option<(MacroId, MacroDefId)>,
|
|
|
|
) -> Result<(MacroId, MacroDefId, MacroCallId), UnresolvedMacro> {
|
|
|
|
let (macro_id, def_id) = resolver(item_attr.path.clone())
|
2021-04-16 13:48:03 +00:00
|
|
|
.ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?;
|
2022-07-24 12:05:37 +00:00
|
|
|
let call_id = def_id.as_lazy_macro(
|
2021-06-13 04:18:15 +00:00
|
|
|
db.upcast(),
|
|
|
|
krate,
|
|
|
|
MacroCallKind::Derive {
|
|
|
|
ast_id: item_attr.ast_id,
|
2022-02-20 23:02:10 +00:00
|
|
|
derive_index: derive_pos,
|
2021-06-13 04:18:15 +00:00
|
|
|
derive_attr_index: derive_attr.ast_index,
|
|
|
|
},
|
|
|
|
);
|
2022-07-24 12:05:37 +00:00
|
|
|
Ok((macro_id, def_id, call_id))
|
2020-02-17 04:57:24 +00:00
|
|
|
}
|
2021-05-31 11:37:11 +00:00
|
|
|
|
|
|
|
fn attr_macro_as_call_id(
|
2022-02-21 01:42:58 +00:00
|
|
|
db: &dyn db::DefDatabase,
|
2021-05-31 11:37:11 +00:00
|
|
|
item_attr: &AstIdWithPath<ast::Item>,
|
|
|
|
macro_attr: &Attr,
|
|
|
|
krate: CrateId,
|
2022-01-05 16:26:34 +00:00
|
|
|
def: MacroDefId,
|
2022-02-21 01:42:58 +00:00
|
|
|
is_derive: bool,
|
2022-01-05 16:26:34 +00:00
|
|
|
) -> MacroCallId {
|
2021-11-16 19:23:56 +00:00
|
|
|
let mut arg = match macro_attr.input.as_deref() {
|
|
|
|
Some(attr::AttrInput::TokenTree(tt, map)) => (tt.clone(), map.clone()),
|
|
|
|
_ => Default::default(),
|
2021-05-31 11:37:11 +00:00
|
|
|
};
|
2021-11-16 19:23:56 +00:00
|
|
|
|
2021-05-31 11:37:11 +00:00
|
|
|
// The parentheses are always disposed here.
|
2021-08-21 16:19:18 +00:00
|
|
|
arg.0.delimiter = None;
|
2021-05-31 11:37:11 +00:00
|
|
|
|
2021-06-13 04:18:15 +00:00
|
|
|
let res = def.as_lazy_macro(
|
|
|
|
db.upcast(),
|
|
|
|
krate,
|
|
|
|
MacroCallKind::Attr {
|
|
|
|
ast_id: item_attr.ast_id,
|
2022-02-20 21:53:04 +00:00
|
|
|
attr_args: Arc::new(arg),
|
2021-06-13 04:18:15 +00:00
|
|
|
invoc_attr_index: macro_attr.id.ast_index,
|
2022-02-21 01:42:58 +00:00
|
|
|
is_derive,
|
2021-06-13 04:18:15 +00:00
|
|
|
},
|
|
|
|
);
|
2022-01-05 16:26:34 +00:00
|
|
|
res
|
2021-05-31 11:37:11 +00:00
|
|
|
}
|