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.rs | 63 |
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(); } } |