rune/hir/
hir.rs

1use core::fmt;
2use core::num::NonZeroUsize;
3
4use crate as rune;
5use crate::alloc::prelude::*;
6use crate::ast::{self, Span, Spanned};
7use crate::compile::{ItemId, ModId};
8use crate::parse::NonZeroId;
9use crate::runtime::{format, Type, TypeCheck};
10use crate::Hash;
11
12#[derive(TryClone, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
13#[try_clone(copy)]
14#[repr(transparent)]
15pub(crate) struct Variable(#[try_clone(copy)] pub(crate) NonZeroId);
16
17impl fmt::Display for Variable {
18    #[inline]
19    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20        self.0.fmt(f)
21    }
22}
23
24impl fmt::Debug for Variable {
25    #[inline]
26    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27        self.0.fmt(f)
28    }
29}
30
31/// A captured variable.
32#[derive(TryClone, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
33#[try_clone(copy)]
34pub(crate) enum Name<'hir> {
35    /// Capture of the `self` value.
36    SelfValue,
37    /// Capture of a named variable.
38    Str(&'hir str),
39}
40
41impl fmt::Display for Name<'_> {
42    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43        match self {
44            Name::SelfValue => write!(f, "self"),
45            Name::Str(name) => name.fmt(f),
46        }
47    }
48}
49
50impl fmt::Debug for Name<'_> {
51    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52        match self {
53            Name::SelfValue => write!(f, "self"),
54            Name::Str(name) => name.fmt(f),
55        }
56    }
57}
58
59/// A pattern.
60#[derive(Debug, TryClone, Clone, Copy, Spanned)]
61#[try_clone(copy)]
62#[non_exhaustive]
63pub(crate) struct Pat<'hir> {
64    /// The span of the pattern.
65    #[rune(span)]
66    pub(crate) span: Span,
67    /// The kind of the pattern.
68    pub(crate) kind: PatKind<'hir>,
69}
70
71/// A pattern with collected bindings.
72#[derive(Debug, TryClone, Clone, Copy, Spanned)]
73#[try_clone(copy)]
74#[non_exhaustive]
75pub(crate) struct PatBinding<'hir> {
76    /// The kind of the pattern.
77    #[rune(span)]
78    pub(crate) pat: Pat<'hir>,
79    /// Names that will be defined by this pattern.
80    pub(crate) names: &'hir [Variable],
81}
82
83#[derive(Debug, TryClone, Clone, Copy)]
84#[try_clone(copy)]
85pub(crate) enum PatPathKind<'hir> {
86    Kind(&'hir PatSequenceKind),
87    Ident(Variable),
88}
89
90/// The kind of a [Pat].
91#[derive(Debug, TryClone, Clone, Copy)]
92#[try_clone(copy)]
93pub(crate) enum PatKind<'hir> {
94    /// An ignored binding.
95    Ignore,
96    /// A path pattern.
97    Path(&'hir PatPathKind<'hir>),
98    /// A literal pattern. This is represented as an expression.
99    Lit(&'hir Expr<'hir>),
100    /// A tuple pattern.
101    Sequence(&'hir PatSequence<'hir>),
102    /// An object pattern.
103    Object(&'hir PatObject<'hir>),
104}
105
106#[derive(Debug, TryClone, Clone, Copy)]
107#[try_clone(copy)]
108pub(crate) enum PatSequenceKind {
109    Type {
110        hash: Hash,
111    },
112    BuiltInVariant {
113        type_check: TypeCheck,
114    },
115    Variant {
116        enum_hash: Hash,
117        variant_hash: Hash,
118    },
119    Anonymous {
120        type_check: TypeCheck,
121        count: usize,
122        is_open: bool,
123    },
124}
125
126/// Items pattern matching.
127#[derive(Debug, TryClone, Clone, Copy)]
128#[try_clone(copy)]
129#[non_exhaustive]
130pub(crate) struct PatSequence<'hir> {
131    /// The kind of pattern items.
132    pub(crate) kind: PatSequenceKind,
133    /// The items in the tuple.
134    pub(crate) items: &'hir [Pat<'hir>],
135}
136
137/// Object pattern matching.
138#[derive(Debug, TryClone, Clone, Copy)]
139#[try_clone(copy)]
140#[non_exhaustive]
141pub(crate) struct PatObject<'hir> {
142    /// The kind of pattern items.
143    pub(crate) kind: PatSequenceKind,
144    /// Bindings associated with the pattern.
145    pub(crate) bindings: &'hir [Binding<'hir>],
146}
147
148#[derive(Debug, TryClone, Clone, Copy)]
149#[try_clone(copy)]
150#[non_exhaustive]
151pub(crate) enum Binding<'hir> {
152    Binding(Span, &'hir str, &'hir Pat<'hir>),
153    Ident(Span, &'hir str, Variable),
154}
155
156impl Spanned for Binding<'_> {
157    fn span(&self) -> Span {
158        match self {
159            Binding::Binding(span, _, _) => *span,
160            Binding::Ident(span, _, _) => *span,
161        }
162    }
163}
164
165impl<'hir> Binding<'hir> {
166    pub(crate) fn key(&self) -> &'hir str {
167        match *self {
168            Self::Binding(_, key, _) => key,
169            Self::Ident(_, key, _) => key,
170        }
171    }
172}
173
174/// An expression.
175#[derive(Debug, TryClone, Clone, Copy, Spanned)]
176#[try_clone(copy)]
177#[non_exhaustive]
178pub(crate) struct Expr<'hir> {
179    /// Span of the expression.
180    #[rune(span)]
181    pub(crate) span: Span,
182    /// The kind of the expression.
183    pub(crate) kind: ExprKind<'hir>,
184}
185
186/// The kind of a number.
187#[derive(Debug, TryClone, Clone, Copy)]
188#[try_clone(copy)]
189#[non_exhaustive]
190pub(crate) enum Lit<'hir> {
191    Bool(bool),
192    Unsigned(u64),
193    Signed(i64),
194    Float(f64),
195    Char(char),
196    Str(&'hir str),
197    ByteStr(&'hir [u8]),
198}
199
200/// The kind of an [Expr].
201#[derive(Debug, TryClone, Clone, Copy)]
202#[try_clone(copy)]
203#[non_exhaustive]
204pub(crate) enum ExprKind<'hir> {
205    Variable(Variable),
206    Type(Type),
207    Fn(Hash),
208    Path,
209    Assign(&'hir ExprAssign<'hir>),
210    Loop(&'hir ExprLoop<'hir>),
211    For(&'hir ExprFor<'hir>),
212    Let(&'hir ExprLet<'hir>),
213    If(&'hir Conditional<'hir>),
214    Match(&'hir ExprMatch<'hir>),
215    Call(&'hir ExprCall<'hir>),
216    FieldAccess(&'hir ExprFieldAccess<'hir>),
217    Binary(&'hir ExprBinary<'hir>),
218    Unary(&'hir ExprUnary<'hir>),
219    Index(&'hir ExprIndex<'hir>),
220    AsyncBlock(&'hir ExprAsyncBlock<'hir>),
221    Block(&'hir Block<'hir>),
222    Break(&'hir ExprBreak<'hir>),
223    Continue(&'hir ExprContinue<'hir>),
224    Yield(Option<&'hir Expr<'hir>>),
225    Return(Option<&'hir Expr<'hir>>),
226    Await(&'hir Expr<'hir>),
227    Try(&'hir Expr<'hir>),
228    Select(&'hir ExprSelect<'hir>),
229    CallClosure(&'hir ExprCallClosure<'hir>),
230    Lit(Lit<'hir>),
231    Object(&'hir ExprObject<'hir>),
232    Tuple(&'hir ExprSeq<'hir>),
233    Vec(&'hir ExprSeq<'hir>),
234    Range(&'hir ExprRange<'hir>),
235    Group(&'hir Expr<'hir>),
236    Template(&'hir BuiltInTemplate<'hir>),
237    Format(&'hir BuiltInFormat<'hir>),
238    Const(Hash),
239}
240
241/// An internally resolved template.
242#[derive(Debug, TryClone, Clone, Copy, Spanned)]
243#[try_clone(copy)]
244pub(crate) struct BuiltInTemplate<'hir> {
245    /// The span of the built-in template.
246    #[rune(span)]
247    pub(crate) span: Span,
248    /// Indicate if template originated from literal.
249    pub(crate) from_literal: bool,
250    /// Expressions being concatenated as a template.
251    pub(crate) exprs: &'hir [Expr<'hir>],
252}
253
254/// The specification for a format spec.
255#[derive(Default, Debug, TryClone, Clone, Copy)]
256#[try_clone(copy)]
257pub(crate) struct BuiltInFormatSpec {
258    /// The fill character to use.
259    pub(crate) fill: Option<char>,
260    /// Alignment specification.
261    pub(crate) align: Option<format::Alignment>,
262    /// Width to fill.
263    pub(crate) width: Option<NonZeroUsize>,
264    /// Precision to fill.
265    pub(crate) precision: Option<NonZeroUsize>,
266    /// A specification of flags.
267    pub(crate) flags: Option<format::Flags>,
268    /// The format specification type.
269    pub(crate) format_type: Option<format::Type>,
270}
271
272/// An internal format specification.
273#[derive(Debug, TryClone, Clone, Copy, Spanned)]
274#[try_clone(copy)]
275pub(crate) struct BuiltInFormat<'hir> {
276    /// The format spec.
277    pub(crate) spec: BuiltInFormatSpec,
278    /// The value being formatted.
279    #[rune(span)]
280    pub(crate) value: &'hir Expr<'hir>,
281}
282
283/// An assign expression `a = b`.
284#[derive(Debug, TryClone, Clone, Copy)]
285#[try_clone(copy)]
286#[non_exhaustive]
287pub(crate) struct ExprAssign<'hir> {
288    /// The expression being assigned to.
289    pub(crate) lhs: Expr<'hir>,
290    /// The value.
291    pub(crate) rhs: Expr<'hir>,
292}
293
294/// A `loop` expression: `loop { ... }`.
295#[derive(Debug, TryClone, Clone, Copy)]
296#[try_clone(copy)]
297#[non_exhaustive]
298pub(crate) struct ExprLoop<'hir> {
299    /// A label.
300    pub(crate) label: Option<&'hir str>,
301    /// A condition to execute the loop, if a condition is necessary.
302    pub(crate) condition: Option<&'hir Condition<'hir>>,
303    /// The body of the loop.
304    pub(crate) body: Block<'hir>,
305    /// Variables that have been defined by the loop header.
306    #[allow(unused)]
307    pub(crate) drop: &'hir [Variable],
308}
309
310/// A `for` loop over an iterator: `for i in [1, 2, 3] {}`.
311#[derive(Debug, TryClone, Clone, Copy)]
312#[try_clone(copy)]
313#[non_exhaustive]
314pub(crate) struct ExprFor<'hir> {
315    /// The label of the loop.
316    pub(crate) label: Option<&'hir str>,
317    /// The pattern binding to use.
318    /// Non-trivial pattern bindings will panic if the value doesn't match.
319    pub(crate) binding: PatBinding<'hir>,
320    /// Expression producing the iterator.
321    pub(crate) iter: Expr<'hir>,
322    /// The body of the loop.
323    pub(crate) body: Block<'hir>,
324    /// Variables that have been defined by the loop header.
325    #[allow(unused)]
326    pub(crate) drop: &'hir [Variable],
327}
328
329/// A let expression `let <name> = <expr>`
330#[derive(Debug, TryClone, Clone, Copy, Spanned)]
331#[try_clone(copy)]
332#[non_exhaustive]
333pub(crate) struct ExprLet<'hir> {
334    /// The name of the binding.
335    pub(crate) pat: PatBinding<'hir>,
336    /// The expression the binding is assigned to.
337    pub(crate) expr: Expr<'hir>,
338}
339
340/// A sequence of conditional branches.
341///
342/// This is lower from if statements, such as:
343///
344/// ```text
345/// if cond { true } else { false }
346/// ```
347#[derive(Debug, TryClone, Clone, Copy)]
348#[try_clone(copy)]
349#[non_exhaustive]
350pub(crate) struct Conditional<'hir> {
351    /// Conditional branches.
352    pub(crate) branches: &'hir [ConditionalBranch<'hir>],
353    /// Fallback branches.
354    pub(crate) fallback: Option<&'hir Block<'hir>>,
355}
356
357/// An else branch of an if expression.
358#[derive(Debug, TryClone, Clone, Copy, Spanned)]
359#[try_clone(copy)]
360#[non_exhaustive]
361pub(crate) struct ConditionalBranch<'hir> {
362    /// Span of the expression.
363    #[rune(span)]
364    pub(crate) span: Span,
365    /// The condition for the branch. Empty condition means that this is the
366    /// fallback branch.
367    pub(crate) condition: &'hir Condition<'hir>,
368    /// The body of the else statement.
369    pub(crate) block: Block<'hir>,
370    /// Variables that have been defined by the conditional header.
371    #[allow(unused)]
372    pub(crate) drop: &'hir [Variable],
373}
374
375/// A match expression.
376#[derive(Debug, TryClone, Clone, Copy)]
377#[try_clone(copy)]
378#[non_exhaustive]
379pub(crate) struct ExprMatch<'hir> {
380    /// The expression who's result we match over.
381    pub(crate) expr: &'hir Expr<'hir>,
382    /// Branches.
383    pub(crate) branches: &'hir [ExprMatchBranch<'hir>],
384}
385
386/// A match branch.
387#[derive(Debug, TryClone, Clone, Copy, Spanned)]
388#[try_clone(copy)]
389#[non_exhaustive]
390pub(crate) struct ExprMatchBranch<'hir> {
391    /// Span of the expression.
392    #[rune(span)]
393    pub(crate) span: Span,
394    /// The pattern to match.
395    pub(crate) pat: PatBinding<'hir>,
396    /// The branch condition.
397    pub(crate) condition: Option<&'hir Expr<'hir>>,
398    /// The body of the match.
399    pub(crate) body: Expr<'hir>,
400    /// Variables that have been defined by this match branch, which needs to be
401    /// dropped.
402    #[allow(unused)]
403    pub(crate) drop: &'hir [Variable],
404}
405
406#[derive(Debug, TryClone, Clone, Copy)]
407#[try_clone(copy)]
408pub(crate) enum Call<'hir> {
409    Var {
410        /// The name of the variable being called.
411        name: Variable,
412    },
413    Associated {
414        /// The target expression being called.
415        target: &'hir Expr<'hir>,
416        /// Hash of the fn being called.
417        hash: Hash,
418    },
419    Meta {
420        /// Hash being called.
421        hash: Hash,
422    },
423    /// An expression being called.
424    Expr { expr: &'hir Expr<'hir> },
425    /// A constant function call.
426    ConstFn {
427        /// The module the constant function is being called from.
428        from_module: ModId,
429        /// The item the constant function is being called from.
430        from_item: ItemId,
431        /// The identifier of the constant function.
432        id: ItemId,
433    },
434}
435
436/// A function call `<expr>(<args>)`.
437#[derive(Debug, TryClone, Clone, Copy)]
438#[try_clone(copy)]
439#[non_exhaustive]
440pub(crate) struct ExprCall<'hir> {
441    /// The call being performed.
442    pub(crate) call: Call<'hir>,
443    /// The arguments of the function call.
444    pub(crate) args: &'hir [Expr<'hir>],
445}
446
447/// A field access `<expr>.<field>`.
448#[derive(Debug, TryClone, Clone, Copy)]
449#[try_clone(copy)]
450#[non_exhaustive]
451pub(crate) struct ExprFieldAccess<'hir> {
452    /// The expr where the field is being accessed.
453    pub(crate) expr: Expr<'hir>,
454    /// The field being accessed.
455    pub(crate) expr_field: ExprField<'hir>,
456}
457
458/// The field being accessed.
459#[derive(Debug, TryClone, Clone, Copy)]
460#[try_clone(copy)]
461#[non_exhaustive]
462pub(crate) enum ExprField<'hir> {
463    /// A tuple index.
464    ///
465    /// ```text
466    /// 1
467    /// ```
468    Index(usize),
469    /// A field identifier.
470    ///
471    /// ```text
472    /// field
473    /// ```
474    Ident(&'hir str),
475    /// A field identifier immediately followed by generic expressions.
476    ///
477    /// ```text
478    /// field<1, string>
479    /// ```
480    IdentGenerics(&'hir str, Hash),
481}
482
483/// A binary expression.
484#[derive(Debug, TryClone, Clone, Copy)]
485#[try_clone(copy)]
486#[non_exhaustive]
487pub(crate) struct ExprBinary<'hir> {
488    /// The left-hand side of a binary operation.
489    pub(crate) lhs: Expr<'hir>,
490    /// The operator.
491    pub(crate) op: ast::BinOp,
492    /// The right-hand side of a binary operation.
493    pub(crate) rhs: Expr<'hir>,
494}
495
496/// A unary expression.
497#[derive(Debug, TryClone, Clone, Copy)]
498#[try_clone(copy)]
499#[non_exhaustive]
500pub(crate) struct ExprUnary<'hir> {
501    /// The operation to apply.
502    pub(crate) op: ast::UnOp,
503    /// The expression of the operation.
504    pub(crate) expr: Expr<'hir>,
505}
506
507/// An index get operation `<t>[<index>]`.
508#[derive(Debug, TryClone, Clone, Copy)]
509#[try_clone(copy)]
510#[non_exhaustive]
511pub(crate) struct ExprIndex<'hir> {
512    /// The target of the index set.
513    pub(crate) target: Expr<'hir>,
514    /// The indexing expression.
515    pub(crate) index: Expr<'hir>,
516}
517
518/// An async block being called.
519#[derive(Debug, TryClone, Clone, Copy)]
520#[try_clone(copy)]
521#[non_exhaustive]
522pub(crate) struct ExprAsyncBlock<'hir> {
523    pub(crate) hash: Hash,
524    pub(crate) do_move: bool,
525    pub(crate) captures: &'hir [Variable],
526}
527
528#[derive(Debug, TryClone, Clone, Copy)]
529#[try_clone(copy)]
530pub(crate) struct ExprBreak<'hir> {
531    /// Label being continued.
532    pub(crate) label: Option<&'hir str>,
533    /// Value being broken with.
534    pub(crate) expr: Option<&'hir Expr<'hir>>,
535    /// Variables that goes out of scope.
536    #[allow(unused)]
537    pub(crate) drop: &'hir [Variable],
538}
539
540#[derive(Debug, TryClone, Clone, Copy)]
541#[try_clone(copy)]
542pub(crate) struct ExprContinue<'hir> {
543    /// Label being continued.
544    pub(crate) label: Option<&'hir str>,
545    /// Variables that goes out of scope.
546    #[allow(unused)]
547    pub(crate) drop: &'hir [Variable],
548}
549
550/// A `select` expression that selects over a collection of futures.
551#[derive(Debug, TryClone, Clone, Copy)]
552#[try_clone(copy)]
553#[non_exhaustive]
554pub(crate) struct ExprSelect<'hir> {
555    /// The expressions associated with non-default branches.
556    pub(crate) exprs: &'hir [Expr<'hir>],
557    /// The branches of the select.
558    pub(crate) branches: &'hir [ExprSelectBranch<'hir>],
559    /// The expresssion associated with the default branch.
560    pub(crate) default: Option<&'hir Expr<'hir>>,
561}
562
563/// A single selection branch.
564#[derive(Debug, TryClone, Clone, Copy)]
565#[try_clone(copy)]
566#[non_exhaustive]
567pub(crate) struct ExprSelectBranch<'hir> {
568    /// The identifier to bind the result to.
569    pub(crate) pat: PatBinding<'hir>,
570    /// The body of the expression.
571    pub(crate) body: Expr<'hir>,
572    /// Variables that need to be dropped by the end of this block.
573    #[allow(unused)]
574    pub(crate) drop: &'hir [Variable],
575}
576
577/// Calling a closure.
578#[derive(Debug, TryClone, Clone, Copy)]
579#[try_clone(copy)]
580#[non_exhaustive]
581pub(crate) struct ExprCallClosure<'hir> {
582    pub(crate) do_move: bool,
583    pub(crate) hash: Hash,
584    pub(crate) captures: &'hir [Variable],
585}
586
587/// A closure expression.
588#[derive(Debug, TryClone, Clone, Copy, Spanned)]
589#[try_clone(copy)]
590#[non_exhaustive]
591pub(crate) struct ExprClosure<'hir> {
592    /// Arguments to the closure.
593    pub(crate) args: &'hir [FnArg<'hir>],
594    /// The body of the closure.
595    #[rune(span)]
596    pub(crate) body: &'hir Expr<'hir>,
597    /// Captures in the closure.
598    pub(crate) captures: &'hir [Variable],
599}
600
601#[derive(Debug, TryClone, Clone, Copy)]
602#[try_clone(copy)]
603pub(crate) enum ExprObjectKind {
604    Struct { hash: Hash },
605    ExternalType { hash: Hash, args: usize },
606    Anonymous,
607}
608
609/// An object expression.
610#[derive(Debug, TryClone, Clone, Copy)]
611#[try_clone(copy)]
612#[non_exhaustive]
613pub(crate) struct ExprObject<'hir> {
614    /// The kind of an object being created.
615    pub(crate) kind: ExprObjectKind,
616    /// Assignments in the object.
617    pub(crate) assignments: &'hir [FieldAssign<'hir>],
618}
619
620/// A single field assignment in an object expression.
621#[derive(Debug, TryClone, Clone, Copy)]
622#[try_clone(copy)]
623#[non_exhaustive]
624pub(crate) struct FieldAssign<'hir> {
625    /// The key of the field.
626    pub(crate) key: (Span, &'hir str),
627    /// The assigned expression of the field.
628    pub(crate) assign: Expr<'hir>,
629    /// The position of the field in its containing type declaration.
630    pub(crate) position: Option<usize>,
631}
632
633/// A literal vector.
634#[derive(Debug, TryClone, Clone, Copy)]
635#[try_clone(copy)]
636#[non_exhaustive]
637pub(crate) struct ExprSeq<'hir> {
638    /// Items in the vector.
639    pub(crate) items: &'hir [Expr<'hir>],
640}
641
642/// A range expression such as `a .. b` or `a ..= b`.
643#[derive(Debug, TryClone, Clone, Copy)]
644#[try_clone(copy)]
645#[non_exhaustive]
646pub(crate) enum ExprRange<'hir> {
647    /// `start..`.
648    RangeFrom { start: Expr<'hir> },
649    /// `..`.
650    RangeFull,
651    /// `start..=end`.
652    RangeInclusive { start: Expr<'hir>, end: Expr<'hir> },
653    /// `..=end`.
654    RangeToInclusive { end: Expr<'hir> },
655    /// `..end`.
656    RangeTo { end: Expr<'hir> },
657    /// `start..end`.
658    Range { start: Expr<'hir>, end: Expr<'hir> },
659}
660
661/// The condition in an if statement.
662#[derive(Debug, TryClone, Clone, Copy, Spanned)]
663#[try_clone(copy)]
664#[non_exhaustive]
665pub(crate) enum Condition<'hir> {
666    /// A regular expression.
667    Expr(&'hir Expr<'hir>),
668    /// A pattern match.
669    ExprLet(&'hir ExprLet<'hir>),
670}
671
672impl Condition<'_> {
673    /// The number of variables which would be defined by this condition.
674    pub(crate) fn count(&self) -> Option<usize> {
675        match self {
676            Condition::Expr(_) => None,
677            Condition::ExprLet(hir) => Some(hir.pat.names.len()),
678        }
679    }
680}
681
682#[derive(Debug, TryClone, Clone, Copy, Spanned)]
683#[try_clone(copy)]
684#[non_exhaustive]
685pub(crate) struct ItemFn<'hir> {
686    /// The span of the function.
687    #[rune(span)]
688    pub(crate) span: Span,
689    /// The arguments of the function.
690    pub(crate) args: &'hir [FnArg<'hir>],
691    /// The body of the function.
692    pub(crate) body: Block<'hir>,
693}
694
695/// A single argument to a function.
696#[derive(Debug, TryClone, Clone, Copy, Spanned)]
697#[try_clone(copy)]
698#[non_exhaustive]
699pub(crate) enum FnArg<'hir> {
700    /// The `self` parameter.
701    SelfValue(#[rune(span)] Span, Variable),
702    /// Function argument is a pattern binding.
703    Pat(&'hir PatBinding<'hir>),
704}
705
706/// A block of statements.
707#[derive(Debug, TryClone, Clone, Copy, Spanned)]
708#[try_clone(copy)]
709#[non_exhaustive]
710pub(crate) struct Block<'hir> {
711    /// The span of the block.
712    #[rune(span)]
713    pub(crate) span: Span,
714    /// A label for the block.
715    pub(crate) label: Option<&'hir str>,
716    /// Statements in the block.
717    pub(crate) statements: &'hir [Stmt<'hir>],
718    /// Default value produced by the block.
719    pub(crate) value: Option<&'hir Expr<'hir>>,
720    /// Variables that need to be dropped by the end of this block.
721    #[allow(unused)]
722    pub(crate) drop: &'hir [Variable],
723}
724
725#[derive(Debug, TryClone, Clone, Copy, Spanned)]
726#[try_clone(copy)]
727pub(crate) struct AsyncBlock<'hir> {
728    #[rune(span)]
729    pub(crate) block: &'hir Block<'hir>,
730    pub(crate) captures: &'hir [Variable],
731}
732
733/// A statement within a block.
734#[derive(Debug, TryClone, Clone, Copy, Spanned)]
735#[try_clone(copy)]
736#[non_exhaustive]
737pub(crate) enum Stmt<'hir> {
738    /// A local declaration.
739    Local(&'hir Local<'hir>),
740    /// An expression.
741    Expr(&'hir Expr<'hir>),
742}
743
744/// A local variable declaration `let <pattern> = <expr>;`
745#[derive(Debug, TryClone, Clone, Copy, Spanned)]
746#[try_clone(copy)]
747#[non_exhaustive]
748pub(crate) struct Local<'hir> {
749    /// The span of the local declaration.
750    #[rune(span)]
751    pub(crate) span: Span,
752    /// The name of the binding.
753    pub(crate) pat: PatBinding<'hir>,
754    /// The expression the binding is assigned to.
755    pub(crate) expr: Expr<'hir>,
756}