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