//! Defines `ExpressionStore`: a lowered representation of functions, statics and //! consts. pub mod body; mod expander; pub mod lower; pub mod path; pub mod pretty; pub mod scope; #[cfg(test)] mod tests; use std::{ ops::{Deref, Index}, sync::LazyLock, }; use cfg::{CfgExpr, CfgOptions}; use either::Either; use hir_expand::{ExpandError, InFile, MacroCallId, mod_path::ModPath, name::Name}; use la_arena::{Arena, ArenaMap}; use rustc_hash::FxHashMap; use smallvec::SmallVec; use span::{Edition, SyntaxContext}; use syntax::{AstPtr, SyntaxNodePtr, ast}; use thin_vec::ThinVec; use triomphe::Arc; use tt::TextRange; use crate::{ BlockId, SyntheticSyntax, db::DefDatabase, expr_store::path::Path, hir::{ Array, AsmOperand, Binding, BindingId, Expr, ExprId, ExprOrPatId, Label, LabelId, Pat, PatId, RecordFieldPat, Statement, }, nameres::{DefMap, block_def_map}, type_ref::{LifetimeRef, LifetimeRefId, PathId, TypeRef, TypeRefId}, }; pub use self::body::{Body, BodySourceMap}; pub use self::lower::{ hir_assoc_type_binding_to_ast, hir_generic_arg_to_ast, hir_segment_to_ast_segment, }; /// A wrapper around [`span::SyntaxContextId`] that is intended only for comparisons. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct HygieneId(span::SyntaxContext); impl HygieneId { // The edition doesn't matter here, we only use this for comparisons and to lookup the macro. pub const ROOT: Self = Self(span::SyntaxContext::root(Edition::Edition2015)); pub fn new(mut ctx: span::SyntaxContext) -> Self { // See `Name` for why we're doing that. ctx.remove_root_edition(); Self(ctx) } // FIXME: Inline this pub(crate) fn lookup(self) -> SyntaxContext { self.0 } pub(crate) fn is_root(self) -> bool { self.0.is_root() } } pub type ExprPtr = AstPtr; pub type ExprSource = InFile; pub type PatPtr = AstPtr; pub type PatSource = InFile; pub type LabelPtr = AstPtr; pub type LabelSource = InFile; pub type FieldPtr = AstPtr; pub type FieldSource = InFile; pub type PatFieldPtr = AstPtr>; pub type PatFieldSource = InFile; pub type ExprOrPatPtr = AstPtr>; pub type ExprOrPatSource = InFile; pub type SelfParamPtr = AstPtr; pub type MacroCallPtr = AstPtr; pub type TypePtr = AstPtr; pub type TypeSource = InFile; pub type LifetimePtr = AstPtr; pub type LifetimeSource = InFile; // We split the store into types-only and expressions, because most stores (e.g. generics) // don't store any expressions and this saves memory. Same thing for the source map. #[derive(Debug, PartialEq, Eq)] struct ExpressionOnlyStore { exprs: Arena, pats: Arena, bindings: Arena, labels: Arena