Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/expr_store.rs')
-rw-r--r--crates/hir-def/src/expr_store.rs63
1 files changed, 47 insertions, 16 deletions
diff --git a/crates/hir-def/src/expr_store.rs b/crates/hir-def/src/expr_store.rs
index c9a7566c8d..05c220d223 100644
--- a/crates/hir-def/src/expr_store.rs
+++ b/crates/hir-def/src/expr_store.rs
@@ -1,10 +1,11 @@
//! Defines `ExpressionStore`: a lowered representation of functions, statics and
//! consts.
-mod body;
-mod lower;
-mod pretty;
+pub mod body;
+mod expander;
+pub mod lower;
+pub mod path;
+pub(crate) mod pretty;
pub mod scope;
-
#[cfg(test)]
mod tests;
@@ -12,7 +13,7 @@ use std::ops::{Deref, Index};
use cfg::{CfgExpr, CfgOptions};
use either::Either;
-use hir_expand::{ExpandError, InFile, name::Name};
+use hir_expand::{ExpandError, InFile, mod_path::ModPath, name::Name};
use la_arena::{Arena, ArenaMap};
use rustc_hash::FxHashMap;
use smallvec::SmallVec;
@@ -22,18 +23,19 @@ use triomphe::Arc;
use tt::TextRange;
use crate::{
- BlockId, DefWithBodyId, Lookup, SyntheticSyntax,
+ BlockId, SyntheticSyntax,
db::DefDatabase,
+ expr_store::path::Path,
hir::{
Array, AsmOperand, Binding, BindingId, Expr, ExprId, ExprOrPatId, Label, LabelId, Pat,
PatId, RecordFieldPat, Statement,
},
nameres::DefMap,
- path::{ModPath, Path},
- type_ref::{TypeRef, TypeRefId, TypesMap, TypesSourceMap},
+ type_ref::{PathId, TypeRef, TypeRefId},
};
pub use self::body::{Body, BodySourceMap};
+pub use self::lower::hir_segment_to_ast_segment;
/// A wrapper around [`span::SyntaxContextId`] that is intended only for comparisons.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -80,16 +82,19 @@ pub type ExprOrPatSource = InFile<ExprOrPatPtr>;
pub type SelfParamPtr = AstPtr<ast::SelfParam>;
pub type MacroCallPtr = AstPtr<ast::MacroCall>;
+pub type TypePtr = AstPtr<ast::Type>;
+pub type TypeSource = InFile<TypePtr>;
+
#[derive(Debug, Eq, PartialEq)]
pub struct ExpressionStore {
pub exprs: Arena<Expr>,
pub pats: Arena<Pat>,
pub bindings: Arena<Binding>,
pub labels: Arena<Label>,
+ pub types: Arena<TypeRef>,
/// Id of the closure/coroutine that owns the corresponding binding. If a binding is owned by the
/// top level expression, it will not be listed in here.
pub binding_owners: FxHashMap<BindingId, ExprId>,
- pub types: TypesMap,
/// Block expressions in this store that may contain inner items.
block_scopes: Box<[BlockId]>,
@@ -128,15 +133,16 @@ pub struct ExpressionStoreSourceMap {
field_map_back: FxHashMap<ExprId, FieldSource>,
pat_field_map_back: FxHashMap<PatId, PatFieldSource>,
- pub types: TypesSourceMap,
+ types_map_back: ArenaMap<TypeRefId, TypeSource>,
+ types_map: FxHashMap<TypeSource, TypeRefId>,
template_map: Option<Box<FormatTemplate>>,
- expansions: FxHashMap<InFile<MacroCallPtr>, MacroFileId>,
+ pub expansions: FxHashMap<InFile<MacroCallPtr>, MacroFileId>,
/// Diagnostics accumulated during lowering. These contain `AstPtr`s and so are stored in
/// the source map (since they're just as volatile).
- diagnostics: Vec<ExpressionStoreDiagnostics>,
+ pub diagnostics: Vec<ExpressionStoreDiagnostics>,
}
/// The body of an item (function, const etc.).
@@ -147,7 +153,7 @@ pub struct ExpressionStoreBuilder {
pub bindings: Arena<Binding>,
pub labels: Arena<Label>,
pub binding_owners: FxHashMap<BindingId, ExprId>,
- pub types: TypesMap,
+ pub types: Arena<TypeRef>,
block_scopes: Vec<BlockId>,
binding_hygiene: FxHashMap<BindingId, HygieneId>,
ident_hygiene: FxHashMap<ExprOrPatId, HygieneId>,
@@ -178,7 +184,7 @@ pub enum ExpressionStoreDiagnostics {
}
impl ExpressionStoreBuilder {
- fn finish(self) -> ExpressionStore {
+ pub fn finish(self) -> ExpressionStore {
let Self {
block_scopes,
mut exprs,
@@ -601,6 +607,17 @@ impl Index<TypeRefId> for ExpressionStore {
&self.types[b]
}
}
+impl Index<PathId> for ExpressionStore {
+ type Output = Path;
+
+ #[inline]
+ fn index(&self, index: PathId) -> &Self::Output {
+ let TypeRef::Path(path) = &self[index.type_ref()] else {
+ unreachable!("`PathId` always points to `TypeRef::Path`");
+ };
+ path
+ }
+}
// FIXME: Change `node_` prefix to something more reasonable.
// Perhaps `expr_syntax` and `expr_id`?
@@ -638,6 +655,14 @@ impl ExpressionStoreSourceMap {
self.pat_map.get(&node.map(AstPtr::new)).cloned()
}
+ pub fn type_syntax(&self, id: TypeRefId) -> Result<TypeSource, SyntheticSyntax> {
+ self.types_map_back.get(id).cloned().ok_or(SyntheticSyntax)
+ }
+
+ pub fn node_type(&self, node: InFile<&ast::Type>) -> Option<TypeRefId> {
+ self.types_map.get(&node.map(AstPtr::new)).cloned()
+ }
+
pub fn label_syntax(&self, label: LabelId) -> LabelSource {
self.label_map_back[label]
}
@@ -668,6 +693,10 @@ impl ExpressionStoreSourceMap {
self.expansions.iter()
}
+ pub fn expansion(&self, node: InFile<&ast::MacroCall>) -> Option<MacroFileId> {
+ self.expansions.get(&node.map(AstPtr::new)).copied()
+ }
+
pub fn implicit_format_args(
&self,
node: InFile<&ast::FormatArgsExpr>,
@@ -717,7 +746,8 @@ impl ExpressionStoreSourceMap {
template_map,
diagnostics,
binding_definitions,
- types,
+ types_map,
+ types_map_back,
} = self;
if let Some(template_map) = template_map {
let FormatTemplate {
@@ -740,6 +770,7 @@ impl ExpressionStoreSourceMap {
expansions.shrink_to_fit();
diagnostics.shrink_to_fit();
binding_definitions.shrink_to_fit();
- types.shrink_to_fit();
+ types_map.shrink_to_fit();
+ types_map_back.shrink_to_fit();
}
}