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.
|
|
|
|
|
2023-12-05 04:35:09 -06:00
|
|
|
#![warn(rust_2018_idioms, unused_lifetimes)]
|
2023-09-15 09:40:11 -05:00
|
|
|
#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
|
2022-07-20 07:59:42 -05:00
|
|
|
|
2024-01-08 08:30:26 -06:00
|
|
|
#[cfg(feature = "in-rust-tree")]
|
|
|
|
extern crate rustc_parse_format;
|
|
|
|
|
|
|
|
#[cfg(not(feature = "in-rust-tree"))]
|
|
|
|
extern crate ra_ap_rustc_parse_format as rustc_parse_format;
|
2020-04-06 09:58:16 -05:00
|
|
|
|
2024-01-08 08:39:35 -06:00
|
|
|
#[cfg(feature = "in-rust-tree")]
|
|
|
|
extern crate rustc_abi;
|
|
|
|
|
|
|
|
#[cfg(not(feature = "in-rust-tree"))]
|
|
|
|
extern crate ra_ap_rustc_abi as rustc_abi;
|
|
|
|
|
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;
|
2019-10-31 02:51:54 -05:00
|
|
|
pub mod builtin_type;
|
2019-12-20 08:38:17 -06:00
|
|
|
pub mod item_scope;
|
2024-01-26 03:43:25 -06:00
|
|
|
pub mod path;
|
|
|
|
pub mod per_ns;
|
2019-11-24 08:00:10 -06:00
|
|
|
|
2023-04-17 10:31:39 -05:00
|
|
|
pub mod expander;
|
2024-01-26 03:43:25 -06:00
|
|
|
pub mod lower;
|
2023-04-17 10:31:39 -05:00
|
|
|
|
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-27 08:46:02 -06:00
|
|
|
pub mod nameres;
|
2024-01-26 03:43:25 -06:00
|
|
|
mod trace;
|
2019-11-22 12:43:36 -06:00
|
|
|
|
2019-12-05 16:34:12 -06:00
|
|
|
pub mod child_by_source;
|
2024-01-26 03:43:25 -06:00
|
|
|
pub mod src;
|
2019-11-28 09:05:28 -06:00
|
|
|
|
2019-12-30 07:25:19 -06:00
|
|
|
pub mod find_path;
|
2020-05-20 16:51:20 -05:00
|
|
|
pub mod import_map;
|
2024-01-26 03:43:25 -06:00
|
|
|
pub mod visibility;
|
2019-12-24 13:32:42 -06:00
|
|
|
|
2024-01-08 08:39:35 -06: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
|
|
|
|
2021-10-09 05:42:32 -05:00
|
|
|
#[cfg(test)]
|
|
|
|
mod macro_expansion_tests;
|
2022-08-15 06:51:45 -05:00
|
|
|
mod pretty;
|
2024-01-26 03:43:25 -06:00
|
|
|
#[cfg(test)]
|
|
|
|
mod test_db;
|
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
|
|
|
|
2024-02-10 08:36:26 -06:00
|
|
|
use base_db::{
|
|
|
|
impl_intern_key,
|
|
|
|
salsa::{self, impl_intern_value_trivial},
|
|
|
|
CrateId, Edition,
|
|
|
|
};
|
2020-02-16 22:57:24 -06:00
|
|
|
use hir_expand::{
|
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,
|
2023-12-20 14:24:20 -06:00
|
|
|
impl_intern_lookup,
|
2023-10-04 00:19:09 -05:00
|
|
|
name::Name,
|
2023-12-18 05:09:54 -06:00
|
|
|
proc_macro::{CustomProcMacroExpander, ProcMacroKind},
|
2023-04-16 08:46:12 -05:00
|
|
|
AstId, ExpandError, ExpandResult, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind,
|
2023-11-24 09:38:48 -06:00
|
|
|
MacroDefId, MacroDefKind,
|
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;
|
2024-03-15 06:47:05 -05:00
|
|
|
use span::{AstIdNode, FileAstId, FileId, SyntaxContextId};
|
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;
|
2023-11-17 12:07:31 -06:00
|
|
|
use syntax::{ast, AstNode};
|
2019-10-30 05:10:38 -05:00
|
|
|
|
2023-12-20 14:24:20 -06:00
|
|
|
pub use hir_expand::{tt, Intern, Lookup};
|
2023-01-31 04:49:49 -06: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 15:31:59 -05:00
|
|
|
use crate::{
|
|
|
|
builtin_type::BuiltinType,
|
2023-04-06 12:23:29 -05:00
|
|
|
data::adt::VariantData,
|
2023-12-20 14:24:20 -06:00
|
|
|
db::DefDatabase,
|
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::{
|
2024-02-10 04:37:59 -06:00
|
|
|
Const, Enum, ExternCrate, Function, Impl, ItemTreeId, ItemTreeNode, Macro2, MacroRules,
|
|
|
|
Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use, Variant,
|
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
|
|
|
|
2020-06-22 08:07:06 -05:00
|
|
|
#[derive(Debug)]
|
2024-02-10 04:37:59 -06:00
|
|
|
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>,
|
|
|
|
}
|
|
|
|
|
2024-02-10 04:37:59 -06:00
|
|
|
impl<N: ItemTreeNode> Clone for ItemLoc<N> {
|
2020-06-22 08:07:06 -05:00
|
|
|
fn clone(&self) -> Self {
|
2024-02-09 07:37:42 -06:00
|
|
|
*self
|
2020-06-22 08:07:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-10 04:37:59 -06:00
|
|
|
impl<N: ItemTreeNode> Copy for ItemLoc<N> {}
|
2020-06-22 08:07:06 -05:00
|
|
|
|
2024-02-10 04:37:59 -06:00
|
|
|
impl<N: ItemTreeNode> PartialEq for ItemLoc<N> {
|
2020-06-22 08:07:06 -05:00
|
|
|
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
|
|
|
|
2024-02-10 04:37:59 -06:00
|
|
|
impl<N: ItemTreeNode> Eq for ItemLoc<N> {}
|
2020-06-22 08:07:06 -05:00
|
|
|
|
2024-02-10 04:37:59 -06:00
|
|
|
impl<N: ItemTreeNode> Hash for ItemLoc<N> {
|
2020-06-22 08:07:06 -05:00
|
|
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
|
|
self.container.hash(state);
|
|
|
|
self.id.hash(state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
2024-02-10 04:37:59 -06:00
|
|
|
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>,
|
|
|
|
}
|
|
|
|
|
2024-02-10 04:37:59 -06:00
|
|
|
impl<N: ItemTreeNode> Clone for AssocItemLoc<N> {
|
2020-06-22 08:07:06 -05:00
|
|
|
fn clone(&self) -> Self {
|
2024-02-09 07:37:42 -06:00
|
|
|
*self
|
2020-06-22 08:07:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-10 04:37:59 -06:00
|
|
|
impl<N: ItemTreeNode> Copy for AssocItemLoc<N> {}
|
2020-06-22 08:07:06 -05:00
|
|
|
|
2024-02-10 04:37:59 -06:00
|
|
|
impl<N: ItemTreeNode> PartialEq for AssocItemLoc<N> {
|
2020-06-22 08:07:06 -05:00
|
|
|
fn eq(&self, other: &Self) -> bool {
|
|
|
|
self.container == other.container && self.id == other.id
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-10 04:37:59 -06:00
|
|
|
impl<N: ItemTreeNode> Eq for AssocItemLoc<N> {}
|
2020-06-22 08:07:06 -05:00
|
|
|
|
2024-02-10 04:37:59 -06:00
|
|
|
impl<N: ItemTreeNode> Hash for AssocItemLoc<N> {
|
2020-06-22 08:07:06 -05:00
|
|
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
|
|
self.container.hash(state);
|
|
|
|
self.id.hash(state);
|
|
|
|
}
|
2019-11-20 07:03:59 -06:00
|
|
|
}
|
|
|
|
|
2024-02-10 04:37:59 -06:00
|
|
|
pub trait ItemTreeLoc {
|
|
|
|
type Container;
|
|
|
|
type Id;
|
|
|
|
fn item_tree_id(&self) -> ItemTreeId<Self::Id>;
|
|
|
|
fn container(&self) -> Self::Container;
|
|
|
|
}
|
|
|
|
|
2019-12-20 06:19:41 -06:00
|
|
|
macro_rules! impl_intern {
|
|
|
|
($id:ident, $loc:ident, $intern:ident, $lookup:ident) => {
|
|
|
|
impl_intern_key!($id);
|
2024-02-10 08:36:26 -06:00
|
|
|
impl_intern_value_trivial!($loc);
|
2023-12-20 14:24:20 -06:00
|
|
|
impl_intern_lookup!(DefDatabase, $id, $loc, $intern, $lookup);
|
2019-12-20 06:19:41 -06:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2024-02-10 04:37:59 -06:00
|
|
|
macro_rules! impl_loc {
|
|
|
|
($loc:ident, $id:ident: $id_ty:ident, $container:ident: $container_type:ident) => {
|
|
|
|
impl ItemTreeLoc for $loc {
|
|
|
|
type Container = $container_type;
|
|
|
|
type Id = $id_ty;
|
|
|
|
fn item_tree_id(&self) -> ItemTreeId<Self::Id> {
|
|
|
|
self.$id
|
|
|
|
}
|
|
|
|
fn container(&self) -> Self::Container {
|
|
|
|
self.$container
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
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);
|
2024-02-10 04:37:59 -06:00
|
|
|
impl_loc!(FunctionLoc, id: Function, container: ItemContainerId);
|
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);
|
2024-02-10 04:37:59 -06:00
|
|
|
impl_loc!(StructLoc, id: Struct, container: ModuleId);
|
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);
|
2024-02-10 04:37:59 -06:00
|
|
|
impl_loc!(UnionLoc, id: Union, container: ModuleId);
|
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);
|
2024-02-10 04:37:59 -06:00
|
|
|
impl_loc!(EnumLoc, id: Enum, container: ModuleId);
|
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);
|
2024-02-10 04:37:59 -06:00
|
|
|
impl_loc!(ConstLoc, id: Const, container: ItemContainerId);
|
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);
|
2024-02-10 04:37:59 -06:00
|
|
|
impl_loc!(StaticLoc, id: Static, container: ItemContainerId);
|
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);
|
2024-02-10 04:37:59 -06:00
|
|
|
impl_loc!(TraitLoc, id: Trait, container: ModuleId);
|
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);
|
2024-02-10 04:37:59 -06:00
|
|
|
impl_loc!(TraitAliasLoc, id: TraitAlias, container: ModuleId);
|
2023-03-03 09:24:07 -06:00
|
|
|
|
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);
|
2024-02-10 04:37:59 -06:00
|
|
|
impl_loc!(TypeAliasLoc, id: TypeAlias, container: ItemContainerId);
|
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);
|
2024-02-10 04:37:59 -06:00
|
|
|
impl_loc!(ImplLoc, id: Impl, container: ModuleId);
|
2019-11-15 10:14:50 -06:00
|
|
|
|
2023-06-15 05:28:03 -05:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
2023-08-02 07:19:38 -05:00
|
|
|
pub struct UseId(salsa::InternId);
|
|
|
|
type UseLoc = ItemLoc<Use>;
|
|
|
|
impl_intern!(UseId, UseLoc, intern_use, lookup_intern_use);
|
2024-02-10 04:37:59 -06:00
|
|
|
impl_loc!(UseLoc, id: Use, container: ModuleId);
|
2023-06-15 05:28:03 -05: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);
|
2024-02-10 04:37:59 -06:00
|
|
|
impl_loc!(ExternCrateLoc, id: ExternCrate, container: ModuleId);
|
2023-06-15 05:28:03 -05: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);
|
2024-02-10 04:37:59 -06:00
|
|
|
impl_loc!(ExternBlockLoc, id: ExternBlock, container: ModuleId);
|
2021-12-07 10:31:26 -06:00
|
|
|
|
2022-03-08 14:41:19 -06:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
2024-02-10 05:40:23 -06:00
|
|
|
pub struct EnumVariantId(salsa::InternId);
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct EnumVariantLoc {
|
|
|
|
pub id: ItemTreeId<Variant>,
|
|
|
|
pub parent: EnumId,
|
|
|
|
pub index: u32,
|
2022-03-08 14:41:19 -06:00
|
|
|
}
|
2024-02-10 05:40:23 -06:00
|
|
|
impl_intern!(EnumVariantId, EnumVariantLoc, intern_enum_variant, lookup_intern_enum_variant);
|
|
|
|
impl_loc!(EnumVariantLoc, id: Variant, parent: EnumId);
|
2022-03-08 14:41:19 -06:00
|
|
|
|
|
|
|
#[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,
|
2023-12-21 02:18:06 -06:00
|
|
|
pub id: ItemTreeId<Macro2>,
|
2022-03-08 14:41:19 -06:00
|
|
|
pub expander: MacroExpander,
|
2023-01-30 08:41:08 -06:00
|
|
|
pub allow_internal_unsafe: bool,
|
2023-12-21 09:20:27 -06:00
|
|
|
pub edition: Edition,
|
2022-03-08 14:41:19 -06:00
|
|
|
}
|
|
|
|
impl_intern!(Macro2Id, Macro2Loc, intern_macro2, lookup_intern_macro2);
|
2024-02-10 04:37:59 -06:00
|
|
|
impl_loc!(Macro2Loc, id: Macro2, container: ModuleId);
|
2022-03-08 14:41:19 -06:00
|
|
|
|
|
|
|
#[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-12-21 09:20:27 -06:00
|
|
|
pub flags: MacroRulesLocFlags,
|
|
|
|
pub edition: Edition,
|
2022-03-08 14:41:19 -06:00
|
|
|
}
|
|
|
|
impl_intern!(MacroRulesId, MacroRulesLoc, intern_macro_rules, lookup_intern_macro_rules);
|
2024-02-10 04:37:59 -06:00
|
|
|
impl_loc!(MacroRulesLoc, id: MacroRules, container: ModuleId);
|
2022-03-08 14:41:19 -06:00
|
|
|
|
2023-12-21 09:20:27 -06:00
|
|
|
bitflags::bitflags! {
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct MacroRulesLocFlags: u8 {
|
|
|
|
const ALLOW_INTERNAL_UNSAFE = 1 << 0;
|
|
|
|
const LOCAL_INNER = 1 << 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-10 05:40:23 -06:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub enum MacroExpander {
|
|
|
|
Declarative,
|
|
|
|
BuiltIn(BuiltinFnLikeExpander),
|
|
|
|
BuiltInAttr(BuiltinAttrExpander),
|
|
|
|
BuiltInDerive(BuiltinDeriveExpander),
|
|
|
|
BuiltInEager(EagerExpander),
|
|
|
|
}
|
2022-03-08 14:41:19 -06:00
|
|
|
#[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 05:59:52 -05:00
|
|
|
pub container: CrateRootModuleId,
|
2022-03-08 14:41:19 -06:00
|
|
|
pub id: ItemTreeId<Function>,
|
2023-12-18 05:09:54 -06:00
|
|
|
pub expander: CustomProcMacroExpander,
|
2022-03-08 14:41:19 -06:00
|
|
|
pub kind: ProcMacroKind,
|
2023-12-21 09:20:27 -06:00
|
|
|
pub edition: Edition,
|
2022-03-08 14:41:19 -06:00
|
|
|
}
|
|
|
|
impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro);
|
2024-02-10 04:37:59 -06:00
|
|
|
impl_loc!(ProcMacroLoc, id: Function, container: CrateRootModuleId);
|
2022-03-08 14:41:19 -06:00
|
|
|
|
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);
|
|
|
|
|
2024-02-10 05:40:23 -06: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.
|
|
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
|
|
|
pub struct ConstBlockId(salsa::InternId);
|
|
|
|
impl_intern!(ConstBlockId, ConstBlockLoc, intern_anonymous_const, lookup_intern_anonymous_const);
|
|
|
|
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq, Clone)]
|
|
|
|
pub struct ConstBlockLoc {
|
|
|
|
/// The parent of the anonymous const block.
|
|
|
|
pub parent: DefWithBodyId,
|
|
|
|
/// The root expression of this const block in the parent body.
|
|
|
|
pub root: hir::ExprId,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A `ModuleId` that is always a crate's root module.
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct CrateRootModuleId {
|
|
|
|
krate: CrateId,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl CrateRootModuleId {
|
|
|
|
pub fn def_map(&self, db: &dyn DefDatabase) -> Arc<DefMap> {
|
|
|
|
db.crate_def_map(self.krate)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn krate(self) -> CrateId {
|
|
|
|
self.krate
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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 From<CrateId> for CrateRootModuleId {
|
|
|
|
fn from(krate: CrateId) -> Self {
|
|
|
|
CrateRootModuleId { krate }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
|
|
|
pub struct ModuleId {
|
|
|
|
krate: CrateId,
|
|
|
|
/// 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`.
|
|
|
|
block: Option<BlockId>,
|
|
|
|
/// The module's ID in its originating `DefMap`.
|
|
|
|
pub local_id: LocalModuleId,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ModuleId {
|
|
|
|
pub fn def_map(self, db: &dyn DefDatabase) -> Arc<DefMap> {
|
|
|
|
match self.block {
|
|
|
|
Some(block) => db.block_def_map(block),
|
|
|
|
None => db.crate_def_map(self.krate),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn krate(self) -> CrateId {
|
|
|
|
self.krate
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn name(self, db: &dyn 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
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn containing_module(self, db: &dyn DefDatabase) -> Option<ModuleId> {
|
|
|
|
self.def_map(db).containing_module(self.local_id)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn containing_block(self) -> Option<BlockId> {
|
|
|
|
self.block
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_block_module(self) -> bool {
|
|
|
|
self.block.is_some() && self.local_id == DefMap::ROOT
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl PartialEq<CrateRootModuleId> for ModuleId {
|
|
|
|
fn eq(&self, other: &CrateRootModuleId) -> bool {
|
|
|
|
other == self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<CrateRootModuleId> for ModuleId {
|
|
|
|
fn from(CrateRootModuleId { krate }: CrateRootModuleId) -> Self {
|
|
|
|
ModuleId { krate, block: None, local_id: DefMap::ROOT }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<CrateRootModuleId> for ModuleDefId {
|
|
|
|
fn from(value: CrateRootModuleId) -> Self {
|
|
|
|
ModuleDefId::ModuleId(value.into())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// An ID of a module, **local** to a `DefMap`.
|
|
|
|
pub type LocalModuleId = Idx<nameres::ModuleData>;
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct FieldId {
|
|
|
|
pub parent: VariantId,
|
|
|
|
pub local_id: LocalFieldId,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub type LocalFieldId = Idx<data::adt::FieldData>;
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct TupleId(pub u32);
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
|
|
pub struct TupleFieldId {
|
|
|
|
pub tuple: TupleId,
|
|
|
|
pub index: u32,
|
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
2024-02-10 08:36:26 -06:00
|
|
|
impl_intern_value_trivial!(TypeOrConstParamId);
|
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
|
2023-07-06 09:03:17 -05:00
|
|
|
pub fn from_unchecked(it: TypeOrConstParamId) -> Self {
|
|
|
|
Self(it)
|
2021-12-29 07:35:59 -06:00
|
|
|
}
|
|
|
|
}
|
2022-03-09 12:50:24 -06:00
|
|
|
|
2021-12-29 07:35:59 -06:00
|
|
|
impl From<TypeParamId> for TypeOrConstParamId {
|
2023-07-06 09:03:17 -05:00
|
|
|
fn from(it: TypeParamId) -> Self {
|
|
|
|
it.0
|
2021-12-29 07:35:59 -06:00
|
|
|
}
|
|
|
|
}
|
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
|
2023-07-06 09:03:17 -05:00
|
|
|
pub fn from_unchecked(it: TypeOrConstParamId) -> Self {
|
|
|
|
Self(it)
|
2021-12-29 07:35:59 -06:00
|
|
|
}
|
|
|
|
}
|
2022-03-09 12:50:24 -06:00
|
|
|
|
2021-12-29 07:35:59 -06:00
|
|
|
impl From<ConstParamId> for TypeOrConstParamId {
|
2023-07-06 09:03:17 -05:00
|
|
|
fn from(it: ConstParamId) -> Self {
|
|
|
|
it.0
|
2021-12-29 07:35:59 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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>;
|
2024-02-10 08:36:26 -06:00
|
|
|
impl_intern_value_trivial!(LifetimeParamId);
|
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 {
|
2023-12-20 14:24:20 -06:00
|
|
|
pub fn is_attribute(self, db: &dyn DefDatabase) -> bool {
|
2023-09-22 01:08:00 -05:00
|
|
|
matches!(self, MacroId::ProcMacroId(it) if it.lookup(db).kind == ProcMacroKind::Attr)
|
2022-03-08 14:41:19 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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-12-14 07:11:12 -06: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 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),
|
2023-06-05 06:27:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl TypeOwnerId {
|
|
|
|
fn as_generic_def_id(self) -> Option<GenericDefId> {
|
2023-06-10 17:06:32 -05:00
|
|
|
Some(match self {
|
2023-07-06 09:03:17 -05: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 07:11:12 -06:00
|
|
|
TypeOwnerId::InTypeConstId(_) | TypeOwnerId::StaticId(_) => return None,
|
2023-06-10 17:06:32 -05:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl_from!(
|
|
|
|
FunctionId,
|
|
|
|
StaticId,
|
|
|
|
ConstId,
|
|
|
|
InTypeConstId,
|
|
|
|
AdtId,
|
|
|
|
TraitId,
|
|
|
|
TraitAliasId,
|
|
|
|
TypeAliasId,
|
|
|
|
ImplId,
|
2023-12-14 07:11:12 -06:00
|
|
|
EnumVariantId
|
2023-06-10 17:06:32 -05:00
|
|
|
for TypeOwnerId
|
|
|
|
);
|
|
|
|
|
2023-07-06 09:03:17 -05:00
|
|
|
// Every `DefWithBodyId` is a type owner, since bodies can contain type (e.g. `{ let it: Type = _; }`)
|
2023-06-10 17:06:32 -05:00
|
|
|
impl From<DefWithBodyId> for TypeOwnerId {
|
|
|
|
fn from(value: DefWithBodyId) -> Self {
|
|
|
|
match value {
|
2023-07-06 09:03:17 -05: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 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 {
|
2023-07-06 09:03:17 -05: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 17:06:32 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-06-05 06:27:19 -05:00
|
|
|
|
2023-06-12 11:21:17 -05:00
|
|
|
// FIXME: This should not be a thing
|
2023-06-11 16:07:11 -05: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 18:42:41 -05: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 16:07:11 -05: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 06:27:19 -05:00
|
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
2023-06-12 11:21:17 -05:00
|
|
|
pub struct InTypeConstId(salsa::InternId);
|
2023-06-05 06:27:19 -05:00
|
|
|
impl_intern!(InTypeConstId, InTypeConstLoc, intern_in_type_const, lookup_intern_in_type_const);
|
|
|
|
|
2024-02-09 08:36:47 -06:00
|
|
|
// We would like to set `derive(PartialEq)`
|
|
|
|
// but the compiler complains about that `.expected_ty` does not implement the `Copy` trait.
|
|
|
|
#[allow(clippy::derived_hash_with_manual_eq)]
|
2023-06-12 11:21:17 -05: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 07:11:12 -06:00
|
|
|
// FIXME(const-generic-body): The expected type should not be
|
|
|
|
pub expected_ty: Box<dyn OpaqueInternableThing>,
|
2023-06-12 11:21:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl PartialEq for InTypeConstLoc {
|
|
|
|
fn eq(&self, other: &Self) -> bool {
|
2024-01-19 09:03:30 -06:00
|
|
|
self.id == other.id && self.owner == other.owner && *self.expected_ty == *other.expected_ty
|
2023-06-12 11:21:17 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-05 06:27:19 -05:00
|
|
|
impl InTypeConstId {
|
2023-12-20 14:24:20 -06:00
|
|
|
pub fn source(&self, db: &dyn DefDatabase) -> ast::ConstArg {
|
2023-06-12 11:21:17 -05:00
|
|
|
let src = self.lookup(db).id;
|
2023-06-05 06:27:19 -05: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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-30 07:43:43 -06:00
|
|
|
/// A constant, which might appears as a const item, an anonymous const block in expressions
|
2023-05-12 09:47:15 -05:00
|
|
|
/// 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 16:07:11 -05:00
|
|
|
ConstBlockId(ConstBlockId),
|
2023-06-05 06:27:19 -05:00
|
|
|
InTypeConstId(InTypeConstId),
|
2023-05-12 09:47:15 -05:00
|
|
|
}
|
|
|
|
|
2023-06-11 16:07:11 -05:00
|
|
|
impl_from!(ConstId, ConstBlockId, InTypeConstId for GeneralConstId);
|
2023-05-12 09:47:15 -05:00
|
|
|
|
|
|
|
impl GeneralConstId {
|
2023-12-20 14:24:20 -06:00
|
|
|
pub fn generic_def(self, db: &dyn DefDatabase) -> Option<GenericDefId> {
|
2023-05-12 09:47:15 -05:00
|
|
|
match self {
|
2023-06-12 11:21:17 -05: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 09:47:15 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-20 14:24:20 -06:00
|
|
|
pub fn name(self, db: &dyn DefDatabase) -> String {
|
2023-05-12 09:47:15 -05:00
|
|
|
match self {
|
|
|
|
GeneralConstId::ConstId(const_id) => db
|
|
|
|
.const_data(const_id)
|
|
|
|
.name
|
|
|
|
.as_ref()
|
2023-07-06 09:03:17 -05:00
|
|
|
.and_then(|it| it.as_str())
|
2023-05-12 09:47:15 -05:00
|
|
|
.unwrap_or("_")
|
|
|
|
.to_owned(),
|
2023-06-11 16:07:11 -05:00
|
|
|
GeneralConstId::ConstBlockId(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
|
|
|
|
2024-02-10 05:09:12 -06:00
|
|
|
impl GenericDefId {
|
|
|
|
fn file_id_and_params_of(
|
|
|
|
self,
|
|
|
|
db: &dyn DefDatabase,
|
|
|
|
) -> (HirFileId, Option<ast::GenericParamList>) {
|
|
|
|
fn file_id_and_params_of_item_loc<Loc>(
|
|
|
|
db: &dyn DefDatabase,
|
|
|
|
def: impl for<'db> Lookup<Database<'db> = dyn DefDatabase + 'db, Data = Loc>,
|
|
|
|
) -> (HirFileId, Option<ast::GenericParamList>)
|
|
|
|
where
|
|
|
|
Loc: src::HasSource,
|
|
|
|
Loc::Value: ast::HasGenericParams,
|
|
|
|
{
|
|
|
|
let src = def.lookup(db).source(db);
|
|
|
|
(src.file_id, ast::HasGenericParams::generic_param_list(&src.value))
|
|
|
|
}
|
|
|
|
|
|
|
|
match self {
|
|
|
|
GenericDefId::FunctionId(it) => file_id_and_params_of_item_loc(db, it),
|
|
|
|
GenericDefId::TypeAliasId(it) => file_id_and_params_of_item_loc(db, it),
|
|
|
|
GenericDefId::ConstId(_) => (FileId::BOGUS.into(), None),
|
|
|
|
GenericDefId::AdtId(AdtId::StructId(it)) => file_id_and_params_of_item_loc(db, it),
|
|
|
|
GenericDefId::AdtId(AdtId::UnionId(it)) => file_id_and_params_of_item_loc(db, it),
|
|
|
|
GenericDefId::AdtId(AdtId::EnumId(it)) => file_id_and_params_of_item_loc(db, it),
|
|
|
|
GenericDefId::TraitId(it) => file_id_and_params_of_item_loc(db, it),
|
|
|
|
GenericDefId::TraitAliasId(it) => file_id_and_params_of_item_loc(db, it),
|
|
|
|
GenericDefId::ImplId(it) => file_id_and_params_of_item_loc(db, it),
|
|
|
|
// We won't be using this ID anyway
|
|
|
|
GenericDefId::EnumVariantId(_) => (FileId::BOGUS.into(), None),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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),
|
2023-06-15 05:28:40 -05:00
|
|
|
ExternCrateId(ExternCrateId),
|
2023-08-02 07:53:45 -05:00
|
|
|
UseId(UseId),
|
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,
|
2023-08-16 04:18:11 -05:00
|
|
|
TraitAliasId,
|
2019-11-23 02:14:10 -06:00
|
|
|
TypeAliasId,
|
2022-03-09 04:26:06 -06:00
|
|
|
MacroId(Macro2Id, MacroRulesId, ProcMacroId),
|
2021-01-01 17:42:07 -06:00
|
|
|
ImplId,
|
2023-06-15 05:28:40 -05:00
|
|
|
GenericParamId,
|
2023-08-17 05:17:41 -05:00
|
|
|
ExternCrateId,
|
|
|
|
UseId
|
2020-07-13 09:16:53 -05:00
|
|
|
for AttrDefId
|
2019-11-23 02:14:10 -06:00
|
|
|
);
|
|
|
|
|
2023-08-16 04:18:11 -05: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 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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-08-17 05:17:41 -05: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),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-01-16 17:28:05 -06:00
|
|
|
impl From<VariantId> for AttrDefId {
|
|
|
|
fn from(vid: VariantId) -> Self {
|
|
|
|
match vid {
|
|
|
|
VariantId::EnumVariantId(id) => id.into(),
|
|
|
|
VariantId::StructId(id) => id.into(),
|
|
|
|
VariantId::UnionId(id) => id.into(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
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 {
|
2023-12-20 14:24:20 -06:00
|
|
|
pub fn variant_data(self, db: &dyn DefDatabase) -> Arc<VariantData> {
|
2021-04-06 10:59:18 -05:00
|
|
|
match self {
|
|
|
|
VariantId::StructId(it) => db.struct_data(it).variant_data.clone(),
|
|
|
|
VariantId::UnionId(it) => db.union_data(it).variant_data.clone(),
|
2024-01-15 03:24:14 -06:00
|
|
|
VariantId::EnumVariantId(it) => db.enum_variant_data(it).variant_data.clone(),
|
2021-04-06 10:59:18 -05:00
|
|
|
}
|
|
|
|
}
|
2021-04-06 15:25:44 -05:00
|
|
|
|
2023-12-20 14:24:20 -06:00
|
|
|
pub fn file_id(self, db: &dyn DefDatabase) -> HirFileId {
|
2021-04-06 15:25:44 -05:00
|
|
|
match self {
|
2024-01-15 03:24:14 -06:00
|
|
|
VariantId::EnumVariantId(it) => it.lookup(db).id.file_id(),
|
2021-04-06 15:25:44 -05:00
|
|
|
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
|
|
|
|
2024-01-15 03:24:14 -06:00
|
|
|
pub fn adt_id(self, db: &dyn DefDatabase) -> AdtId {
|
2021-05-23 11:10:40 -05:00
|
|
|
match self {
|
2024-01-15 03:24:14 -06:00
|
|
|
VariantId::EnumVariantId(it) => it.lookup(db).parent.into(),
|
2021-05-23 11:10:40 -05:00
|
|
|
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
|
|
|
pub trait HasModule {
|
2024-02-09 18:48:41 -06:00
|
|
|
/// Returns the enclosing module this thing is defined within.
|
2023-12-20 14:24:20 -06:00
|
|
|
fn module(&self, db: &dyn DefDatabase) -> ModuleId;
|
2024-02-09 18:48:41 -06:00
|
|
|
/// Returns the crate this thing is defined within.
|
|
|
|
#[inline]
|
|
|
|
#[doc(alias = "crate")]
|
|
|
|
fn krate(&self, db: &dyn DefDatabase) -> CrateId {
|
|
|
|
self.module(db).krate
|
|
|
|
}
|
2019-11-20 07:03:59 -06:00
|
|
|
}
|
|
|
|
|
2024-02-10 04:37:59 -06:00
|
|
|
// In theory this impl should work out for us, but rustc thinks it collides with all the other
|
|
|
|
// manual impls that do not have a ModuleId container...
|
|
|
|
// impl<N, ItemId, Data> HasModule for ItemId
|
|
|
|
// where
|
|
|
|
// N: ItemTreeNode,
|
|
|
|
// ItemId: for<'db> Lookup<Database<'db> = dyn DefDatabase + 'db, Data = Data> + Copy,
|
|
|
|
// Data: ItemTreeLoc<Id = N, Container = ModuleId>,
|
|
|
|
// {
|
|
|
|
// #[inline]
|
|
|
|
// fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
|
|
|
// self.lookup(db).container()
|
|
|
|
// }
|
|
|
|
// }
|
2019-11-20 07:03:59 -06:00
|
|
|
|
2024-02-09 18:48:41 -06:00
|
|
|
impl<N, ItemId> HasModule for ItemId
|
|
|
|
where
|
2024-02-10 04:37:59 -06:00
|
|
|
N: ItemTreeNode,
|
2024-02-09 18:48:41 -06:00
|
|
|
ItemId: for<'db> Lookup<Database<'db> = dyn DefDatabase + 'db, Data = ItemLoc<N>> + Copy,
|
|
|
|
{
|
2024-01-15 05:03:31 -06:00
|
|
|
#[inline]
|
2023-12-20 14:24:20 -06:00
|
|
|
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
2024-02-09 18:48:41 -06:00
|
|
|
self.lookup(db).container
|
2019-11-20 09:00:01 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-09 18:48:41 -06:00
|
|
|
// Technically this does not overlap with the above, but rustc currently forbids this, hence why we
|
|
|
|
// need to write the 3 impls manually instead
|
|
|
|
// impl<N, ItemId> HasModule for ItemId
|
|
|
|
// where
|
|
|
|
// N: ItemTreeModItemNode,
|
|
|
|
// ItemId: for<'db> Lookup<Database<'db> = dyn DefDatabase + 'db, Data = AssocItemLoc<N>> + Copy,
|
|
|
|
// {
|
|
|
|
// #[inline]
|
|
|
|
// fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
|
|
|
// self.lookup(db).container.module(db)
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// region: manual-assoc-has-module-impls
|
|
|
|
#[inline]
|
|
|
|
fn module_for_assoc_item_loc<'db>(
|
|
|
|
db: &(dyn 'db + DefDatabase),
|
2024-02-10 04:37:59 -06:00
|
|
|
id: impl Lookup<Database<'db> = dyn DefDatabase + 'db, Data = AssocItemLoc<impl ItemTreeNode>>,
|
2024-02-09 18:48:41 -06:00
|
|
|
) -> ModuleId {
|
|
|
|
id.lookup(db).container.module(db)
|
|
|
|
}
|
|
|
|
|
|
|
|
impl HasModule for FunctionId {
|
|
|
|
#[inline]
|
2023-12-20 14:24:20 -06:00
|
|
|
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
2024-02-09 18:48:41 -06:00
|
|
|
module_for_assoc_item_loc(db, *self)
|
2019-11-24 13:47:58 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-09 18:48:41 -06:00
|
|
|
impl HasModule for ConstId {
|
2024-01-15 05:03:31 -06:00
|
|
|
#[inline]
|
|
|
|
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
2024-02-09 18:48:41 -06:00
|
|
|
module_for_assoc_item_loc(db, *self)
|
2024-01-15 05:03:31 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-09 18:48:41 -06:00
|
|
|
impl HasModule for StaticId {
|
|
|
|
#[inline]
|
|
|
|
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
|
|
|
module_for_assoc_item_loc(db, *self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl HasModule for TypeAliasId {
|
|
|
|
#[inline]
|
|
|
|
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
|
|
|
module_for_assoc_item_loc(db, *self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// endregion: manual-assoc-has-module-impls
|
|
|
|
|
2024-01-15 05:03:31 -06:00
|
|
|
impl HasModule for EnumVariantId {
|
|
|
|
#[inline]
|
|
|
|
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
|
|
|
self.lookup(db).parent.module(db)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-09 18:48:41 -06:00
|
|
|
impl HasModule for MacroRulesId {
|
2024-01-15 05:03:31 -06:00
|
|
|
#[inline]
|
2023-12-20 14:24:20 -06:00
|
|
|
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
2023-06-15 05:28:40 -05:00
|
|
|
self.lookup(db).container
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-09 18:48:41 -06:00
|
|
|
impl HasModule for Macro2Id {
|
|
|
|
#[inline]
|
|
|
|
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
|
|
|
self.lookup(db).container
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl HasModule for ProcMacroId {
|
|
|
|
#[inline]
|
|
|
|
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
|
|
|
self.lookup(db).container.into()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl HasModule for ItemContainerId {
|
|
|
|
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
|
|
|
match *self {
|
|
|
|
ItemContainerId::ModuleId(it) => it,
|
|
|
|
ItemContainerId::ImplId(it) => it.module(db),
|
|
|
|
ItemContainerId::TraitId(it) => it.module(db),
|
|
|
|
ItemContainerId::ExternBlockId(it) => it.module(db),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl HasModule for AdtId {
|
|
|
|
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
|
|
|
match *self {
|
|
|
|
AdtId::StructId(it) => it.module(db),
|
|
|
|
AdtId::UnionId(it) => it.module(db),
|
|
|
|
AdtId::EnumId(it) => it.module(db),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-17 07:29:29 -06:00
|
|
|
impl HasModule for VariantId {
|
2023-12-20 14:24:20 -06:00
|
|
|
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
2024-02-09 18:48:41 -06:00
|
|
|
match *self {
|
|
|
|
VariantId::EnumVariantId(it) => it.module(db),
|
|
|
|
VariantId::StructId(it) => it.module(db),
|
|
|
|
VariantId::UnionId(it) => it.module(db),
|
2020-12-17 07:29:29 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-08 14:41:19 -06:00
|
|
|
impl HasModule for MacroId {
|
2023-12-20 14:24:20 -06:00
|
|
|
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
2024-02-09 18:48:41 -06:00
|
|
|
match *self {
|
|
|
|
MacroId::MacroRulesId(it) => it.module(db),
|
|
|
|
MacroId::Macro2Id(it) => it.module(db),
|
|
|
|
MacroId::ProcMacroId(it) => it.module(db),
|
2022-03-08 14:41:19 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-05 06:27:19 -05:00
|
|
|
impl HasModule for TypeOwnerId {
|
2023-12-20 14:24:20 -06:00
|
|
|
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
2024-02-09 18:48:41 -06:00
|
|
|
match *self {
|
|
|
|
TypeOwnerId::FunctionId(it) => it.module(db),
|
|
|
|
TypeOwnerId::StaticId(it) => it.module(db),
|
|
|
|
TypeOwnerId::ConstId(it) => it.module(db),
|
2023-07-06 09:03:17 -05:00
|
|
|
TypeOwnerId::AdtId(it) => it.module(db),
|
2024-02-09 18:48:41 -06:00
|
|
|
TypeOwnerId::TraitId(it) => it.module(db),
|
|
|
|
TypeOwnerId::TraitAliasId(it) => it.module(db),
|
|
|
|
TypeOwnerId::TypeAliasId(it) => it.module(db),
|
|
|
|
TypeOwnerId::ImplId(it) => it.module(db),
|
|
|
|
TypeOwnerId::EnumVariantId(it) => it.module(db),
|
|
|
|
TypeOwnerId::InTypeConstId(it) => it.lookup(db).owner.module(db),
|
2019-11-26 05:02:57 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-05 06:27:19 -05:00
|
|
|
impl HasModule for DefWithBodyId {
|
2023-12-20 14:24:20 -06:00
|
|
|
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
2020-06-22 08:07:06 -05:00
|
|
|
match self {
|
2024-02-09 18:48:41 -06:00
|
|
|
DefWithBodyId::FunctionId(it) => it.module(db),
|
|
|
|
DefWithBodyId::StaticId(it) => it.module(db),
|
|
|
|
DefWithBodyId::ConstId(it) => it.module(db),
|
|
|
|
DefWithBodyId::VariantId(it) => it.module(db),
|
2023-06-12 11:21:17 -05:00
|
|
|
DefWithBodyId::InTypeConstId(it) => it.lookup(db).owner.module(db),
|
2020-06-22 08:07:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-07 12:52:09 -06:00
|
|
|
impl HasModule for GenericDefId {
|
2023-12-20 14:24:20 -06:00
|
|
|
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
2019-12-07 12:52:09 -06:00
|
|
|
match self {
|
2024-02-09 18:48:41 -06:00
|
|
|
GenericDefId::FunctionId(it) => it.module(db),
|
2019-12-07 12:52:09 -06:00
|
|
|
GenericDefId::AdtId(it) => it.module(db),
|
2024-02-09 18:48:41 -06:00
|
|
|
GenericDefId::TraitId(it) => it.module(db),
|
|
|
|
GenericDefId::TraitAliasId(it) => it.module(db),
|
|
|
|
GenericDefId::TypeAliasId(it) => it.module(db),
|
|
|
|
GenericDefId::ImplId(it) => it.module(db),
|
|
|
|
GenericDefId::EnumVariantId(it) => it.module(db),
|
|
|
|
GenericDefId::ConstId(it) => it.module(db),
|
2019-12-07 12:52:09 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-10 05:40:23 -06:00
|
|
|
impl HasModule for AttrDefId {
|
|
|
|
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
|
|
|
match self {
|
|
|
|
AttrDefId::ModuleId(it) => *it,
|
|
|
|
AttrDefId::FieldId(it) => it.parent.module(db),
|
|
|
|
AttrDefId::AdtId(it) => it.module(db),
|
|
|
|
AttrDefId::FunctionId(it) => it.module(db),
|
|
|
|
AttrDefId::EnumVariantId(it) => it.module(db),
|
|
|
|
AttrDefId::StaticId(it) => it.module(db),
|
|
|
|
AttrDefId::ConstId(it) => it.module(db),
|
|
|
|
AttrDefId::TraitId(it) => it.module(db),
|
|
|
|
AttrDefId::TraitAliasId(it) => it.module(db),
|
|
|
|
AttrDefId::TypeAliasId(it) => it.module(db),
|
|
|
|
AttrDefId::ImplId(it) => it.module(db),
|
|
|
|
AttrDefId::ExternBlockId(it) => it.module(db),
|
|
|
|
AttrDefId::GenericParamId(it) => match it {
|
|
|
|
GenericParamId::TypeParamId(it) => it.parent(),
|
|
|
|
GenericParamId::ConstParamId(it) => it.parent(),
|
|
|
|
GenericParamId::LifetimeParamId(it) => it.parent,
|
|
|
|
}
|
|
|
|
.module(db),
|
|
|
|
AttrDefId::MacroId(it) => it.module(db),
|
|
|
|
AttrDefId::ExternCrateId(it) => it.module(db),
|
|
|
|
AttrDefId::UseId(it) => it.module(db),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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.
|
2023-12-20 14:24:20 -06:00
|
|
|
pub fn module(&self, db: &dyn DefDatabase) -> Option<ModuleId> {
|
2021-03-01 12:36:34 -06:00
|
|
|
Some(match self {
|
|
|
|
ModuleDefId::ModuleId(id) => *id,
|
2024-02-09 18:48:41 -06:00
|
|
|
ModuleDefId::FunctionId(id) => id.module(db),
|
2021-03-01 12:36:34 -06:00
|
|
|
ModuleDefId::AdtId(id) => id.module(db),
|
2024-02-09 18:48:41 -06:00
|
|
|
ModuleDefId::EnumVariantId(id) => id.module(db),
|
|
|
|
ModuleDefId::ConstId(id) => id.module(db),
|
|
|
|
ModuleDefId::StaticId(id) => id.module(db),
|
|
|
|
ModuleDefId::TraitId(id) => id.module(db),
|
|
|
|
ModuleDefId::TraitAliasId(id) => id.module(db),
|
|
|
|
ModuleDefId::TypeAliasId(id) => id.module(db),
|
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-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,
|
2023-08-01 05:38:53 -05:00
|
|
|
resolver: impl Fn(path::ModPath) -> Option<MacroDefId> + Copy,
|
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,
|
2023-08-01 05:38:53 -05:00
|
|
|
resolver: impl Fn(path::ModPath) -> Option<MacroDefId> + Copy,
|
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,
|
2023-08-01 05:38:53 -05:00
|
|
|
resolver: impl Fn(path::ModPath) -> Option<MacroDefId> + Copy,
|
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-11-17 12:07:31 -06:00
|
|
|
let span_map = db.span_map(self.file_id);
|
2024-03-07 07:14:59 -06:00
|
|
|
let path = self.value.path().and_then(|path| {
|
2024-03-14 06:02:23 -05:00
|
|
|
let range = path.syntax().text_range();
|
|
|
|
let mod_path = path::ModPath::from_src(db, path, &mut |range| {
|
2024-03-07 07:14:59 -06:00
|
|
|
span_map.as_ref().span_for_range(range).ctx
|
2024-03-14 06:02:23 -05:00
|
|
|
})?;
|
|
|
|
let call_site = span_map.span_for_range(range);
|
|
|
|
Some((call_site, mod_path))
|
2024-03-07 07:14:59 -06:00
|
|
|
});
|
2020-12-02 09:52:14 -06:00
|
|
|
|
2024-03-14 06:02:23 -05:00
|
|
|
let Some((call_site, 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-08-01 05:38:53 -05:00
|
|
|
macro_call_as_call_id_with_eager(
|
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),
|
2024-03-15 06:47:05 -05:00
|
|
|
call_site.ctx,
|
2021-09-05 14:30:06 -05:00
|
|
|
expands_to,
|
2021-02-28 05:12:11 -06:00
|
|
|
krate,
|
|
|
|
resolver,
|
2023-08-01 05:38:53 -05:00
|
|
|
resolver,
|
2021-02-28 05:12:11 -06:00
|
|
|
)
|
2020-02-16 22:57:24 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Helper wrapper for `AstId` with `ModPath`
|
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2023-07-04 02:16:15 -05:00
|
|
|
struct AstIdWithPath<T: AstIdNode> {
|
2020-11-02 06:13:32 -06:00
|
|
|
ast_id: AstId<T>,
|
|
|
|
path: path::ModPath,
|
2020-02-16 22:57:24 -06:00
|
|
|
}
|
|
|
|
|
2023-07-04 02:16:15 -05:00
|
|
|
impl<T: AstIdNode> 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>,
|
2024-03-15 06:47:05 -05:00
|
|
|
call_site: SyntaxContextId,
|
2021-09-05 14:30:06 -05:00
|
|
|
expand_to: ExpandTo,
|
2021-02-28 05:12:11 -06:00
|
|
|
krate: CrateId,
|
2023-08-01 05:38:53 -05:00
|
|
|
resolver: impl Fn(path::ModPath) -> Option<MacroDefId> + Copy,
|
2023-04-16 11:29:42 -05:00
|
|
|
) -> Result<Option<MacroCallId>, UnresolvedMacro> {
|
2023-11-17 12:07:31 -06:00
|
|
|
macro_call_as_call_id_with_eager(db, call, call_site, expand_to, krate, resolver, resolver)
|
2023-08-01 05:38:53 -05:00
|
|
|
.map(|res| res.value)
|
2023-04-16 11:29:42 -05:00
|
|
|
}
|
|
|
|
|
2023-08-01 05:38:53 -05:00
|
|
|
fn macro_call_as_call_id_with_eager(
|
2023-04-17 10:31:39 -05:00
|
|
|
db: &dyn ExpandDatabase,
|
2023-04-16 11:29:42 -05:00
|
|
|
call: &AstIdWithPath<ast::MacroCall>,
|
2024-03-15 06:47:05 -05:00
|
|
|
call_site: SyntaxContextId,
|
2023-04-16 11:29:42 -05:00
|
|
|
expand_to: ExpandTo,
|
|
|
|
krate: CrateId,
|
2023-08-01 05:38:53 -05:00
|
|
|
resolver: impl FnOnce(path::ModPath) -> Option<MacroDefId>,
|
|
|
|
eager_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
|
|
|
|
2023-07-30 05:18:19 -05:00
|
|
|
let res = match def.kind {
|
2024-03-13 12:47:56 -05:00
|
|
|
MacroDefKind::BuiltInEager(..) => expand_eager_macro_input(
|
|
|
|
db,
|
|
|
|
krate,
|
|
|
|
&call.ast_id.to_node(db),
|
|
|
|
call.ast_id,
|
|
|
|
def,
|
|
|
|
call_site,
|
|
|
|
&|path| eager_resolver(path).filter(MacroDefId::is_fn_like),
|
|
|
|
),
|
2023-07-30 05:18:19 -05:00
|
|
|
_ if def.is_fn_like() => ExpandResult {
|
2024-03-13 12:05:27 -05:00
|
|
|
value: Some(def.make_call(
|
2023-04-17 10:31:39 -05:00
|
|
|
db,
|
2023-04-16 08:46:12 -05:00
|
|
|
krate,
|
2024-03-13 12:05:27 -05:00
|
|
|
MacroCallKind::FnLike { ast_id: call.ast_id, expand_to, eager: None },
|
2023-11-17 12:07:31 -06:00
|
|
|
call_site,
|
2023-04-16 08:46:12 -05:00
|
|
|
)),
|
|
|
|
err: None,
|
2023-07-30 05:18:19 -05:00
|
|
|
},
|
|
|
|
_ => return Err(UnresolvedMacro { path: call.path.clone() }),
|
2021-02-28 05:12:11 -06:00
|
|
|
};
|
|
|
|
Ok(res)
|
2020-02-16 22:57:24 -06:00
|
|
|
}
|
|
|
|
|
2023-11-24 09:38:48 -06:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct UnresolvedMacro {
|
|
|
|
pub path: hir_expand::mod_path::ModPath,
|
|
|
|
}
|
|
|
|
|
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,
|
|
|
|
);
|