1use crate::{
25 ArrayAccess,
26 ArrayExpression,
27 ArrayType,
28 AssertStatement,
29 AssertVariant,
30 AssignStatement,
31 AsyncExpression,
32 BinaryExpression,
33 Block,
34 CallExpression,
35 CastExpression,
36 CompositeExpression,
37 CompositeFieldInitializer,
38 CompositeType,
39 ConditionalStatement,
40 ConstDeclaration,
41 DefinitionPlace,
42 DefinitionStatement,
43 DynamicOpExpression,
44 DynamicOpKind,
45 ErrExpression,
46 Expression,
47 ExpressionStatement,
48 FutureType,
49 Identifier,
50 IntrinsicExpression,
51 IterationStatement,
52 Literal,
53 MappingType,
54 MemberAccess,
55 NodeID,
56 OptionalType,
57 ProgramId,
58 RepeatExpression,
59 ReturnStatement,
60 Statement,
61 TernaryExpression,
62 TupleAccess,
63 TupleExpression,
64 TupleType,
65 TypeKind,
66 TypeNode,
67 UnaryExpression,
68 UnitExpression,
69 VectorType,
70};
71use leo_span::Span;
72
73pub trait Canonicalize: Sized {
74 #[must_use]
75 fn canonicalize(self) -> Self;
76}
77
78impl<T: Canonicalize> Canonicalize for Box<T> {
79 fn canonicalize(self) -> Self {
80 Box::new((*self).canonicalize())
81 }
82}
83
84impl<T: Canonicalize> Canonicalize for Vec<T> {
85 fn canonicalize(self) -> Self {
86 self.into_iter().map(Canonicalize::canonicalize).collect()
87 }
88}
89
90impl<T: Canonicalize> Canonicalize for Option<T> {
91 fn canonicalize(self) -> Self {
92 self.map(Canonicalize::canonicalize)
93 }
94}
95
96impl Canonicalize for Identifier {
97 fn canonicalize(self) -> Self {
98 let Self { name, span: _, id: _ } = self;
99 Self { name, span: Span::default(), id: NodeID::default() }
100 }
101}
102
103impl Canonicalize for ProgramId {
104 fn canonicalize(self) -> Self {
105 let Self { name, network } = self;
106 Self { name: name.canonicalize(), network: network.canonicalize() }
107 }
108}
109
110impl Canonicalize for TypeNode {
113 fn canonicalize(self) -> Self {
114 let (kind, _, type_) = self.into_parts();
117 TypeNode::from_parts(kind.canonicalize(), Span::default(), type_)
118 }
119}
120
121impl Canonicalize for TypeKind {
122 fn canonicalize(self) -> Self {
123 match self {
124 TypeKind::Array(a) => TypeKind::Array(a.canonicalize()),
125 TypeKind::Composite(c) => TypeKind::Composite(c.canonicalize()),
126 TypeKind::Future(f) => TypeKind::Future(f.canonicalize()),
127 TypeKind::Ident(i) => TypeKind::Ident(i.canonicalize()),
128 TypeKind::Mapping(m) => TypeKind::Mapping(m.canonicalize()),
129 TypeKind::Optional(o) => TypeKind::Optional(o.canonicalize()),
130 TypeKind::Tuple(t) => TypeKind::Tuple(t.canonicalize()),
131 TypeKind::Vector(v) => TypeKind::Vector(v.canonicalize()),
132 t @ (TypeKind::Address
133 | TypeKind::Boolean
134 | TypeKind::Field
135 | TypeKind::Group
136 | TypeKind::Integer(_)
137 | TypeKind::Identifier
138 | TypeKind::DynRecord
139 | TypeKind::Scalar
140 | TypeKind::Signature
141 | TypeKind::String
142 | TypeKind::Numeric
143 | TypeKind::Unit
144 | TypeKind::Err) => t,
145 }
146 }
147}
148
149impl Canonicalize for ArrayType {
150 fn canonicalize(self) -> Self {
151 let Self { element_type, length } = self;
152 Self { element_type: element_type.canonicalize(), length: length.canonicalize() }
153 }
154}
155
156impl Canonicalize for CompositeType {
157 fn canonicalize(self) -> Self {
158 let Self { path, const_arguments } = self;
159 Self { path: path.canonicalize(), const_arguments: const_arguments.canonicalize() }
160 }
161}
162
163impl Canonicalize for FutureType {
164 fn canonicalize(self) -> Self {
165 let Self { inputs, location, is_explicit } = self;
166 Self { inputs: inputs.canonicalize(), location, is_explicit }
167 }
168}
169
170impl Canonicalize for MappingType {
171 fn canonicalize(self) -> Self {
172 let Self { key, value } = self;
173 Self { key: key.canonicalize(), value: value.canonicalize() }
174 }
175}
176
177impl Canonicalize for OptionalType {
178 fn canonicalize(self) -> Self {
179 let Self { inner } = self;
180 Self { inner: inner.canonicalize() }
181 }
182}
183
184impl Canonicalize for TupleType {
185 fn canonicalize(self) -> Self {
186 let Self { elements } = self;
187 Self { elements: elements.canonicalize() }
188 }
189}
190
191impl Canonicalize for VectorType {
192 fn canonicalize(self) -> Self {
193 let Self { element_type } = self;
194 Self { element_type: element_type.canonicalize() }
195 }
196}
197
198impl Canonicalize for Expression {
199 fn canonicalize(self) -> Self {
200 match self {
201 Expression::ArrayAccess(n) => Expression::ArrayAccess(n.canonicalize()),
202 Expression::Async(n) => Expression::Async(n.canonicalize()),
203 Expression::Array(n) => Expression::Array(n.canonicalize()),
204 Expression::Binary(n) => Expression::Binary(n.canonicalize()),
205 Expression::Intrinsic(n) => Expression::Intrinsic(n.canonicalize()),
206 Expression::Call(n) => Expression::Call(n.canonicalize()),
207 Expression::DynamicOp(n) => Expression::DynamicOp(n.canonicalize()),
208 Expression::Cast(n) => Expression::Cast(n.canonicalize()),
209 Expression::Composite(n) => Expression::Composite(n.canonicalize()),
210 Expression::Err(n) => Expression::Err(n.canonicalize()),
211 Expression::Path(n) => Expression::Path(n.canonicalize()),
212 Expression::Literal(n) => Expression::Literal(n.canonicalize()),
213 Expression::MemberAccess(n) => Expression::MemberAccess(n.canonicalize()),
214 Expression::Repeat(n) => Expression::Repeat(n.canonicalize()),
215 Expression::Ternary(n) => Expression::Ternary(n.canonicalize()),
216 Expression::Tuple(n) => Expression::Tuple(n.canonicalize()),
217 Expression::TupleAccess(n) => Expression::TupleAccess(n.canonicalize()),
218 Expression::Unary(n) => Expression::Unary(n.canonicalize()),
219 Expression::Unit(n) => Expression::Unit(n.canonicalize()),
220 }
221 }
222}
223
224impl Canonicalize for ArrayAccess {
225 fn canonicalize(self) -> Self {
226 let Self { array, index, span: _, id: _ } = self;
227 Self { array: array.canonicalize(), index: index.canonicalize(), span: Span::default(), id: NodeID::default() }
228 }
229}
230
231impl Canonicalize for AsyncExpression {
232 fn canonicalize(self) -> Self {
233 let Self { block, span: _, id: _ } = self;
234 Self { block: block.canonicalize(), span: Span::default(), id: NodeID::default() }
235 }
236}
237
238impl Canonicalize for ArrayExpression {
239 fn canonicalize(self) -> Self {
240 let Self { elements, span: _, id: _ } = self;
241 Self { elements: elements.canonicalize(), span: Span::default(), id: NodeID::default() }
242 }
243}
244
245impl Canonicalize for BinaryExpression {
246 fn canonicalize(self) -> Self {
247 let Self { left, right, op, span: _, id: _ } = self;
248 Self {
249 left: left.canonicalize(),
250 right: right.canonicalize(),
251 op,
252 span: Span::default(),
253 id: NodeID::default(),
254 }
255 }
256}
257
258impl Canonicalize for IntrinsicExpression {
259 fn canonicalize(self) -> Self {
260 let Self { name, type_parameters, input_types, return_types, arguments, span: _, id: _ } = self;
261 Self {
262 name,
263 type_parameters: type_parameters.into_iter().map(|(ty, _)| (ty.canonicalize(), Span::default())).collect(),
264 input_types: input_types
265 .into_iter()
266 .map(|(mode, ty, _)| (mode, ty.canonicalize(), Span::default()))
267 .collect(),
268 return_types: return_types
269 .into_iter()
270 .map(|(mode, ty, _)| (mode, ty.canonicalize(), Span::default()))
271 .collect(),
272 arguments: arguments.canonicalize(),
273 span: Span::default(),
274 id: NodeID::default(),
275 }
276 }
277}
278
279impl Canonicalize for CallExpression {
280 fn canonicalize(self) -> Self {
281 let Self { function, const_arguments, arguments, span: _, id: _ } = self;
282 Self {
283 function: function.canonicalize(),
284 const_arguments: const_arguments.canonicalize(),
285 arguments: arguments.canonicalize(),
286 span: Span::default(),
287 id: NodeID::default(),
288 }
289 }
290}
291
292impl Canonicalize for DynamicOpExpression {
293 fn canonicalize(self) -> Self {
294 let Self { interface, target_program, network, kind, span: _, id: _ } = self;
295 Self {
296 interface: interface.canonicalize(),
297 target_program: target_program.canonicalize(),
298 network: network.canonicalize(),
299 kind: kind.canonicalize(),
300 span: Span::default(),
301 id: NodeID::default(),
302 }
303 }
304}
305
306impl Canonicalize for DynamicOpKind {
307 fn canonicalize(self) -> Self {
308 match self {
309 DynamicOpKind::Call { function, arguments } => {
310 DynamicOpKind::Call { function: function.canonicalize(), arguments: arguments.canonicalize() }
311 }
312 DynamicOpKind::Read { storage } => DynamicOpKind::Read { storage: storage.canonicalize() },
313 DynamicOpKind::Op { member, op, arguments } => DynamicOpKind::Op {
314 member: member.canonicalize(),
315 op: op.canonicalize(),
316 arguments: arguments.canonicalize(),
317 },
318 }
319 }
320}
321
322impl Canonicalize for CastExpression {
323 fn canonicalize(self) -> Self {
324 let Self { expression, type_, span: _, id: _ } = self;
325 Self {
326 expression: expression.canonicalize(),
327 type_: type_.canonicalize(),
328 span: Span::default(),
329 id: NodeID::default(),
330 }
331 }
332}
333
334impl Canonicalize for CompositeExpression {
335 fn canonicalize(self) -> Self {
336 let Self { path, const_arguments, members, base, span: _, id: _ } = self;
337 Self {
338 path: path.canonicalize(),
339 const_arguments: const_arguments.canonicalize(),
340 members: members.canonicalize(),
341 base: base.canonicalize(),
342 span: Span::default(),
343 id: NodeID::default(),
344 }
345 }
346}
347
348impl Canonicalize for CompositeFieldInitializer {
349 fn canonicalize(self) -> Self {
350 let Self { identifier, expression, span: _, id: _ } = self;
351 Self {
352 identifier: identifier.canonicalize(),
353 expression: expression.canonicalize(),
354 span: Span::default(),
355 id: NodeID::default(),
356 }
357 }
358}
359
360impl Canonicalize for ErrExpression {
361 fn canonicalize(self) -> Self {
362 let Self { span: _, id: _ } = self;
363 Self { span: Span::default(), id: NodeID::default() }
364 }
365}
366
367impl Canonicalize for Literal {
368 fn canonicalize(self) -> Self {
369 let Self { variant, span: _, id: _ } = self;
370 Self { variant, span: Span::default(), id: NodeID::default() }
372 }
373}
374
375impl Canonicalize for MemberAccess {
376 fn canonicalize(self) -> Self {
377 let Self { inner, name, span: _, id: _ } = self;
378 Self { inner: inner.canonicalize(), name: name.canonicalize(), span: Span::default(), id: NodeID::default() }
379 }
380}
381
382impl Canonicalize for RepeatExpression {
383 fn canonicalize(self) -> Self {
384 let Self { expr, count, span: _, id: _ } = self;
385 Self { expr: expr.canonicalize(), count: count.canonicalize(), span: Span::default(), id: NodeID::default() }
386 }
387}
388
389impl Canonicalize for TernaryExpression {
390 fn canonicalize(self) -> Self {
391 let Self { condition, if_true, if_false, span: _, id: _ } = self;
392 Self {
393 condition: condition.canonicalize(),
394 if_true: if_true.canonicalize(),
395 if_false: if_false.canonicalize(),
396 span: Span::default(),
397 id: NodeID::default(),
398 }
399 }
400}
401
402impl Canonicalize for TupleExpression {
403 fn canonicalize(self) -> Self {
404 let Self { elements, span: _, id: _ } = self;
405 Self { elements: elements.canonicalize(), span: Span::default(), id: NodeID::default() }
406 }
407}
408
409impl Canonicalize for TupleAccess {
410 fn canonicalize(self) -> Self {
411 let Self { tuple, index, span: _, id: _ } = self;
412 Self { tuple: tuple.canonicalize(), index, span: Span::default(), id: NodeID::default() }
413 }
414}
415
416impl Canonicalize for UnaryExpression {
417 fn canonicalize(self) -> Self {
418 let Self { receiver, op, span: _, id: _ } = self;
419 Self { receiver: receiver.canonicalize(), op, span: Span::default(), id: NodeID::default() }
420 }
421}
422
423impl Canonicalize for UnitExpression {
424 fn canonicalize(self) -> Self {
425 let Self { span: _, id: _ } = self;
426 Self { span: Span::default(), id: NodeID::default() }
427 }
428}
429
430impl Canonicalize for Block {
431 fn canonicalize(self) -> Self {
432 let Self { statements, span: _, id: _ } = self;
433 Self { statements: statements.canonicalize(), span: Span::default(), id: NodeID::default() }
434 }
435}
436
437impl Canonicalize for Statement {
438 fn canonicalize(self) -> Self {
439 match self {
440 Statement::Assert(s) => Statement::Assert(s.canonicalize()),
441 Statement::Assign(s) => Statement::Assign(s.canonicalize()),
442 Statement::Block(s) => Statement::Block(s.canonicalize()),
443 Statement::Conditional(s) => Statement::Conditional(s.canonicalize()),
444 Statement::Const(s) => Statement::Const(s.canonicalize()),
445 Statement::Definition(s) => Statement::Definition(s.canonicalize()),
446 Statement::Expression(s) => Statement::Expression(s.canonicalize()),
447 Statement::Iteration(s) => Statement::Iteration(s.canonicalize()),
448 Statement::Return(s) => Statement::Return(s.canonicalize()),
449 }
450 }
451}
452
453impl Canonicalize for AssertStatement {
454 fn canonicalize(self) -> Self {
455 let Self { variant, span: _, id: _ } = self;
456 Self { variant: variant.canonicalize(), span: Span::default(), id: NodeID::default() }
457 }
458}
459
460impl Canonicalize for AssertVariant {
461 fn canonicalize(self) -> Self {
462 match self {
463 AssertVariant::Assert(e) => AssertVariant::Assert(e.canonicalize()),
464 AssertVariant::AssertEq(a, b) => AssertVariant::AssertEq(a.canonicalize(), b.canonicalize()),
465 AssertVariant::AssertNeq(a, b) => AssertVariant::AssertNeq(a.canonicalize(), b.canonicalize()),
466 }
467 }
468}
469
470impl Canonicalize for AssignStatement {
471 fn canonicalize(self) -> Self {
472 let Self { place, value, span: _, id: _ } = self;
473 Self { place: place.canonicalize(), value: value.canonicalize(), span: Span::default(), id: NodeID::default() }
474 }
475}
476
477impl Canonicalize for ConditionalStatement {
478 fn canonicalize(self) -> Self {
479 let Self { condition, then, otherwise, span: _, id: _ } = self;
480 Self {
481 condition: condition.canonicalize(),
482 then: then.canonicalize(),
483 otherwise: otherwise.canonicalize(),
484 span: Span::default(),
485 id: NodeID::default(),
486 }
487 }
488}
489
490impl Canonicalize for ConstDeclaration {
491 fn canonicalize(self) -> Self {
492 let Self { is_exported, place, type_, value, span: _, id: _ } = self;
493 Self {
494 is_exported,
495 place: place.canonicalize(),
496 type_: type_.canonicalize(),
497 value: value.canonicalize(),
498 span: Span::default(),
499 id: NodeID::default(),
500 }
501 }
502}
503
504impl Canonicalize for DefinitionStatement {
505 fn canonicalize(self) -> Self {
506 let Self { place, type_, value, span: _, id: _ } = self;
507 Self {
508 place: place.canonicalize(),
509 type_: type_.canonicalize(),
510 value: value.canonicalize(),
511 span: Span::default(),
512 id: NodeID::default(),
513 }
514 }
515}
516
517impl Canonicalize for DefinitionPlace {
518 fn canonicalize(self) -> Self {
519 match self {
520 DefinitionPlace::Single(id) => DefinitionPlace::Single(id.canonicalize()),
521 DefinitionPlace::Multiple(ids) => DefinitionPlace::Multiple(ids.canonicalize()),
522 }
523 }
524}
525
526impl Canonicalize for ExpressionStatement {
527 fn canonicalize(self) -> Self {
528 let Self { expression, span: _, id: _ } = self;
529 Self { expression: expression.canonicalize(), span: Span::default(), id: NodeID::default() }
530 }
531}
532
533impl Canonicalize for IterationStatement {
534 fn canonicalize(self) -> Self {
535 let Self { variable, type_, start, stop, inclusive, block, span: _, id: _ } = self;
536 Self {
537 variable: variable.canonicalize(),
538 type_: type_.canonicalize(),
539 start: start.canonicalize(),
540 stop: stop.canonicalize(),
541 inclusive,
542 block: block.canonicalize(),
543 span: Span::default(),
544 id: NodeID::default(),
545 }
546 }
547}
548
549impl Canonicalize for ReturnStatement {
550 fn canonicalize(self) -> Self {
551 let Self { expression, span: _, id: _ } = self;
552 Self { expression: expression.canonicalize(), span: Span::default(), id: NodeID::default() }
553 }
554}