sway_core/semantic_analysis/
symbol_resolve.rs

1use sway_error::handler::Handler;
2
3use crate::{
4    ast_elements::binding::SymbolResolveTypeBinding,
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        if let Some(call_path) = self.call_path_tree_mut() {
398            call_path.resolve_symbols(handler, ctx);
399        }
400    }
401}
402
403impl ResolveSymbols for TypeParameter {
404    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
405        match self {
406            TypeParameter::Type(p) => p
407                .trait_constraints
408                .iter_mut()
409                .for_each(|tc| tc.resolve_symbols(handler, ctx.by_ref())),
410            TypeParameter::Const(_) => todo!(),
411        }
412    }
413}
414
415impl ResolveSymbols for TraitConstraint {
416    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
417        self.trait_name.resolve_symbols(handler, ctx.by_ref());
418        self.type_arguments
419            .iter_mut()
420            .for_each(|tc| tc.resolve_symbols(handler, ctx.by_ref()));
421    }
422}
423
424impl ResolveSymbols for CallPath {
425    fn resolve_symbols(&mut self, _handler: &Handler, _ctx: SymbolResolveContext) {}
426}
427
428impl ResolveSymbols for CallPathTree {
429    fn resolve_symbols(&mut self, _handler: &Handler, _ctx: SymbolResolveContext) {}
430}
431
432impl ResolveSymbols for CodeBlock {
433    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
434        for expr in self.contents.iter_mut() {
435            expr.resolve_symbols(handler, ctx.by_ref())
436        }
437    }
438}
439
440impl ResolveSymbols for StructExpressionField {
441    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
442        self.value.resolve_symbols(handler, ctx);
443    }
444}
445
446impl ResolveSymbols for Scrutinee {
447    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
448        match self {
449            Scrutinee::Or {
450                ref mut elems,
451                span: _,
452            } => elems
453                .iter_mut()
454                .for_each(|e| e.resolve_symbols(handler, ctx.by_ref())),
455            Scrutinee::CatchAll { .. } => {}
456            Scrutinee::Literal { .. } => {}
457            Scrutinee::Variable { .. } => {}
458            Scrutinee::AmbiguousSingleIdent(_) => {}
459            Scrutinee::StructScrutinee {
460                struct_name,
461                fields,
462                span: _,
463            } => {
464                struct_name.resolve_symbols(handler, ctx.by_ref());
465                fields
466                    .iter_mut()
467                    .for_each(|f| f.resolve_symbols(handler, ctx.by_ref()))
468            }
469            Scrutinee::EnumScrutinee {
470                call_path,
471                value,
472                span: _,
473            } => {
474                call_path.resolve_symbols(handler, ctx.by_ref());
475                value.resolve_symbols(handler, ctx.by_ref());
476            }
477            Scrutinee::Tuple { elems, span: _ } => {
478                elems
479                    .iter_mut()
480                    .for_each(|s| s.resolve_symbols(handler, ctx.by_ref()));
481            }
482            Scrutinee::Error { .. } => {}
483        }
484    }
485}
486
487impl ResolveSymbols for StructScrutineeField {
488    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
489        match self {
490            StructScrutineeField::Rest { .. } => {}
491            StructScrutineeField::Field {
492                field: _,
493                scrutinee,
494                span: _,
495            } => {
496                if let Some(scrutinee) = scrutinee.as_mut() {
497                    scrutinee.resolve_symbols(handler, ctx.by_ref());
498                }
499            }
500        }
501    }
502}
503
504impl ResolveSymbols for Expression {
505    fn resolve_symbols(&mut self, handler: &Handler, ctx: SymbolResolveContext) {
506        self.kind.resolve_symbols(handler, ctx);
507    }
508}
509
510impl ResolveSymbols for ExpressionKind {
511    fn resolve_symbols(&mut self, handler: &Handler, mut ctx: SymbolResolveContext) {
512        match self {
513            ExpressionKind::Error(_, _) => {}
514            ExpressionKind::Literal(_) => {}
515            ExpressionKind::AmbiguousPathExpression(_) => {}
516            ExpressionKind::FunctionApplication(expr) => {
517                let result = SymbolResolveTypeBinding::resolve_symbol(
518                    &mut expr.call_path_binding,
519                    &Handler::default(),
520                    ctx.by_ref(),
521                );
522                if let Ok(result) = result {
523                    expr.resolved_call_path_binding = Some(TypeBinding::<
524                        ResolvedCallPath<ParsedDeclId<FunctionDeclaration>>,
525                    > {
526                        inner: ResolvedCallPath {
527                            decl: result,
528                            unresolved_call_path: expr.call_path_binding.inner.clone(),
529                        },
530                        span: expr.call_path_binding.span.clone(),
531                        type_arguments: expr.call_path_binding.type_arguments.clone(),
532                    });
533                }
534                expr.arguments
535                    .iter_mut()
536                    .for_each(|a| a.resolve_symbols(handler, ctx.by_ref()))
537            }
538            ExpressionKind::LazyOperator(expr) => {
539                expr.lhs.resolve_symbols(handler, ctx.by_ref());
540                expr.rhs.resolve_symbols(handler, ctx.by_ref());
541            }
542            ExpressionKind::AmbiguousVariableExpression(_) => {}
543            ExpressionKind::Variable(_) => {}
544            ExpressionKind::Tuple(exprs) => {
545                exprs
546                    .iter_mut()
547                    .for_each(|expr| expr.resolve_symbols(handler, ctx.by_ref()));
548            }
549            ExpressionKind::TupleIndex(expr) => {
550                expr.prefix.resolve_symbols(handler, ctx.by_ref());
551            }
552            ExpressionKind::Array(ArrayExpression::Explicit { contents, .. }) => contents
553                .iter_mut()
554                .for_each(|e| e.resolve_symbols(handler, ctx.by_ref())),
555            ExpressionKind::Array(ArrayExpression::Repeat { value, length }) => {
556                value.resolve_symbols(handler, ctx.by_ref());
557                length.resolve_symbols(handler, ctx.by_ref());
558            }
559            ExpressionKind::Struct(expr) => {
560                expr.call_path_binding
561                    .resolve_symbols(handler, ctx.by_ref());
562                let result = SymbolResolveTypeBinding::resolve_symbol(
563                    &mut expr.call_path_binding,
564                    &Handler::default(),
565                    ctx.by_ref(),
566                );
567                if let Ok(result) = result {
568                    expr.resolved_call_path_binding = Some(TypeBinding::<
569                        ResolvedCallPath<ParsedDeclId<StructDeclaration>>,
570                    > {
571                        inner: ResolvedCallPath {
572                            decl: result,
573                            unresolved_call_path: expr.call_path_binding.inner.clone(),
574                        },
575                        span: expr.call_path_binding.span.clone(),
576                        type_arguments: expr.call_path_binding.type_arguments.clone(),
577                    });
578                }
579            }
580            ExpressionKind::CodeBlock(block) => {
581                block
582                    .contents
583                    .iter_mut()
584                    .for_each(|node| node.resolve_symbols(handler, ctx.by_ref()));
585            }
586            ExpressionKind::If(expr) => {
587                expr.condition.resolve_symbols(handler, ctx.by_ref());
588                expr.then.resolve_symbols(handler, ctx.by_ref());
589                if let Some(r#else) = expr.r#else.as_mut() {
590                    r#else.resolve_symbols(handler, ctx.by_ref());
591                }
592            }
593            ExpressionKind::Match(expr) => {
594                expr.value.resolve_symbols(handler, ctx.by_ref());
595                expr.branches.iter_mut().for_each(|branch| {
596                    branch.scrutinee.resolve_symbols(handler, ctx.by_ref());
597                    branch.result.resolve_symbols(handler, ctx.by_ref());
598                });
599            }
600            ExpressionKind::Asm(asm_expr) => asm_expr.registers.iter_mut().for_each(|reg| {
601                if let Some(initializer) = reg.initializer.as_mut() {
602                    initializer.resolve_symbols(handler, ctx.by_ref());
603                }
604            }),
605            ExpressionKind::MethodApplication(expr) => {
606                expr.method_name_binding
607                    .resolve_symbols(handler, ctx.by_ref());
608                expr.contract_call_params
609                    .iter_mut()
610                    .for_each(|field| field.resolve_symbols(handler, ctx.by_ref()));
611                expr.arguments
612                    .iter_mut()
613                    .for_each(|arg| arg.resolve_symbols(handler, ctx.by_ref()));
614            }
615            ExpressionKind::Subfield(expr) => expr.prefix.resolve_symbols(handler, ctx),
616            ExpressionKind::DelineatedPath(expr) => {
617                expr.call_path_binding.resolve_symbols(handler, ctx)
618            }
619            ExpressionKind::AbiCast(expr) => {
620                expr.abi_name.resolve_symbols(handler, ctx.by_ref());
621                expr.address.resolve_symbols(handler, ctx.by_ref());
622            }
623            ExpressionKind::ArrayIndex(expr) => {
624                expr.index.resolve_symbols(handler, ctx.by_ref());
625                expr.prefix.resolve_symbols(handler, ctx.by_ref());
626            }
627            ExpressionKind::StorageAccess(_expr) => {}
628            ExpressionKind::IntrinsicFunction(expr) => {
629                expr.arguments
630                    .iter_mut()
631                    .for_each(|arg| arg.resolve_symbols(handler, ctx.by_ref()));
632                expr.kind_binding.resolve_symbols(handler, ctx);
633            }
634            ExpressionKind::WhileLoop(expr) => {
635                expr.condition.resolve_symbols(handler, ctx.by_ref());
636                expr.body.resolve_symbols(handler, ctx.by_ref());
637            }
638            ExpressionKind::ForLoop(expr) => expr.desugared.resolve_symbols(handler, ctx.by_ref()),
639            ExpressionKind::Break => {}
640            ExpressionKind::Continue => {}
641            ExpressionKind::Reassignment(expr) => {
642                match &mut expr.lhs {
643                    ReassignmentTarget::ElementAccess(expr) => {
644                        expr.resolve_symbols(handler, ctx.by_ref())
645                    }
646                    ReassignmentTarget::Deref(expr) => expr.resolve_symbols(handler, ctx.by_ref()),
647                };
648                expr.rhs.resolve_symbols(handler, ctx.by_ref());
649            }
650            ExpressionKind::ImplicitReturn(expr) => expr.resolve_symbols(handler, ctx),
651            ExpressionKind::Return(expr) => expr.resolve_symbols(handler, ctx.by_ref()),
652            ExpressionKind::Ref(expr) => expr.value.resolve_symbols(handler, ctx.by_ref()),
653            ExpressionKind::Deref(expr) => expr.resolve_symbols(handler, ctx.by_ref()),
654        }
655    }
656}