Skip to main content

hir_def/
expr_store.rs

1//! Defines `ExpressionStore`: a lowered representation of functions, statics and
2//! consts.
3pub mod body;
4mod expander;
5pub mod lower;
6pub mod path;
7pub mod pretty;
8pub mod scope;
9#[cfg(test)]
10mod tests;
11
12use std::{
13    borrow::Borrow,
14    ops::{Deref, Index},
15};
16
17use base_db::SourceDatabase;
18use cfg::{CfgExpr, CfgOptions};
19use either::Either;
20use hir_expand::{InFile, MacroCallId, mod_path::ModPath, name::Name};
21use la_arena::{Arena, ArenaMap};
22use smallvec::SmallVec;
23use span::{Edition, SyntaxContext};
24use syntax::{AstPtr, SyntaxNodePtr, ast};
25use thin_vec::ThinVec;
26use tt::TextRange;
27
28use crate::{
29    AdtId, BlockId, ExpressionStoreOwnerId, GenericDefId, SyntheticSyntax, ThinFxHashMap,
30    expr_store::path::{AssociatedTypeBinding, GenericArg, GenericArgs, NormalPath, Path},
31    hir::{
32        Array, AsmOperand, Binding, BindingId, Expr, ExprId, ExprOrPatId, ExprOrPatIdPacked,
33        InlineAsm, Label, LabelId, MatchArm, OffsetOf, Pat, PatId, RecordFieldPat, RecordLitField,
34        RecordSpread, Statement,
35    },
36    nameres::{DefMap, block_def_map},
37    signatures::VariantFields,
38    type_ref::{
39        ArrayType, ConstRef, FnType, LifetimeRef, LifetimeRefId, PathId, RefType, TypeBound,
40        TypeRef, TypeRefId, UseArgRef,
41    },
42};
43
44pub use self::body::{Body, BodySourceMap};
45pub use self::lower::{
46    hir_assoc_type_binding_to_ast, hir_generic_arg_to_ast, hir_segment_to_ast_segment,
47};
48
49/// A wrapper around [`span::SyntaxContext`] that is intended only for comparisons.
50#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
51pub struct HygieneId(span::SyntaxContext);
52
53impl HygieneId {
54    // The edition doesn't matter here, we only use this for comparisons and to lookup the macro.
55    pub const ROOT: Self = Self(span::SyntaxContext::root(Edition::Edition2015));
56
57    pub fn new(mut ctx: span::SyntaxContext) -> Self {
58        // See `Name` for why we're doing that.
59        ctx.remove_root_edition();
60        Self(ctx)
61    }
62
63    pub(crate) fn syntax_context(self) -> SyntaxContext {
64        self.0
65    }
66
67    pub(crate) fn is_root(self) -> bool {
68        self.0.is_root()
69    }
70}
71
72pub type ExprPtr = AstPtr<ast::Expr>;
73pub type ExprSource = InFile<ExprPtr>;
74
75pub type PatPtr = AstPtr<ast::Pat>;
76pub type PatSource = InFile<PatPtr>;
77
78/// BlockExpr -> Desugared label from try block
79pub type LabelPtr = AstPtr<Either<ast::Label, ast::BlockExpr>>;
80pub type LabelSource = InFile<LabelPtr>;
81
82pub type FieldPtr = AstPtr<ast::RecordExprField>;
83pub type FieldSource = InFile<FieldPtr>;
84
85pub type PatFieldPtr = AstPtr<Either<ast::RecordExprField, ast::RecordPatField>>;
86pub type PatFieldSource = InFile<PatFieldPtr>;
87
88pub type ExprOrPatPtr = AstPtr<Either<ast::Expr, ast::Pat>>;
89pub type ExprOrPatSource = InFile<ExprOrPatPtr>;
90
91pub type SelfParamPtr = AstPtr<ast::SelfParam>;
92pub type MacroCallPtr = AstPtr<ast::MacroCall>;
93
94pub type TypePtr = AstPtr<ast::Type>;
95pub type TypeSource = InFile<TypePtr>;
96
97pub type LifetimePtr = AstPtr<ast::Lifetime>;
98pub type LifetimeSource = InFile<LifetimePtr>;
99
100#[derive(Debug, Clone, Copy, PartialEq, Eq)]
101struct ExprRoot {
102    root: ExprId,
103    // We store, for each root, the range of exprs (and pats and bindings) it holds.
104    // We store only the end (exclusive), since the start can be inferred from the previous
105    // roots or is zero.
106    exprs_end: ExprId,
107    pats_end: PatId,
108    bindings_end: BindingId,
109}
110
111// We split the store into types-only and expressions, because most stores (e.g. generics)
112// don't store any expressions and this saves memory. Same thing for the source map.
113#[derive(Debug, Clone, PartialEq, Eq)]
114struct ExpressionOnlyStore {
115    exprs: Arena<Expr>,
116    pats: Arena<Pat>,
117    bindings: Arena<Binding>,
118    labels: Arena<Label>,
119    /// Id of the closure/coroutine/anon const that owns the corresponding binding. If a binding is owned by the
120    /// top level expression, it will not be listed in here.
121    binding_owners: ThinFxHashMap<BindingId, ExprId>,
122    /// Block expressions in this store that may contain inner items.
123    block_scopes: Box<[BlockId]>,
124
125    /// A map from an variable usages to their hygiene ID.
126    ///
127    /// Expressions (and destructuring patterns) that can be recorded here are single segment path, although not all single segments path refer
128    /// to variables and have hygiene (some refer to items, we don't know at this stage).
129    ident_hygiene: ThinFxHashMap<ExprOrPatIdPacked, HygieneId>,
130
131    /// Maps expression roots to their origin.
132    ///
133    /// Note: while every root expr is an inference root (aka. an `AnonConst`), there could be other roots that do not appear here.
134    /// This can happen when anon consts are nested, for example:
135    ///
136    /// ```
137    /// [
138    ///     ();
139    ///     {
140    ///         // this repeat expr is anon const #1, and *only it* appears in this list.
141    ///         [
142    ///             ();
143    ///             {
144    ///                 // this repeat expr is anon const #2.
145    ///                 0
146    ///             }
147    ///         ];
148    ///         0
149    ///     }
150    /// ]
151    /// ```
152    /// We do this because this allows us to search this list using a binary search,
153    /// and it does not bother us because we use this list for two things: constructing `ExprScopes`, which
154    /// works fine with nested exprs, and retrieving inference results, and we copy the inner const's inference
155    /// into the outer const.
156    expr_roots: SmallVec<[ExprRoot; 1]>,
157}
158
159#[derive(Debug, Clone, PartialEq, Eq)]
160pub struct ExpressionStore {
161    expr_only: Option<Box<ExpressionOnlyStore>>,
162    pub types: Arena<TypeRef>,
163    pub lifetimes: Arena<LifetimeRef>,
164}
165
166#[derive(Debug, Eq, Default)]
167struct ExpressionOnlySourceMap {
168    // AST expressions can create patterns in destructuring assignments. Therefore, `ExprSource` can also map
169    // to `PatId`, and `PatId` can also map to `ExprSource` (the other way around is unaffected).
170    expr_map: ThinFxHashMap<ExprSource, ExprOrPatIdPacked>,
171    expr_map_back: ArenaMap<ExprId, ExprOrPatSource>,
172
173    pat_map: ThinFxHashMap<PatSource, ExprOrPatIdPacked>,
174    pat_map_back: ArenaMap<PatId, ExprOrPatSource>,
175
176    label_map: ThinFxHashMap<LabelSource, LabelId>,
177    label_map_back: ArenaMap<LabelId, LabelSource>,
178
179    binding_definitions:
180        ArenaMap<BindingId, SmallVec<[PatId; 2 * size_of::<usize>() / size_of::<PatId>()]>>,
181
182    /// We don't create explicit nodes for record fields (`S { record_field: 92 }`).
183    /// Instead, we use id of expression (`92`) to identify the field.
184    field_map_back: ThinFxHashMap<ExprId, FieldSource>,
185    pat_field_map_back: ThinFxHashMap<PatId, PatFieldSource>,
186
187    template_map: Option<Box<FormatTemplate>>,
188
189    expansions: ThinFxHashMap<InFile<MacroCallPtr>, MacroCallId>,
190
191    /// Diagnostics accumulated during lowering. These contain `AstPtr`s and so are stored in
192    /// the source map (since they're just as volatile).
193    //
194    // We store diagnostics on the `ExpressionOnlySourceMap` because diagnostics are rare (except
195    // maybe for cfgs, and they are also not common in type places).
196    diagnostics: ThinVec<ExpressionStoreDiagnostics>,
197}
198
199impl PartialEq for ExpressionOnlySourceMap {
200    fn eq(&self, other: &Self) -> bool {
201        // we only need to compare one of the two mappings
202        // as the other is a reverse mapping and thus will compare
203        // the same as normal mapping
204        let Self {
205            expr_map: _,
206            expr_map_back,
207            pat_map: _,
208            pat_map_back,
209            label_map: _,
210            label_map_back,
211            // If this changed, our pattern data must have changed
212            binding_definitions: _,
213            // If this changed, our expression data must have changed
214            field_map_back: _,
215            // If this changed, our pattern data must have changed
216            pat_field_map_back: _,
217            template_map,
218            expansions,
219            diagnostics,
220        } = self;
221        *expr_map_back == other.expr_map_back
222            && *pat_map_back == other.pat_map_back
223            && *label_map_back == other.label_map_back
224            && *template_map == other.template_map
225            && *expansions == other.expansions
226            && *diagnostics == other.diagnostics
227    }
228}
229
230#[derive(Debug, Eq, Default)]
231pub struct ExpressionStoreSourceMap {
232    expr_only: Option<Box<ExpressionOnlySourceMap>>,
233
234    types_map_back: ArenaMap<TypeRefId, TypeSource>,
235    types_map: ThinFxHashMap<TypeSource, TypeRefId>,
236
237    lifetime_map_back: ArenaMap<LifetimeRefId, LifetimeSource>,
238    #[expect(
239        unused,
240        reason = "this is here for completeness, and maybe we'll need it in the future"
241    )]
242    lifetime_map: ThinFxHashMap<LifetimeSource, LifetimeRefId>,
243}
244
245impl PartialEq for ExpressionStoreSourceMap {
246    fn eq(&self, other: &Self) -> bool {
247        // we only need to compare one of the two mappings
248        // as the other is a reverse mapping and thus will compare
249        // the same as normal mapping
250        let Self { expr_only, types_map_back, types_map: _, lifetime_map_back, lifetime_map: _ } =
251            self;
252        *expr_only == other.expr_only
253            && *types_map_back == other.types_map_back
254            && *lifetime_map_back == other.lifetime_map_back
255    }
256}
257
258/// The body of an item (function, const etc.).
259#[derive(Debug, Eq, PartialEq, Default)]
260pub struct ExpressionStoreBuilder {
261    pub exprs: Arena<Expr>,
262    pub pats: Arena<Pat>,
263    pub bindings: Arena<Binding>,
264    pub labels: Arena<Label>,
265    pub lifetimes: Arena<LifetimeRef>,
266    pub binding_owners: ThinFxHashMap<BindingId, ExprId>,
267    pub types: Arena<TypeRef>,
268    block_scopes: Vec<BlockId>,
269    ident_hygiene: ThinFxHashMap<ExprOrPatIdPacked, HygieneId>,
270    inference_roots: Option<SmallVec<[ExprRoot; 1]>>,
271
272    // AST expressions can create patterns in destructuring assignments. Therefore, `ExprSource` can also map
273    // to `PatId`, and `PatId` can also map to `ExprSource` (the other way around is unaffected).
274    expr_map: ThinFxHashMap<ExprSource, ExprOrPatIdPacked>,
275    expr_map_back: ArenaMap<ExprId, ExprOrPatSource>,
276
277    pat_map: ThinFxHashMap<PatSource, ExprOrPatIdPacked>,
278    pat_map_back: ArenaMap<PatId, ExprOrPatSource>,
279
280    label_map: ThinFxHashMap<LabelSource, LabelId>,
281    label_map_back: ArenaMap<LabelId, LabelSource>,
282
283    types_map_back: ArenaMap<TypeRefId, TypeSource>,
284    types_map: ThinFxHashMap<TypeSource, TypeRefId>,
285
286    lifetime_map_back: ArenaMap<LifetimeRefId, LifetimeSource>,
287    lifetime_map: ThinFxHashMap<LifetimeSource, LifetimeRefId>,
288
289    binding_definitions:
290        ArenaMap<BindingId, SmallVec<[PatId; 2 * size_of::<usize>() / size_of::<PatId>()]>>,
291
292    /// We don't create explicit nodes for record fields (`S { record_field: 92 }`).
293    /// Instead, we use id of expression (`92`) to identify the field.
294    field_map_back: ThinFxHashMap<ExprId, FieldSource>,
295    pat_field_map_back: ThinFxHashMap<PatId, PatFieldSource>,
296
297    template_map: Option<Box<FormatTemplate>>,
298
299    expansions: ThinFxHashMap<InFile<MacroCallPtr>, MacroCallId>,
300
301    /// Diagnostics accumulated during lowering. These contain `AstPtr`s and so are stored in
302    /// the source map (since they're just as volatile).
303    //
304    // We store diagnostics on the `ExpressionOnlySourceMap` because diagnostics are rare (except
305    // maybe for cfgs, and they are also not common in type places).
306    pub(crate) diagnostics: Vec<ExpressionStoreDiagnostics>,
307}
308
309#[derive(Default, Debug, Eq, PartialEq)]
310struct FormatTemplate {
311    /// A map from `format_args!()` expressions to their captures.
312    format_args_to_captures: ThinFxHashMap<ExprId, (HygieneId, Vec<(syntax::TextRange, Name)>)>,
313    /// A map from `asm!()` expressions to their captures.
314    asm_to_captures: ThinFxHashMap<ExprId, Vec<Vec<(syntax::TextRange, usize)>>>,
315    /// A map from desugared expressions of implicit captures to their source.
316    ///
317    /// The value stored for each capture is its template literal and offset inside it. The template literal
318    /// is from the `format_args[_nl]!()` macro and so needs to be mapped up once to go to the user-written
319    /// template.
320    implicit_capture_to_source: ThinFxHashMap<ExprId, InFile<(ExprPtr, TextRange)>>,
321}
322
323#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
324pub enum MissingBodyItemKind {
325    AssocConst,
326    AssocType,
327    Const,
328    Static,
329    TypeAlias,
330}
331
332#[derive(Debug, Eq, PartialEq)]
333pub enum ExpressionStoreDiagnostics {
334    InactiveCode { node: InFile<SyntaxNodePtr>, cfg: CfgExpr, opts: CfgOptions },
335    UnresolvedMacroCall { node: InFile<MacroCallPtr>, path: ModPath },
336    UnreachableLabel { node: InFile<AstPtr<ast::Lifetime>>, name: Name },
337    AwaitOutsideOfAsync { node: InFile<AstPtr<ast::AwaitExpr>>, location: String },
338    UndeclaredLabel { node: InFile<AstPtr<ast::Lifetime>>, name: Name },
339    PatternArgInExternFn { node: InFile<AstPtr<ast::Pat>> },
340    FruInDestructuringAssignment { node: InFile<AstPtr<ast::Expr>> },
341    MissingBody { node: InFile<SyntaxNodePtr>, kind: MissingBodyItemKind },
342}
343
344impl ExpressionStoreBuilder {
345    pub fn finish(self) -> (ExpressionStore, ExpressionStoreSourceMap) {
346        let Self {
347            block_scopes,
348            mut exprs,
349            mut labels,
350            mut pats,
351            mut bindings,
352            mut binding_owners,
353            mut ident_hygiene,
354            inference_roots: mut expr_roots,
355            mut types,
356            mut lifetimes,
357
358            mut expr_map,
359            mut expr_map_back,
360            mut pat_map,
361            mut pat_map_back,
362            mut label_map,
363            mut label_map_back,
364            mut types_map_back,
365            mut types_map,
366            mut lifetime_map_back,
367            mut lifetime_map,
368            mut binding_definitions,
369            mut field_map_back,
370            mut pat_field_map_back,
371            mut template_map,
372            mut expansions,
373            diagnostics,
374        } = self;
375        exprs.shrink_to_fit();
376        labels.shrink_to_fit();
377        pats.shrink_to_fit();
378        bindings.shrink_to_fit();
379        binding_owners.shrink_to_fit();
380        ident_hygiene.shrink_to_fit();
381        types.shrink_to_fit();
382        lifetimes.shrink_to_fit();
383
384        expr_map.shrink_to_fit();
385        expr_map_back.shrink_to_fit();
386        pat_map.shrink_to_fit();
387        pat_map_back.shrink_to_fit();
388        label_map.shrink_to_fit();
389        label_map_back.shrink_to_fit();
390        types_map_back.shrink_to_fit();
391        types_map.shrink_to_fit();
392        lifetime_map_back.shrink_to_fit();
393        lifetime_map.shrink_to_fit();
394        binding_definitions.shrink_to_fit();
395        field_map_back.shrink_to_fit();
396        pat_field_map_back.shrink_to_fit();
397        if let Some(template_map) = &mut template_map {
398            let FormatTemplate {
399                format_args_to_captures,
400                asm_to_captures,
401                implicit_capture_to_source,
402            } = &mut **template_map;
403            format_args_to_captures.shrink_to_fit();
404            asm_to_captures.shrink_to_fit();
405            implicit_capture_to_source.shrink_to_fit();
406        }
407        expansions.shrink_to_fit();
408
409        let has_exprs =
410            !exprs.is_empty() || !labels.is_empty() || !pats.is_empty() || !bindings.is_empty();
411
412        let store = {
413            let expr_only = if has_exprs {
414                if let Some(expr_roots) = &mut expr_roots {
415                    expr_roots.shrink_to_fit();
416                }
417                Some(Box::new(ExpressionOnlyStore {
418                    exprs,
419                    pats,
420                    bindings,
421                    labels,
422                    binding_owners,
423                    block_scopes: block_scopes.into_boxed_slice(),
424                    ident_hygiene,
425                    expr_roots: expr_roots
426                        .expect("should always finish with a `Some(_)` expr_roots"),
427                }))
428            } else {
429                None
430            };
431            ExpressionStore { expr_only, types, lifetimes }
432        };
433
434        let source_map = {
435            let expr_only = if has_exprs || !expansions.is_empty() || !diagnostics.is_empty() {
436                Some(Box::new(ExpressionOnlySourceMap {
437                    expr_map,
438                    expr_map_back,
439                    pat_map,
440                    pat_map_back,
441                    label_map,
442                    label_map_back,
443                    binding_definitions,
444                    field_map_back,
445                    pat_field_map_back,
446                    template_map,
447                    expansions,
448                    diagnostics: ThinVec::from_iter(diagnostics),
449                }))
450            } else {
451                None
452            };
453            ExpressionStoreSourceMap {
454                expr_only,
455                types_map_back,
456                types_map,
457                lifetime_map_back,
458                lifetime_map,
459            }
460        };
461
462        (store, source_map)
463    }
464}
465
466impl ExpressionStore {
467    const EMPTY: &ExpressionStore =
468        &ExpressionStore { expr_only: None, types: Arena::new(), lifetimes: Arena::new() };
469
470    #[inline]
471    pub fn empty() -> &'static ExpressionStore {
472        ExpressionStore::EMPTY
473    }
474
475    pub fn of(db: &dyn SourceDatabase, def: ExpressionStoreOwnerId) -> &ExpressionStore {
476        match def {
477            ExpressionStoreOwnerId::Signature(def) => {
478                use crate::signatures::{
479                    ConstSignature, EnumSignature, FunctionSignature, ImplSignature,
480                    StaticSignature, StructSignature, TraitSignature, TypeAliasSignature,
481                    UnionSignature,
482                };
483                match def {
484                    GenericDefId::AdtId(AdtId::EnumId(id)) => &EnumSignature::of(db, id).store,
485                    GenericDefId::AdtId(AdtId::StructId(id)) => &StructSignature::of(db, id).store,
486                    GenericDefId::AdtId(AdtId::UnionId(id)) => &UnionSignature::of(db, id).store,
487                    GenericDefId::ConstId(id) => &ConstSignature::of(db, id).store,
488                    GenericDefId::FunctionId(id) => &FunctionSignature::of(db, id).store,
489                    GenericDefId::ImplId(id) => &ImplSignature::of(db, id).store,
490                    GenericDefId::StaticId(id) => &StaticSignature::of(db, id).store,
491                    GenericDefId::TraitId(id) => &TraitSignature::of(db, id).store,
492                    GenericDefId::TypeAliasId(id) => &TypeAliasSignature::of(db, id).store,
493                }
494            }
495            ExpressionStoreOwnerId::Body(body) => &Body::of(db, body).store,
496            ExpressionStoreOwnerId::VariantFields(variant_id) => {
497                &VariantFields::of(db, variant_id).store
498            }
499        }
500    }
501
502    pub fn with_source_map(
503        db: &dyn SourceDatabase,
504        def: ExpressionStoreOwnerId,
505    ) -> (&ExpressionStore, &ExpressionStoreSourceMap) {
506        match def {
507            ExpressionStoreOwnerId::Signature(def) => {
508                use crate::signatures::{
509                    ConstSignature, EnumSignature, FunctionSignature, ImplSignature,
510                    StaticSignature, StructSignature, TraitSignature, TypeAliasSignature,
511                    UnionSignature,
512                };
513                match def {
514                    GenericDefId::AdtId(AdtId::EnumId(id)) => {
515                        let sig = EnumSignature::with_source_map(db, id);
516                        (&sig.0.store, &sig.1)
517                    }
518                    GenericDefId::AdtId(AdtId::StructId(id)) => {
519                        let sig = StructSignature::with_source_map(db, id);
520                        (&sig.0.store, &sig.1)
521                    }
522                    GenericDefId::AdtId(AdtId::UnionId(id)) => {
523                        let sig = UnionSignature::with_source_map(db, id);
524                        (&sig.0.store, &sig.1)
525                    }
526                    GenericDefId::ConstId(id) => {
527                        let sig = ConstSignature::with_source_map(db, id);
528                        (&sig.0.store, &sig.1)
529                    }
530                    GenericDefId::FunctionId(id) => {
531                        let sig = FunctionSignature::with_source_map(db, id);
532                        (&sig.0.store, &sig.1)
533                    }
534                    GenericDefId::ImplId(id) => {
535                        let sig = ImplSignature::with_source_map(db, id);
536                        (&sig.0.store, &sig.1)
537                    }
538                    GenericDefId::StaticId(id) => {
539                        let sig = StaticSignature::with_source_map(db, id);
540                        (&sig.0.store, &sig.1)
541                    }
542                    GenericDefId::TraitId(id) => {
543                        let sig = TraitSignature::with_source_map(db, id);
544                        (&sig.0.store, &sig.1)
545                    }
546                    GenericDefId::TypeAliasId(id) => {
547                        let sig = TypeAliasSignature::with_source_map(db, id);
548                        (&sig.0.store, &sig.1)
549                    }
550                }
551            }
552            ExpressionStoreOwnerId::Body(body) => {
553                let (store, sm) = Body::with_source_map(db, body);
554                (&store.store, &sm.store)
555            }
556            ExpressionStoreOwnerId::VariantFields(variant_id) => {
557                let (store, sm) = VariantFields::with_source_map(db, variant_id);
558                (&store.store, sm)
559            }
560        }
561    }
562
563    /// Returns all expression root `ExprId`s found in this store.
564    pub fn expr_roots(&self) -> impl DoubleEndedIterator<Item = ExprId> {
565        self.expr_only
566            .as_ref()
567            .map_or(&[][..], |expr_only| &expr_only.expr_roots)
568            .iter()
569            .map(|root| root.root)
570    }
571
572    fn find_root_for(
573        &self,
574        mut get: impl FnMut(&ExprRoot) -> la_arena::RawIdx,
575        find: la_arena::RawIdx,
576    ) -> ExprId {
577        let expr_only = self.assert_expr_only();
578        let find = find.into_u32();
579        let entry = expr_only.expr_roots.partition_point(|root| get(root).into_u32() <= find);
580        expr_only.expr_roots[entry].root
581    }
582
583    pub fn find_root_for_expr(&self, expr: ExprId) -> ExprId {
584        self.find_root_for(|root| root.exprs_end.into_raw(), expr.into_raw())
585    }
586
587    pub fn find_root_for_pat(&self, pat: PatId) -> ExprId {
588        self.find_root_for(|root| root.pats_end.into_raw(), pat.into_raw())
589    }
590
591    pub fn find_root_for_binding(&self, binding: BindingId) -> ExprId {
592        self.find_root_for(|root| root.bindings_end.into_raw(), binding.into_raw())
593    }
594
595    /// Returns an iterator over all block expressions in this store that define inner items.
596    pub fn blocks<'a>(
597        &'a self,
598        db: &'a dyn SourceDatabase,
599    ) -> impl Iterator<Item = (BlockId, &'a DefMap)> + 'a {
600        self.expr_only
601            .as_ref()
602            .map(|it| &*it.block_scopes)
603            .unwrap_or_default()
604            .iter()
605            .map(move |&block| (block, block_def_map(db, block)))
606    }
607
608    pub fn walk_bindings_in_pat(&self, pat_id: PatId, mut f: impl FnMut(BindingId)) {
609        self.walk_pats(pat_id, &mut |pat| {
610            if let Pat::Bind { id, .. } = &self[pat] {
611                f(*id);
612            }
613        });
614    }
615
616    pub fn visit_pat_children(&self, pat_id: PatId, mut visitor: impl StoreVisitor) {
617        // Do not use `..` patterns or field accesses here, only destructuring, to ensure we cover all cases
618        // (we've had multiple bugs with this in the past).
619        let pat = &self[pat_id];
620        match pat {
621            Pat::Range { start, end, range_type: _ } => {
622                visitor.on_expr_opt(*start);
623                visitor.on_expr_opt(*end);
624            }
625            Pat::Lit(expr) | Pat::Expr(expr) => visitor.on_expr(*expr),
626            Pat::Path(path) => visitor.on_path(path),
627            Pat::Wild | Pat::Missing | Pat::Rest | Pat::NotNull => {}
628            &Pat::Bind { subpat, id: _ } => visitor.on_pat_opt(subpat),
629            Pat::Or(args) | Pat::Tuple { args, ellipsis: _ } => visitor.on_pats(args),
630            Pat::TupleStruct { args, ellipsis: _, path } => {
631                visitor.on_pats(args);
632                visitor.on_path(path);
633            }
634            Pat::Ref { pat, mutability: _ } => visitor.on_pat(*pat),
635            Pat::Slice { prefix, slice, suffix } => {
636                visitor.on_pats(prefix);
637                visitor.on_pat_opt(*slice);
638                visitor.on_pats(suffix);
639            }
640            Pat::Record { args, ellipsis: _, path } => {
641                args.iter().for_each(|RecordFieldPat { pat, name: _ }| visitor.on_pat(*pat));
642                visitor.on_path(path);
643            }
644            Pat::Box { inner } | Pat::Deref { inner } => visitor.on_pat(*inner),
645        }
646    }
647
648    pub fn walk_pats_shallow(&self, pat_id: PatId, f: impl FnMut(PatId)) {
649        return self.visit_pat_children(pat_id, Visitor(f));
650
651        struct Visitor<F>(F);
652
653        impl<F: FnMut(PatId)> StoreVisitor for Visitor<F> {
654            fn on_pat(&mut self, pat: PatId) {
655                (self.0)(pat);
656            }
657        }
658    }
659
660    pub fn walk_pats(&self, pat_id: PatId, f: &mut impl FnMut(PatId)) {
661        f(pat_id);
662        self.walk_pats_shallow(pat_id, |p| self.walk_pats(p, f));
663    }
664
665    #[inline]
666    pub fn binding_owner(&self, id: BindingId) -> Option<ExprId> {
667        self.expr_only.as_ref()?.binding_owners.get(&id).copied()
668    }
669
670    pub fn visit_expr_children(&self, expr_id: ExprId, mut visitor: impl StoreVisitor) {
671        // Do not use `..` patterns or field accesses here, only destructuring, to ensure we cover all cases
672        // (we've had multiple bugs with this in the past).
673        match &self[expr_id] {
674            Expr::OffsetOf(OffsetOf { container, fields: _ }) => visitor.on_type(*container),
675            Expr::Path(path) => visitor.on_path(path),
676            Expr::Continue { label: _ } | Expr::Missing | Expr::Literal(_) | Expr::Underscore => {}
677            Expr::InlineAsm(InlineAsm { operands, options: _, kind: _ }) => {
678                operands.iter().for_each(|(_, op)| match op {
679                    AsmOperand::In { expr, reg: _ }
680                    | AsmOperand::Out { expr: Some(expr), late: _, reg: _ }
681                    | AsmOperand::InOut { expr, late: _, reg: _ }
682                    | AsmOperand::Const(expr)
683                    | AsmOperand::Label(expr) => visitor.on_expr(*expr),
684                    AsmOperand::SplitInOut { in_expr, out_expr, late: _, reg: _ } => {
685                        visitor.on_expr(*in_expr);
686                        visitor.on_expr_opt(*out_expr);
687                    }
688                    AsmOperand::Out { expr: None, late: _, reg: _ } | AsmOperand::Sym(_) => (),
689                })
690            }
691            Expr::If { condition, then_branch, else_branch } => {
692                visitor.on_expr(*condition);
693                visitor.on_expr(*then_branch);
694                visitor.on_expr_opt(*else_branch);
695            }
696            Expr::Let { expr, pat } => {
697                visitor.on_pat(*pat);
698                visitor.on_expr(*expr);
699            }
700            Expr::Block { statements, tail, id: _, label: _, unsafe_: _ } => {
701                for stmt in statements {
702                    match stmt {
703                        Statement::Let { initializer, else_branch, pat, type_ref } => {
704                            visitor.on_expr_opt(*initializer);
705                            visitor.on_expr_opt(*else_branch);
706                            visitor.on_pat(*pat);
707                            visitor.on_type_opt(*type_ref);
708                        }
709                        Statement::Expr { expr: expression, has_semi: _ } => {
710                            visitor.on_expr(*expression)
711                        }
712                        Statement::Item(_) => (),
713                    }
714                }
715                visitor.on_expr_opt(*tail);
716            }
717            Expr::Loop { body, label: _, source: _ } => visitor.on_expr(*body),
718            Expr::Call { callee, args } => {
719                visitor.on_expr(*callee);
720                visitor.on_exprs(args);
721            }
722            Expr::MethodCall { receiver, args, generic_args, method_name: _ } => {
723                visitor.on_expr(*receiver);
724                visitor.on_exprs(args);
725                visitor.on_generic_args_opt(generic_args);
726            }
727            Expr::Match { expr, arms } => {
728                visitor.on_expr(*expr);
729                arms.iter().for_each(|MatchArm { pat, guard, expr }| {
730                    visitor.on_expr(*expr);
731                    visitor.on_expr_opt(*guard);
732                    visitor.on_pat(*pat);
733                });
734            }
735            Expr::Break { expr, label: _ }
736            | Expr::Return { expr }
737            | Expr::Yield { expr }
738            | Expr::Yeet { expr } => visitor.on_expr_opt(*expr),
739            Expr::Become { expr } => visitor.on_expr(*expr),
740            Expr::RecordLit { fields, spread, path } => {
741                for RecordLitField { name: _, expr } in fields.iter() {
742                    visitor.on_expr(*expr);
743                }
744                match spread {
745                    RecordSpread::Expr(expr) => visitor.on_expr(*expr),
746                    RecordSpread::None | RecordSpread::FieldDefaults => {}
747                }
748                visitor.on_path(path);
749            }
750            Expr::Closure { body, args, arg_types, ret_type, capture_by: _, closure_kind: _ } => {
751                visitor.on_expr(*body);
752                visitor.on_pats(args);
753                arg_types.iter().for_each(|arg_type| visitor.on_type_opt(*arg_type));
754                visitor.on_type_opt(*ret_type);
755            }
756            Expr::BinaryOp { lhs, rhs, op: _ } => {
757                visitor.on_expr(*lhs);
758                visitor.on_expr(*rhs);
759            }
760            Expr::Index { base, index } => {
761                visitor.on_expr(*base);
762                visitor.on_expr(*index);
763            }
764            Expr::Cast { expr, type_ref } => {
765                visitor.on_expr(*expr);
766                visitor.on_type(*type_ref);
767            }
768            Expr::Field { expr, name: _ }
769            | Expr::Await { expr }
770            | Expr::Ref { expr, mutability: _, rawness: _ }
771            | Expr::UnaryOp { expr, op: _ } => visitor.on_expr(*expr),
772            Expr::Const(expr) => visitor.on_anon_const_expr(*expr),
773            Expr::Tuple { exprs } => visitor.on_exprs(exprs),
774            Expr::Array(a) => match a {
775                Array::ElementList { elements } => visitor.on_exprs(elements),
776                Array::Repeat { initializer, repeat } => {
777                    visitor.on_expr(*initializer);
778                    visitor.on_anon_const_expr(*repeat)
779                }
780            },
781            &Expr::Assignment { target, value } => {
782                visitor.on_pat(target);
783                visitor.on_expr(value);
784            }
785            Expr::IncludeBytes => {}
786        }
787    }
788
789    /// Walks the immediate children expressions and calls `f` for each child expression.
790    pub fn walk_child_exprs(&self, expr_id: ExprId, callback: impl FnMut(ExprId)) {
791        return self.visit_expr_children(expr_id, Visitor { callback, store: self });
792
793        struct Visitor<'a, F> {
794            callback: F,
795            store: &'a ExpressionStore,
796        }
797
798        impl<F: FnMut(ExprId)> StoreVisitor for Visitor<'_, F> {
799            fn on_expr(&mut self, expr: ExprId) {
800                (self.callback)(expr);
801            }
802
803            fn on_pat(&mut self, pat: PatId) {
804                self.store.walk_exprs_in_pat(pat, &mut self.callback);
805            }
806        }
807    }
808
809    /// Walks the immediate children expressions and calls `f` for each child expression but does
810    /// not walk expressions within patterns.
811    pub fn walk_child_exprs_without_pats(&self, expr_id: ExprId, callback: impl FnMut(ExprId)) {
812        return self.visit_expr_children(expr_id, Visitor { callback });
813
814        struct Visitor<F> {
815            callback: F,
816        }
817
818        impl<F: FnMut(ExprId)> StoreVisitor for Visitor<F> {
819            fn on_expr(&mut self, expr: ExprId) {
820                (self.callback)(expr);
821            }
822        }
823    }
824
825    pub fn walk_exprs_in_pat(&self, pat_id: PatId, callback: impl FnMut(ExprId)) {
826        return Visitor { callback, store: self }.on_pat(pat_id);
827
828        struct Visitor<'a, F> {
829            callback: F,
830            store: &'a ExpressionStore,
831        }
832
833        impl<F: FnMut(ExprId)> StoreVisitor for Visitor<'_, F> {
834            fn on_expr(&mut self, expr: ExprId) {
835                (self.callback)(expr);
836            }
837
838            fn on_pat(&mut self, pat: PatId) {
839                self.store.visit_pat_children(pat, self);
840            }
841        }
842    }
843
844    pub fn visit_type_ref_children(&self, type_ref: TypeRefId, mut visitor: impl StoreVisitor) {
845        match &self[type_ref] {
846            TypeRef::Never | TypeRef::Placeholder | TypeRef::TypeParam(_) | TypeRef::Error => {}
847            &TypeRef::PatternType(ty, pat) => {
848                visitor.on_type(ty);
849                visitor.on_pat(pat)
850            }
851            TypeRef::Tuple(types) => visitor.on_types(types),
852            TypeRef::Path(path) => visitor.on_path(path),
853            TypeRef::RawPtr(inner, _) | TypeRef::Slice(inner) => visitor.on_type(*inner),
854            TypeRef::Reference(ref_type) => {
855                let RefType { ty, lifetime, mutability: _ } = &**ref_type;
856                visitor.on_type(*ty);
857                visitor.on_lifetime_opt(*lifetime);
858            }
859            TypeRef::Array(ArrayType { ty, len: ConstRef { expr: len } }) => {
860                visitor.on_type(*ty);
861                visitor.on_anon_const_expr(*len);
862            }
863            TypeRef::Fn(fn_type) => {
864                let FnType { params, is_varargs: _, is_unsafe: _, abi: _, binder: _ } = &**fn_type;
865                params.iter().for_each(|(_, param_ty)| visitor.on_type(*param_ty));
866            }
867            TypeRef::ImplTrait(bounds) | TypeRef::DynTrait(bounds) => {
868                visitor.on_type_bounds(bounds)
869            }
870        }
871    }
872
873    #[inline]
874    #[track_caller]
875    fn assert_expr_only(&self) -> &ExpressionOnlyStore {
876        self.expr_only.as_ref().expect("should have `ExpressionStore::expr_only`")
877    }
878
879    fn binding_hygiene(&self, binding: BindingId) -> HygieneId {
880        self.assert_expr_only().bindings[binding].hygiene
881    }
882
883    pub fn expr_path_hygiene(&self, expr: ExprId) -> HygieneId {
884        self.assert_expr_only().ident_hygiene.get(&expr.into()).copied().unwrap_or(HygieneId::ROOT)
885    }
886
887    pub fn pat_path_hygiene(&self, pat: PatId) -> HygieneId {
888        self.assert_expr_only().ident_hygiene.get(&pat.into()).copied().unwrap_or(HygieneId::ROOT)
889    }
890
891    pub fn expr_or_pat_path_hygiene(&self, id: ExprOrPatId) -> HygieneId {
892        match id {
893            ExprOrPatId::ExprId(id) => self.expr_path_hygiene(id),
894            ExprOrPatId::PatId(id) => self.pat_path_hygiene(id),
895        }
896    }
897
898    #[inline]
899    pub fn exprs(&self) -> impl Iterator<Item = (ExprId, &Expr)> {
900        match &self.expr_only {
901            Some(it) => it.exprs.iter(),
902            None => const { &Arena::new() }.iter(),
903        }
904    }
905
906    #[inline]
907    pub fn pats(&self) -> impl Iterator<Item = (PatId, &Pat)> {
908        match &self.expr_only {
909            Some(it) => it.pats.iter(),
910            None => const { &Arena::new() }.iter(),
911        }
912    }
913
914    #[inline]
915    pub fn bindings(&self) -> impl Iterator<Item = (BindingId, &Binding)> {
916        match &self.expr_only {
917            Some(it) => it.bindings.iter(),
918            None => const { &Arena::new() }.iter(),
919        }
920    }
921
922    /// The coroutine associated with a coroutine closure.
923    #[inline]
924    pub fn coroutine_for_closure(coroutine_closure: ExprId) -> ExprId {
925        // We keep the async closure exactly one expr before.
926        ExprId::from_raw(la_arena::RawIdx::from_u32(coroutine_closure.into_raw().into_u32() - 1))
927    }
928
929    /// The opposite of [`Self::coroutine_for_closure()`].
930    #[inline]
931    pub fn closure_for_coroutine(coroutine: ExprId) -> ExprId {
932        // We keep the async closure exactly one expr before.
933        ExprId::from_raw(la_arena::RawIdx::from_u32(coroutine.into_raw().into_u32() + 1))
934    }
935}
936
937pub trait StoreVisitor: Sized {
938    fn on_expr(&mut self, expr: ExprId) {
939        let _ = expr;
940    }
941    fn on_anon_const_expr(&mut self, expr: ExprId) {
942        self.on_expr(expr);
943    }
944    fn on_pat(&mut self, pat: PatId) {
945        let _ = pat;
946    }
947    fn on_type(&mut self, ty: TypeRefId) {
948        let _ = ty;
949    }
950    fn on_lifetime(&mut self, lifetime: LifetimeRefId) {
951        let _ = lifetime;
952    }
953
954    fn on_generic_args(&mut self, args: &GenericArgs) {
955        visit_generic_args(self, args);
956    }
957}
958
959pub(crate) fn visit_generic_args<V: StoreVisitor>(visitor: &mut V, args: &GenericArgs) {
960    let GenericArgs { args, bindings, parenthesized: _, has_self_type: _ } = args;
961    for arg in args {
962        match arg {
963            GenericArg::Type(arg) => visitor.on_type(*arg),
964            GenericArg::Const(ConstRef { expr }) => visitor.on_anon_const_expr(*expr),
965            GenericArg::Lifetime(arg) => visitor.on_lifetime(*arg),
966        }
967    }
968    for AssociatedTypeBinding { name: _, args, type_ref, bounds } in bindings {
969        visitor.on_generic_args_opt(args);
970        visitor.on_type_opt(*type_ref);
971        visitor.on_type_bounds(bounds);
972    }
973}
974
975impl<V: StoreVisitor> StoreVisitor for &mut V {
976    fn on_expr(&mut self, expr: ExprId) {
977        V::on_expr(self, expr);
978    }
979    fn on_anon_const_expr(&mut self, expr: ExprId) {
980        V::on_anon_const_expr(self, expr);
981    }
982    fn on_pat(&mut self, pat: PatId) {
983        V::on_pat(self, pat);
984    }
985    fn on_type(&mut self, ty: TypeRefId) {
986        V::on_type(self, ty);
987    }
988    fn on_lifetime(&mut self, lifetime: LifetimeRefId) {
989        V::on_lifetime(self, lifetime);
990    }
991
992    fn on_generic_args(&mut self, args: &GenericArgs) {
993        V::on_generic_args(self, args);
994    }
995}
996
997pub trait StoreVisitorExt: StoreVisitor {
998    fn on_type_bound(&mut self, bound: &TypeBound) {
999        match bound {
1000            TypeBound::Path(path_id, _) => self.on_type(path_id.type_ref()),
1001            TypeBound::ForLifetime(_, path_id) => self.on_type(path_id.type_ref()),
1002            TypeBound::Lifetime(lifetime) => self.on_lifetime(*lifetime),
1003            TypeBound::Use(args) => {
1004                for arg in args {
1005                    match arg {
1006                        UseArgRef::Lifetime(lifetime) => self.on_lifetime(*lifetime),
1007                        UseArgRef::Name(_) => {}
1008                    }
1009                }
1010            }
1011            TypeBound::Error => {}
1012        }
1013    }
1014
1015    fn on_path(&mut self, path: &Path) {
1016        match path {
1017            Path::Normal(path) => {
1018                let NormalPath { generic_args, type_anchor, mod_path: _ } = &**path;
1019                generic_args.iter().for_each(|generic_arg| self.on_generic_args_opt(generic_arg));
1020                self.on_type_opt(*type_anchor);
1021            }
1022            Path::BarePath(_) | Path::LangItem(..) => {}
1023        }
1024    }
1025
1026    fn on_expr_opt(&mut self, expr: Option<ExprId>) {
1027        if let Some(expr) = expr {
1028            self.on_expr(expr);
1029        }
1030    }
1031    fn on_pat_opt(&mut self, pat: Option<PatId>) {
1032        if let Some(pat) = pat {
1033            self.on_pat(pat);
1034        }
1035    }
1036    fn on_type_opt(&mut self, ty: Option<TypeRefId>) {
1037        if let Some(ty) = ty {
1038            self.on_type(ty);
1039        }
1040    }
1041    fn on_lifetime_opt(&mut self, lifetime: Option<LifetimeRefId>) {
1042        if let Some(lifetime) = lifetime {
1043            self.on_lifetime(lifetime);
1044        }
1045    }
1046    fn on_generic_args_opt(&mut self, args: &Option<impl Borrow<GenericArgs>>) {
1047        if let Some(args) = args {
1048            self.on_generic_args(args.borrow());
1049        }
1050    }
1051
1052    fn on_exprs(&mut self, exprs: impl IntoIterator<Item: Borrow<ExprId>>) {
1053        exprs.into_iter().for_each(|expr| self.on_expr(*expr.borrow()));
1054    }
1055    fn on_pats(&mut self, pats: impl IntoIterator<Item: Borrow<PatId>>) {
1056        pats.into_iter().for_each(|pat| self.on_pat(*pat.borrow()));
1057    }
1058    fn on_types(&mut self, types: impl IntoIterator<Item: Borrow<TypeRefId>>) {
1059        types.into_iter().for_each(|ty| self.on_type(*ty.borrow()));
1060    }
1061    fn on_type_bounds(&mut self, bounds: impl IntoIterator<Item: Borrow<TypeBound>>) {
1062        bounds.into_iter().for_each(|bound| self.on_type_bound(bound.borrow()));
1063    }
1064}
1065impl<V: StoreVisitor> StoreVisitorExt for V {}
1066
1067impl Index<ExprId> for ExpressionStore {
1068    type Output = Expr;
1069
1070    #[inline]
1071    fn index(&self, expr: ExprId) -> &Expr {
1072        &self.assert_expr_only().exprs[expr]
1073    }
1074}
1075
1076impl Index<PatId> for ExpressionStore {
1077    type Output = Pat;
1078
1079    #[inline]
1080    fn index(&self, pat: PatId) -> &Pat {
1081        &self.assert_expr_only().pats[pat]
1082    }
1083}
1084
1085impl Index<LabelId> for ExpressionStore {
1086    type Output = Label;
1087
1088    #[inline]
1089    fn index(&self, label: LabelId) -> &Label {
1090        &self.assert_expr_only().labels[label]
1091    }
1092}
1093
1094impl Index<BindingId> for ExpressionStore {
1095    type Output = Binding;
1096
1097    #[inline]
1098    fn index(&self, b: BindingId) -> &Binding {
1099        &self.assert_expr_only().bindings[b]
1100    }
1101}
1102
1103impl Index<TypeRefId> for ExpressionStore {
1104    type Output = TypeRef;
1105
1106    #[inline]
1107    fn index(&self, b: TypeRefId) -> &TypeRef {
1108        &self.types[b]
1109    }
1110}
1111
1112impl Index<LifetimeRefId> for ExpressionStore {
1113    type Output = LifetimeRef;
1114
1115    #[inline]
1116    fn index(&self, b: LifetimeRefId) -> &LifetimeRef {
1117        &self.lifetimes[b]
1118    }
1119}
1120
1121impl Index<PathId> for ExpressionStore {
1122    type Output = Path;
1123
1124    #[inline]
1125    fn index(&self, index: PathId) -> &Self::Output {
1126        let TypeRef::Path(path) = &self[index.type_ref()] else {
1127            unreachable!("`PathId` always points to `TypeRef::Path`");
1128        };
1129        path
1130    }
1131}
1132
1133// FIXME: Change `node_` prefix to something more reasonable.
1134// Perhaps `expr_syntax` and `expr_id`?
1135impl ExpressionStoreSourceMap {
1136    pub fn expr_or_pat_syntax(&self, id: ExprOrPatId) -> Result<ExprOrPatSource, SyntheticSyntax> {
1137        match id {
1138            ExprOrPatId::ExprId(id) => self.expr_syntax(id),
1139            ExprOrPatId::PatId(id) => self.pat_syntax(id),
1140        }
1141    }
1142
1143    #[inline]
1144    fn expr_or_synthetic(&self) -> Result<&ExpressionOnlySourceMap, SyntheticSyntax> {
1145        self.expr_only.as_deref().ok_or(SyntheticSyntax)
1146    }
1147
1148    #[inline]
1149    fn expr_only(&self) -> Option<&ExpressionOnlySourceMap> {
1150        self.expr_only.as_deref()
1151    }
1152
1153    #[inline]
1154    #[track_caller]
1155    fn assert_expr_only(&self) -> &ExpressionOnlySourceMap {
1156        self.expr_only.as_ref().expect("should have `ExpressionStoreSourceMap::expr_only`")
1157    }
1158
1159    pub fn expr_syntax(&self, expr: ExprId) -> Result<ExprOrPatSource, SyntheticSyntax> {
1160        self.expr_or_synthetic()?.expr_map_back.get(expr).cloned().ok_or(SyntheticSyntax)
1161    }
1162
1163    pub fn node_expr(&self, node: InFile<&ast::Expr>) -> Option<ExprOrPatId> {
1164        let src = node.map(AstPtr::new);
1165        self.expr_only()?.expr_map.get(&src).cloned().map(ExprOrPatIdPacked::unpack)
1166    }
1167
1168    pub fn node_macro_file(&self, node: InFile<&ast::MacroCall>) -> Option<MacroCallId> {
1169        let src = node.map(AstPtr::new);
1170        self.expr_only()?.expansions.get(&src).cloned()
1171    }
1172
1173    pub fn macro_calls(&self) -> impl Iterator<Item = (InFile<MacroCallPtr>, MacroCallId)> + '_ {
1174        self.expr_only().into_iter().flat_map(|it| it.expansions.iter().map(|(&a, &b)| (a, b)))
1175    }
1176
1177    pub fn pat_syntax(&self, pat: PatId) -> Result<ExprOrPatSource, SyntheticSyntax> {
1178        self.expr_or_synthetic()?.pat_map_back.get(pat).cloned().ok_or(SyntheticSyntax)
1179    }
1180
1181    pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option<ExprOrPatId> {
1182        self.expr_only()?
1183            .pat_map
1184            .get(&node.map(AstPtr::new))
1185            .cloned()
1186            .map(ExprOrPatIdPacked::unpack)
1187    }
1188
1189    pub fn type_syntax(&self, id: TypeRefId) -> Result<TypeSource, SyntheticSyntax> {
1190        self.types_map_back.get(id).cloned().ok_or(SyntheticSyntax)
1191    }
1192
1193    pub fn node_type(&self, node: InFile<&ast::Type>) -> Option<TypeRefId> {
1194        self.types_map.get(&node.map(AstPtr::new)).cloned()
1195    }
1196
1197    pub fn label_syntax(&self, label: LabelId) -> LabelSource {
1198        self.assert_expr_only().label_map_back[label]
1199    }
1200
1201    pub fn patterns_for_binding(&self, binding: BindingId) -> &[PatId] {
1202        self.assert_expr_only().binding_definitions.get(binding).map_or(&[], Deref::deref)
1203    }
1204
1205    pub fn node_label(&self, node: InFile<&ast::Label>) -> Option<LabelId> {
1206        let src = node.map(AstPtr::new).map(AstPtr::wrap_left);
1207        self.expr_only()?.label_map.get(&src).cloned()
1208    }
1209
1210    pub fn field_syntax(&self, expr: ExprId) -> FieldSource {
1211        self.assert_expr_only().field_map_back[&expr]
1212    }
1213
1214    pub fn pat_field_syntax(&self, pat: PatId) -> PatFieldSource {
1215        self.assert_expr_only().pat_field_map_back[&pat]
1216    }
1217
1218    pub fn macro_expansion_expr(&self, node: InFile<&ast::MacroExpr>) -> Option<ExprOrPatId> {
1219        let src = node.map(AstPtr::new).map(AstPtr::upcast::<ast::MacroExpr>).map(AstPtr::upcast);
1220        self.expr_only()?.expr_map.get(&src).copied().map(ExprOrPatIdPacked::unpack)
1221    }
1222
1223    pub fn expansions(&self) -> impl Iterator<Item = (&InFile<MacroCallPtr>, &MacroCallId)> {
1224        self.expr_only().into_iter().flat_map(|it| it.expansions.iter())
1225    }
1226
1227    pub fn expansion(&self, node: InFile<&ast::MacroCall>) -> Option<MacroCallId> {
1228        self.expr_only()?.expansions.get(&node.map(AstPtr::new)).copied()
1229    }
1230
1231    pub fn implicit_format_args(
1232        &self,
1233        node: InFile<&ast::FormatArgsExpr>,
1234    ) -> Option<(HygieneId, &[(syntax::TextRange, Name)])> {
1235        let expr_only = self.expr_only()?;
1236        let src = node.map(AstPtr::new).map(AstPtr::upcast::<ast::Expr>);
1237        let (hygiene, names) = expr_only
1238            .template_map
1239            .as_ref()?
1240            .format_args_to_captures
1241            .get(&expr_only.expr_map.get(&src)?.as_expr()?)?;
1242        Some((*hygiene, &**names))
1243    }
1244
1245    pub fn format_args_implicit_capture(
1246        &self,
1247        capture_expr: ExprId,
1248    ) -> Option<InFile<(ExprPtr, TextRange)>> {
1249        self.expr_only()?
1250            .template_map
1251            .as_ref()?
1252            .implicit_capture_to_source
1253            .get(&capture_expr)
1254            .copied()
1255    }
1256
1257    pub fn asm_template_args(
1258        &self,
1259        node: InFile<&ast::AsmExpr>,
1260    ) -> Option<(ExprId, &[Vec<(syntax::TextRange, usize)>])> {
1261        let expr_only = self.expr_only()?;
1262        let src = node.map(AstPtr::new).map(AstPtr::upcast::<ast::Expr>);
1263        let expr = expr_only.expr_map.get(&src)?.as_expr()?;
1264        Some(expr).zip(
1265            expr_only.template_map.as_ref()?.asm_to_captures.get(&expr).map(std::ops::Deref::deref),
1266        )
1267    }
1268
1269    /// Get a reference to the source map's diagnostics.
1270    pub fn diagnostics(&self) -> &[ExpressionStoreDiagnostics] {
1271        self.expr_only().map(|it| &*it.diagnostics).unwrap_or_default()
1272    }
1273}