2019-10-30 05:10:38 -05: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 07:59:42 -05:00
|
|
|
#![warn(rust_2018_idioms, unused_lifetimes, semicolon_in_expressions_from_macros)]
|
|
|
|
|
2020-04-06 09:58:16 -05:00
|
|
|
#[allow(unused)]
|
|
|
|
macro_rules! eprintln {
|
|
|
|
($($tt:tt)*) => { stdx::eprintln!($($tt)*) };
|
|
|
|
}
|
|
|
|
|
2019-10-30 05:10:38 -05:00
|
|
|
pub mod db;
|
2019-11-24 08:00:10 -06:00
|
|
|
|
2019-10-30 08:12:55 -05:00
|
|
|
pub mod attr;
|
|
|
|
pub mod path;
|
2019-10-31 02:51:54 -05:00
|
|
|
pub mod builtin_type;
|
2019-11-24 08:00:10 -06:00
|
|
|
pub mod per_ns;
|
2019-12-20 08:38:17 -06:00
|
|
|
pub mod item_scope;
|
2019-11-24 08:00:10 -06:00
|
|
|
|
2023-04-17 10:31:39 -05:00
|
|
|
pub mod lower;
|
|
|
|
pub mod expander;
|
|
|
|
|
2019-12-05 16:34:12 -06:00
|
|
|
pub mod dyn_map;
|
|
|
|
|
2020-03-25 09:33:01 -05:00
|
|
|
pub mod item_tree;
|
|
|
|
|
2019-11-22 08:32:10 -06:00
|
|
|
pub mod data;
|
2019-11-24 08:00:10 -06:00
|
|
|
pub mod generics;
|
2019-11-23 03:58:01 -06:00
|
|
|
pub mod lang_item;
|
2019-11-24 08:00:10 -06:00
|
|
|
|
2023-04-06 12:36:25 -05:00
|
|
|
pub mod hir;
|
|
|
|
pub use self::hir::type_ref;
|
2019-11-24 08:00:10 -06:00
|
|
|
pub mod body;
|
|
|
|
pub mod resolver;
|
2019-10-30 08:12:55 -05:00
|
|
|
|
2019-11-22 12:43:36 -06:00
|
|
|
mod trace;
|
2019-11-27 08:46:02 -06:00
|
|
|
pub mod nameres;
|
2019-11-22 12:43:36 -06:00
|
|
|
|
2019-11-28 09:05:28 -06:00
|
|
|
pub mod src;
|
2019-12-05 16:34:12 -06:00
|
|
|
pub mod child_by_source;
|
2019-11-28 09:05:28 -06:00
|
|
|
|
2019-12-24 13:32:42 -06:00
|
|
|
pub mod visibility;
|
2019-12-30 07:25:19 -06:00
|
|
|
pub mod find_path;
|
2020-05-20 16:51:20 -05:00
|
|
|
pub mod import_map;
|
2019-12-24 13:32:42 -06:00
|
|
|
|
2023-04-16 05:21:12 -05:00
|
|
|
pub use rustc_abi as layout;
|
2023-05-02 09:12:22 -05:00
|
|
|
use triomphe::Arc;
|
2023-04-16 05:21:12 -05:00
|
|
|
|
2019-11-03 11:53:17 -06:00
|
|
|
#[cfg(test)]
|
|
|
|
mod test_db;
|
2021-10-09 05:42:32 -05:00
|
|
|
#[cfg(test)]
|
|
|
|
mod macro_expansion_tests;
|
2022-08-15 06:51:45 -05:00
|
|
|
mod pretty;
|
2019-11-03 11:53:17 -06:00
|
|
|
|
2023-06-06 18:42:41 -05:00
|
|
|
use std::{
|
|
|
|
hash::{Hash, Hasher},
|
|
|
|
panic::{RefUnwindSafe, UnwindSafe},
|
|
|
|
};
|
2019-10-30 05:10:38 -05:00
|
|
|
|
2023-05-12 09:47:15 -05:00
|
|
|
use base_db::{
|
|
|
|
impl_intern_key,
|
|
|
|
salsa::{self, InternId},
|
|
|
|
CrateId, ProcMacroKind,
|
|
|
|
};
|
2020-02-16 22:57:24 -06:00
|
|
|
use hir_expand::{
|
2021-02-28 05:12:11 -06:00
|
|
|
ast_id_map::FileAstId,
|
2023-01-09 12:29:28 -06:00
|
|
|
attrs::{Attr, AttrId, AttrInput},
|
2022-03-08 14:41:19 -06:00
|
|
|
builtin_attr_macro::BuiltinAttrExpander,
|
|
|
|
builtin_derive_macro::BuiltinDeriveExpander,
|
|
|
|
builtin_fn_macro::{BuiltinFnLikeExpander, EagerExpander},
|
2023-04-17 10:31:39 -05:00
|
|
|
db::ExpandDatabase,
|
2023-06-07 04:20:10 -05:00
|
|
|
eager::expand_eager_macro_input,
|
2021-02-28 05:12:11 -06:00
|
|
|
hygiene::Hygiene,
|
2022-03-08 14:41:19 -06:00
|
|
|
proc_macro::ProcMacroExpander,
|
2023-04-16 08:46:12 -05:00
|
|
|
AstId, ExpandError, ExpandResult, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind,
|
|
|
|
MacroDefId, MacroDefKind, UnresolvedMacro,
|
2020-02-16 22:57:24 -06:00
|
|
|
};
|
2021-12-07 10:31:26 -06:00
|
|
|
use item_tree::ExternBlock;
|
2021-01-14 09:47:42 -06:00
|
|
|
use la_arena::Idx;
|
2021-01-22 09:31:40 -06: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 15:31:59 -05:00
|
|
|
use stdx::impl_from;
|
2020-08-12 11:26:51 -05:00
|
|
|
use syntax::ast;
|
2019-10-30 05:10:38 -05:00
|
|
|
|
2023-01-31 04:49:49 -06:00
|
|
|
use ::tt::token_id as tt;
|
|
|
|
|
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 15:31:59 -05:00
|
|
|
use crate::{
|
|
|
|
builtin_type::BuiltinType,
|
2023-04-06 12:23:29 -05:00
|
|
|
data::adt::VariantData,
|
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 15:31:59 -05:00
|
|
|
item_tree::{
|
2023-06-05 06:27:19 -05:00
|
|
|
Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, MacroDef, MacroRules, Static,
|
|
|
|
Struct, Trait, TraitAlias, 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 15:31:59 -05:00
|
|
|
},
|
2020-06-22 08:07:06 -05:00
|
|
|
};
|
2019-10-30 05:10:38 -05:00
|
|
|
|
2019-11-23 07:49:05 -06:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
2019-10-30 04:27:54 -05:00
|
|
|
pub struct ModuleId {
|
2021-01-22 11:09:55 -06:00
|
|
|
krate: CrateId,
|
2021-03-18 18:06:35 -05: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 12:02:05 -06:00
|
|
|
block: Option<BlockId>,
|
2021-03-18 18:06:35 -05:00
|
|
|
/// The module's ID in its originating `DefMap`.
|
2019-11-27 12:31:51 -06:00
|
|
|
pub local_id: LocalModuleId,
|
2019-10-30 04:27:54 -05:00
|
|
|
}
|
|
|
|
|
2021-01-22 09:31:40 -06:00
|
|
|
impl ModuleId {
|
|
|
|
pub fn def_map(&self, db: &dyn db::DefDatabase) -> Arc<DefMap> {
|
2021-01-25 12:02:05 -06:00
|
|
|
match self.block {
|
2023-04-14 05:15:48 -05:00
|
|
|
Some(block) => db.block_def_map(block),
|
2021-01-25 12:02:05 -06:00
|
|
|
None => db.crate_def_map(self.krate),
|
|
|
|
}
|
2021-01-22 09:31:40 -06:00
|
|
|
}
|
2021-01-22 11:09:55 -06:00
|
|
|
|
|
|
|
pub fn krate(&self) -> CrateId {
|
|
|
|
self.krate
|
|
|
|
}
|
2021-03-01 12:36:34 -06:00
|
|
|
|
|
|
|
pub fn containing_module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId> {
|
|
|
|
self.def_map(db).containing_module(self.local_id)
|
|
|
|
}
|
2021-04-18 18:06:04 -05:00
|
|
|
|
2021-06-13 06:00:34 -05:00
|
|
|
pub fn containing_block(&self) -> Option<BlockId> {
|
|
|
|
self.block
|
|
|
|
}
|
2021-01-22 09:31:40 -06:00
|
|
|
}
|
|
|
|
|
2023-02-19 04:02:51 -06:00
|
|
|
/// An ID of a module, **local** to a `DefMap`.
|
2020-03-19 10:00:11 -05:00
|
|
|
pub type LocalModuleId = Idx<nameres::ModuleData>;
|
2019-10-30 05:10:38 -05:00
|
|
|
|
2020-06-22 08:07:06 -05:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct ItemLoc<N: ItemTreeNode> {
|
2021-03-09 12:09:02 -06:00
|
|
|
pub container: ModuleId,
|
2020-06-22 08:07:06 -05: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 06:11:01 -06:00
|
|
|
}
|
2019-10-30 05:10:38 -05:00
|
|
|
|
2020-06-22 08:07:06 -05: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 10:31:26 -06:00
|
|
|
pub container: ItemContainerId,
|
2020-06-22 08:07:06 -05: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 07:03:59 -06:00
|
|
|
}
|
|
|
|
|
2019-12-20 06:19:41 -06: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 10:05:46 -05:00
|
|
|
fn intern(self, db: &dyn db::DefDatabase) -> $id {
|
2019-12-20 06:19:41 -06:00
|
|
|
db.$intern(self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Lookup for $id {
|
|
|
|
type Data = $loc;
|
2020-03-13 10:05:46 -05:00
|
|
|
fn lookup(&self, db: &dyn db::DefDatabase) -> $loc {
|
2019-12-20 06:19:41 -06:00
|
|
|
db.$lookup(*self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-12-20 06:11:01 -06:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct FunctionId(salsa::InternId);
|
2020-06-22 08:07:06 -05:00
|
|
|
type FunctionLoc = AssocItemLoc<Function>;
|
2019-12-20 06:19:41 -06:00
|
|
|
impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function);
|
2019-10-30 05:10:38 -05:00
|
|
|
|
2020-07-15 14:47:45 -05:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
2019-11-25 08:30:50 -06:00
|
|
|
pub struct StructId(salsa::InternId);
|
2020-06-22 08:07:06 -05:00
|
|
|
type StructLoc = ItemLoc<Struct>;
|
2019-12-20 06:19:41 -06:00
|
|
|
impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct);
|
2019-10-30 05:10:38 -05:00
|
|
|
|
2020-07-15 14:47:45 -05:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
2019-11-25 08:30:50 -06:00
|
|
|
pub struct UnionId(salsa::InternId);
|
2020-06-22 08:07:06 -05:00
|
|
|
pub type UnionLoc = ItemLoc<Union>;
|
2019-12-20 06:19:41 -06:00
|
|
|
impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union);
|
2019-10-30 08:12:55 -05:00
|
|
|
|
2020-07-15 14:47:45 -05:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
2019-10-30 05:10:38 -05:00
|
|
|
pub struct EnumId(salsa::InternId);
|
2020-06-22 08:07:06 -05:00
|
|
|
pub type EnumLoc = ItemLoc<Enum>;
|
2019-12-20 06:19:41 -06:00
|
|
|
impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum);
|
2019-10-30 05:10:38 -05:00
|
|
|
|
2019-10-30 08:12:55 -05:00
|
|
|
// FIXME: rename to `VariantId`, only enums can ave variants
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct EnumVariantId {
|
2019-10-31 10:45:10 -05:00
|
|
|
pub parent: EnumId,
|
|
|
|
pub local_id: LocalEnumVariantId,
|
2019-10-30 08:12:55 -05:00
|
|
|
}
|
|
|
|
|
2023-04-06 12:23:29 -05:00
|
|
|
pub type LocalEnumVariantId = Idx<data::adt::EnumVariantData>;
|
2019-10-30 08:12:55 -05:00
|
|
|
|
2019-10-31 08:40:36 -05:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
2020-04-25 07:23:34 -05:00
|
|
|
pub struct FieldId {
|
2019-11-23 02:14:10 -06:00
|
|
|
pub parent: VariantId,
|
2020-04-25 07:23:34 -05:00
|
|
|
pub local_id: LocalFieldId,
|
2019-10-31 08:40:36 -05:00
|
|
|
}
|
|
|
|
|
2023-04-06 12:23:29 -05:00
|
|
|
pub type LocalFieldId = Idx<data::adt::FieldData>;
|
2019-10-31 08:40:36 -05:00
|
|
|
|
2019-10-30 05:10:38 -05:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct ConstId(salsa::InternId);
|
2020-06-22 08:07:06 -05:00
|
|
|
type ConstLoc = AssocItemLoc<Const>;
|
2019-12-20 06:19:41 -06:00
|
|
|
impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const);
|
2019-10-30 05:10:38 -05:00
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct StaticId(salsa::InternId);
|
2021-12-07 10:31:26 -06:00
|
|
|
pub type StaticLoc = AssocItemLoc<Static>;
|
2019-12-20 06:19:41 -06:00
|
|
|
impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static);
|
2019-10-30 05:10:38 -05:00
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct TraitId(salsa::InternId);
|
2020-06-22 08:07:06 -05:00
|
|
|
pub type TraitLoc = ItemLoc<Trait>;
|
2019-12-20 06:19:41 -06:00
|
|
|
impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait);
|
2019-10-30 05:10:38 -05:00
|
|
|
|
2023-03-03 09:24:07 -06:00
|
|
|
#[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);
|
|
|
|
|
2019-10-30 05:10:38 -05:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct TypeAliasId(salsa::InternId);
|
2020-06-22 08:07:06 -05:00
|
|
|
type TypeAliasLoc = AssocItemLoc<TypeAlias>;
|
2019-12-20 06:19:41 -06:00
|
|
|
impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias);
|
2019-10-31 03:23:30 -05:00
|
|
|
|
2020-06-18 18:29:34 -05:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
2019-11-15 10:14:50 -06:00
|
|
|
pub struct ImplId(salsa::InternId);
|
2020-06-22 08:07:06 -05:00
|
|
|
type ImplLoc = ItemLoc<Impl>;
|
2019-12-20 06:47:44 -06:00
|
|
|
impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl);
|
2019-11-15 10:14:50 -06:00
|
|
|
|
2021-12-07 10:31:26 -06: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 14:41:19 -06: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,
|
2023-01-30 08:41:08 -06:00
|
|
|
pub allow_internal_unsafe: bool,
|
2022-03-08 14:41:19 -06:00
|
|
|
}
|
|
|
|
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,
|
2023-01-30 08:41:08 -06:00
|
|
|
pub allow_internal_unsafe: bool,
|
|
|
|
pub local_inner: bool,
|
2022-03-08 14:41:19 -06:00
|
|
|
}
|
|
|
|
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 12:02:05 -06: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 06:32:43 -06:00
|
|
|
/// The containing module.
|
2021-01-25 12:02:05 -06:00
|
|
|
module: ModuleId,
|
|
|
|
}
|
|
|
|
impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block);
|
|
|
|
|
2019-12-20 06:11:01 -06:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
2021-12-29 07:35:59 -06:00
|
|
|
pub struct TypeOrConstParamId {
|
2019-12-20 06:11:01 -06:00
|
|
|
pub parent: GenericDefId,
|
2021-12-29 07:35:59 -06:00
|
|
|
pub local_id: LocalTypeOrConstParamId,
|
2019-12-20 06:11:01 -06:00
|
|
|
}
|
|
|
|
|
2021-12-29 07:35:59 -06:00
|
|
|
/// A TypeOrConstParamId with an invariant that it actually belongs to a type
|
2022-03-08 14:41:19 -06:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
2021-12-29 07:35:59 -06: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 12:50:24 -06: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 07:35:59 -06:00
|
|
|
Self(x)
|
|
|
|
}
|
|
|
|
}
|
2022-03-09 12:50:24 -06:00
|
|
|
|
2021-12-29 07:35:59 -06:00
|
|
|
impl From<TypeParamId> for TypeOrConstParamId {
|
|
|
|
fn from(x: TypeParamId) -> Self {
|
|
|
|
x.0
|
|
|
|
}
|
|
|
|
}
|
2019-12-20 06:11:01 -06:00
|
|
|
|
2021-12-29 07:35:59 -06:00
|
|
|
/// A TypeOrConstParamId with an invariant that it actually belongs to a const
|
2022-06-12 09:07:08 -05:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
2021-12-29 07:35:59 -06: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 06:49:32 -06:00
|
|
|
}
|
2021-12-29 07:35:59 -06:00
|
|
|
|
2022-03-09 12:50:24 -06: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 07:35:59 -06:00
|
|
|
Self(x)
|
|
|
|
}
|
|
|
|
}
|
2022-03-09 12:50:24 -06:00
|
|
|
|
2021-12-29 07:35:59 -06:00
|
|
|
impl From<ConstParamId> for TypeOrConstParamId {
|
|
|
|
fn from(x: ConstParamId) -> Self {
|
|
|
|
x.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub type LocalTypeOrConstParamId = Idx<generics::TypeOrConstParamData>;
|
2020-12-11 06:49:32 -06:00
|
|
|
|
2021-01-01 03:06:42 -06:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
2021-12-29 07:35:59 -06:00
|
|
|
pub struct LifetimeParamId {
|
2021-01-01 03:06:42 -06:00
|
|
|
pub parent: GenericDefId,
|
2021-12-29 07:35:59 -06:00
|
|
|
pub local_id: LocalLifetimeParamId,
|
2021-01-01 03:06:42 -06:00
|
|
|
}
|
2021-12-29 07:35:59 -06:00
|
|
|
pub type LocalLifetimeParamId = Idx<generics::LifetimeParamData>;
|
2021-01-01 03:06:42 -06:00
|
|
|
|
2019-12-20 05:07:23 -06:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
2021-12-07 10:31:26 -06:00
|
|
|
pub enum ItemContainerId {
|
|
|
|
ExternBlockId(ExternBlockId),
|
2021-03-09 11:27:16 -06:00
|
|
|
ModuleId(ModuleId),
|
2019-11-20 08:49:57 -06:00
|
|
|
ImplId(ImplId),
|
|
|
|
TraitId(TraitId),
|
|
|
|
}
|
2021-12-07 10:31:26 -06:00
|
|
|
impl_from!(ModuleId for ItemContainerId);
|
2019-11-20 08:49:57 -06:00
|
|
|
|
2019-10-31 03:23:30 -05:00
|
|
|
/// A Data Type
|
2020-07-15 14:47:45 -05:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
2019-10-31 03:23:30 -05:00
|
|
|
pub enum AdtId {
|
|
|
|
StructId(StructId),
|
|
|
|
UnionId(UnionId),
|
|
|
|
EnumId(EnumId),
|
|
|
|
}
|
2020-07-13 09:16:53 -05:00
|
|
|
impl_from!(StructId, UnionId, EnumId for AdtId);
|
2019-10-31 03:23:30 -05:00
|
|
|
|
2022-03-08 14:41:19 -06: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 17:42:07 -06:00
|
|
|
/// A generic param
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
|
|
|
pub enum GenericParamId {
|
|
|
|
TypeParamId(TypeParamId),
|
|
|
|
ConstParamId(ConstParamId),
|
2021-12-29 07:35:59 -06:00
|
|
|
LifetimeParamId(LifetimeParamId),
|
2021-01-01 17:42:07 -06:00
|
|
|
}
|
|
|
|
impl_from!(TypeParamId, LifetimeParamId, ConstParamId for GenericParamId);
|
|
|
|
|
2019-10-31 03:23:30 -05: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),
|
2023-03-03 09:24:07 -06:00
|
|
|
TraitAliasId(TraitAliasId),
|
2019-10-31 03:23:30 -05:00
|
|
|
TypeAliasId(TypeAliasId),
|
|
|
|
BuiltinType(BuiltinType),
|
2022-03-08 14:41:19 -06:00
|
|
|
MacroId(MacroId),
|
2019-10-31 03:23:30 -05:00
|
|
|
}
|
2020-07-13 09:16:53 -05:00
|
|
|
impl_from!(
|
2022-03-08 17:19:53 -06:00
|
|
|
MacroId(Macro2Id, MacroRulesId, ProcMacroId),
|
2020-07-13 09:16:53 -05:00
|
|
|
ModuleId,
|
2019-10-31 03:23:30 -05:00
|
|
|
FunctionId,
|
|
|
|
AdtId(StructId, EnumId, UnionId),
|
|
|
|
EnumVariantId,
|
|
|
|
ConstId,
|
|
|
|
StaticId,
|
|
|
|
TraitId,
|
2023-03-03 09:24:07 -06:00
|
|
|
TraitAliasId,
|
2019-10-31 03:23:30 -05:00
|
|
|
TypeAliasId,
|
|
|
|
BuiltinType
|
2020-07-13 09:16:53 -05:00
|
|
|
for ModuleDefId
|
2019-10-31 03:23:30 -05:00
|
|
|
);
|
2019-11-14 08:37:22 -06:00
|
|
|
|
2023-06-05 06:27:19 -05:00
|
|
|
/// 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.
|
2023-05-12 09:47:15 -05:00
|
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
|
|
|
pub struct AnonymousConstId(InternId);
|
|
|
|
impl_intern_key!(AnonymousConstId);
|
|
|
|
|
2023-06-05 06:27:19 -05:00
|
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
|
|
|
pub enum TypeOwnerId {
|
2023-06-10 17:06:32 -05:00
|
|
|
FunctionId(FunctionId),
|
|
|
|
StaticId(StaticId),
|
|
|
|
ConstId(ConstId),
|
|
|
|
InTypeConstId(InTypeConstId),
|
|
|
|
AdtId(AdtId),
|
|
|
|
TraitId(TraitId),
|
|
|
|
TraitAliasId(TraitAliasId),
|
|
|
|
TypeAliasId(TypeAliasId),
|
|
|
|
ImplId(ImplId),
|
|
|
|
EnumVariantId(EnumVariantId),
|
|
|
|
// FIXME(const-generic-body): ModuleId should not be a type owner. This needs to be fixed to make `TypeOwnerId` actually
|
|
|
|
// useful for assigning ids to in type consts.
|
2023-06-05 06:27:19 -05:00
|
|
|
ModuleId(ModuleId),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TypeOwnerId {
|
|
|
|
fn as_generic_def_id(self) -> Option<GenericDefId> {
|
2023-06-10 17:06:32 -05:00
|
|
|
Some(match self {
|
|
|
|
TypeOwnerId::FunctionId(x) => GenericDefId::FunctionId(x),
|
|
|
|
TypeOwnerId::ConstId(x) => GenericDefId::ConstId(x),
|
|
|
|
TypeOwnerId::AdtId(x) => GenericDefId::AdtId(x),
|
|
|
|
TypeOwnerId::TraitId(x) => GenericDefId::TraitId(x),
|
|
|
|
TypeOwnerId::TraitAliasId(x) => GenericDefId::TraitAliasId(x),
|
|
|
|
TypeOwnerId::TypeAliasId(x) => GenericDefId::TypeAliasId(x),
|
|
|
|
TypeOwnerId::ImplId(x) => GenericDefId::ImplId(x),
|
|
|
|
TypeOwnerId::EnumVariantId(x) => GenericDefId::EnumVariantId(x),
|
|
|
|
TypeOwnerId::InTypeConstId(_) | TypeOwnerId::ModuleId(_) | TypeOwnerId::StaticId(_) => {
|
|
|
|
return None
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl_from!(
|
|
|
|
FunctionId,
|
|
|
|
StaticId,
|
|
|
|
ConstId,
|
|
|
|
InTypeConstId,
|
|
|
|
AdtId,
|
|
|
|
TraitId,
|
|
|
|
TraitAliasId,
|
|
|
|
TypeAliasId,
|
|
|
|
ImplId,
|
|
|
|
EnumVariantId,
|
|
|
|
ModuleId
|
|
|
|
for TypeOwnerId
|
|
|
|
);
|
|
|
|
|
|
|
|
// Every `DefWithBodyId` is a type owner, since bodies can contain type (e.g. `{ let x: Type = _; }`)
|
|
|
|
impl From<DefWithBodyId> for TypeOwnerId {
|
|
|
|
fn from(value: DefWithBodyId) -> Self {
|
|
|
|
match value {
|
|
|
|
DefWithBodyId::FunctionId(x) => x.into(),
|
|
|
|
DefWithBodyId::StaticId(x) => x.into(),
|
|
|
|
DefWithBodyId::ConstId(x) => x.into(),
|
|
|
|
DefWithBodyId::InTypeConstId(x) => x.into(),
|
|
|
|
DefWithBodyId::VariantId(x) => x.into(),
|
2023-06-05 06:27:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-10 17:06:32 -05:00
|
|
|
impl From<GenericDefId> for TypeOwnerId {
|
|
|
|
fn from(value: GenericDefId) -> Self {
|
|
|
|
match value {
|
|
|
|
GenericDefId::FunctionId(x) => x.into(),
|
|
|
|
GenericDefId::AdtId(x) => x.into(),
|
|
|
|
GenericDefId::TraitId(x) => x.into(),
|
|
|
|
GenericDefId::TraitAliasId(x) => x.into(),
|
|
|
|
GenericDefId::TypeAliasId(x) => x.into(),
|
|
|
|
GenericDefId::ImplId(x) => x.into(),
|
|
|
|
GenericDefId::EnumVariantId(x) => x.into(),
|
|
|
|
GenericDefId::ConstId(x) => x.into(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-06-05 06:27:19 -05:00
|
|
|
|
2023-06-06 18:42:41 -05:00
|
|
|
/// A thing that we want to store in interned ids, but we don't know its type in `hir-def`
|
|
|
|
pub trait OpaqueInternableThing:
|
|
|
|
std::any::Any + std::fmt::Debug + Sync + Send + UnwindSafe + RefUnwindSafe
|
|
|
|
{
|
|
|
|
fn as_any(&self) -> &dyn std::any::Any;
|
|
|
|
fn box_any(&self) -> Box<dyn std::any::Any>;
|
|
|
|
fn dyn_hash(&self, state: &mut dyn Hasher);
|
|
|
|
fn dyn_eq(&self, other: &dyn OpaqueInternableThing) -> bool;
|
|
|
|
fn dyn_clone(&self) -> Box<dyn OpaqueInternableThing>;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Hash for dyn OpaqueInternableThing {
|
|
|
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
|
|
self.dyn_hash(state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl PartialEq for dyn OpaqueInternableThing {
|
|
|
|
fn eq(&self, other: &Self) -> bool {
|
|
|
|
self.dyn_eq(other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Eq for dyn OpaqueInternableThing {}
|
|
|
|
|
|
|
|
impl Clone for Box<dyn OpaqueInternableThing> {
|
|
|
|
fn clone(&self) -> Self {
|
|
|
|
self.dyn_clone()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-05 06:27:19 -05:00
|
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
|
|
|
pub struct InTypeConstId(InternId);
|
2023-06-08 15:17:45 -05:00
|
|
|
type InTypeConstLoc = (AstId<ast::ConstArg>, TypeOwnerId, Box<dyn OpaqueInternableThing>);
|
2023-06-05 06:27:19 -05:00
|
|
|
impl_intern!(InTypeConstId, InTypeConstLoc, intern_in_type_const, lookup_intern_in_type_const);
|
|
|
|
|
|
|
|
impl InTypeConstId {
|
2023-06-08 15:17:45 -05:00
|
|
|
pub fn source(&self, db: &dyn db::DefDatabase) -> ast::ConstArg {
|
2023-06-05 06:27:19 -05:00
|
|
|
let src = self.lookup(db).0;
|
|
|
|
let file_id = src.file_id;
|
|
|
|
let root = &db.parse_or_expand(file_id);
|
|
|
|
db.ast_id_map(file_id).get(src.value).to_node(root)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-12 09:47:15 -05:00
|
|
|
/// A constant, which might appears as a const item, an annonymous const block in expressions
|
|
|
|
/// or patterns, or as a constant in types with const generics.
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub enum GeneralConstId {
|
|
|
|
ConstId(ConstId),
|
|
|
|
AnonymousConstId(AnonymousConstId),
|
2023-06-05 06:27:19 -05:00
|
|
|
InTypeConstId(InTypeConstId),
|
2023-05-12 09:47:15 -05:00
|
|
|
}
|
|
|
|
|
2023-06-05 06:27:19 -05:00
|
|
|
impl_from!(ConstId, AnonymousConstId, InTypeConstId for GeneralConstId);
|
2023-05-12 09:47:15 -05:00
|
|
|
|
|
|
|
impl GeneralConstId {
|
|
|
|
pub fn generic_def(self, db: &dyn db::DefDatabase) -> Option<GenericDefId> {
|
|
|
|
match self {
|
|
|
|
GeneralConstId::ConstId(x) => Some(x.into()),
|
|
|
|
GeneralConstId::AnonymousConstId(x) => {
|
|
|
|
let (parent, _) = db.lookup_intern_anonymous_const(x);
|
|
|
|
parent.as_generic_def_id()
|
|
|
|
}
|
2023-06-05 06:27:19 -05:00
|
|
|
GeneralConstId::InTypeConstId(x) => {
|
2023-06-06 18:42:41 -05:00
|
|
|
let (_, parent, _) = x.lookup(db);
|
2023-06-05 06:27:19 -05:00
|
|
|
parent.as_generic_def_id()
|
|
|
|
}
|
2023-05-12 09:47:15 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn name(self, db: &dyn db::DefDatabase) -> String {
|
|
|
|
match self {
|
|
|
|
GeneralConstId::ConstId(const_id) => db
|
|
|
|
.const_data(const_id)
|
|
|
|
.name
|
|
|
|
.as_ref()
|
|
|
|
.and_then(|x| x.as_str())
|
|
|
|
.unwrap_or("_")
|
|
|
|
.to_owned(),
|
|
|
|
GeneralConstId::AnonymousConstId(id) => format!("{{anonymous const {id:?}}}"),
|
2023-06-05 06:27:19 -05:00
|
|
|
GeneralConstId::InTypeConstId(id) => format!("{{in type const {id:?}}}"),
|
2023-05-12 09:47:15 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-14 08:37:22 -06:00
|
|
|
/// The defs which have a body.
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub enum DefWithBodyId {
|
|
|
|
FunctionId(FunctionId),
|
|
|
|
StaticId(StaticId),
|
|
|
|
ConstId(ConstId),
|
2023-06-05 06:27:19 -05:00
|
|
|
InTypeConstId(InTypeConstId),
|
2022-08-06 11:50:21 -05:00
|
|
|
VariantId(EnumVariantId),
|
2019-11-14 08:37:22 -06:00
|
|
|
}
|
|
|
|
|
2023-06-05 06:27:19 -05:00
|
|
|
impl_from!(FunctionId, ConstId, StaticId, InTypeConstId for DefWithBodyId);
|
2019-11-15 12:28:00 -06:00
|
|
|
|
2022-08-06 11:50:21 -05:00
|
|
|
impl From<EnumVariantId> for DefWithBodyId {
|
|
|
|
fn from(id: EnumVariantId) -> Self {
|
|
|
|
DefWithBodyId::VariantId(id)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-13 13:38:11 -06: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()),
|
2022-08-06 11:50:21 -05:00
|
|
|
DefWithBodyId::VariantId(c) => Some(c.into()),
|
2023-06-05 06:27:19 -05:00
|
|
|
// FIXME: stable rust doesn't allow generics in constants, but we should
|
|
|
|
// use `TypeOwnerId::as_generic_def_id` when it does.
|
|
|
|
DefWithBodyId::InTypeConstId(_) => None,
|
2021-03-13 13:38:11 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-15 12:28:00 -06: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 09:16:53 -05:00
|
|
|
impl_from!(FunctionId, ConstId, TypeAliasId for AssocItemId);
|
2019-11-20 03:25:02 -06:00
|
|
|
|
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
|
|
|
pub enum GenericDefId {
|
|
|
|
FunctionId(FunctionId),
|
|
|
|
AdtId(AdtId),
|
|
|
|
TraitId(TraitId),
|
2023-03-03 09:24:07 -06:00
|
|
|
TraitAliasId(TraitAliasId),
|
2019-11-20 03:25:02 -06:00
|
|
|
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 09:16:53 -05:00
|
|
|
impl_from!(
|
|
|
|
FunctionId,
|
2019-11-20 03:25:02 -06:00
|
|
|
AdtId(StructId, EnumId, UnionId),
|
|
|
|
TraitId,
|
2023-03-03 09:24:07 -06:00
|
|
|
TraitAliasId,
|
2019-11-20 03:25:02 -06:00
|
|
|
TypeAliasId,
|
|
|
|
ImplId,
|
|
|
|
EnumVariantId,
|
|
|
|
ConstId
|
2020-07-13 09:16:53 -05:00
|
|
|
for GenericDefId
|
2019-11-20 03:25:02 -06:00
|
|
|
);
|
2019-11-20 07:03:59 -06:00
|
|
|
|
2019-11-27 03:31:40 -06: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 02:14:10 -06:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
|
|
|
pub enum AttrDefId {
|
|
|
|
ModuleId(ModuleId),
|
2020-04-25 07:23:34 -05:00
|
|
|
FieldId(FieldId),
|
2019-11-23 02:14:10 -06:00
|
|
|
AdtId(AdtId),
|
|
|
|
FunctionId(FunctionId),
|
|
|
|
EnumVariantId(EnumVariantId),
|
|
|
|
StaticId(StaticId),
|
|
|
|
ConstId(ConstId),
|
|
|
|
TraitId(TraitId),
|
2023-03-03 09:24:07 -06:00
|
|
|
TraitAliasId(TraitAliasId),
|
2019-11-23 02:14:10 -06:00
|
|
|
TypeAliasId(TypeAliasId),
|
2022-03-08 16:51:19 -06:00
|
|
|
MacroId(MacroId),
|
2019-11-23 03:01:56 -06:00
|
|
|
ImplId(ImplId),
|
2021-01-01 17:42:07 -06:00
|
|
|
GenericParamId(GenericParamId),
|
2021-12-07 10:31:26 -06:00
|
|
|
ExternBlockId(ExternBlockId),
|
2019-11-23 02:14:10 -06:00
|
|
|
}
|
|
|
|
|
2020-07-13 09:16:53 -05:00
|
|
|
impl_from!(
|
|
|
|
ModuleId,
|
2020-04-25 07:23:34 -05:00
|
|
|
FieldId,
|
2019-11-23 02:14:10 -06:00
|
|
|
AdtId(StructId, EnumId, UnionId),
|
|
|
|
EnumVariantId,
|
|
|
|
StaticId,
|
|
|
|
ConstId,
|
|
|
|
FunctionId,
|
|
|
|
TraitId,
|
|
|
|
TypeAliasId,
|
2022-03-09 04:26:06 -06:00
|
|
|
MacroId(Macro2Id, MacroRulesId, ProcMacroId),
|
2021-01-01 17:42:07 -06:00
|
|
|
ImplId,
|
|
|
|
GenericParamId
|
2020-07-13 09:16:53 -05:00
|
|
|
for AttrDefId
|
2019-11-23 02:14:10 -06:00
|
|
|
);
|
|
|
|
|
2021-12-07 10:31:26 -06:00
|
|
|
impl From<ItemContainerId> for AttrDefId {
|
|
|
|
fn from(acid: ItemContainerId) -> Self {
|
2021-04-08 06:37:34 -05:00
|
|
|
match acid {
|
2021-12-07 10:31:26 -06: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 06:37:34 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-24 14:48:39 -06:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub enum VariantId {
|
|
|
|
EnumVariantId(EnumVariantId),
|
|
|
|
StructId(StructId),
|
2019-11-25 08:34:15 -06:00
|
|
|
UnionId(UnionId),
|
2019-11-24 14:48:39 -06:00
|
|
|
}
|
2020-07-13 09:16:53 -05:00
|
|
|
impl_from!(EnumVariantId, StructId, UnionId for VariantId);
|
2019-11-24 14:48:39 -06:00
|
|
|
|
2021-04-06 10:59:18 -05: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 15:25:44 -05: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 11:10:40 -05: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 10:59:18 -05:00
|
|
|
}
|
|
|
|
|
2019-11-20 07:03:59 -06:00
|
|
|
trait Intern {
|
|
|
|
type ID;
|
2020-03-13 10:05:46 -05:00
|
|
|
fn intern(self, db: &dyn db::DefDatabase) -> Self::ID;
|
2019-11-20 07:03:59 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
pub trait Lookup {
|
|
|
|
type Data;
|
2020-03-13 10:05:46 -05:00
|
|
|
fn lookup(&self, db: &dyn db::DefDatabase) -> Self::Data;
|
2019-11-20 07:03:59 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
pub trait HasModule {
|
2020-03-13 10:05:46 -05:00
|
|
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId;
|
2019-11-20 07:03:59 -06:00
|
|
|
}
|
|
|
|
|
2021-12-07 10:31:26 -06:00
|
|
|
impl HasModule for ItemContainerId {
|
2020-03-13 10:05:46 -05:00
|
|
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
2019-12-19 11:12:46 -06:00
|
|
|
match *self {
|
2021-12-07 10:31:26 -06: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 07:03:59 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-22 08:07:06 -05:00
|
|
|
impl<N: ItemTreeNode> HasModule for AssocItemLoc<N> {
|
2020-03-13 10:05:46 -05:00
|
|
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
2019-12-19 11:12:46 -06:00
|
|
|
self.container.module(db)
|
2019-11-20 09:00:01 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-24 13:47:58 -06:00
|
|
|
impl HasModule for AdtId {
|
2020-03-13 10:05:46 -05:00
|
|
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
2019-11-24 13:47:58 -06:00
|
|
|
match self {
|
2019-12-12 07:58:04 -06:00
|
|
|
AdtId::StructId(it) => it.lookup(db).container,
|
2019-12-12 08:11:57 -06:00
|
|
|
AdtId::UnionId(it) => it.lookup(db).container,
|
|
|
|
AdtId::EnumId(it) => it.lookup(db).container,
|
2019-11-24 13:47:58 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-17 07:29:29 -06:00
|
|
|
impl HasModule for VariantId {
|
|
|
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
|
|
|
match self {
|
2021-03-09 12:09:02 -06: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 07:29:29 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-08 14:41:19 -06: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,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-05 06:27:19 -05:00
|
|
|
impl HasModule for TypeOwnerId {
|
2020-03-13 10:05:46 -05:00
|
|
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
2019-11-26 05:02:57 -06:00
|
|
|
match self {
|
2023-06-10 17:06:32 -05:00
|
|
|
TypeOwnerId::FunctionId(x) => x.lookup(db).module(db),
|
|
|
|
TypeOwnerId::StaticId(x) => x.lookup(db).module(db),
|
|
|
|
TypeOwnerId::ConstId(x) => x.lookup(db).module(db),
|
|
|
|
TypeOwnerId::InTypeConstId(x) => x.lookup(db).1.module(db),
|
|
|
|
TypeOwnerId::AdtId(x) => x.module(db),
|
|
|
|
TypeOwnerId::TraitId(x) => x.lookup(db).container,
|
|
|
|
TypeOwnerId::TraitAliasId(x) => x.lookup(db).container,
|
|
|
|
TypeOwnerId::TypeAliasId(x) => x.lookup(db).module(db),
|
|
|
|
TypeOwnerId::ImplId(x) => x.lookup(db).container,
|
|
|
|
TypeOwnerId::EnumVariantId(x) => x.parent.lookup(db).container,
|
2023-06-05 06:27:19 -05:00
|
|
|
TypeOwnerId::ModuleId(x) => *x,
|
2019-11-26 05:02:57 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-05 06:27:19 -05:00
|
|
|
impl HasModule for DefWithBodyId {
|
|
|
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
2020-06-22 08:07:06 -05:00
|
|
|
match self {
|
2023-06-05 06:27:19 -05:00
|
|
|
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.parent.lookup(db).container,
|
|
|
|
DefWithBodyId::InTypeConstId(it) => it.lookup(db).1.module(db),
|
2020-06-22 08:07:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-07 12:52:09 -06:00
|
|
|
impl HasModule for GenericDefId {
|
2020-03-13 10:05:46 -05:00
|
|
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
2019-12-07 12:52:09 -06:00
|
|
|
match self {
|
|
|
|
GenericDefId::FunctionId(it) => it.lookup(db).module(db),
|
|
|
|
GenericDefId::AdtId(it) => it.module(db),
|
2021-03-09 12:09:02 -06:00
|
|
|
GenericDefId::TraitId(it) => it.lookup(db).container,
|
2023-03-03 09:24:07 -06:00
|
|
|
GenericDefId::TraitAliasId(it) => it.lookup(db).container,
|
2019-12-07 12:52:09 -06:00
|
|
|
GenericDefId::TypeAliasId(it) => it.lookup(db).module(db),
|
2021-03-09 12:09:02 -06:00
|
|
|
GenericDefId::ImplId(it) => it.lookup(db).container,
|
|
|
|
GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container,
|
2019-12-07 12:52:09 -06:00
|
|
|
GenericDefId::ConstId(it) => it.lookup(db).module(db),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-13 06:00:34 -05: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 12:36:34 -06: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 12:09:02 -06:00
|
|
|
ModuleDefId::EnumVariantId(id) => id.parent.lookup(db).container,
|
2021-03-01 12:36:34 -06:00
|
|
|
ModuleDefId::ConstId(id) => id.lookup(db).container.module(db),
|
2021-12-07 10:31:26 -06:00
|
|
|
ModuleDefId::StaticId(id) => id.lookup(db).module(db),
|
2021-03-09 12:09:02 -06:00
|
|
|
ModuleDefId::TraitId(id) => id.lookup(db).container,
|
2023-03-03 09:24:07 -06:00
|
|
|
ModuleDefId::TraitAliasId(id) => id.lookup(db).container,
|
2021-03-01 12:36:34 -06:00
|
|
|
ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db),
|
2022-03-08 14:41:19 -06:00
|
|
|
ModuleDefId::MacroId(id) => id.module(db),
|
2021-03-01 12:36:34 -06:00
|
|
|
ModuleDefId::BuiltinType(_) => return None,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-17 07:29:29 -06: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 12:09:02 -06:00
|
|
|
AttrDefId::EnumVariantId(it) => it.parent.lookup(db).container.krate,
|
2020-12-17 07:29:29 -06:00
|
|
|
AttrDefId::StaticId(it) => it.lookup(db).module(db).krate,
|
|
|
|
AttrDefId::ConstId(it) => it.lookup(db).module(db).krate,
|
2021-03-09 12:09:02 -06:00
|
|
|
AttrDefId::TraitId(it) => it.lookup(db).container.krate,
|
2023-03-03 09:24:07 -06:00
|
|
|
AttrDefId::TraitAliasId(it) => it.lookup(db).container.krate,
|
2020-12-17 07:29:29 -06:00
|
|
|
AttrDefId::TypeAliasId(it) => it.lookup(db).module(db).krate,
|
2021-03-09 12:09:02 -06:00
|
|
|
AttrDefId::ImplId(it) => it.lookup(db).container.krate,
|
2021-12-07 10:31:26 -06:00
|
|
|
AttrDefId::ExternBlockId(it) => it.lookup(db).container.krate,
|
2021-01-01 17:42:07 -06:00
|
|
|
AttrDefId::GenericParamId(it) => {
|
|
|
|
match it {
|
2021-12-29 07:35:59 -06:00
|
|
|
GenericParamId::TypeParamId(it) => it.parent(),
|
|
|
|
GenericParamId::ConstParamId(it) => it.parent(),
|
2021-01-01 17:42:07 -06:00
|
|
|
GenericParamId::LifetimeParamId(it) => it.parent,
|
|
|
|
}
|
|
|
|
.module(db)
|
|
|
|
.krate
|
|
|
|
}
|
2022-03-08 16:51:19 -06:00
|
|
|
AttrDefId::MacroId(it) => it.module(db).krate,
|
2020-12-17 07:29:29 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-16 22:57:24 -06:00
|
|
|
/// A helper trait for converting to MacroCallId
|
|
|
|
pub trait AsMacroCall {
|
|
|
|
fn as_call_id(
|
|
|
|
&self,
|
2023-04-17 10:31:39 -05:00
|
|
|
db: &dyn ExpandDatabase,
|
2020-06-11 05:08:24 -05:00
|
|
|
krate: CrateId,
|
2020-02-16 22:57:24 -06:00
|
|
|
resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
|
2020-12-02 09:52:14 -06:00
|
|
|
) -> Option<MacroCallId> {
|
2023-04-16 08:46:12 -05:00
|
|
|
self.as_call_id_with_errors(db, krate, resolver).ok()?.value
|
2020-12-02 09:52:14 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
fn as_call_id_with_errors(
|
|
|
|
&self,
|
2023-04-17 10:31:39 -05:00
|
|
|
db: &dyn ExpandDatabase,
|
2020-12-02 09:52:14 -06:00
|
|
|
krate: CrateId,
|
|
|
|
resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
|
2023-04-16 08:46:12 -05:00
|
|
|
) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro>;
|
2020-02-16 22:57:24 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
impl AsMacroCall for InFile<&ast::MacroCall> {
|
2020-12-02 09:52:14 -06:00
|
|
|
fn as_call_id_with_errors(
|
2020-02-16 22:57:24 -06:00
|
|
|
&self,
|
2023-04-17 10:31:39 -05:00
|
|
|
db: &dyn ExpandDatabase,
|
2020-06-11 05:08:24 -05:00
|
|
|
krate: CrateId,
|
2020-02-16 22:57:24 -06:00
|
|
|
resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
|
2023-04-16 08:46:12 -05:00
|
|
|
) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
|
2021-09-05 14:30:06 -05:00
|
|
|
let expands_to = hir_expand::ExpandTo::from_call_site(self.value);
|
2020-02-16 22:57:24 -06:00
|
|
|
let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value));
|
2023-04-17 10:31:39 -05:00
|
|
|
let h = Hygiene::new(db, self.file_id);
|
|
|
|
let path = self.value.path().and_then(|path| path::ModPath::from_src(db, path, &h));
|
2020-12-02 09:52:14 -06:00
|
|
|
|
2023-04-16 08:46:12 -05:00
|
|
|
let Some(path) = path else {
|
2023-06-07 04:20:10 -05:00
|
|
|
return Ok(ExpandResult::only_err(ExpandError::other("malformed macro invocation")));
|
2021-03-16 02:46:57 -05:00
|
|
|
};
|
2020-02-16 22:57:24 -06:00
|
|
|
|
2023-04-16 11:29:42 -05:00
|
|
|
macro_call_as_call_id_(
|
2022-02-20 19:42:58 -06:00
|
|
|
db,
|
2021-03-16 02:46:57 -05:00
|
|
|
&AstIdWithPath::new(ast_id.file_id, ast_id.value, path),
|
2021-09-05 14:30:06 -05:00
|
|
|
expands_to,
|
2021-02-28 05:12:11 -06:00
|
|
|
krate,
|
|
|
|
resolver,
|
|
|
|
)
|
2020-02-16 22:57:24 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Helper wrapper for `AstId` with `ModPath`
|
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
|
|
struct AstIdWithPath<T: ast::AstNode> {
|
2020-11-02 06:13:32 -06:00
|
|
|
ast_id: AstId<T>,
|
|
|
|
path: path::ModPath,
|
2020-02-16 22:57:24 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: ast::AstNode> AstIdWithPath<T> {
|
2020-11-02 06:13:32 -06:00
|
|
|
fn new(file_id: HirFileId, ast_id: FileAstId<T>, path: path::ModPath) -> AstIdWithPath<T> {
|
2020-02-16 22:57:24 -06:00
|
|
|
AstIdWithPath { ast_id: AstId::new(file_id, ast_id), path }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-28 05:12:11 -06:00
|
|
|
fn macro_call_as_call_id(
|
2023-04-17 10:31:39 -05:00
|
|
|
db: &dyn ExpandDatabase,
|
2021-02-28 05:12:11 -06:00
|
|
|
call: &AstIdWithPath<ast::MacroCall>,
|
2021-09-05 14:30:06 -05:00
|
|
|
expand_to: ExpandTo,
|
2021-02-28 05:12:11 -06:00
|
|
|
krate: CrateId,
|
|
|
|
resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
|
2023-04-16 11:29:42 -05:00
|
|
|
) -> Result<Option<MacroCallId>, UnresolvedMacro> {
|
|
|
|
macro_call_as_call_id_(db, call, expand_to, krate, resolver).map(|res| res.value)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn macro_call_as_call_id_(
|
2023-04-17 10:31:39 -05:00
|
|
|
db: &dyn ExpandDatabase,
|
2023-04-16 11:29:42 -05:00
|
|
|
call: &AstIdWithPath<ast::MacroCall>,
|
|
|
|
expand_to: ExpandTo,
|
|
|
|
krate: CrateId,
|
|
|
|
resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
|
2023-04-16 08:46:12 -05:00
|
|
|
) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
|
2022-03-08 14:41:19 -06:00
|
|
|
let def =
|
2021-04-16 08:48:03 -05:00
|
|
|
resolver(call.path.clone()).ok_or_else(|| UnresolvedMacro { path: call.path.clone() })?;
|
2021-02-28 05:12:11 -06:00
|
|
|
|
2021-03-18 09:37:14 -05:00
|
|
|
let res = if let MacroDefKind::BuiltInEager(..) = def.kind {
|
2023-04-17 10:31:39 -05:00
|
|
|
let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db));
|
2023-06-07 04:20:10 -05:00
|
|
|
expand_eager_macro_input(db, krate, macro_call, def, &resolver)?
|
2021-02-28 05:12:11 -06:00
|
|
|
} else {
|
2023-04-16 08:46:12 -05:00
|
|
|
ExpandResult {
|
|
|
|
value: Some(def.as_lazy_macro(
|
2023-04-17 10:31:39 -05:00
|
|
|
db,
|
2023-04-16 08:46:12 -05:00
|
|
|
krate,
|
|
|
|
MacroCallKind::FnLike { ast_id: call.ast_id, expand_to },
|
|
|
|
)),
|
|
|
|
err: None,
|
|
|
|
}
|
2021-02-28 05:12:11 -06:00
|
|
|
};
|
|
|
|
Ok(res)
|
2020-02-16 22:57:24 -06:00
|
|
|
}
|
|
|
|
|
2022-03-08 16:51:19 -06:00
|
|
|
pub fn macro_id_to_def_id(db: &dyn db::DefDatabase, id: MacroId) -> MacroDefId {
|
2022-03-08 14:41:19 -06: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,
|
2023-01-30 08:41:08 -06:00
|
|
|
allow_internal_unsafe: loc.allow_internal_unsafe,
|
2022-03-08 14:41:19 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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,
|
2023-01-30 08:41:08 -06:00
|
|
|
allow_internal_unsafe: loc.allow_internal_unsafe,
|
2022-03-08 14:41:19 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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,
|
2023-01-30 08:41:08 -06:00
|
|
|
allow_internal_unsafe: false,
|
2022-03-08 14:41:19 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-19 08:23:13 -05:00
|
|
|
fn derive_macro_as_call_id(
|
2022-02-20 19:42:58 -06:00
|
|
|
db: &dyn db::DefDatabase,
|
2022-01-07 07:19:11 -06:00
|
|
|
item_attr: &AstIdWithPath<ast::Adt>,
|
2023-01-09 13:47:51 -06:00
|
|
|
derive_attr_index: AttrId,
|
2022-02-20 17:02:10 -06:00
|
|
|
derive_pos: u32,
|
2021-02-28 05:12:11 -06:00
|
|
|
krate: CrateId,
|
2022-07-24 07:05:37 -05: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 08:48:03 -05:00
|
|
|
.ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?;
|
2022-07-24 07:05:37 -05:00
|
|
|
let call_id = def_id.as_lazy_macro(
|
2021-06-12 23:18:15 -05:00
|
|
|
db.upcast(),
|
|
|
|
krate,
|
|
|
|
MacroCallKind::Derive {
|
|
|
|
ast_id: item_attr.ast_id,
|
2022-02-20 17:02:10 -06:00
|
|
|
derive_index: derive_pos,
|
2023-01-09 13:47:51 -06:00
|
|
|
derive_attr_index,
|
2021-06-12 23:18:15 -05:00
|
|
|
},
|
|
|
|
);
|
2022-07-24 07:05:37 -05:00
|
|
|
Ok((macro_id, def_id, call_id))
|
2020-02-16 22:57:24 -06:00
|
|
|
}
|
2021-05-31 06:37:11 -05:00
|
|
|
|
|
|
|
fn attr_macro_as_call_id(
|
2022-02-20 19:42:58 -06:00
|
|
|
db: &dyn db::DefDatabase,
|
2021-05-31 06:37:11 -05:00
|
|
|
item_attr: &AstIdWithPath<ast::Item>,
|
|
|
|
macro_attr: &Attr,
|
|
|
|
krate: CrateId,
|
2022-01-05 10:26:34 -06:00
|
|
|
def: MacroDefId,
|
|
|
|
) -> MacroCallId {
|
2023-01-31 04:49:49 -06:00
|
|
|
let arg = match macro_attr.input.as_deref() {
|
2023-06-09 18:21:52 -05:00
|
|
|
Some(AttrInput::TokenTree(tt)) => (
|
2023-01-31 04:49:49 -06:00
|
|
|
{
|
2023-06-09 18:21:52 -05:00
|
|
|
let mut tt = tt.0.clone();
|
2023-01-31 04:49:49 -06:00
|
|
|
tt.delimiter = tt::Delimiter::UNSPECIFIED;
|
|
|
|
tt
|
|
|
|
},
|
2023-06-09 18:21:52 -05:00
|
|
|
tt.1.clone(),
|
2023-01-31 04:49:49 -06:00
|
|
|
),
|
|
|
|
_ => (tt::Subtree::empty(), Default::default()),
|
2021-05-31 06:37:11 -05:00
|
|
|
};
|
2021-11-16 13:23:56 -06:00
|
|
|
|
2023-01-31 04:49:49 -06:00
|
|
|
def.as_lazy_macro(
|
2021-06-12 23:18:15 -05:00
|
|
|
db.upcast(),
|
|
|
|
krate,
|
|
|
|
MacroCallKind::Attr {
|
|
|
|
ast_id: item_attr.ast_id,
|
2022-02-20 15:53:04 -06:00
|
|
|
attr_args: Arc::new(arg),
|
2023-01-09 13:47:51 -06:00
|
|
|
invoc_attr_index: macro_attr.id,
|
2021-06-12 23:18:15 -05:00
|
|
|
},
|
2023-01-31 04:49:49 -06:00
|
|
|
)
|
2021-05-31 06:37:11 -05:00
|
|
|
}
|
2023-01-09 12:29:28 -06:00
|
|
|
intern::impl_internable!(
|
|
|
|
crate::type_ref::TypeRef,
|
|
|
|
crate::type_ref::TraitRef,
|
|
|
|
crate::type_ref::TypeBound,
|
|
|
|
crate::path::GenericArgs,
|
|
|
|
generics::GenericParams,
|
|
|
|
);
|