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