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.
|
|
|
|
|
2023-12-05 10:35:09 +00:00
|
|
|
#![warn(rust_2018_idioms, unused_lifetimes)]
|
2023-09-15 14:40:11 +00:00
|
|
|
#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
|
2022-07-20 12:59:42 +00:00
|
|
|
|
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;
|
2019-10-31 07:51:54 +00:00
|
|
|
pub mod builtin_type;
|
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
|
|
|
|
2023-04-17 15:31:39 +00:00
|
|
|
pub mod lower;
|
|
|
|
pub mod expander;
|
|
|
|
|
2019-12-05 22:34:12 +00:00
|
|
|
pub mod dyn_map;
|
|
|
|
|
2020-03-25 14:33:01 +00:00
|
|
|
pub mod item_tree;
|
|
|
|
|
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
|
|
|
|
2023-04-06 17:36:25 +00:00
|
|
|
pub mod hir;
|
|
|
|
pub use self::hir::type_ref;
|
2019-11-24 14:00:10 +00:00
|
|
|
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
|
|
|
|
2023-09-15 14:40:11 +00:00
|
|
|
pub use rustc_dependencies::abi as layout;
|
2023-05-02 14:12:22 +00:00
|
|
|
use triomphe::Arc;
|
2023-04-16 10:21:12 +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;
|
2022-08-15 11:51:45 +00:00
|
|
|
mod pretty;
|
2019-11-03 17:53:17 +00:00
|
|
|
|
2023-06-06 23:42:41 +00:00
|
|
|
use std::{
|
|
|
|
hash::{Hash, Hasher},
|
|
|
|
panic::{RefUnwindSafe, UnwindSafe},
|
|
|
|
};
|
2019-10-30 10:10:38 +00:00
|
|
|
|
2023-12-18 12:30:41 +00:00
|
|
|
use base_db::{impl_intern_key, salsa, CrateId};
|
2020-02-17 04:57:24 +00:00
|
|
|
use hir_expand::{
|
2023-07-04 07:16:15 +00:00
|
|
|
ast_id_map::{AstIdNode, FileAstId},
|
2023-01-09 18:29:28 +00:00
|
|
|
attrs::{Attr, AttrId, AttrInput},
|
2022-03-08 20:41:19 +00:00
|
|
|
builtin_attr_macro::BuiltinAttrExpander,
|
|
|
|
builtin_derive_macro::BuiltinDeriveExpander,
|
|
|
|
builtin_fn_macro::{BuiltinFnLikeExpander, EagerExpander},
|
2023-04-17 15:31:39 +00:00
|
|
|
db::ExpandDatabase,
|
2023-06-07 09:20:10 +00:00
|
|
|
eager::expand_eager_macro_input,
|
2023-10-04 05:19:09 +00:00
|
|
|
name::Name,
|
2023-12-18 11:09:54 +00:00
|
|
|
proc_macro::{CustomProcMacroExpander, ProcMacroKind},
|
2023-04-16 13:46:12 +00:00
|
|
|
AstId, ExpandError, ExpandResult, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind,
|
2023-11-24 15:38:48 +00:00
|
|
|
MacroDefId, MacroDefKind,
|
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;
|
2023-12-20 11:53:46 +00:00
|
|
|
use span::Span;
|
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;
|
2023-11-17 18:07:31 +00:00
|
|
|
use syntax::{ast, AstNode};
|
2019-10-30 10:10:38 +00:00
|
|
|
|
2023-09-29 10:37:57 +00:00
|
|
|
pub use hir_expand::tt;
|
2023-01-31 10:49:49 +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::{
|
|
|
|
builtin_type::BuiltinType,
|
2023-04-06 17:23:29 +00: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 20:31:59 +00:00
|
|
|
item_tree::{
|
2023-08-02 12:19:38 +00:00
|
|
|
Const, Enum, ExternCrate, Function, Impl, ItemTreeId, ItemTreeNode, MacroDef, MacroRules,
|
|
|
|
Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use,
|
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
|
|
|
|
2023-06-13 10:59:52 +00:00
|
|
|
/// A `ModuleId` that is always a crate's root module.
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct CrateRootModuleId {
|
|
|
|
krate: CrateId,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl CrateRootModuleId {
|
|
|
|
pub fn def_map(&self, db: &dyn db::DefDatabase) -> Arc<DefMap> {
|
|
|
|
db.crate_def_map(self.krate)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn krate(self) -> CrateId {
|
|
|
|
self.krate
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-09 13:20:42 +00:00
|
|
|
impl PartialEq<ModuleId> for CrateRootModuleId {
|
|
|
|
fn eq(&self, other: &ModuleId) -> bool {
|
|
|
|
other.block.is_none() && other.local_id == DefMap::ROOT && self.krate == other.krate
|
|
|
|
}
|
|
|
|
}
|
|
|
|
impl PartialEq<CrateRootModuleId> for ModuleId {
|
|
|
|
fn eq(&self, other: &CrateRootModuleId) -> bool {
|
|
|
|
other == self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-13 10:59:52 +00:00
|
|
|
impl From<CrateRootModuleId> for ModuleId {
|
|
|
|
fn from(CrateRootModuleId { krate }: CrateRootModuleId) -> Self {
|
|
|
|
ModuleId { krate, block: None, local_id: DefMap::ROOT }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<CrateRootModuleId> for ModuleDefId {
|
|
|
|
fn from(value: CrateRootModuleId) -> Self {
|
|
|
|
ModuleDefId::ModuleId(value.into())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-02 09:52:55 +00:00
|
|
|
impl From<CrateId> for CrateRootModuleId {
|
|
|
|
fn from(krate: CrateId) -> Self {
|
|
|
|
CrateRootModuleId { krate }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-13 10:59:52 +00:00
|
|
|
impl TryFrom<ModuleId> for CrateRootModuleId {
|
|
|
|
type Error = ();
|
|
|
|
|
|
|
|
fn try_from(ModuleId { krate, block, local_id }: ModuleId) -> Result<Self, Self::Error> {
|
|
|
|
if block.is_none() && local_id == DefMap::ROOT {
|
|
|
|
Ok(CrateRootModuleId { krate })
|
|
|
|
} else {
|
|
|
|
Err(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-11 14:42:09 +00:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
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 {
|
2023-06-27 06:22:18 +00:00
|
|
|
pub fn def_map(self, db: &dyn db::DefDatabase) -> Arc<DefMap> {
|
2021-01-25 18:02:05 +00:00
|
|
|
match self.block {
|
2023-04-14 10:15:48 +00:00
|
|
|
Some(block) => db.block_def_map(block),
|
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
|
|
|
|
2023-06-27 06:22:18 +00:00
|
|
|
pub fn krate(self) -> CrateId {
|
2021-01-22 17:09:55 +00:00
|
|
|
self.krate
|
|
|
|
}
|
2021-03-01 18:36:34 +00:00
|
|
|
|
2023-10-04 05:19:09 +00:00
|
|
|
pub fn name(self, db: &dyn db::DefDatabase) -> Option<Name> {
|
|
|
|
let def_map = self.def_map(db);
|
|
|
|
let parent = def_map[self.local_id].parent?;
|
|
|
|
def_map[parent].children.iter().find_map(|(name, module_id)| {
|
|
|
|
if *module_id == self.local_id {
|
|
|
|
Some(name.clone())
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-06-27 06:22:18 +00:00
|
|
|
pub fn containing_module(self, db: &dyn db::DefDatabase) -> Option<ModuleId> {
|
2021-03-01 18:36:34 +00:00
|
|
|
self.def_map(db).containing_module(self.local_id)
|
|
|
|
}
|
2021-04-18 23:06:04 +00:00
|
|
|
|
2023-06-27 06:22:18 +00:00
|
|
|
pub fn containing_block(self) -> Option<BlockId> {
|
2021-06-13 11:00:34 +00:00
|
|
|
self.block
|
|
|
|
}
|
2023-06-27 06:22:18 +00:00
|
|
|
|
|
|
|
pub fn is_block_module(self) -> bool {
|
|
|
|
self.block.is_some() && self.local_id == DefMap::ROOT
|
|
|
|
}
|
2021-01-22 15:31:40 +00:00
|
|
|
}
|
|
|
|
|
2023-02-19 10:02:51 +00:00
|
|
|
/// An ID of a module, **local** to a `DefMap`.
|
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
|
|
|
}
|
|
|
|
|
2023-04-06 17:23:29 +00:00
|
|
|
pub type LocalEnumVariantId = Idx<data::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
|
|
|
}
|
|
|
|
|
2023-04-06 17:23:29 +00:00
|
|
|
pub type LocalFieldId = Idx<data::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
|
|
|
|
2023-03-03 15:24:07 +00: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 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
|
|
|
|
2023-06-15 10:28:03 +00:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
2023-08-02 12:19:38 +00:00
|
|
|
pub struct UseId(salsa::InternId);
|
|
|
|
type UseLoc = ItemLoc<Use>;
|
|
|
|
impl_intern!(UseId, UseLoc, intern_use, lookup_intern_use);
|
2023-06-15 10:28:03 +00:00
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
|
|
|
pub struct ExternCrateId(salsa::InternId);
|
|
|
|
type ExternCrateLoc = ItemLoc<ExternCrate>;
|
|
|
|
impl_intern!(ExternCrateId, ExternCrateLoc, intern_extern_crate, lookup_intern_extern_crate);
|
|
|
|
|
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,
|
2023-01-30 14:41:08 +00:00
|
|
|
pub allow_internal_unsafe: bool,
|
2022-03-08 20:41:19 +00: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 14:41:08 +00:00
|
|
|
pub allow_internal_unsafe: bool,
|
|
|
|
pub local_inner: bool,
|
2022-03-08 20:41:19 +00: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 {
|
2023-06-13 10:59:52 +00:00
|
|
|
pub container: CrateRootModuleId,
|
2022-03-08 20:41:19 +00:00
|
|
|
pub id: ItemTreeId<Function>,
|
2023-12-18 11:09:54 +00:00
|
|
|
pub expander: CustomProcMacroExpander,
|
2022-03-08 20:41:19 +00:00
|
|
|
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
|
2023-07-06 14:03:17 +00:00
|
|
|
pub fn from_unchecked(it: TypeOrConstParamId) -> Self {
|
|
|
|
Self(it)
|
2021-12-29 13:35:59 +00:00
|
|
|
}
|
|
|
|
}
|
2022-03-09 18:50:24 +00:00
|
|
|
|
2021-12-29 13:35:59 +00:00
|
|
|
impl From<TypeParamId> for TypeOrConstParamId {
|
2023-07-06 14:03:17 +00:00
|
|
|
fn from(it: TypeParamId) -> Self {
|
|
|
|
it.0
|
2021-12-29 13:35:59 +00:00
|
|
|
}
|
|
|
|
}
|
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
|
2023-07-06 14:03:17 +00:00
|
|
|
pub fn from_unchecked(it: TypeOrConstParamId) -> Self {
|
|
|
|
Self(it)
|
2021-12-29 13:35:59 +00:00
|
|
|
}
|
|
|
|
}
|
2022-03-09 18:50:24 +00:00
|
|
|
|
2021-12-29 13:35:59 +00:00
|
|
|
impl From<ConstParamId> for TypeOrConstParamId {
|
2023-07-06 14:03:17 +00:00
|
|
|
fn from(it: ConstParamId) -> Self {
|
|
|
|
it.0
|
2021-12-29 13:35:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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 {
|
2023-09-22 06:08:00 +00:00
|
|
|
matches!(self, MacroId::ProcMacroId(it) if it.lookup(db).kind == ProcMacroKind::Attr)
|
2022-03-08 20:41:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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),
|
2023-03-03 15:24:07 +00:00
|
|
|
TraitAliasId(TraitAliasId),
|
2019-10-31 08:23:30 +00:00
|
|
|
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,
|
2023-03-03 15:24:07 +00:00
|
|
|
TraitAliasId,
|
2019-10-31 08:23:30 +00:00
|
|
|
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
|
|
|
|
2023-06-05 11:27:19 +00: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 14:47:15 +00:00
|
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
2023-06-12 16:21:17 +00:00
|
|
|
pub struct ConstBlockId(salsa::InternId);
|
|
|
|
impl_intern!(ConstBlockId, ConstBlockLoc, intern_anonymous_const, lookup_intern_anonymous_const);
|
|
|
|
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq, Clone)]
|
|
|
|
pub struct ConstBlockLoc {
|
|
|
|
/// The parent of the anonymous const block.
|
|
|
|
pub parent: DefWithBodyId,
|
|
|
|
/// The root expression of this const block in the parent body.
|
|
|
|
pub root: hir::ExprId,
|
|
|
|
}
|
2023-05-12 14:47:15 +00:00
|
|
|
|
2023-12-14 13:11:12 +00:00
|
|
|
/// Something that holds types, required for the current const arg lowering implementation as they
|
|
|
|
/// need to be able to query where they are defined.
|
2023-06-05 11:27:19 +00:00
|
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
|
|
|
pub enum TypeOwnerId {
|
2023-06-10 22:06:32 +00:00
|
|
|
FunctionId(FunctionId),
|
|
|
|
StaticId(StaticId),
|
|
|
|
ConstId(ConstId),
|
|
|
|
InTypeConstId(InTypeConstId),
|
|
|
|
AdtId(AdtId),
|
|
|
|
TraitId(TraitId),
|
|
|
|
TraitAliasId(TraitAliasId),
|
|
|
|
TypeAliasId(TypeAliasId),
|
|
|
|
ImplId(ImplId),
|
|
|
|
EnumVariantId(EnumVariantId),
|
2023-06-05 11:27:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl TypeOwnerId {
|
|
|
|
fn as_generic_def_id(self) -> Option<GenericDefId> {
|
2023-06-10 22:06:32 +00:00
|
|
|
Some(match self {
|
2023-07-06 14:03:17 +00:00
|
|
|
TypeOwnerId::FunctionId(it) => GenericDefId::FunctionId(it),
|
|
|
|
TypeOwnerId::ConstId(it) => GenericDefId::ConstId(it),
|
|
|
|
TypeOwnerId::AdtId(it) => GenericDefId::AdtId(it),
|
|
|
|
TypeOwnerId::TraitId(it) => GenericDefId::TraitId(it),
|
|
|
|
TypeOwnerId::TraitAliasId(it) => GenericDefId::TraitAliasId(it),
|
|
|
|
TypeOwnerId::TypeAliasId(it) => GenericDefId::TypeAliasId(it),
|
|
|
|
TypeOwnerId::ImplId(it) => GenericDefId::ImplId(it),
|
|
|
|
TypeOwnerId::EnumVariantId(it) => GenericDefId::EnumVariantId(it),
|
2023-12-14 13:11:12 +00:00
|
|
|
TypeOwnerId::InTypeConstId(_) | TypeOwnerId::StaticId(_) => return None,
|
2023-06-10 22:06:32 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl_from!(
|
|
|
|
FunctionId,
|
|
|
|
StaticId,
|
|
|
|
ConstId,
|
|
|
|
InTypeConstId,
|
|
|
|
AdtId,
|
|
|
|
TraitId,
|
|
|
|
TraitAliasId,
|
|
|
|
TypeAliasId,
|
|
|
|
ImplId,
|
2023-12-14 13:11:12 +00:00
|
|
|
EnumVariantId
|
2023-06-10 22:06:32 +00:00
|
|
|
for TypeOwnerId
|
|
|
|
);
|
|
|
|
|
2023-07-06 14:03:17 +00:00
|
|
|
// Every `DefWithBodyId` is a type owner, since bodies can contain type (e.g. `{ let it: Type = _; }`)
|
2023-06-10 22:06:32 +00:00
|
|
|
impl From<DefWithBodyId> for TypeOwnerId {
|
|
|
|
fn from(value: DefWithBodyId) -> Self {
|
|
|
|
match value {
|
2023-07-06 14:03:17 +00:00
|
|
|
DefWithBodyId::FunctionId(it) => it.into(),
|
|
|
|
DefWithBodyId::StaticId(it) => it.into(),
|
|
|
|
DefWithBodyId::ConstId(it) => it.into(),
|
|
|
|
DefWithBodyId::InTypeConstId(it) => it.into(),
|
|
|
|
DefWithBodyId::VariantId(it) => it.into(),
|
2023-06-05 11:27:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-10 22:06:32 +00:00
|
|
|
impl From<GenericDefId> for TypeOwnerId {
|
|
|
|
fn from(value: GenericDefId) -> Self {
|
|
|
|
match value {
|
2023-07-06 14:03:17 +00:00
|
|
|
GenericDefId::FunctionId(it) => it.into(),
|
|
|
|
GenericDefId::AdtId(it) => it.into(),
|
|
|
|
GenericDefId::TraitId(it) => it.into(),
|
|
|
|
GenericDefId::TraitAliasId(it) => it.into(),
|
|
|
|
GenericDefId::TypeAliasId(it) => it.into(),
|
|
|
|
GenericDefId::ImplId(it) => it.into(),
|
|
|
|
GenericDefId::EnumVariantId(it) => it.into(),
|
|
|
|
GenericDefId::ConstId(it) => it.into(),
|
2023-06-10 22:06:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-06-05 11:27:19 +00:00
|
|
|
|
2023-06-12 16:21:17 +00:00
|
|
|
// FIXME: This should not be a thing
|
2023-06-11 21:07:11 +00:00
|
|
|
/// A thing that we want to store in interned ids, but we don't know its type in `hir-def`. This is
|
|
|
|
/// currently only used in `InTypeConstId` for storing the type (which has type `Ty` defined in
|
|
|
|
/// the `hir-ty` crate) of the constant in its id, which is a temporary hack so we may want
|
|
|
|
/// to remove this after removing that.
|
2023-06-06 23:42:41 +00:00
|
|
|
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-11 21:07:11 +00:00
|
|
|
// FIXME(const-generic-body): Use an stable id for in type consts.
|
|
|
|
//
|
|
|
|
// The current id uses `AstId<ast::ConstArg>` which will be changed by every change in the code. Ideally
|
|
|
|
// we should use an id which is relative to the type owner, so that every change will only invalidate the
|
|
|
|
// id if it happens inside of the type owner.
|
|
|
|
//
|
|
|
|
// The solution probably is to have some query on `TypeOwnerId` to traverse its constant children and store
|
|
|
|
// their `AstId` in a list (vector or arena), and use the index of that list in the id here. That query probably
|
|
|
|
// needs name resolution, and might go far and handles the whole path lowering or type lowering for a `TypeOwnerId`.
|
|
|
|
//
|
|
|
|
// Whatever path the solution takes, it should answer 3 questions at the same time:
|
|
|
|
// * Is the id stable enough?
|
|
|
|
// * How to find a constant id using an ast node / position in the source code? This is needed when we want to
|
|
|
|
// provide ide functionalities inside an in type const (which we currently don't support) e.g. go to definition
|
|
|
|
// for a local defined there. A complex id might have some trouble in this reverse mapping.
|
|
|
|
// * How to find the return type of a constant using its id? We have this data when we are doing type lowering
|
|
|
|
// and the name of the struct that contains this constant is resolved, so a query that only traverses the
|
|
|
|
// type owner by its syntax tree might have a hard time here.
|
|
|
|
|
|
|
|
/// A constant in a type as a substitution for const generics (like `Foo<{ 2 + 2 }>`) or as an array
|
|
|
|
/// length (like `[u8; 2 + 2]`). These constants are body owner and are a variant of `DefWithBodyId`. These
|
|
|
|
/// are not called `AnonymousConstId` to prevent confusion with [`ConstBlockId`].
|
2023-06-05 11:27:19 +00:00
|
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
2023-06-12 16:21:17 +00:00
|
|
|
pub struct InTypeConstId(salsa::InternId);
|
2023-06-05 11:27:19 +00:00
|
|
|
impl_intern!(InTypeConstId, InTypeConstLoc, intern_in_type_const, lookup_intern_in_type_const);
|
|
|
|
|
2023-06-12 16:21:17 +00:00
|
|
|
#[derive(Debug, Hash, Eq, Clone)]
|
|
|
|
pub struct InTypeConstLoc {
|
|
|
|
pub id: AstId<ast::ConstArg>,
|
|
|
|
/// The thing this const arg appears in
|
|
|
|
pub owner: TypeOwnerId,
|
2023-12-14 13:11:12 +00:00
|
|
|
// FIXME(const-generic-body): The expected type should not be
|
|
|
|
pub expected_ty: Box<dyn OpaqueInternableThing>,
|
2023-06-12 16:21:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl PartialEq for InTypeConstLoc {
|
|
|
|
fn eq(&self, other: &Self) -> bool {
|
2023-12-14 13:11:12 +00:00
|
|
|
self.id == other.id
|
|
|
|
&& self.owner == other.owner
|
|
|
|
&& &*self.expected_ty == &*other.expected_ty
|
2023-06-12 16:21:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-05 11:27:19 +00:00
|
|
|
impl InTypeConstId {
|
2023-06-08 20:17:45 +00:00
|
|
|
pub fn source(&self, db: &dyn db::DefDatabase) -> ast::ConstArg {
|
2023-06-12 16:21:17 +00:00
|
|
|
let src = self.lookup(db).id;
|
2023-06-05 11:27:19 +00:00
|
|
|
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 14:47:15 +00: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),
|
2023-06-11 21:07:11 +00:00
|
|
|
ConstBlockId(ConstBlockId),
|
2023-06-05 11:27:19 +00:00
|
|
|
InTypeConstId(InTypeConstId),
|
2023-05-12 14:47:15 +00:00
|
|
|
}
|
|
|
|
|
2023-06-11 21:07:11 +00:00
|
|
|
impl_from!(ConstId, ConstBlockId, InTypeConstId for GeneralConstId);
|
2023-05-12 14:47:15 +00:00
|
|
|
|
|
|
|
impl GeneralConstId {
|
|
|
|
pub fn generic_def(self, db: &dyn db::DefDatabase) -> Option<GenericDefId> {
|
|
|
|
match self {
|
2023-06-12 16:21:17 +00:00
|
|
|
GeneralConstId::ConstId(it) => Some(it.into()),
|
|
|
|
GeneralConstId::ConstBlockId(it) => it.lookup(db).parent.as_generic_def_id(),
|
|
|
|
GeneralConstId::InTypeConstId(it) => it.lookup(db).owner.as_generic_def_id(),
|
2023-05-12 14:47:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn name(self, db: &dyn db::DefDatabase) -> String {
|
|
|
|
match self {
|
|
|
|
GeneralConstId::ConstId(const_id) => db
|
|
|
|
.const_data(const_id)
|
|
|
|
.name
|
|
|
|
.as_ref()
|
2023-07-06 14:03:17 +00:00
|
|
|
.and_then(|it| it.as_str())
|
2023-05-12 14:47:15 +00:00
|
|
|
.unwrap_or("_")
|
|
|
|
.to_owned(),
|
2023-06-11 21:07:11 +00:00
|
|
|
GeneralConstId::ConstBlockId(id) => format!("{{anonymous const {id:?}}}"),
|
2023-06-05 11:27:19 +00:00
|
|
|
GeneralConstId::InTypeConstId(id) => format!("{{in type const {id:?}}}"),
|
2023-05-12 14:47:15 +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),
|
2023-06-05 11:27:19 +00:00
|
|
|
InTypeConstId(InTypeConstId),
|
2022-08-06 16:50:21 +00:00
|
|
|
VariantId(EnumVariantId),
|
2019-11-14 14:37:22 +00:00
|
|
|
}
|
|
|
|
|
2023-06-05 11:27:19 +00:00
|
|
|
impl_from!(FunctionId, ConstId, StaticId, InTypeConstId for DefWithBodyId);
|
2019-11-15 18:28:00 +00:00
|
|
|
|
2022-08-06 16:50:21 +00:00
|
|
|
impl From<EnumVariantId> for DefWithBodyId {
|
|
|
|
fn from(id: EnumVariantId) -> Self {
|
|
|
|
DefWithBodyId::VariantId(id)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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()),
|
2022-08-06 16:50:21 +00:00
|
|
|
DefWithBodyId::VariantId(c) => Some(c.into()),
|
2023-06-05 11:27:19 +00: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 19:38:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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),
|
2023-03-03 15:24:07 +00:00
|
|
|
TraitAliasId(TraitAliasId),
|
2019-11-20 09:25:02 +00: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 14:16:53 +00:00
|
|
|
impl_from!(
|
|
|
|
FunctionId,
|
2019-11-20 09:25:02 +00:00
|
|
|
AdtId(StructId, EnumId, UnionId),
|
|
|
|
TraitId,
|
2023-03-03 15:24:07 +00:00
|
|
|
TraitAliasId,
|
2019-11-20 09:25:02 +00:00
|
|
|
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),
|
2023-03-03 15:24:07 +00:00
|
|
|
TraitAliasId(TraitAliasId),
|
2019-11-23 08:14:10 +00:00
|
|
|
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),
|
2023-06-15 10:28:40 +00:00
|
|
|
ExternCrateId(ExternCrateId),
|
2023-08-02 12:53:45 +00:00
|
|
|
UseId(UseId),
|
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,
|
2023-08-16 09:18:11 +00:00
|
|
|
TraitAliasId,
|
2019-11-23 08:14:10 +00:00
|
|
|
TypeAliasId,
|
2022-03-09 10:26:06 +00:00
|
|
|
MacroId(Macro2Id, MacroRulesId, ProcMacroId),
|
2021-01-01 23:42:07 +00:00
|
|
|
ImplId,
|
2023-06-15 10:28:40 +00:00
|
|
|
GenericParamId,
|
2023-08-17 10:17:41 +00:00
|
|
|
ExternCrateId,
|
|
|
|
UseId
|
2020-07-13 14:16:53 +00:00
|
|
|
for AttrDefId
|
2019-11-23 08:14:10 +00:00
|
|
|
);
|
|
|
|
|
2023-08-16 09:18:11 +00:00
|
|
|
impl TryFrom<ModuleDefId> for AttrDefId {
|
|
|
|
type Error = ();
|
|
|
|
|
|
|
|
fn try_from(value: ModuleDefId) -> Result<Self, Self::Error> {
|
|
|
|
match value {
|
|
|
|
ModuleDefId::ModuleId(it) => Ok(it.into()),
|
|
|
|
ModuleDefId::FunctionId(it) => Ok(it.into()),
|
|
|
|
ModuleDefId::AdtId(it) => Ok(it.into()),
|
|
|
|
ModuleDefId::EnumVariantId(it) => Ok(it.into()),
|
|
|
|
ModuleDefId::ConstId(it) => Ok(it.into()),
|
|
|
|
ModuleDefId::StaticId(it) => Ok(it.into()),
|
|
|
|
ModuleDefId::TraitId(it) => Ok(it.into()),
|
|
|
|
ModuleDefId::TypeAliasId(it) => Ok(it.into()),
|
|
|
|
ModuleDefId::TraitAliasId(id) => Ok(id.into()),
|
|
|
|
ModuleDefId::MacroId(id) => Ok(id.into()),
|
|
|
|
ModuleDefId::BuiltinType(_) => Err(()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-08-17 10:17:41 +00:00
|
|
|
impl From<AssocItemId> for AttrDefId {
|
|
|
|
fn from(assoc: AssocItemId) -> Self {
|
|
|
|
match assoc {
|
|
|
|
AssocItemId::FunctionId(it) => AttrDefId::FunctionId(it),
|
|
|
|
AssocItemId::ConstId(it) => AttrDefId::ConstId(it),
|
|
|
|
AssocItemId::TypeAliasId(it) => AttrDefId::TypeAliasId(it),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-15 10:28:40 +00:00
|
|
|
impl HasModule for ExternCrateId {
|
|
|
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
|
|
|
self.lookup(db).container
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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,
|
2023-06-13 10:59:52 +00:00
|
|
|
MacroId::ProcMacroId(it) => it.lookup(db).container.into(),
|
2022-03-08 20:41:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-05 11:27:19 +00:00
|
|
|
impl HasModule for TypeOwnerId {
|
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 {
|
2023-07-06 14:03:17 +00:00
|
|
|
TypeOwnerId::FunctionId(it) => it.lookup(db).module(db),
|
|
|
|
TypeOwnerId::StaticId(it) => it.lookup(db).module(db),
|
|
|
|
TypeOwnerId::ConstId(it) => it.lookup(db).module(db),
|
|
|
|
TypeOwnerId::InTypeConstId(it) => it.lookup(db).owner.module(db),
|
|
|
|
TypeOwnerId::AdtId(it) => it.module(db),
|
|
|
|
TypeOwnerId::TraitId(it) => it.lookup(db).container,
|
|
|
|
TypeOwnerId::TraitAliasId(it) => it.lookup(db).container,
|
|
|
|
TypeOwnerId::TypeAliasId(it) => it.lookup(db).module(db),
|
|
|
|
TypeOwnerId::ImplId(it) => it.lookup(db).container,
|
|
|
|
TypeOwnerId::EnumVariantId(it) => it.parent.lookup(db).container,
|
2019-11-26 11:02:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-05 11:27:19 +00:00
|
|
|
impl HasModule for DefWithBodyId {
|
|
|
|
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
|
2020-06-22 13:07:06 +00:00
|
|
|
match self {
|
2023-06-05 11:27:19 +00: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,
|
2023-06-12 16:21:17 +00:00
|
|
|
DefWithBodyId::InTypeConstId(it) => it.lookup(db).owner.module(db),
|
2020-06-22 13:07:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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,
|
2023-03-03 15:24:07 +00:00
|
|
|
GenericDefId::TraitAliasId(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,
|
2023-03-03 15:24:07 +00:00
|
|
|
ModuleDefId::TraitAliasId(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,
|
2023-03-03 15:24:07 +00:00
|
|
|
AttrDefId::TraitAliasId(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,
|
2023-06-15 10:28:40 +00:00
|
|
|
AttrDefId::ExternCrateId(it) => it.lookup(db).container.krate,
|
2023-08-02 12:53:45 +00:00
|
|
|
AttrDefId::UseId(it) => it.lookup(db).container.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,
|
2023-04-17 15:31:39 +00:00
|
|
|
db: &dyn ExpandDatabase,
|
2020-06-11 10:08:24 +00:00
|
|
|
krate: CrateId,
|
2023-08-01 10:38:53 +00:00
|
|
|
resolver: impl Fn(path::ModPath) -> Option<MacroDefId> + Copy,
|
2020-12-02 15:52:14 +00:00
|
|
|
) -> Option<MacroCallId> {
|
2023-04-16 13:46:12 +00:00
|
|
|
self.as_call_id_with_errors(db, krate, resolver).ok()?.value
|
2020-12-02 15:52:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn as_call_id_with_errors(
|
|
|
|
&self,
|
2023-04-17 15:31:39 +00:00
|
|
|
db: &dyn ExpandDatabase,
|
2020-12-02 15:52:14 +00:00
|
|
|
krate: CrateId,
|
2023-08-01 10:38:53 +00:00
|
|
|
resolver: impl Fn(path::ModPath) -> Option<MacroDefId> + Copy,
|
2023-04-16 13:46:12 +00:00
|
|
|
) -> Result<ExpandResult<Option<MacroCallId>>, 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,
|
2023-04-17 15:31:39 +00:00
|
|
|
db: &dyn ExpandDatabase,
|
2020-06-11 10:08:24 +00:00
|
|
|
krate: CrateId,
|
2023-08-01 10:38:53 +00:00
|
|
|
resolver: impl Fn(path::ModPath) -> Option<MacroDefId> + Copy,
|
2023-04-16 13:46:12 +00:00
|
|
|
) -> Result<ExpandResult<Option<MacroCallId>>, 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));
|
2023-11-17 18:07:31 +00:00
|
|
|
let span_map = db.span_map(self.file_id);
|
2023-11-24 15:38:48 +00:00
|
|
|
let path =
|
|
|
|
self.value.path().and_then(|path| path::ModPath::from_src(db, path, span_map.as_ref()));
|
2020-12-02 15:52:14 +00:00
|
|
|
|
2023-04-16 13:46:12 +00:00
|
|
|
let Some(path) = path else {
|
2023-06-07 09:20:10 +00:00
|
|
|
return Ok(ExpandResult::only_err(ExpandError::other("malformed macro invocation")));
|
2021-03-16 07:46:57 +00:00
|
|
|
};
|
2020-02-17 04:57:24 +00:00
|
|
|
|
2023-12-20 11:53:46 +00:00
|
|
|
let call_site = span_map.span_for_range(self.value.syntax().text_range());
|
2023-11-17 18:07:31 +00:00
|
|
|
|
2023-08-01 10:38:53 +00:00
|
|
|
macro_call_as_call_id_with_eager(
|
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),
|
2023-11-17 18:07:31 +00:00
|
|
|
call_site,
|
2021-09-05 19:30:06 +00:00
|
|
|
expands_to,
|
2021-02-28 11:12:11 +00:00
|
|
|
krate,
|
|
|
|
resolver,
|
2023-08-01 10:38:53 +00:00
|
|
|
resolver,
|
2021-02-28 11:12:11 +00:00
|
|
|
)
|
2020-02-17 04:57:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Helper wrapper for `AstId` with `ModPath`
|
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-07-04 07:16:15 +00:00
|
|
|
struct AstIdWithPath<T: AstIdNode> {
|
2020-11-02 12:13:32 +00:00
|
|
|
ast_id: AstId<T>,
|
|
|
|
path: path::ModPath,
|
2020-02-17 04:57:24 +00:00
|
|
|
}
|
|
|
|
|
2023-07-04 07:16:15 +00:00
|
|
|
impl<T: AstIdNode> 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(
|
2023-04-17 15:31:39 +00:00
|
|
|
db: &dyn ExpandDatabase,
|
2021-02-28 11:12:11 +00:00
|
|
|
call: &AstIdWithPath<ast::MacroCall>,
|
2023-12-20 11:53:46 +00:00
|
|
|
call_site: Span,
|
2021-09-05 19:30:06 +00:00
|
|
|
expand_to: ExpandTo,
|
2021-02-28 11:12:11 +00:00
|
|
|
krate: CrateId,
|
2023-08-01 10:38:53 +00:00
|
|
|
resolver: impl Fn(path::ModPath) -> Option<MacroDefId> + Copy,
|
2023-04-16 16:29:42 +00:00
|
|
|
) -> Result<Option<MacroCallId>, UnresolvedMacro> {
|
2023-11-17 18:07:31 +00:00
|
|
|
macro_call_as_call_id_with_eager(db, call, call_site, expand_to, krate, resolver, resolver)
|
2023-08-01 10:38:53 +00:00
|
|
|
.map(|res| res.value)
|
2023-04-16 16:29:42 +00:00
|
|
|
}
|
|
|
|
|
2023-08-01 10:38:53 +00:00
|
|
|
fn macro_call_as_call_id_with_eager(
|
2023-04-17 15:31:39 +00:00
|
|
|
db: &dyn ExpandDatabase,
|
2023-04-16 16:29:42 +00:00
|
|
|
call: &AstIdWithPath<ast::MacroCall>,
|
2023-12-20 11:53:46 +00:00
|
|
|
call_site: Span,
|
2023-04-16 16:29:42 +00:00
|
|
|
expand_to: ExpandTo,
|
|
|
|
krate: CrateId,
|
2023-08-01 10:38:53 +00:00
|
|
|
resolver: impl FnOnce(path::ModPath) -> Option<MacroDefId>,
|
|
|
|
eager_resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
|
2023-04-16 13:46:12 +00:00
|
|
|
) -> Result<ExpandResult<Option<MacroCallId>>, 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
|
|
|
|
2023-07-30 10:18:19 +00:00
|
|
|
let res = match def.kind {
|
|
|
|
MacroDefKind::BuiltInEager(..) => {
|
|
|
|
let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db));
|
2023-11-24 15:38:48 +00:00
|
|
|
expand_eager_macro_input(db, krate, macro_call, def, call_site, &|path| {
|
2023-08-01 10:38:53 +00:00
|
|
|
eager_resolver(path).filter(MacroDefId::is_fn_like)
|
2023-08-01 09:20:15 +00:00
|
|
|
})
|
2023-07-30 10:18:19 +00:00
|
|
|
}
|
|
|
|
_ if def.is_fn_like() => ExpandResult {
|
2023-04-16 13:46:12 +00:00
|
|
|
value: Some(def.as_lazy_macro(
|
2023-04-17 15:31:39 +00:00
|
|
|
db,
|
2023-04-16 13:46:12 +00:00
|
|
|
krate,
|
|
|
|
MacroCallKind::FnLike { ast_id: call.ast_id, expand_to },
|
2023-11-17 18:07:31 +00:00
|
|
|
call_site,
|
2023-04-16 13:46:12 +00:00
|
|
|
)),
|
|
|
|
err: None,
|
2023-07-30 10:18:19 +00:00
|
|
|
},
|
|
|
|
_ => return Err(UnresolvedMacro { path: call.path.clone() }),
|
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,
|
2023-01-30 14:41:08 +00:00
|
|
|
allow_internal_unsafe: loc.allow_internal_unsafe,
|
2022-03-08 20:41:19 +00: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 14:41:08 +00:00
|
|
|
allow_internal_unsafe: loc.allow_internal_unsafe,
|
2022-03-08 20:41:19 +00: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 14:41:08 +00:00
|
|
|
allow_internal_unsafe: false,
|
2022-03-08 20:41:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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>,
|
2023-01-09 19:47:51 +00:00
|
|
|
derive_attr_index: AttrId,
|
2022-02-20 23:02:10 +00:00
|
|
|
derive_pos: u32,
|
2023-12-20 11:53:46 +00:00
|
|
|
call_site: Span,
|
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())
|
2023-07-30 10:18:19 +00:00
|
|
|
.filter(|(_, def_id)| def_id.is_derive())
|
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,
|
2023-01-09 19:47:51 +00:00
|
|
|
derive_attr_index,
|
2021-06-13 04:18:15 +00:00
|
|
|
},
|
2023-11-19 17:42:25 +00:00
|
|
|
call_site,
|
2021-06-13 04:18:15 +00:00
|
|
|
);
|
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,
|
|
|
|
) -> MacroCallId {
|
2023-01-31 10:49:49 +00:00
|
|
|
let arg = match macro_attr.input.as_deref() {
|
2023-09-29 10:37:57 +00:00
|
|
|
Some(AttrInput::TokenTree(tt)) => {
|
|
|
|
let mut tt = tt.as_ref().clone();
|
2023-12-20 13:00:14 +00:00
|
|
|
tt.delimiter = tt::Delimiter::invisible_spanned(macro_attr.span);
|
2023-12-01 12:56:25 +00:00
|
|
|
Some(tt)
|
2023-09-29 10:37:57 +00:00
|
|
|
}
|
|
|
|
|
2023-12-01 12:56:25 +00:00
|
|
|
_ => None,
|
2021-05-31 11:37:11 +00:00
|
|
|
};
|
2021-11-16 19:23:56 +00:00
|
|
|
|
2023-01-31 10:49:49 +00:00
|
|
|
def.as_lazy_macro(
|
2021-06-13 04:18:15 +00:00
|
|
|
db.upcast(),
|
|
|
|
krate,
|
|
|
|
MacroCallKind::Attr {
|
|
|
|
ast_id: item_attr.ast_id,
|
2023-12-01 12:56:25 +00:00
|
|
|
attr_args: arg.map(Arc::new),
|
2023-01-09 19:47:51 +00:00
|
|
|
invoc_attr_index: macro_attr.id,
|
2021-06-13 04:18:15 +00:00
|
|
|
},
|
2023-12-20 11:53:46 +00:00
|
|
|
macro_attr.span,
|
2023-01-31 10:49:49 +00:00
|
|
|
)
|
2021-05-31 11:37:11 +00:00
|
|
|
}
|
2023-11-24 15:38:48 +00:00
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct UnresolvedMacro {
|
|
|
|
pub path: hir_expand::mod_path::ModPath,
|
|
|
|
}
|
|
|
|
|
2023-01-09 18:29:28 +00:00
|
|
|
intern::impl_internable!(
|
|
|
|
crate::type_ref::TypeRef,
|
|
|
|
crate::type_ref::TraitRef,
|
|
|
|
crate::type_ref::TypeBound,
|
|
|
|
crate::path::GenericArgs,
|
|
|
|
generics::GenericParams,
|
|
|
|
);
|