sway_core/semantic_analysis/
symbol_resolve.rs

1use sway_error::handler::Handler;
2
3use crate::{
4    ast_elements::{binding::SymbolResolveTypeBinding, type_argument::GenericTypeArgument},
5    decl_engine::{parsed_engine::ParsedDeclEngineReplace, parsed_id::ParsedDeclId},
6    language::{
7        parsed::{
8            AbiDeclaration, ArrayExpression, AstNode, AstNodeContent, CodeBlock,
9            ConfigurableDeclaration, ConstantDeclaration, Declaration, EnumDeclaration,
10            EnumVariant, Expression, ExpressionKind, FunctionDeclaration, FunctionParameter,
11            ImplItem, ImplSelfOrTrait, ParseModule, ParseProgram, ReassignmentTarget, Scrutinee,
12            StorageDeclaration, StorageEntry, StructDeclaration, StructExpressionField,
13            StructField, StructScrutineeField, Supertrait, TraitDeclaration, TraitFn, TraitItem,
14            TraitTypeDeclaration, TypeAliasDeclaration, VariableDeclaration,
15        },
16        CallPath, CallPathTree, ResolvedCallPath,
17    },
18    GenericArgument, TraitConstraint, TypeBinding, TypeParameter,
19};
20
21use super::symbol_resolve_context::SymbolResolveContext;
22
23pub trait ResolveSymbols {
24    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext);
25}
26
27impl ResolveSymbols for ParseProgram {
28    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
29        let ParseProgram { root, .. } = self;
30        root.resolve_symbols(handler, ctx.by_ref());
31    }
32}
33
34impl ResolveSymbols for ParseModule {
35    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
36        let ParseModule {
37            submodules,
38            tree,
39            module_eval_order,
40            attributes: _,
41            span: _,
42            hash: _,
43            ..
44        } = self;
45
46        // Analyze submodules first in order of evaluation previously computed by the dependency graph.
47        module_eval_order.iter().for_each(|eval_mod_name| {
48            let (_name, submodule) = submodules
49                .iter_mut()
50                .find(|(submod_name, _submodule)| eval_mod_name == submod_name)
51                .unwrap();
52            submodule.module.resolve_symbols(handler, ctx.by_ref());
53        });
54
55        tree.root_nodes
56            .iter_mut()
57            .for_each(|node| node.resolve_symbols(handler, ctx.by_ref()))
58    }
59}
60
61impl ResolveSymbols for AstNode {
62    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
63        match &mut self.content {
64            AstNodeContent::UseStatement(_) => {}
65            AstNodeContent::Declaration(decl) => decl.resolve_symbols(handler, ctx),
66            AstNodeContent::Expression(expr) => expr.resolve_symbols(handler, ctx),
67            AstNodeContent::IncludeStatement(_) => {}
68            AstNodeContent::Error(_, _) => {}
69        }
70    }
71}
72
73impl ResolveSymbols for Declaration {
74    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
75        match self {
76            Declaration::VariableDeclaration(decl_id) => decl_id.resolve_symbols(handler, ctx),
77            Declaration::FunctionDeclaration(decl_id) => decl_id.resolve_symbols(handler, ctx),
78            Declaration::TraitDeclaration(decl_id) => decl_id.resolve_symbols(handler, ctx),
79            Declaration::StructDeclaration(decl_id) => decl_id.resolve_symbols(handler, ctx),
80            Declaration::EnumDeclaration(decl_id) => decl_id.resolve_symbols(handler, ctx),
81            Declaration::EnumVariantDeclaration(_decl) => unreachable!(),
82            Declaration::ImplSelfOrTrait(decl_id) => decl_id.resolve_symbols(handler, ctx),
83            Declaration::AbiDeclaration(decl_id) => decl_id.resolve_symbols(handler, ctx),
84            Declaration::ConstantDeclaration(decl_id) => decl_id.resolve_symbols(handler, ctx),
85            Declaration::StorageDeclaration(decl_id) => decl_id.resolve_symbols(handler, ctx),
86            Declaration::TypeAliasDeclaration(decl_id) => decl_id.resolve_symbols(handler, ctx),
87            Declaration::TraitTypeDeclaration(decl_id) => decl_id.resolve_symbols(handler, ctx),
88            Declaration::TraitFnDeclaration(decl_id) => decl_id.resolve_symbols(handler, ctx),
89            Declaration::ConfigurableDeclaration(decl_id) => decl_id.resolve_symbols(handler, ctx),
90            Declaration::ConstGenericDeclaration(_) => {
91                todo!("Will be implemented by https://github.com/FuelLabs/sway/issues/6860")
92            }
93        }
94    }
95}
96
97impl ResolveSymbols for ParsedDeclId<VariableDeclaration> {
98    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
99        let pe = ctx.engines().pe();
100        let mut var_decl = pe.get_variable(self).as_ref().clone();
101        var_decl.body.resolve_symbols(handler, ctx);
102        pe.replace(*self, var_decl);
103    }
104}
105
106impl ResolveSymbols for ParsedDeclId<FunctionDeclaration> {
107    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
108        let pe = ctx.engines().pe();
109        let mut fn_decl = pe.get_function(self).as_ref().clone();
110        fn_decl.body.resolve_symbols(handler, ctx);
111        pe.replace(*self, fn_decl);
112    }
113}
114
115impl ResolveSymbols for ParsedDeclId<TraitDeclaration> {
116    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
117        let pe = ctx.engines().pe();
118        let mut trait_decl = ctx.engines().pe().get_trait(self).as_ref().clone();
119        trait_decl.resolve_symbols(handler, ctx);
120        pe.replace(*self, trait_decl);
121    }
122}
123
124impl ResolveSymbols for ParsedDeclId<StructDeclaration> {
125    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
126        let pe = ctx.engines().pe();
127        let mut struct_decl = ctx.engines().pe().get_struct(self).as_ref().clone();
128        struct_decl.resolve_symbols(handler, ctx);
129        pe.replace(*self, struct_decl);
130    }
131}
132
133impl ResolveSymbols for ParsedDeclId<EnumDeclaration> {
134    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
135        let pe = ctx.engines().pe();
136        let mut enum_decl = ctx.engines().pe().get_enum(self).as_ref().clone();
137        enum_decl.resolve_symbols(handler, ctx);
138        pe.replace(*self, enum_decl);
139    }
140}
141
142impl ResolveSymbols for ParsedDeclId<ConfigurableDeclaration> {
143    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
144        let pe = ctx.engines().pe();
145        let mut configurable_decl = ctx.engines().pe().get_configurable(self).as_ref().clone();
146        configurable_decl.resolve_symbols(handler, ctx);
147        pe.replace(*self, configurable_decl);
148    }
149}
150
151impl ResolveSymbols for ParsedDeclId<ConstantDeclaration> {
152    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
153        let pe = ctx.engines().pe();
154        let mut constant_decl = ctx.engines().pe().get_constant(self).as_ref().clone();
155        constant_decl.resolve_symbols(handler, ctx);
156        pe.replace(*self, constant_decl);
157    }
158}
159
160impl ResolveSymbols for ParsedDeclId<TraitTypeDeclaration> {
161    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
162        let pe = ctx.engines().pe();
163        let mut trait_type_decl = ctx.engines().pe().get_trait_type(self).as_ref().clone();
164        trait_type_decl.resolve_symbols(handler, ctx);
165        pe.replace(*self, trait_type_decl);
166    }
167}
168
169impl ResolveSymbols for ParsedDeclId<TraitFn> {
170    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
171        let pe = ctx.engines().pe();
172        let mut trait_fn_decl = ctx.engines().pe().get_trait_fn(self).as_ref().clone();
173        trait_fn_decl.resolve_symbols(handler, ctx);
174        pe.replace(*self, trait_fn_decl);
175    }
176}
177
178impl ResolveSymbols for ParsedDeclId<ImplSelfOrTrait> {
179    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
180        let pe = ctx.engines().pe();
181        let mut impl_self_or_trait = ctx
182            .engines()
183            .pe()
184            .get_impl_self_or_trait(self)
185            .as_ref()
186            .clone();
187        impl_self_or_trait.resolve_symbols(handler, ctx);
188        pe.replace(*self, impl_self_or_trait);
189    }
190}
191
192impl ResolveSymbols for ParsedDeclId<AbiDeclaration> {
193    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
194        let pe = ctx.engines().pe();
195        let mut abi_decl = ctx.engines().pe().get_abi(self).as_ref().clone();
196        abi_decl.resolve_symbols(handler, ctx);
197        pe.replace(*self, abi_decl);
198    }
199}
200
201impl ResolveSymbols for ParsedDeclId<StorageDeclaration> {
202    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
203        let pe = ctx.engines().pe();
204        let mut storage_decl = ctx.engines().pe().get_storage(self).as_ref().clone();
205        storage_decl.resolve_symbols(handler, ctx);
206        pe.replace(*self, storage_decl);
207    }
208}
209
210impl ResolveSymbols for ParsedDeclId<TypeAliasDeclaration> {
211    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
212        let pe = ctx.engines().pe();
213        let mut type_alias = ctx.engines().pe().get_type_alias(self).as_ref().clone();
214        type_alias.resolve_symbols(handler, ctx);
215        pe.replace(*self, type_alias);
216    }
217}
218
219impl ResolveSymbols for ConfigurableDeclaration {
220    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
221        self.type_ascription.resolve_symbols(handler, ctx.by_ref());
222        if let Some(value) = self.value.as_mut() {
223            value.resolve_symbols(handler, ctx.by_ref())
224        }
225    }
226}
227
228impl ResolveSymbols for ConstantDeclaration {
229    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
230        self.type_ascription.resolve_symbols(handler, ctx.by_ref());
231        if let Some(value) = self.value.as_mut() {
232            value.resolve_symbols(handler, ctx.by_ref())
233        }
234    }
235}
236
237impl ResolveSymbols for StructDeclaration {
238    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
239        self.type_parameters
240            .iter_mut()
241            .for_each(|tp| tp.resolve_symbols(handler, ctx.by_ref()));
242        self.fields
243            .iter_mut()
244            .for_each(|f| f.resolve_symbols(handler, ctx.by_ref()));
245    }
246}
247
248impl ResolveSymbols for StructField {
249    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
250        self.type_argument.resolve_symbols(handler, ctx);
251    }
252}
253
254impl ResolveSymbols for EnumDeclaration {
255    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
256        self.type_parameters
257            .iter_mut()
258            .for_each(|tp| tp.resolve_symbols(handler, ctx.by_ref()));
259        self.variants
260            .iter_mut()
261            .for_each(|f| f.resolve_symbols(handler, ctx.by_ref()));
262    }
263}
264
265impl ResolveSymbols for EnumVariant {
266    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
267        self.type_argument.resolve_symbols(handler, ctx);
268    }
269}
270
271impl ResolveSymbols for TraitDeclaration {
272    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
273        self.supertraits
274            .iter_mut()
275            .for_each(|st| st.resolve_symbols(handler, ctx.by_ref()));
276        self.interface_surface
277            .iter_mut()
278            .for_each(|item| item.resolve_symbols(handler, ctx.by_ref()));
279        self.methods
280            .iter_mut()
281            .for_each(|m| m.resolve_symbols(handler, ctx.by_ref()));
282    }
283}
284
285impl ResolveSymbols for AbiDeclaration {
286    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
287        self.supertraits
288            .iter_mut()
289            .for_each(|st| st.resolve_symbols(handler, ctx.by_ref()));
290        self.interface_surface
291            .iter_mut()
292            .for_each(|item| item.resolve_symbols(handler, ctx.by_ref()));
293        self.methods
294            .iter_mut()
295            .for_each(|m| m.resolve_symbols(handler, ctx.by_ref()));
296    }
297}
298
299impl ResolveSymbols for TraitItem {
300    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
301        match self {
302            TraitItem::TraitFn(ref mut id) => id.resolve_symbols(handler, ctx.by_ref()),
303            TraitItem::Constant(ref mut id) => id.resolve_symbols(handler, ctx.by_ref()),
304            TraitItem::Type(ref mut id) => id.resolve_symbols(handler, ctx.by_ref()),
305            TraitItem::Error(_, _) => {}
306        }
307    }
308}
309
310impl ResolveSymbols for TraitFn {
311    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
312        self.parameters
313            .iter_mut()
314            .for_each(|f| f.resolve_symbols(handler, ctx.by_ref()));
315        self.return_type.resolve_symbols(handler, ctx.by_ref());
316    }
317}
318
319impl ResolveSymbols for Supertrait {
320    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
321        self.name.resolve_symbols(handler, ctx.by_ref());
322    }
323}
324
325impl ResolveSymbols for FunctionParameter {
326    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
327        self.type_argument.resolve_symbols(handler, ctx.by_ref());
328    }
329}
330
331impl ResolveSymbols for ImplSelfOrTrait {
332    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
333        self.impl_type_parameters
334            .iter_mut()
335            .for_each(|f| f.resolve_symbols(handler, ctx.by_ref()));
336        self.trait_name.resolve_symbols(handler, ctx.by_ref());
337        self.trait_type_arguments
338            .iter_mut()
339            .for_each(|tp| tp.resolve_symbols(handler, ctx.by_ref()));
340        self.implementing_for.resolve_symbols(handler, ctx.by_ref());
341        self.items
342            .iter_mut()
343            .for_each(|tp| tp.resolve_symbols(handler, ctx.by_ref()));
344    }
345}
346
347impl ResolveSymbols for ImplItem {
348    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
349        match self {
350            ImplItem::Fn(decl_id) => decl_id.resolve_symbols(handler, ctx),
351            ImplItem::Constant(decl_id) => decl_id.resolve_symbols(handler, ctx),
352            ImplItem::Type(decl_id) => decl_id.resolve_symbols(handler, ctx),
353        }
354    }
355}
356
357impl ResolveSymbols for TraitTypeDeclaration {
358    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
359        if let Some(ty) = self.ty_opt.as_mut() {
360            ty.resolve_symbols(handler, ctx)
361        }
362    }
363}
364
365impl ResolveSymbols for StorageDeclaration {
366    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
367        self.entries
368            .iter_mut()
369            .for_each(|e| e.resolve_symbols(handler, ctx.by_ref()));
370    }
371}
372
373impl ResolveSymbols for StorageEntry {
374    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
375        match self {
376            StorageEntry::Namespace(ref mut ns) => {
377                ns.entries
378                    .iter_mut()
379                    .for_each(|e| e.resolve_symbols(handler, ctx.by_ref()));
380            }
381            StorageEntry::Field(ref mut f) => {
382                f.type_argument.resolve_symbols(handler, ctx.by_ref());
383                f.initializer.resolve_symbols(handler, ctx.by_ref());
384            }
385        }
386    }
387}
388
389impl ResolveSymbols for TypeAliasDeclaration {
390    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
391        self.ty.resolve_symbols(handler, ctx)
392    }
393}
394
395impl ResolveSymbols for GenericArgument {
396    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
397        match self {
398            GenericArgument::Type(arg) => {
399                arg.resolve_symbols(handler, ctx);
400            }
401            GenericArgument::Const(_) => {}
402        }
403    }
404}
405
406impl ResolveSymbols for GenericTypeArgument {
407    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
408        if let Some(call_path_tree) = self.call_path_tree.as_mut() {
409            call_path_tree.resolve_symbols(handler, ctx);
410        }
411    }
412}
413
414impl ResolveSymbols for TypeParameter {
415    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
416        match self {
417            TypeParameter::Type(p) => p
418                .trait_constraints
419                .iter_mut()
420                .for_each(|tc| tc.resolve_symbols(handler, ctx.by_ref())),
421            TypeParameter::Const(_) => todo!(),
422        }
423    }
424}
425
426impl ResolveSymbols for TraitConstraint {
427    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
428        self.trait_name.resolve_symbols(handler, ctx.by_ref());
429        self.type_arguments
430            .iter_mut()
431            .for_each(|tc| tc.resolve_symbols(handler, ctx.by_ref()));
432    }
433}
434
435impl ResolveSymbols for CallPath {
436    fn resolve_symbols(&mut self, _handler: &Handler, _ctx: SymbolResolveContext) {}
437}
438
439impl ResolveSymbols for CallPathTree {
440    fn resolve_symbols(&mut self, _handler: &Handler, _ctx: SymbolResolveContext) {}
441}
442
443impl ResolveSymbols for CodeBlock {
444    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
445        for expr in self.contents.iter_mut() {
446            expr.resolve_symbols(handler, ctx.by_ref())
447        }
448    }
449}
450
451impl ResolveSymbols for StructExpressionField {
452    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
453        self.value.resolve_symbols(handler, ctx);
454    }
455}
456
457impl ResolveSymbols for Scrutinee {
458    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
459        match self {
460            Scrutinee::Or {
461                ref mut elems,
462                span: _,
463            } => elems
464                .iter_mut()
465                .for_each(|e| e.resolve_symbols(handler, ctx.by_ref())),
466            Scrutinee::CatchAll { .. } => {}
467            Scrutinee::Literal { .. } => {}
468            Scrutinee::Variable { .. } => {}
469            Scrutinee::AmbiguousSingleIdent(_) => {}
470            Scrutinee::StructScrutinee {
471                struct_name,
472                fields,
473                span: _,
474            } => {
475                struct_name.resolve_symbols(handler, ctx.by_ref());
476                fields
477                    .iter_mut()
478                    .for_each(|f| f.resolve_symbols(handler, ctx.by_ref()))
479            }
480            Scrutinee::EnumScrutinee {
481                call_path,
482                value,
483                span: _,
484            } => {
485                call_path.resolve_symbols(handler, ctx.by_ref());
486                value.resolve_symbols(handler, ctx.by_ref());
487            }
488            Scrutinee::Tuple { elems, span: _ } => {
489                elems
490                    .iter_mut()
491                    .for_each(|s| s.resolve_symbols(handler, ctx.by_ref()));
492            }
493            Scrutinee::Error { .. } => {}
494        }
495    }
496}
497
498impl ResolveSymbols for StructScrutineeField {
499    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
500        match self {
501            StructScrutineeField::Rest { .. } => {}
502            StructScrutineeField::Field {
503                field: _,
504                scrutinee,
505                span: _,
506            } => {
507                if let Some(scrutinee) = scrutinee.as_mut() {
508                    scrutinee.resolve_symbols(handler, ctx.by_ref());
509                }
510            }
511        }
512    }
513}
514
515impl ResolveSymbols for Expression {
516    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
517        self.kind.resolve_symbols(handler, ctx);
518    }
519}
520
521impl ResolveSymbols for ExpressionKind {
522    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
523        match self {
524            ExpressionKind::Error(_, _) => {}
525            ExpressionKind::Literal(_) => {}
526            ExpressionKind::AmbiguousPathExpression(_) => {}
527            ExpressionKind::FunctionApplication(expr) => {
528                let result = SymbolResolveTypeBinding::resolve_symbol(
529                    &mut expr.call_path_binding,
530                    &Handler::default(),
531                    ctx.by_ref(),
532                );
533                if let Ok(result) = result {
534                    expr.resolved_call_path_binding = Some(TypeBinding::<
535                        ResolvedCallPath<ParsedDeclId<FunctionDeclaration>>,
536                    > {
537                        inner: ResolvedCallPath {
538                            decl: result,
539                            unresolved_call_path: expr.call_path_binding.inner.clone(),
540                        },
541                        span: expr.call_path_binding.span.clone(),
542                        type_arguments: expr.call_path_binding.type_arguments.clone(),
543                    });
544                }
545                expr.arguments
546                    .iter_mut()
547                    .for_each(|a| a.resolve_symbols(handler, ctx.by_ref()))
548            }
549            ExpressionKind::LazyOperator(expr) => {
550                expr.lhs.resolve_symbols(handler, ctx.by_ref());
551                expr.rhs.resolve_symbols(handler, ctx.by_ref());
552            }
553            ExpressionKind::AmbiguousVariableExpression(_) => {}
554            ExpressionKind::Variable(_) => {}
555            ExpressionKind::Tuple(exprs) => {
556                exprs
557                    .iter_mut()
558                    .for_each(|expr| expr.resolve_symbols(handler, ctx.by_ref()));
559            }
560            ExpressionKind::TupleIndex(expr) => {
561                expr.prefix.resolve_symbols(handler, ctx.by_ref());
562            }
563            ExpressionKind::Array(ArrayExpression::Explicit { contents, .. }) => contents
564                .iter_mut()
565                .for_each(|e| e.resolve_symbols(handler, ctx.by_ref())),
566            ExpressionKind::Array(ArrayExpression::Repeat { value, length }) => {
567                value.resolve_symbols(handler, ctx.by_ref());
568                length.resolve_symbols(handler, ctx.by_ref());
569            }
570            ExpressionKind::Struct(expr) => {
571                expr.call_path_binding
572                    .resolve_symbols(handler, ctx.by_ref());
573                let result = SymbolResolveTypeBinding::resolve_symbol(
574                    &mut expr.call_path_binding,
575                    &Handler::default(),
576                    ctx.by_ref(),
577                );
578                if let Ok(result) = result {
579                    expr.resolved_call_path_binding = Some(TypeBinding::<
580                        ResolvedCallPath<ParsedDeclId<StructDeclaration>>,
581                    > {
582                        inner: ResolvedCallPath {
583                            decl: result,
584                            unresolved_call_path: expr.call_path_binding.inner.clone(),
585                        },
586                        span: expr.call_path_binding.span.clone(),
587                        type_arguments: expr.call_path_binding.type_arguments.clone(),
588                    });
589                }
590            }
591            ExpressionKind::CodeBlock(block) => {
592                block
593                    .contents
594                    .iter_mut()
595                    .for_each(|node| node.resolve_symbols(handler, ctx.by_ref()));
596            }
597            ExpressionKind::If(expr) => {
598                expr.condition.resolve_symbols(handler, ctx.by_ref());
599                expr.then.resolve_symbols(handler, ctx.by_ref());
600                if let Some(r#else) = expr.r#else.as_mut() {
601                    r#else.resolve_symbols(handler, ctx.by_ref());
602                }
603            }
604            ExpressionKind::Match(expr) => {
605                expr.value.resolve_symbols(handler, ctx.by_ref());
606                expr.branches.iter_mut().for_each(|branch| {
607                    branch.scrutinee.resolve_symbols(handler, ctx.by_ref());
608                    branch.result.resolve_symbols(handler, ctx.by_ref());
609                });
610            }
611            ExpressionKind::Asm(asm_expr) => asm_expr.registers.iter_mut().for_each(|reg| {
612                if let Some(initializer) = reg.initializer.as_mut() {
613                    initializer.resolve_symbols(handler, ctx.by_ref());
614                }
615            }),
616            ExpressionKind::MethodApplication(expr) => {
617                expr.method_name_binding
618                    .resolve_symbols(handler, ctx.by_ref());
619                expr.contract_call_params
620                    .iter_mut()
621                    .for_each(|field| field.resolve_symbols(handler, ctx.by_ref()));
622                expr.arguments
623                    .iter_mut()
624                    .for_each(|arg| arg.resolve_symbols(handler, ctx.by_ref()));
625            }
626            ExpressionKind::Subfield(expr) => expr.prefix.resolve_symbols(handler, ctx),
627            ExpressionKind::DelineatedPath(expr) => {
628                expr.call_path_binding.resolve_symbols(handler, ctx)
629            }
630            ExpressionKind::AbiCast(expr) => {
631                expr.abi_name.resolve_symbols(handler, ctx.by_ref());
632                expr.address.resolve_symbols(handler, ctx.by_ref());
633            }
634            ExpressionKind::ArrayIndex(expr) => {
635                expr.index.resolve_symbols(handler, ctx.by_ref());
636                expr.prefix.resolve_symbols(handler, ctx.by_ref());
637            }
638            ExpressionKind::StorageAccess(_expr) => {}
639            ExpressionKind::IntrinsicFunction(expr) => {
640                expr.arguments
641                    .iter_mut()
642                    .for_each(|arg| arg.resolve_symbols(handler, ctx.by_ref()));
643                expr.kind_binding.resolve_symbols(handler, ctx);
644            }
645            ExpressionKind::WhileLoop(expr) => {
646                expr.condition.resolve_symbols(handler, ctx.by_ref());
647                expr.body.resolve_symbols(handler, ctx.by_ref());
648            }
649            ExpressionKind::ForLoop(expr) => expr.desugared.resolve_symbols(handler, ctx.by_ref()),
650            ExpressionKind::Break => {}
651            ExpressionKind::Continue => {}
652            ExpressionKind::Reassignment(expr) => {
653                match &mut expr.lhs {
654                    ReassignmentTarget::ElementAccess(expr) => {
655                        expr.resolve_symbols(handler, ctx.by_ref())
656                    }
657                    ReassignmentTarget::Deref(expr) => expr.resolve_symbols(handler, ctx.by_ref()),
658                };
659                expr.rhs.resolve_symbols(handler, ctx.by_ref());
660            }
661            ExpressionKind::ImplicitReturn(expr) => expr.resolve_symbols(handler, ctx),
662            ExpressionKind::Return(expr) => expr.resolve_symbols(handler, ctx.by_ref()),
663            ExpressionKind::Panic(expr) => expr.resolve_symbols(handler, ctx.by_ref()),
664            ExpressionKind::Ref(expr) => expr.value.resolve_symbols(handler, ctx.by_ref()),
665            ExpressionKind::Deref(expr) => expr.resolve_symbols(handler, ctx.by_ref()),
666        }
667    }
668}