Skip to main content

rib/
expr.rs

1// Copyright 2024-2025 Golem Cloud
2//
3// Licensed under the Golem Source License v1.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://license.golem.cloud/LICENSE
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::call_type::CallType;
16use crate::inferred_type::DefaultType;
17use crate::parser::block::block;
18use crate::parser::type_name::TypeName;
19use crate::rib_source_span::SourceSpan;
20use crate::rib_type_error::RibTypeErrorInternal;
21use crate::type_inference as ti;
22use crate::wit_type::WitType;
23use crate::{
24    from_string, text, type_checker, type_inference, ComponentDependency, ComponentDependencyKey,
25    CustomInstanceSpec, DynamicParsedFunctionName, GlobalVariableTypeSpec, InferredType,
26    InstanceIdentifier, VariableId,
27};
28use crate::{IntoValueAndType, ValueAndType};
29use bigdecimal::{BigDecimal, ToPrimitive};
30use combine::parser::char::spaces;
31use combine::stream::position;
32use combine::Parser;
33use combine::{eof, EasyParser};
34use serde::{Deserialize, Serialize, Serializer};
35use serde_json::Value;
36use std::collections::VecDeque;
37use std::fmt::Display;
38use std::ops::Deref;
39use std::sync::Arc;
40
41#[derive(Debug, Hash, Clone, PartialEq, Eq, PartialOrd, Ord)]
42pub enum Expr {
43    Let {
44        variable_id: VariableId,
45        type_annotation: Option<TypeName>,
46        expr: Box<Expr>,
47        inferred_type: InferredType,
48        source_span: SourceSpan,
49    },
50    SelectField {
51        expr: Box<Expr>,
52        field: String,
53        type_annotation: Option<TypeName>,
54        inferred_type: InferredType,
55        source_span: SourceSpan,
56    },
57    SelectIndex {
58        expr: Box<Expr>,
59        index: Box<Expr>,
60        type_annotation: Option<TypeName>,
61        inferred_type: InferredType,
62        source_span: SourceSpan,
63    },
64    Sequence {
65        exprs: Vec<Expr>,
66        type_annotation: Option<TypeName>,
67        inferred_type: InferredType,
68        source_span: SourceSpan,
69    },
70    Range {
71        range: Range,
72        type_annotation: Option<TypeName>,
73        inferred_type: InferredType,
74        source_span: SourceSpan,
75    },
76    Record {
77        exprs: Vec<(String, Box<Expr>)>,
78        type_annotation: Option<TypeName>,
79        inferred_type: InferredType,
80        source_span: SourceSpan,
81    },
82    Tuple {
83        exprs: Vec<Expr>,
84        type_annotation: Option<TypeName>,
85        inferred_type: InferredType,
86        source_span: SourceSpan,
87    },
88    Literal {
89        value: String,
90        type_annotation: Option<TypeName>,
91        inferred_type: InferredType,
92        source_span: SourceSpan,
93    },
94    Number {
95        number: Number,
96        type_annotation: Option<TypeName>,
97        inferred_type: InferredType,
98        source_span: SourceSpan,
99    },
100    Flags {
101        flags: Vec<String>,
102        type_annotation: Option<TypeName>,
103        inferred_type: InferredType,
104        source_span: SourceSpan,
105    },
106    Identifier {
107        variable_id: VariableId,
108        type_annotation: Option<TypeName>,
109        inferred_type: InferredType,
110        source_span: SourceSpan,
111    },
112    Boolean {
113        value: bool,
114        type_annotation: Option<TypeName>,
115        inferred_type: InferredType,
116        source_span: SourceSpan,
117    },
118    Concat {
119        exprs: Vec<Expr>,
120        type_annotation: Option<TypeName>,
121        inferred_type: InferredType,
122        source_span: SourceSpan,
123    },
124    ExprBlock {
125        exprs: Vec<Expr>,
126        type_annotation: Option<TypeName>,
127        inferred_type: InferredType,
128        source_span: SourceSpan,
129    },
130    Not {
131        expr: Box<Expr>,
132        inferred_type: InferredType,
133        type_annotation: Option<TypeName>,
134        source_span: SourceSpan,
135    },
136    GreaterThan {
137        lhs: Box<Expr>,
138        rhs: Box<Expr>,
139        type_annotation: Option<TypeName>,
140        inferred_type: InferredType,
141        source_span: SourceSpan,
142    },
143    And {
144        lhs: Box<Expr>,
145        rhs: Box<Expr>,
146        type_annotation: Option<TypeName>,
147        inferred_type: InferredType,
148        source_span: SourceSpan,
149    },
150    Or {
151        lhs: Box<Expr>,
152        rhs: Box<Expr>,
153        type_annotation: Option<TypeName>,
154        inferred_type: InferredType,
155        source_span: SourceSpan,
156    },
157    GreaterThanOrEqualTo {
158        lhs: Box<Expr>,
159        rhs: Box<Expr>,
160        type_annotation: Option<TypeName>,
161        inferred_type: InferredType,
162        source_span: SourceSpan,
163    },
164    LessThanOrEqualTo {
165        lhs: Box<Expr>,
166        rhs: Box<Expr>,
167        type_annotation: Option<TypeName>,
168        inferred_type: InferredType,
169        source_span: SourceSpan,
170    },
171    Plus {
172        lhs: Box<Expr>,
173        rhs: Box<Expr>,
174        type_annotation: Option<TypeName>,
175        inferred_type: InferredType,
176        source_span: SourceSpan,
177    },
178    Multiply {
179        lhs: Box<Expr>,
180        rhs: Box<Expr>,
181        type_annotation: Option<TypeName>,
182        inferred_type: InferredType,
183        source_span: SourceSpan,
184    },
185    Minus {
186        lhs: Box<Expr>,
187        rhs: Box<Expr>,
188        type_annotation: Option<TypeName>,
189        inferred_type: InferredType,
190        source_span: SourceSpan,
191    },
192    Divide {
193        lhs: Box<Expr>,
194        rhs: Box<Expr>,
195        type_annotation: Option<TypeName>,
196        inferred_type: InferredType,
197        source_span: SourceSpan,
198    },
199    EqualTo {
200        lhs: Box<Expr>,
201        rhs: Box<Expr>,
202        type_annotation: Option<TypeName>,
203        inferred_type: InferredType,
204        source_span: SourceSpan,
205    },
206    LessThan {
207        lhs: Box<Expr>,
208        rhs: Box<Expr>,
209        type_annotation: Option<TypeName>,
210        inferred_type: InferredType,
211        source_span: SourceSpan,
212    },
213    Cond {
214        cond: Box<Expr>,
215        lhs: Box<Expr>,
216        rhs: Box<Expr>,
217        type_annotation: Option<TypeName>,
218        inferred_type: InferredType,
219        source_span: SourceSpan,
220    },
221    PatternMatch {
222        predicate: Box<Expr>,
223        match_arms: Vec<MatchArm>,
224        type_annotation: Option<TypeName>,
225        inferred_type: InferredType,
226        source_span: SourceSpan,
227    },
228    Option {
229        expr: Option<Box<Expr>>,
230        type_annotation: Option<TypeName>,
231        inferred_type: InferredType,
232        source_span: SourceSpan,
233    },
234    Result {
235        expr: Result<Box<Expr>, Box<Expr>>,
236        type_annotation: Option<TypeName>,
237        inferred_type: InferredType,
238        source_span: SourceSpan,
239    },
240    // `instance("my-worker")` is parsed as Expr::Call { "instance", vec!["my-worker"] }.
241    // During function call inference phase, the type of this `Expr::Call` will be `Expr::Call { InstanceCreation,.. }
242    // with inferred-type as `InstanceType`. This way any variables attached to the instance creation
243    // will be having the `InstanceType`.
244    Call {
245        call_type: CallType,
246        args: Vec<Expr>,
247        type_annotation: Option<TypeName>,
248        inferred_type: InferredType,
249        source_span: SourceSpan,
250    },
251    // Any calls such as `my-worker-variable-expr.function_name()` will be parsed as Expr::Invoke
252    // such that `my-worker-variable-expr` (lhs) will be of the type `InferredType::InstanceType`. `lhs` will
253    // be `Expr::Call { InstanceCreation }` with type `InferredType::InstanceType`.
254    // As part of a separate type inference phase this will be converted back to `Expr::Call` with fully
255    // qualified function names (the complex version) which further takes part in all other type inference phases.
256    InvokeMethodLazy {
257        lhs: Box<Expr>,
258        method: String,
259        args: Vec<Expr>,
260        type_annotation: Option<TypeName>,
261        inferred_type: InferredType,
262        source_span: SourceSpan,
263    },
264    Unwrap {
265        expr: Box<Expr>,
266        inferred_type: InferredType,
267        type_annotation: Option<TypeName>,
268        source_span: SourceSpan,
269    },
270    Throw {
271        message: String,
272        inferred_type: InferredType,
273        type_annotation: Option<TypeName>,
274        source_span: SourceSpan,
275    },
276    GetTag {
277        expr: Box<Expr>,
278        inferred_type: InferredType,
279        type_annotation: Option<TypeName>,
280        source_span: SourceSpan,
281    },
282    ListComprehension {
283        iterated_variable: VariableId,
284        iterable_expr: Box<Expr>,
285        yield_expr: Box<Expr>,
286        type_annotation: Option<TypeName>,
287        inferred_type: InferredType,
288        source_span: SourceSpan,
289    },
290    ListReduce {
291        reduce_variable: VariableId,
292        iterated_variable: VariableId,
293        iterable_expr: Box<Expr>,
294        type_annotation: Option<TypeName>,
295        yield_expr: Box<Expr>,
296        init_value_expr: Box<Expr>,
297        inferred_type: InferredType,
298        source_span: SourceSpan,
299    },
300    Length {
301        expr: Box<Expr>,
302        inferred_type: InferredType,
303        type_annotation: Option<TypeName>,
304        source_span: SourceSpan,
305    },
306
307    GenerateWorkerName {
308        inferred_type: InferredType,
309        type_annotation: Option<TypeName>,
310        source_span: SourceSpan,
311        variable_id: Option<VariableId>,
312    },
313}
314
315impl Expr {
316    pub fn as_record(&self) -> Option<Vec<(String, Expr)>> {
317        match self {
318            Expr::Record { exprs: fields, .. } => Some(
319                fields
320                    .iter()
321                    .map(|(k, v)| (k.clone(), v.deref().clone()))
322                    .collect::<Vec<_>>(),
323            ),
324            _ => None,
325        }
326    }
327    /// Parse a text directly as Rib expression
328    /// Example of a Rib expression:
329    ///
330    /// ```rib
331    ///   let shopping-cart-worker = instance("my-worker");
332    ///   let result = shopping-cart-worker.add-to-cart({product-name: "apple", quantity: 2});
333    ///
334    ///   match result {
335    ///     ok(id) => "product-id-${id}",
336    ///     err(error_msg) => "Error: ${error_msg}"
337    ///   }
338    /// ```
339    ///
340    /// Rib supports conditional calls, function calls, pattern-matching,
341    /// string interpolation (see error_message above) etc.
342    ///
343    pub fn from_text(input: &str) -> Result<Expr, String> {
344        if input.trim().ends_with(';') {
345            return Err("unexpected `;` at the end of rib expression. \nnote: `;` is used to separate expressions, but it should not appear after the last expression (which is the return value)".to_string());
346        }
347
348        spaces()
349            .with(block().skip(eof()))
350            .easy_parse(position::Stream::new(input))
351            .map(|t| t.0)
352            .map_err(|err| format!("{err}"))
353    }
354
355    pub fn lookup(&self, source_span: &SourceSpan) -> Option<Expr> {
356        let mut expr = self.clone();
357        find_expr(&mut expr, source_span)
358    }
359
360    pub fn is_literal(&self) -> bool {
361        matches!(self, Expr::Literal { .. })
362    }
363
364    pub fn is_block(&self) -> bool {
365        matches!(self, Expr::ExprBlock { .. })
366    }
367
368    pub fn is_number(&self) -> bool {
369        matches!(self, Expr::Number { .. })
370    }
371
372    pub fn is_record(&self) -> bool {
373        matches!(self, Expr::Record { .. })
374    }
375
376    pub fn is_result(&self) -> bool {
377        matches!(self, Expr::Result { .. })
378    }
379
380    pub fn is_option(&self) -> bool {
381        matches!(self, Expr::Option { .. })
382    }
383
384    pub fn is_tuple(&self) -> bool {
385        matches!(self, Expr::Tuple { .. })
386    }
387
388    pub fn is_list(&self) -> bool {
389        matches!(self, Expr::Sequence { .. })
390    }
391
392    pub fn is_flags(&self) -> bool {
393        matches!(self, Expr::Flags { .. })
394    }
395
396    pub fn is_identifier(&self) -> bool {
397        matches!(self, Expr::Identifier { .. })
398    }
399
400    pub fn is_select_field(&self) -> bool {
401        matches!(self, Expr::SelectField { .. })
402    }
403
404    pub fn is_if_else(&self) -> bool {
405        matches!(self, Expr::Cond { .. })
406    }
407
408    pub fn is_function_call(&self) -> bool {
409        matches!(self, Expr::Call { .. })
410    }
411
412    pub fn is_match_expr(&self) -> bool {
413        matches!(self, Expr::PatternMatch { .. })
414    }
415
416    pub fn is_boolean(&self) -> bool {
417        matches!(self, Expr::Boolean { .. })
418    }
419
420    pub fn is_comparison(&self) -> bool {
421        matches!(
422            self,
423            Expr::GreaterThan { .. }
424                | Expr::GreaterThanOrEqualTo { .. }
425                | Expr::LessThanOrEqualTo { .. }
426                | Expr::EqualTo { .. }
427                | Expr::LessThan { .. }
428        )
429    }
430
431    pub fn is_concat(&self) -> bool {
432        matches!(self, Expr::Concat { .. })
433    }
434
435    pub fn is_multiple(&self) -> bool {
436        matches!(self, Expr::ExprBlock { .. })
437    }
438
439    pub fn inbuilt_variant(&self) -> Option<(String, Option<Expr>)> {
440        match self {
441            Expr::Option {
442                expr: Some(expr), ..
443            } => Some(("some".to_string(), Some(expr.deref().clone()))),
444            Expr::Option { expr: None, .. } => Some(("some".to_string(), None)),
445            Expr::Result { expr: Ok(expr), .. } => {
446                Some(("ok".to_string(), Some(expr.deref().clone())))
447            }
448            Expr::Result {
449                expr: Err(expr), ..
450            } => Some(("err".to_string(), Some(expr.deref().clone()))),
451            _ => None,
452        }
453    }
454    pub fn unwrap(&self) -> Self {
455        Expr::Unwrap {
456            expr: Box::new(self.clone()),
457            inferred_type: InferredType::unknown(),
458            source_span: SourceSpan::default(),
459            type_annotation: None,
460        }
461    }
462
463    pub fn length(expr: Expr) -> Self {
464        Expr::Length {
465            expr: Box::new(expr),
466            inferred_type: InferredType::u64(),
467            source_span: SourceSpan::default(),
468            type_annotation: None,
469        }
470    }
471
472    pub fn boolean(value: bool) -> Self {
473        Expr::Boolean {
474            value,
475            inferred_type: InferredType::bool(),
476            source_span: SourceSpan::default(),
477            type_annotation: None,
478        }
479    }
480
481    pub fn and(left: Expr, right: Expr) -> Self {
482        Expr::And {
483            lhs: Box::new(left),
484            rhs: Box::new(right),
485            inferred_type: InferredType::bool(),
486            source_span: SourceSpan::default(),
487            type_annotation: None,
488        }
489    }
490
491    pub fn throw(message: impl AsRef<str>) -> Self {
492        Expr::Throw {
493            message: message.as_ref().to_string(),
494            inferred_type: InferredType::unknown(),
495            source_span: SourceSpan::default(),
496            type_annotation: None,
497        }
498    }
499
500    pub fn generate_worker_name(variable_id: Option<VariableId>) -> Self {
501        Expr::GenerateWorkerName {
502            inferred_type: InferredType::string(),
503            type_annotation: None,
504            source_span: SourceSpan::default(),
505            variable_id,
506        }
507    }
508
509    pub fn plus(left: Expr, right: Expr) -> Self {
510        Expr::Plus {
511            lhs: Box::new(left),
512            rhs: Box::new(right),
513            inferred_type: InferredType::unknown(),
514            source_span: SourceSpan::default(),
515            type_annotation: None,
516        }
517    }
518
519    pub fn minus(left: Expr, right: Expr) -> Self {
520        Expr::Minus {
521            lhs: Box::new(left),
522            rhs: Box::new(right),
523            inferred_type: InferredType::unknown(),
524            source_span: SourceSpan::default(),
525            type_annotation: None,
526        }
527    }
528
529    pub fn divide(left: Expr, right: Expr) -> Self {
530        Expr::Divide {
531            lhs: Box::new(left),
532            rhs: Box::new(right),
533            inferred_type: InferredType::unknown(),
534            source_span: SourceSpan::default(),
535            type_annotation: None,
536        }
537    }
538
539    pub fn multiply(left: Expr, right: Expr) -> Self {
540        Expr::Multiply {
541            lhs: Box::new(left),
542            rhs: Box::new(right),
543            inferred_type: InferredType::unknown(),
544            source_span: SourceSpan::default(),
545            type_annotation: None,
546        }
547    }
548
549    pub fn and_combine(conditions: Vec<Expr>) -> Option<Expr> {
550        let mut cond: Option<Expr> = None;
551
552        for i in conditions {
553            let left = Box::new(cond.clone().unwrap_or(Expr::boolean(true)));
554            cond = Some(Expr::And {
555                lhs: left,
556                rhs: Box::new(i),
557                inferred_type: InferredType::bool(),
558                source_span: SourceSpan::default(),
559                type_annotation: None,
560            });
561        }
562
563        cond
564    }
565
566    pub fn call_worker_function(
567        dynamic_parsed_fn_name: DynamicParsedFunctionName,
568        module_identifier: Option<InstanceIdentifier>,
569        args: Vec<Expr>,
570        component_info: Option<ComponentDependencyKey>,
571    ) -> Self {
572        Expr::Call {
573            call_type: CallType::Function {
574                function_name: dynamic_parsed_fn_name,
575                instance_identifier: module_identifier.map(Box::new),
576                component_info,
577            },
578            args,
579            inferred_type: InferredType::unknown(),
580            source_span: SourceSpan::default(),
581            type_annotation: None,
582        }
583    }
584
585    pub fn call(call_type: CallType, args: Vec<Expr>) -> Self {
586        Expr::Call {
587            call_type,
588            args,
589            inferred_type: InferredType::unknown(),
590            source_span: SourceSpan::default(),
591            type_annotation: None,
592        }
593    }
594
595    pub fn invoke_worker_function(lhs: Expr, function_name: String, args: Vec<Expr>) -> Self {
596        Expr::InvokeMethodLazy {
597            lhs: Box::new(lhs),
598            method: function_name,
599            args,
600            inferred_type: InferredType::unknown(),
601            source_span: SourceSpan::default(),
602            type_annotation: None,
603        }
604    }
605
606    pub fn concat(expressions: Vec<Expr>) -> Self {
607        Expr::Concat {
608            exprs: expressions,
609            inferred_type: InferredType::string(),
610            source_span: SourceSpan::default(),
611            type_annotation: None,
612        }
613    }
614
615    pub fn cond(cond: Expr, lhs: Expr, rhs: Expr) -> Self {
616        Expr::Cond {
617            cond: Box::new(cond),
618            lhs: Box::new(lhs),
619            rhs: Box::new(rhs),
620            inferred_type: InferredType::unknown(),
621            source_span: SourceSpan::default(),
622            type_annotation: None,
623        }
624    }
625
626    pub fn equal_to(left: Expr, right: Expr) -> Self {
627        Expr::EqualTo {
628            lhs: Box::new(left),
629            rhs: Box::new(right),
630            inferred_type: InferredType::bool(),
631            source_span: SourceSpan::default(),
632            type_annotation: None,
633        }
634    }
635
636    pub fn err(expr: Expr, type_annotation: Option<TypeName>) -> Self {
637        let inferred_type = expr.inferred_type();
638        Expr::Result {
639            expr: Err(Box::new(expr)),
640            type_annotation,
641            inferred_type: InferredType::result(Some(InferredType::unknown()), Some(inferred_type)),
642            source_span: SourceSpan::default(),
643        }
644    }
645
646    pub fn flags(flags: Vec<String>) -> Self {
647        Expr::Flags {
648            flags: flags.clone(),
649            inferred_type: InferredType::flags(flags),
650            source_span: SourceSpan::default(),
651            type_annotation: None,
652        }
653    }
654
655    pub fn greater_than(left: Expr, right: Expr) -> Self {
656        Expr::GreaterThan {
657            lhs: Box::new(left),
658            rhs: Box::new(right),
659            inferred_type: InferredType::bool(),
660            source_span: SourceSpan::default(),
661            type_annotation: None,
662        }
663    }
664
665    pub fn greater_than_or_equal_to(left: Expr, right: Expr) -> Self {
666        Expr::GreaterThanOrEqualTo {
667            lhs: Box::new(left),
668            rhs: Box::new(right),
669            inferred_type: InferredType::bool(),
670            source_span: SourceSpan::default(),
671            type_annotation: None,
672        }
673    }
674
675    // An identifier by default is global until name-binding phase is run
676    pub fn identifier_global(name: impl AsRef<str>, type_annotation: Option<TypeName>) -> Self {
677        Expr::Identifier {
678            variable_id: VariableId::global(name.as_ref().to_string()),
679            type_annotation,
680            inferred_type: InferredType::unknown(),
681            source_span: SourceSpan::default(),
682        }
683    }
684
685    pub fn identifier_local(
686        name: impl AsRef<str>,
687        id: u32,
688        type_annotation: Option<TypeName>,
689    ) -> Self {
690        Expr::Identifier {
691            variable_id: VariableId::local(name.as_ref(), id),
692            type_annotation,
693            inferred_type: InferredType::unknown(),
694            source_span: SourceSpan::default(),
695        }
696    }
697
698    pub fn identifier_with_variable_id(
699        variable_id: VariableId,
700        type_annotation: Option<TypeName>,
701    ) -> Self {
702        Expr::Identifier {
703            variable_id,
704            type_annotation,
705            inferred_type: InferredType::unknown(),
706            source_span: SourceSpan::default(),
707        }
708    }
709
710    pub fn less_than(left: Expr, right: Expr) -> Self {
711        Expr::LessThan {
712            lhs: Box::new(left),
713            rhs: Box::new(right),
714            inferred_type: InferredType::bool(),
715            source_span: SourceSpan::default(),
716            type_annotation: None,
717        }
718    }
719
720    pub fn less_than_or_equal_to(left: Expr, right: Expr) -> Self {
721        Expr::LessThanOrEqualTo {
722            lhs: Box::new(left),
723            rhs: Box::new(right),
724            inferred_type: InferredType::bool(),
725            source_span: SourceSpan::default(),
726            type_annotation: None,
727        }
728    }
729
730    pub fn range(from: Expr, to: Expr) -> Self {
731        Expr::Range {
732            range: Range::Range {
733                from: Box::new(from.clone()),
734                to: Box::new(to.clone()),
735            },
736            inferred_type: InferredType::range(from.inferred_type(), Some(to.inferred_type())),
737            source_span: SourceSpan::default(),
738            type_annotation: None,
739        }
740    }
741
742    pub fn range_from(from: Expr) -> Self {
743        Expr::Range {
744            range: Range::RangeFrom {
745                from: Box::new(from.clone()),
746            },
747            inferred_type: InferredType::range(from.inferred_type(), None),
748            source_span: SourceSpan::default(),
749            type_annotation: None,
750        }
751    }
752
753    pub fn range_inclusive(from: Expr, to: Expr) -> Self {
754        Expr::Range {
755            range: Range::RangeInclusive {
756                from: Box::new(from.clone()),
757                to: Box::new(to.clone()),
758            },
759            inferred_type: InferredType::range(from.inferred_type(), Some(to.inferred_type())),
760            source_span: SourceSpan::default(),
761            type_annotation: None,
762        }
763    }
764
765    pub fn let_binding(
766        name: impl AsRef<str>,
767        expr: Expr,
768        type_annotation: Option<TypeName>,
769    ) -> Self {
770        Expr::Let {
771            variable_id: VariableId::global(name.as_ref().to_string()),
772            type_annotation,
773            expr: Box::new(expr),
774            source_span: SourceSpan::default(),
775            inferred_type: InferredType::tuple(vec![]),
776        }
777    }
778
779    pub fn let_binding_with_variable_id(
780        variable_id: VariableId,
781        expr: Expr,
782        type_annotation: Option<TypeName>,
783    ) -> Self {
784        Expr::Let {
785            variable_id,
786            type_annotation,
787            expr: Box::new(expr),
788            source_span: SourceSpan::default(),
789            inferred_type: InferredType::tuple(vec![]),
790        }
791    }
792
793    pub fn typed_list_reduce(
794        reduce_variable: VariableId,
795        iterated_variable: VariableId,
796        iterable_expr: Expr,
797        init_value_expr: Expr,
798        yield_expr: Expr,
799        inferred_type: InferredType,
800    ) -> Self {
801        Expr::ListReduce {
802            reduce_variable,
803            iterated_variable,
804            iterable_expr: Box::new(iterable_expr),
805            yield_expr: Box::new(yield_expr),
806            init_value_expr: Box::new(init_value_expr),
807            inferred_type,
808            source_span: SourceSpan::default(),
809            type_annotation: None,
810        }
811    }
812
813    pub fn list_reduce(
814        reduce_variable: VariableId,
815        iterated_variable: VariableId,
816        iterable_expr: Expr,
817        init_value_expr: Expr,
818        yield_expr: Expr,
819    ) -> Self {
820        Expr::typed_list_reduce(
821            reduce_variable,
822            iterated_variable,
823            iterable_expr,
824            init_value_expr,
825            yield_expr,
826            InferredType::unknown(),
827        )
828    }
829
830    pub fn list_comprehension_typed(
831        iterated_variable: VariableId,
832        iterable_expr: Expr,
833        yield_expr: Expr,
834        inferred_type: InferredType,
835    ) -> Self {
836        Expr::ListComprehension {
837            iterated_variable,
838            iterable_expr: Box::new(iterable_expr),
839            yield_expr: Box::new(yield_expr),
840            inferred_type,
841            source_span: SourceSpan::default(),
842            type_annotation: None,
843        }
844    }
845
846    pub fn list_comprehension(
847        variable_id: VariableId,
848        iterable_expr: Expr,
849        yield_expr: Expr,
850    ) -> Self {
851        Expr::list_comprehension_typed(
852            variable_id,
853            iterable_expr,
854            yield_expr,
855            InferredType::list(InferredType::unknown()),
856        )
857    }
858
859    pub fn literal(value: impl AsRef<str>) -> Self {
860        let default_type = DefaultType::String;
861
862        Expr::Literal {
863            value: value.as_ref().to_string(),
864            inferred_type: InferredType::from(&default_type),
865            source_span: SourceSpan::default(),
866            type_annotation: None,
867        }
868    }
869
870    pub fn empty_expr() -> Self {
871        Expr::literal("")
872    }
873
874    pub fn expr_block(expressions: Vec<Expr>) -> Self {
875        let inferred_type = expressions
876            .last()
877            .map_or(InferredType::unknown(), |e| e.inferred_type());
878
879        Expr::ExprBlock {
880            exprs: expressions,
881            inferred_type,
882            source_span: SourceSpan::default(),
883            type_annotation: None,
884        }
885    }
886
887    #[allow(clippy::should_implement_trait)]
888    pub fn not(expr: Expr) -> Self {
889        Expr::Not {
890            expr: Box::new(expr),
891            inferred_type: InferredType::bool(),
892            source_span: SourceSpan::default(),
893            type_annotation: None,
894        }
895    }
896
897    pub fn ok(expr: Expr, type_annotation: Option<TypeName>) -> Self {
898        let inferred_type = expr.inferred_type();
899
900        Expr::Result {
901            expr: Ok(Box::new(expr)),
902            type_annotation,
903            inferred_type: InferredType::result(Some(inferred_type), Some(InferredType::unknown())),
904            source_span: SourceSpan::default(),
905        }
906    }
907
908    pub fn option(expr: Option<Expr>) -> Self {
909        let inferred_type = match &expr {
910            Some(expr) => expr.inferred_type(),
911            None => InferredType::unknown(),
912        };
913
914        Expr::Option {
915            expr: expr.map(Box::new),
916            type_annotation: None,
917            inferred_type: InferredType::option(inferred_type),
918            source_span: SourceSpan::default(),
919        }
920    }
921
922    pub fn or(left: Expr, right: Expr) -> Self {
923        Expr::Or {
924            lhs: Box::new(left),
925            rhs: Box::new(right),
926            inferred_type: InferredType::bool(),
927            source_span: SourceSpan::default(),
928            type_annotation: None,
929        }
930    }
931
932    pub fn pattern_match(expr: Expr, match_arms: Vec<MatchArm>) -> Self {
933        Expr::PatternMatch {
934            predicate: Box::new(expr),
935            match_arms,
936            inferred_type: InferredType::unknown(),
937            source_span: SourceSpan::default(),
938            type_annotation: None,
939        }
940    }
941
942    pub fn record(expressions: Vec<(String, Expr)>) -> Self {
943        let inferred_type = InferredType::record(
944            expressions
945                .iter()
946                .map(|(field_name, expr)| (field_name.to_string(), expr.inferred_type()))
947                .collect(),
948        );
949
950        Expr::Record {
951            exprs: expressions
952                .into_iter()
953                .map(|(field_name, expr)| (field_name, Box::new(expr)))
954                .collect(),
955            inferred_type,
956            source_span: SourceSpan::default(),
957            type_annotation: None,
958        }
959    }
960
961    pub fn select_field(
962        expr: Expr,
963        field: impl AsRef<str>,
964        type_annotation: Option<TypeName>,
965    ) -> Self {
966        Expr::SelectField {
967            expr: Box::new(expr),
968            field: field.as_ref().to_string(),
969            type_annotation,
970            inferred_type: InferredType::unknown(),
971            source_span: SourceSpan::default(),
972        }
973    }
974
975    pub fn select_index(expr: Expr, index: Expr) -> Self {
976        Expr::SelectIndex {
977            expr: Box::new(expr),
978            index: Box::new(index),
979            type_annotation: None,
980            inferred_type: InferredType::unknown(),
981            source_span: SourceSpan::default(),
982        }
983    }
984
985    pub fn get_tag(expr: Expr) -> Self {
986        Expr::GetTag {
987            expr: Box::new(expr),
988            inferred_type: InferredType::unknown(),
989            source_span: SourceSpan::default(),
990            type_annotation: None,
991        }
992    }
993
994    pub fn tuple(expressions: Vec<Expr>) -> Self {
995        let inferred_type = InferredType::tuple(
996            expressions
997                .iter()
998                .map(|expr| expr.inferred_type())
999                .collect(),
1000        );
1001
1002        Expr::Tuple {
1003            exprs: expressions,
1004            inferred_type,
1005            source_span: SourceSpan::default(),
1006            type_annotation: None,
1007        }
1008    }
1009
1010    pub fn sequence(expressions: Vec<Expr>, type_annotation: Option<TypeName>) -> Self {
1011        let inferred_type = InferredType::list(
1012            expressions
1013                .first()
1014                .map_or(InferredType::unknown(), |x| x.inferred_type()),
1015        );
1016
1017        Expr::Sequence {
1018            exprs: expressions,
1019            type_annotation,
1020            inferred_type,
1021            source_span: SourceSpan::default(),
1022        }
1023    }
1024
1025    pub fn inferred_type_mut(&mut self) -> &mut InferredType {
1026        match self {
1027            Expr::Let { inferred_type, .. }
1028            | Expr::SelectField { inferred_type, .. }
1029            | Expr::SelectIndex { inferred_type, .. }
1030            | Expr::Sequence { inferred_type, .. }
1031            | Expr::Record { inferred_type, .. }
1032            | Expr::Tuple { inferred_type, .. }
1033            | Expr::Literal { inferred_type, .. }
1034            | Expr::Number { inferred_type, .. }
1035            | Expr::Flags { inferred_type, .. }
1036            | Expr::Identifier { inferred_type, .. }
1037            | Expr::Boolean { inferred_type, .. }
1038            | Expr::Concat { inferred_type, .. }
1039            | Expr::ExprBlock { inferred_type, .. }
1040            | Expr::Not { inferred_type, .. }
1041            | Expr::GreaterThan { inferred_type, .. }
1042            | Expr::GreaterThanOrEqualTo { inferred_type, .. }
1043            | Expr::LessThanOrEqualTo { inferred_type, .. }
1044            | Expr::EqualTo { inferred_type, .. }
1045            | Expr::Plus { inferred_type, .. }
1046            | Expr::Minus { inferred_type, .. }
1047            | Expr::Divide { inferred_type, .. }
1048            | Expr::Multiply { inferred_type, .. }
1049            | Expr::LessThan { inferred_type, .. }
1050            | Expr::Cond { inferred_type, .. }
1051            | Expr::PatternMatch { inferred_type, .. }
1052            | Expr::Option { inferred_type, .. }
1053            | Expr::Result { inferred_type, .. }
1054            | Expr::Unwrap { inferred_type, .. }
1055            | Expr::Throw { inferred_type, .. }
1056            | Expr::GetTag { inferred_type, .. }
1057            | Expr::And { inferred_type, .. }
1058            | Expr::Or { inferred_type, .. }
1059            | Expr::ListComprehension { inferred_type, .. }
1060            | Expr::ListReduce { inferred_type, .. }
1061            | Expr::Call { inferred_type, .. }
1062            | Expr::Range { inferred_type, .. }
1063            | Expr::InvokeMethodLazy { inferred_type, .. }
1064            | Expr::Length { inferred_type, .. }
1065            | Expr::GenerateWorkerName { inferred_type, .. } => &mut *inferred_type,
1066        }
1067    }
1068
1069    pub fn inferred_type(&self) -> InferredType {
1070        match self {
1071            Expr::Let { inferred_type, .. }
1072            | Expr::SelectField { inferred_type, .. }
1073            | Expr::SelectIndex { inferred_type, .. }
1074            | Expr::Sequence { inferred_type, .. }
1075            | Expr::Record { inferred_type, .. }
1076            | Expr::Tuple { inferred_type, .. }
1077            | Expr::Literal { inferred_type, .. }
1078            | Expr::Number { inferred_type, .. }
1079            | Expr::Flags { inferred_type, .. }
1080            | Expr::Identifier { inferred_type, .. }
1081            | Expr::Boolean { inferred_type, .. }
1082            | Expr::Concat { inferred_type, .. }
1083            | Expr::ExprBlock { inferred_type, .. }
1084            | Expr::Not { inferred_type, .. }
1085            | Expr::GreaterThan { inferred_type, .. }
1086            | Expr::GreaterThanOrEqualTo { inferred_type, .. }
1087            | Expr::LessThanOrEqualTo { inferred_type, .. }
1088            | Expr::EqualTo { inferred_type, .. }
1089            | Expr::Plus { inferred_type, .. }
1090            | Expr::Minus { inferred_type, .. }
1091            | Expr::Divide { inferred_type, .. }
1092            | Expr::Multiply { inferred_type, .. }
1093            | Expr::LessThan { inferred_type, .. }
1094            | Expr::Cond { inferred_type, .. }
1095            | Expr::PatternMatch { inferred_type, .. }
1096            | Expr::Option { inferred_type, .. }
1097            | Expr::Result { inferred_type, .. }
1098            | Expr::Unwrap { inferred_type, .. }
1099            | Expr::Throw { inferred_type, .. }
1100            | Expr::GetTag { inferred_type, .. }
1101            | Expr::And { inferred_type, .. }
1102            | Expr::Or { inferred_type, .. }
1103            | Expr::ListComprehension { inferred_type, .. }
1104            | Expr::ListReduce { inferred_type, .. }
1105            | Expr::Call { inferred_type, .. }
1106            | Expr::Range { inferred_type, .. }
1107            | Expr::InvokeMethodLazy { inferred_type, .. }
1108            | Expr::Length { inferred_type, .. }
1109            | Expr::GenerateWorkerName { inferred_type, .. } => inferred_type.clone(),
1110        }
1111    }
1112
1113    pub fn infer_types(
1114        &mut self,
1115        component_dependency: &ComponentDependency,
1116        global_variable_type_spec: &Vec<GlobalVariableTypeSpec>,
1117        custom_instance_spec: &[CustomInstanceSpec],
1118    ) -> Result<(), RibTypeErrorInternal> {
1119        let component = Arc::new(component_dependency.clone());
1120
1121        let (mut arena, mut types, root) = {
1122            let _p = crate::profile::Scope::new("type inference: lower to expr arena");
1123
1124            crate::expr_arena::lower(self)
1125        };
1126
1127        {
1128            let _p = crate::profile::Scope::new(
1129                "type inference: run_initial_binding_and_instance_phases",
1130            );
1131            ti::run_initial_binding_and_instance_phases(
1132                root,
1133                &mut arena,
1134                &mut types,
1135                component.clone(),
1136                global_variable_type_spec.as_slice(),
1137                custom_instance_spec,
1138            )?;
1139
1140            ti::infer_variants_lowered(root, &mut arena, &mut types, component.as_ref());
1141            ti::infer_enums(root, &mut arena, &mut types, component.as_ref());
1142            ti::bind_instance_types(root, &arena, &mut types);
1143        }
1144
1145        {
1146            let _p = crate::profile::Scope::new(
1147                "type inference: fixpoint - resolve function calls and instance bindings",
1148            );
1149
1150            ti::type_inference_fix_point(
1151                |root, arena, types| -> Result<(), RibTypeErrorInternal> {
1152                    ti::bind_instance_types(root, arena, types);
1153                    ti::infer_function_invokes(root, arena, types, component.as_ref())
1154                },
1155                root,
1156                &mut arena,
1157                &mut types,
1158            )?;
1159        }
1160
1161        {
1162            let _p = crate::profile::Scope::new("type inference: infer_function_call_types");
1163
1164            ti::infer_function_call_types(
1165                root,
1166                &arena,
1167                &mut types,
1168                component.as_ref(),
1169                custom_instance_spec,
1170            )
1171            .map_err(RibTypeErrorInternal::from)?;
1172        }
1173
1174        {
1175            let _p = crate::profile::Scope::new(
1176                "type inference: fixpoint - main scan for type inference",
1177            );
1178
1179            ti::type_inference_fix_point(
1180                |root, arena, types| -> Result<(), RibTypeErrorInternal> {
1181                    ti::infer_all_identifiers(root, arena, types);
1182                    ti::push_types_down(root, arena, types)?;
1183                    ti::infer_all_identifiers(root, arena, types);
1184                    ti::pull_types_up(root, arena, types, component.as_ref())?;
1185                    ti::infer_global_inputs(root, arena, types);
1186                    ti::infer_function_call_types(
1187                        root,
1188                        arena,
1189                        types,
1190                        component.as_ref(),
1191                        custom_instance_spec,
1192                    )
1193                    .map_err(RibTypeErrorInternal::from)?;
1194                    Ok(())
1195                },
1196                root,
1197                &mut arena,
1198                &mut types,
1199            )?;
1200        }
1201
1202        {
1203            let _p = crate::profile::Scope::new(
1204                "type inference: sync_embedded_worker_exprs_from_calls + bind_instance_types",
1205            );
1206
1207            ti::sync_embedded_worker_exprs_from_calls(root, &arena, &mut types);
1208            ti::bind_instance_types(root, &arena, &mut types);
1209        }
1210
1211        {
1212            let _p = crate::profile::Scope::new("type inference: type check");
1213            type_checker::checker::type_check(root, &arena, &mut types, component.as_ref())?;
1214        }
1215
1216        {
1217            let _p = crate::profile::Scope::new("type inference: unify types");
1218            type_inference::unify_types(root, &arena, &mut types)?;
1219        }
1220
1221        {
1222            let _p = crate::profile::Scope::new("type inference: rebuild_expr");
1223            *self = crate::expr_arena::rebuild_expr(root, &arena, &types);
1224        }
1225
1226        Ok(())
1227    }
1228
1229    pub fn merge_inferred_type(&self, new_inferred_type: InferredType) -> Expr {
1230        let mut expr_copied = self.clone();
1231        expr_copied.add_infer_type_mut(new_inferred_type);
1232        expr_copied
1233    }
1234
1235    pub fn add_infer_type_mut(&mut self, new_inferred_type: InferredType) {
1236        match self {
1237            Expr::Identifier { inferred_type, .. }
1238            | Expr::Let { inferred_type, .. }
1239            | Expr::SelectField { inferred_type, .. }
1240            | Expr::SelectIndex { inferred_type, .. }
1241            | Expr::Sequence { inferred_type, .. }
1242            | Expr::Record { inferred_type, .. }
1243            | Expr::Tuple { inferred_type, .. }
1244            | Expr::Literal { inferred_type, .. }
1245            | Expr::Number { inferred_type, .. }
1246            | Expr::Flags { inferred_type, .. }
1247            | Expr::Boolean { inferred_type, .. }
1248            | Expr::Concat { inferred_type, .. }
1249            | Expr::ExprBlock { inferred_type, .. }
1250            | Expr::Not { inferred_type, .. }
1251            | Expr::GreaterThan { inferred_type, .. }
1252            | Expr::GreaterThanOrEqualTo { inferred_type, .. }
1253            | Expr::LessThanOrEqualTo { inferred_type, .. }
1254            | Expr::EqualTo { inferred_type, .. }
1255            | Expr::Plus { inferred_type, .. }
1256            | Expr::Minus { inferred_type, .. }
1257            | Expr::Divide { inferred_type, .. }
1258            | Expr::Multiply { inferred_type, .. }
1259            | Expr::LessThan { inferred_type, .. }
1260            | Expr::Cond { inferred_type, .. }
1261            | Expr::PatternMatch { inferred_type, .. }
1262            | Expr::Option { inferred_type, .. }
1263            | Expr::Result { inferred_type, .. }
1264            | Expr::Unwrap { inferred_type, .. }
1265            | Expr::Throw { inferred_type, .. }
1266            | Expr::GetTag { inferred_type, .. }
1267            | Expr::And { inferred_type, .. }
1268            | Expr::Or { inferred_type, .. }
1269            | Expr::ListComprehension { inferred_type, .. }
1270            | Expr::ListReduce { inferred_type, .. }
1271            | Expr::InvokeMethodLazy { inferred_type, .. }
1272            | Expr::Range { inferred_type, .. }
1273            | Expr::Length { inferred_type, .. }
1274            | Expr::GenerateWorkerName { inferred_type, .. }
1275            | Expr::Call { inferred_type, .. } => {
1276                if !new_inferred_type.is_unknown() {
1277                    *inferred_type = inferred_type.merge(new_inferred_type);
1278                }
1279            }
1280        }
1281    }
1282
1283    pub fn reset_type(&mut self) {
1284        type_inference::reset_type_info(self);
1285    }
1286
1287    pub fn source_span(&self) -> SourceSpan {
1288        match self {
1289            Expr::Identifier { source_span, .. }
1290            | Expr::Let { source_span, .. }
1291            | Expr::SelectField { source_span, .. }
1292            | Expr::SelectIndex { source_span, .. }
1293            | Expr::Sequence { source_span, .. }
1294            | Expr::Record { source_span, .. }
1295            | Expr::Tuple { source_span, .. }
1296            | Expr::Literal { source_span, .. }
1297            | Expr::Number { source_span, .. }
1298            | Expr::Flags { source_span, .. }
1299            | Expr::Boolean { source_span, .. }
1300            | Expr::Concat { source_span, .. }
1301            | Expr::ExprBlock { source_span, .. }
1302            | Expr::Not { source_span, .. }
1303            | Expr::GreaterThan { source_span, .. }
1304            | Expr::GreaterThanOrEqualTo { source_span, .. }
1305            | Expr::LessThanOrEqualTo { source_span, .. }
1306            | Expr::EqualTo { source_span, .. }
1307            | Expr::LessThan { source_span, .. }
1308            | Expr::Plus { source_span, .. }
1309            | Expr::Minus { source_span, .. }
1310            | Expr::Divide { source_span, .. }
1311            | Expr::Multiply { source_span, .. }
1312            | Expr::Cond { source_span, .. }
1313            | Expr::PatternMatch { source_span, .. }
1314            | Expr::Option { source_span, .. }
1315            | Expr::Result { source_span, .. }
1316            | Expr::Unwrap { source_span, .. }
1317            | Expr::Throw { source_span, .. }
1318            | Expr::And { source_span, .. }
1319            | Expr::Or { source_span, .. }
1320            | Expr::GetTag { source_span, .. }
1321            | Expr::ListComprehension { source_span, .. }
1322            | Expr::ListReduce { source_span, .. }
1323            | Expr::InvokeMethodLazy { source_span, .. }
1324            | Expr::Range { source_span, .. }
1325            | Expr::Length { source_span, .. }
1326            | Expr::Call { source_span, .. }
1327            | Expr::GenerateWorkerName { source_span, .. } => source_span.clone(),
1328        }
1329    }
1330
1331    pub fn type_annotation(&self) -> &Option<TypeName> {
1332        match self {
1333            Expr::Identifier {
1334                type_annotation, ..
1335            }
1336            | Expr::Let {
1337                type_annotation, ..
1338            }
1339            | Expr::SelectField {
1340                type_annotation, ..
1341            }
1342            | Expr::SelectIndex {
1343                type_annotation, ..
1344            }
1345            | Expr::Sequence {
1346                type_annotation, ..
1347            }
1348            | Expr::Record {
1349                type_annotation, ..
1350            }
1351            | Expr::Tuple {
1352                type_annotation, ..
1353            }
1354            | Expr::Literal {
1355                type_annotation, ..
1356            }
1357            | Expr::Number {
1358                type_annotation, ..
1359            }
1360            | Expr::Flags {
1361                type_annotation, ..
1362            }
1363            | Expr::Boolean {
1364                type_annotation, ..
1365            }
1366            | Expr::Concat {
1367                type_annotation, ..
1368            }
1369            | Expr::ExprBlock {
1370                type_annotation, ..
1371            }
1372            | Expr::Not {
1373                type_annotation, ..
1374            }
1375            | Expr::GreaterThan {
1376                type_annotation, ..
1377            }
1378            | Expr::GreaterThanOrEqualTo {
1379                type_annotation, ..
1380            }
1381            | Expr::LessThanOrEqualTo {
1382                type_annotation, ..
1383            }
1384            | Expr::EqualTo {
1385                type_annotation, ..
1386            }
1387            | Expr::LessThan {
1388                type_annotation, ..
1389            }
1390            | Expr::Plus {
1391                type_annotation, ..
1392            }
1393            | Expr::Minus {
1394                type_annotation, ..
1395            }
1396            | Expr::Divide {
1397                type_annotation, ..
1398            }
1399            | Expr::Multiply {
1400                type_annotation, ..
1401            }
1402            | Expr::Cond {
1403                type_annotation, ..
1404            }
1405            | Expr::PatternMatch {
1406                type_annotation, ..
1407            }
1408            | Expr::Option {
1409                type_annotation, ..
1410            }
1411            | Expr::Result {
1412                type_annotation, ..
1413            }
1414            | Expr::Unwrap {
1415                type_annotation, ..
1416            }
1417            | Expr::Throw {
1418                type_annotation, ..
1419            }
1420            | Expr::And {
1421                type_annotation, ..
1422            }
1423            | Expr::Or {
1424                type_annotation, ..
1425            }
1426            | Expr::GetTag {
1427                type_annotation, ..
1428            }
1429            | Expr::ListComprehension {
1430                type_annotation, ..
1431            }
1432            | Expr::ListReduce {
1433                type_annotation, ..
1434            }
1435            | Expr::InvokeMethodLazy {
1436                type_annotation, ..
1437            }
1438            | Expr::Range {
1439                type_annotation, ..
1440            }
1441            | Expr::Length {
1442                type_annotation, ..
1443            }
1444            | Expr::GenerateWorkerName {
1445                type_annotation, ..
1446            }
1447            | Expr::Call {
1448                type_annotation, ..
1449            } => type_annotation,
1450        }
1451    }
1452
1453    pub fn with_type_annotation_opt(&self, type_annotation: Option<TypeName>) -> Expr {
1454        if let Some(type_annotation) = type_annotation {
1455            self.with_type_annotation(type_annotation)
1456        } else {
1457            self.clone()
1458        }
1459    }
1460
1461    pub fn with_type_annotation(&self, type_annotation: TypeName) -> Expr {
1462        let mut expr_copied = self.clone();
1463        expr_copied.with_type_annotation_mut(type_annotation);
1464        expr_copied
1465    }
1466
1467    pub fn with_type_annotation_mut(&mut self, type_annotation: TypeName) {
1468        let new_type_annotation = type_annotation;
1469
1470        match self {
1471            Expr::Identifier {
1472                type_annotation, ..
1473            }
1474            | Expr::Let {
1475                type_annotation, ..
1476            }
1477            | Expr::SelectField {
1478                type_annotation, ..
1479            }
1480            | Expr::SelectIndex {
1481                type_annotation, ..
1482            }
1483            | Expr::Sequence {
1484                type_annotation, ..
1485            }
1486            | Expr::Record {
1487                type_annotation, ..
1488            }
1489            | Expr::Tuple {
1490                type_annotation, ..
1491            }
1492            | Expr::Literal {
1493                type_annotation, ..
1494            }
1495            | Expr::Number {
1496                type_annotation, ..
1497            }
1498            | Expr::Flags {
1499                type_annotation, ..
1500            }
1501            | Expr::Boolean {
1502                type_annotation, ..
1503            }
1504            | Expr::Concat {
1505                type_annotation, ..
1506            }
1507            | Expr::ExprBlock {
1508                type_annotation, ..
1509            }
1510            | Expr::Not {
1511                type_annotation, ..
1512            }
1513            | Expr::GreaterThan {
1514                type_annotation, ..
1515            }
1516            | Expr::GreaterThanOrEqualTo {
1517                type_annotation, ..
1518            }
1519            | Expr::LessThanOrEqualTo {
1520                type_annotation, ..
1521            }
1522            | Expr::EqualTo {
1523                type_annotation, ..
1524            }
1525            | Expr::LessThan {
1526                type_annotation, ..
1527            }
1528            | Expr::Plus {
1529                type_annotation, ..
1530            }
1531            | Expr::Minus {
1532                type_annotation, ..
1533            }
1534            | Expr::Divide {
1535                type_annotation, ..
1536            }
1537            | Expr::Multiply {
1538                type_annotation, ..
1539            }
1540            | Expr::Cond {
1541                type_annotation, ..
1542            }
1543            | Expr::PatternMatch {
1544                type_annotation, ..
1545            }
1546            | Expr::Option {
1547                type_annotation, ..
1548            }
1549            | Expr::Result {
1550                type_annotation, ..
1551            }
1552            | Expr::Unwrap {
1553                type_annotation, ..
1554            }
1555            | Expr::Throw {
1556                type_annotation, ..
1557            }
1558            | Expr::And {
1559                type_annotation, ..
1560            }
1561            | Expr::Or {
1562                type_annotation, ..
1563            }
1564            | Expr::GetTag {
1565                type_annotation, ..
1566            }
1567            | Expr::Range {
1568                type_annotation, ..
1569            }
1570            | Expr::ListComprehension {
1571                type_annotation, ..
1572            }
1573            | Expr::ListReduce {
1574                type_annotation, ..
1575            }
1576            | Expr::InvokeMethodLazy {
1577                type_annotation, ..
1578            }
1579            | Expr::Length {
1580                type_annotation, ..
1581            }
1582            | Expr::GenerateWorkerName {
1583                type_annotation, ..
1584            }
1585            | Expr::Call {
1586                type_annotation, ..
1587            } => {
1588                *type_annotation = Some(new_type_annotation);
1589            }
1590        }
1591    }
1592
1593    pub fn with_source_span(&self, new_source_span: SourceSpan) -> Expr {
1594        let mut expr_copied = self.clone();
1595        expr_copied.with_source_span_mut(new_source_span);
1596        expr_copied
1597    }
1598
1599    pub fn with_source_span_mut(&mut self, new_source_span: SourceSpan) {
1600        match self {
1601            Expr::Identifier { source_span, .. }
1602            | Expr::Let { source_span, .. }
1603            | Expr::SelectField { source_span, .. }
1604            | Expr::SelectIndex { source_span, .. }
1605            | Expr::Sequence { source_span, .. }
1606            | Expr::Number { source_span, .. }
1607            | Expr::Record { source_span, .. }
1608            | Expr::Tuple { source_span, .. }
1609            | Expr::Literal { source_span, .. }
1610            | Expr::Flags { source_span, .. }
1611            | Expr::Boolean { source_span, .. }
1612            | Expr::Concat { source_span, .. }
1613            | Expr::ExprBlock { source_span, .. }
1614            | Expr::Not { source_span, .. }
1615            | Expr::GreaterThan { source_span, .. }
1616            | Expr::GreaterThanOrEqualTo { source_span, .. }
1617            | Expr::LessThanOrEqualTo { source_span, .. }
1618            | Expr::EqualTo { source_span, .. }
1619            | Expr::LessThan { source_span, .. }
1620            | Expr::Plus { source_span, .. }
1621            | Expr::Minus { source_span, .. }
1622            | Expr::Divide { source_span, .. }
1623            | Expr::Multiply { source_span, .. }
1624            | Expr::Cond { source_span, .. }
1625            | Expr::PatternMatch { source_span, .. }
1626            | Expr::Option { source_span, .. }
1627            | Expr::Result { source_span, .. }
1628            | Expr::Unwrap { source_span, .. }
1629            | Expr::Throw { source_span, .. }
1630            | Expr::And { source_span, .. }
1631            | Expr::Or { source_span, .. }
1632            | Expr::GetTag { source_span, .. }
1633            | Expr::Range { source_span, .. }
1634            | Expr::ListComprehension { source_span, .. }
1635            | Expr::ListReduce { source_span, .. }
1636            | Expr::InvokeMethodLazy { source_span, .. }
1637            | Expr::Length { source_span, .. }
1638            | Expr::GenerateWorkerName { source_span, .. }
1639            | Expr::Call { source_span, .. } => {
1640                *source_span = new_source_span;
1641            }
1642        }
1643    }
1644
1645    pub fn with_inferred_type(&self, new_inferred_type: InferredType) -> Expr {
1646        let mut expr_copied = self.clone();
1647        expr_copied.with_inferred_type_mut(new_inferred_type);
1648        expr_copied
1649    }
1650
1651    // `with_inferred_type` overrides the existing inferred_type and returns a new expr
1652    // This is different to `merge_inferred_type` where it tries to combine the new inferred type with the existing one.
1653    pub fn with_inferred_type_mut(&mut self, new_inferred_type: InferredType) {
1654        match self {
1655            Expr::Identifier { inferred_type, .. }
1656            | Expr::Let { inferred_type, .. }
1657            | Expr::SelectField { inferred_type, .. }
1658            | Expr::SelectIndex { inferred_type, .. }
1659            | Expr::Sequence { inferred_type, .. }
1660            | Expr::Record { inferred_type, .. }
1661            | Expr::Tuple { inferred_type, .. }
1662            | Expr::Literal { inferred_type, .. }
1663            | Expr::Number { inferred_type, .. }
1664            | Expr::Flags { inferred_type, .. }
1665            | Expr::Boolean { inferred_type, .. }
1666            | Expr::Concat { inferred_type, .. }
1667            | Expr::ExprBlock { inferred_type, .. }
1668            | Expr::Not { inferred_type, .. }
1669            | Expr::GreaterThan { inferred_type, .. }
1670            | Expr::GreaterThanOrEqualTo { inferred_type, .. }
1671            | Expr::LessThanOrEqualTo { inferred_type, .. }
1672            | Expr::EqualTo { inferred_type, .. }
1673            | Expr::LessThan { inferred_type, .. }
1674            | Expr::Plus { inferred_type, .. }
1675            | Expr::Minus { inferred_type, .. }
1676            | Expr::Divide { inferred_type, .. }
1677            | Expr::Multiply { inferred_type, .. }
1678            | Expr::Cond { inferred_type, .. }
1679            | Expr::PatternMatch { inferred_type, .. }
1680            | Expr::Option { inferred_type, .. }
1681            | Expr::Result { inferred_type, .. }
1682            | Expr::Unwrap { inferred_type, .. }
1683            | Expr::Throw { inferred_type, .. }
1684            | Expr::And { inferred_type, .. }
1685            | Expr::Or { inferred_type, .. }
1686            | Expr::GetTag { inferred_type, .. }
1687            | Expr::ListComprehension { inferred_type, .. }
1688            | Expr::ListReduce { inferred_type, .. }
1689            | Expr::InvokeMethodLazy { inferred_type, .. }
1690            | Expr::Range { inferred_type, .. }
1691            | Expr::Length { inferred_type, .. }
1692            | Expr::GenerateWorkerName { inferred_type, .. }
1693            | Expr::Call { inferred_type, .. } => {
1694                *inferred_type = new_inferred_type;
1695            }
1696        }
1697    }
1698
1699    pub fn visit_expr_nodes_lazy<'a>(&'a mut self, queue: &mut VecDeque<&'a mut Expr>) {
1700        type_inference::collect_children_mut(self, queue);
1701    }
1702
1703    pub fn number_inferred(
1704        big_decimal: BigDecimal,
1705        type_annotation: Option<TypeName>,
1706        inferred_type: InferredType,
1707    ) -> Expr {
1708        Expr::Number {
1709            number: Number { value: big_decimal },
1710            type_annotation,
1711            inferred_type,
1712            source_span: SourceSpan::default(),
1713        }
1714    }
1715
1716    pub fn number(big_decimal: BigDecimal) -> Expr {
1717        let default_type = DefaultType::from(&big_decimal);
1718        let inferred_type = InferredType::from(&default_type);
1719
1720        Expr::number_inferred(big_decimal, None, inferred_type)
1721    }
1722}
1723
1724#[derive(Debug, Hash, Clone, PartialEq, Eq, PartialOrd, Ord)]
1725pub enum Range {
1726    Range { from: Box<Expr>, to: Box<Expr> },
1727    RangeInclusive { from: Box<Expr>, to: Box<Expr> },
1728    RangeFrom { from: Box<Expr> },
1729}
1730
1731impl Range {
1732    pub fn from(&self) -> Option<&Expr> {
1733        match self {
1734            Range::Range { from, .. } => Some(from),
1735            Range::RangeInclusive { from, .. } => Some(from),
1736            Range::RangeFrom { from } => Some(from),
1737        }
1738    }
1739
1740    pub fn to(&self) -> Option<&Expr> {
1741        match self {
1742            Range::Range { to, .. } => Some(to),
1743            Range::RangeInclusive { to, .. } => Some(to),
1744            Range::RangeFrom { .. } => None,
1745        }
1746    }
1747
1748    pub fn inclusive(&self) -> bool {
1749        matches!(self, Range::RangeInclusive { .. })
1750    }
1751
1752    pub fn get_exprs_mut(&mut self) -> Vec<&mut Box<Expr>> {
1753        match self {
1754            Range::Range { from, to } => vec![from, to],
1755            Range::RangeInclusive { from, to } => vec![from, to],
1756            Range::RangeFrom { from } => vec![from],
1757        }
1758    }
1759
1760    pub fn get_exprs(&self) -> Vec<&Expr> {
1761        match self {
1762            Range::Range { from, to } => vec![from.as_ref(), to.as_ref()],
1763            Range::RangeInclusive { from, to } => vec![from.as_ref(), to.as_ref()],
1764            Range::RangeFrom { from } => vec![from.as_ref()],
1765        }
1766    }
1767}
1768
1769#[derive(Debug, Hash, Clone, PartialEq, Ord, PartialOrd)]
1770pub struct Number {
1771    pub value: BigDecimal,
1772}
1773
1774impl Eq for Number {}
1775
1776impl Number {
1777    pub fn to_val(&self, analysed_type: &WitType) -> Option<ValueAndType> {
1778        match analysed_type {
1779            WitType::F64(_) => self.value.to_f64().map(|v| v.into_value_and_type()),
1780            WitType::U64(_) => self.value.to_u64().map(|v| v.into_value_and_type()),
1781            WitType::F32(_) => self.value.to_f32().map(|v| v.into_value_and_type()),
1782            WitType::U32(_) => self.value.to_u32().map(|v| v.into_value_and_type()),
1783            WitType::S32(_) => self.value.to_i32().map(|v| v.into_value_and_type()),
1784            WitType::S64(_) => self.value.to_i64().map(|v| v.into_value_and_type()),
1785            WitType::U8(_) => self.value.to_u8().map(|v| v.into_value_and_type()),
1786            WitType::S8(_) => self.value.to_i8().map(|v| v.into_value_and_type()),
1787            WitType::U16(_) => self.value.to_u16().map(|v| v.into_value_and_type()),
1788            WitType::S16(_) => self.value.to_i16().map(|v| v.into_value_and_type()),
1789            _ => None,
1790        }
1791    }
1792}
1793
1794impl Display for Number {
1795    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1796        write!(f, "{}", self.value)
1797    }
1798}
1799
1800#[derive(Debug, Hash, Clone, PartialEq, Eq, Ord, PartialOrd)]
1801pub struct MatchArm {
1802    pub arm_pattern: ArmPattern,
1803    pub arm_resolution_expr: Box<Expr>,
1804}
1805
1806impl MatchArm {
1807    pub fn new(arm_pattern: ArmPattern, arm_resolution: Expr) -> MatchArm {
1808        MatchArm {
1809            arm_pattern,
1810            arm_resolution_expr: Box::new(arm_resolution),
1811        }
1812    }
1813}
1814
1815#[derive(Debug, Hash, Clone, PartialEq, Eq, Ord, PartialOrd)]
1816pub enum ArmPattern {
1817    WildCard,
1818    As(String, Box<ArmPattern>),
1819    Constructor(String, Vec<ArmPattern>),
1820    TupleConstructor(Vec<ArmPattern>),
1821    RecordConstructor(Vec<(String, ArmPattern)>),
1822    ListConstructor(Vec<ArmPattern>),
1823    Literal(Box<Expr>),
1824}
1825
1826impl ArmPattern {
1827    pub fn is_wildcard(&self) -> bool {
1828        matches!(self, ArmPattern::WildCard)
1829    }
1830
1831    pub fn is_literal_identifier(&self) -> bool {
1832        matches!(self, ArmPattern::Literal(expr) if expr.is_identifier())
1833    }
1834
1835    pub fn constructor(name: &str, patterns: Vec<ArmPattern>) -> ArmPattern {
1836        ArmPattern::Constructor(name.to_string(), patterns)
1837    }
1838
1839    pub fn literal(expr: Expr) -> ArmPattern {
1840        ArmPattern::Literal(Box::new(expr))
1841    }
1842
1843    pub fn get_expr_literals_mut(&mut self) -> Vec<&mut Box<Expr>> {
1844        match self {
1845            ArmPattern::Literal(expr) => vec![expr],
1846            ArmPattern::As(_, pattern) => pattern.get_expr_literals_mut(),
1847            ArmPattern::Constructor(_, patterns) => {
1848                let mut result = vec![];
1849                for pattern in patterns {
1850                    result.extend(pattern.get_expr_literals_mut());
1851                }
1852                result
1853            }
1854            ArmPattern::TupleConstructor(patterns) => {
1855                let mut result = vec![];
1856                for pattern in patterns {
1857                    result.extend(pattern.get_expr_literals_mut());
1858                }
1859                result
1860            }
1861            ArmPattern::RecordConstructor(patterns) => {
1862                let mut result = vec![];
1863                for (_, pattern) in patterns {
1864                    result.extend(pattern.get_expr_literals_mut());
1865                }
1866                result
1867            }
1868            ArmPattern::ListConstructor(patterns) => {
1869                let mut result = vec![];
1870                for pattern in patterns {
1871                    result.extend(pattern.get_expr_literals_mut());
1872                }
1873                result
1874            }
1875            ArmPattern::WildCard => vec![],
1876        }
1877    }
1878
1879    pub fn get_expr_literals(&self) -> Vec<&Expr> {
1880        match self {
1881            ArmPattern::Literal(expr) => vec![expr.as_ref()],
1882            ArmPattern::As(_, pattern) => pattern.get_expr_literals(),
1883            ArmPattern::Constructor(_, patterns) => {
1884                let mut result = vec![];
1885                for pattern in patterns {
1886                    result.extend(pattern.get_expr_literals());
1887                }
1888                result
1889            }
1890            ArmPattern::TupleConstructor(patterns) => {
1891                let mut result = vec![];
1892                for pattern in patterns {
1893                    result.extend(pattern.get_expr_literals());
1894                }
1895                result
1896            }
1897            ArmPattern::RecordConstructor(patterns) => {
1898                let mut result = vec![];
1899                for (_, pattern) in patterns {
1900                    result.extend(pattern.get_expr_literals());
1901                }
1902                result
1903            }
1904            ArmPattern::ListConstructor(patterns) => {
1905                let mut result = vec![];
1906                for pattern in patterns {
1907                    result.extend(pattern.get_expr_literals());
1908                }
1909                result
1910            }
1911            ArmPattern::WildCard => vec![],
1912        }
1913    }
1914    // Helper to construct ok(v). Cannot be used if there is nested constructors such as ok(some(v)))
1915    pub fn ok(binding_variable: &str) -> ArmPattern {
1916        ArmPattern::Literal(Box::new(Expr::Result {
1917            expr: Ok(Box::new(Expr::Identifier {
1918                variable_id: VariableId::global(binding_variable.to_string()),
1919                type_annotation: None,
1920                inferred_type: InferredType::unknown(),
1921                source_span: SourceSpan::default(),
1922            })),
1923            type_annotation: None,
1924            inferred_type: InferredType::result(
1925                Some(InferredType::unknown()),
1926                Some(InferredType::unknown()),
1927            ),
1928            source_span: SourceSpan::default(),
1929        }))
1930    }
1931
1932    // Helper to construct err(v). Cannot be used if there is nested constructors such as err(some(v)))
1933    pub fn err(binding_variable: &str) -> ArmPattern {
1934        ArmPattern::Literal(Box::new(Expr::Result {
1935            expr: Err(Box::new(Expr::Identifier {
1936                variable_id: VariableId::global(binding_variable.to_string()),
1937                type_annotation: None,
1938                inferred_type: InferredType::unknown(),
1939                source_span: SourceSpan::default(),
1940            })),
1941            type_annotation: None,
1942            inferred_type: InferredType::result(
1943                Some(InferredType::unknown()),
1944                Some(InferredType::unknown()),
1945            ),
1946            source_span: SourceSpan::default(),
1947        }))
1948    }
1949
1950    // Helper to construct some(v). Cannot be used if there is nested constructors such as some(ok(v)))
1951    pub fn some(binding_variable: &str) -> ArmPattern {
1952        ArmPattern::Literal(Box::new(Expr::Option {
1953            expr: Some(Box::new(Expr::Identifier {
1954                variable_id: VariableId::local_with_no_id(binding_variable),
1955                type_annotation: None,
1956                inferred_type: InferredType::unknown(),
1957                source_span: SourceSpan::default(),
1958            })),
1959            type_annotation: None,
1960            inferred_type: InferredType::unknown(),
1961            source_span: SourceSpan::default(),
1962        }))
1963    }
1964
1965    pub fn none() -> ArmPattern {
1966        ArmPattern::Literal(Box::new(Expr::Option {
1967            expr: None,
1968            type_annotation: None,
1969            inferred_type: InferredType::unknown(),
1970            source_span: SourceSpan::default(),
1971        }))
1972    }
1973
1974    pub fn identifier(binding_variable: &str) -> ArmPattern {
1975        ArmPattern::Literal(Box::new(Expr::Identifier {
1976            variable_id: VariableId::global(binding_variable.to_string()),
1977            type_annotation: None,
1978            inferred_type: InferredType::unknown(),
1979            source_span: SourceSpan::default(),
1980        }))
1981    }
1982    pub fn custom_constructor(name: &str, args: Vec<ArmPattern>) -> ArmPattern {
1983        ArmPattern::Constructor(name.to_string(), args)
1984    }
1985}
1986
1987impl Display for Expr {
1988    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1989        write!(f, "{}", text::to_string(self).unwrap())
1990    }
1991}
1992
1993impl Display for ArmPattern {
1994    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1995        write!(f, "{}", text::to_string_arm_pattern(self).unwrap())
1996    }
1997}
1998
1999impl<'de> Deserialize<'de> for Expr {
2000    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
2001    where
2002        D: serde::Deserializer<'de>,
2003    {
2004        let value = Value::deserialize(deserializer)?;
2005        match value {
2006            Value::String(expr_string) => match from_string(expr_string.as_str()) {
2007                Ok(expr) => Ok(expr),
2008                Err(message) => Err(serde::de::Error::custom(message.to_string())),
2009            },
2010
2011            e => Err(serde::de::Error::custom(format!(
2012                "Failed to deserialize expression {e}"
2013            ))),
2014        }
2015    }
2016}
2017
2018impl Serialize for Expr {
2019    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2020    where
2021        S: Serializer,
2022    {
2023        match text::to_string(self) {
2024            Ok(value) => Value::serialize(&Value::String(value), serializer),
2025            Err(error) => Err(serde::ser::Error::custom(error.to_string())),
2026        }
2027    }
2028}
2029
2030fn find_expr(expr: &mut Expr, source_span: &SourceSpan) -> Option<Expr> {
2031    let mut expr = expr.clone();
2032    let mut found = None;
2033
2034    type_inference::visit_post_order_rev_mut(&mut expr, &mut |current| {
2035        if found.is_none() {
2036            let span = current.source_span();
2037            if source_span.eq(&span) {
2038                found = Some(current.clone());
2039            }
2040        }
2041    });
2042
2043    found
2044}