sway_core/semantic_analysis/
symbol_resolve.rs

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