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#[derive(TryClone, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
33#[try_clone(copy)]
34pub(crate) enum Name<'hir> {
35 SelfValue,
37 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#[derive(Debug, TryClone, Clone, Copy, Spanned)]
61#[try_clone(copy)]
62#[non_exhaustive]
63pub(crate) struct Pat<'hir> {
64 #[rune(span)]
66 pub(crate) span: Span,
67 pub(crate) kind: PatKind<'hir>,
69}
70
71#[derive(Debug, TryClone, Clone, Copy, Spanned)]
73#[try_clone(copy)]
74#[non_exhaustive]
75pub(crate) struct PatBinding<'hir> {
76 #[rune(span)]
78 pub(crate) pat: Pat<'hir>,
79 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#[derive(Debug, TryClone, Clone, Copy)]
92#[try_clone(copy)]
93pub(crate) enum PatKind<'hir> {
94 Ignore,
96 Path(&'hir PatPathKind<'hir>),
98 Lit(&'hir Expr<'hir>),
100 Sequence(&'hir PatSequence<'hir>),
102 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#[derive(Debug, TryClone, Clone, Copy)]
128#[try_clone(copy)]
129#[non_exhaustive]
130pub(crate) struct PatSequence<'hir> {
131 pub(crate) kind: PatSequenceKind,
133 pub(crate) items: &'hir [Pat<'hir>],
135}
136
137#[derive(Debug, TryClone, Clone, Copy)]
139#[try_clone(copy)]
140#[non_exhaustive]
141pub(crate) struct PatObject<'hir> {
142 pub(crate) kind: PatSequenceKind,
144 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#[derive(Debug, TryClone, Clone, Copy, Spanned)]
176#[try_clone(copy)]
177#[non_exhaustive]
178pub(crate) struct Expr<'hir> {
179 #[rune(span)]
181 pub(crate) span: Span,
182 pub(crate) kind: ExprKind<'hir>,
184}
185
186#[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#[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#[derive(Debug, TryClone, Clone, Copy, Spanned)]
243#[try_clone(copy)]
244pub(crate) struct BuiltInTemplate<'hir> {
245 #[rune(span)]
247 pub(crate) span: Span,
248 pub(crate) from_literal: bool,
250 pub(crate) exprs: &'hir [Expr<'hir>],
252}
253
254#[derive(Default, Debug, TryClone, Clone, Copy)]
256#[try_clone(copy)]
257pub(crate) struct BuiltInFormatSpec {
258 pub(crate) fill: Option<char>,
260 pub(crate) align: Option<format::Alignment>,
262 pub(crate) width: Option<NonZeroUsize>,
264 pub(crate) precision: Option<NonZeroUsize>,
266 pub(crate) flags: Option<format::Flags>,
268 pub(crate) format_type: Option<format::Type>,
270}
271
272#[derive(Debug, TryClone, Clone, Copy, Spanned)]
274#[try_clone(copy)]
275pub(crate) struct BuiltInFormat<'hir> {
276 pub(crate) spec: BuiltInFormatSpec,
278 #[rune(span)]
280 pub(crate) value: &'hir Expr<'hir>,
281}
282
283#[derive(Debug, TryClone, Clone, Copy)]
285#[try_clone(copy)]
286#[non_exhaustive]
287pub(crate) struct ExprAssign<'hir> {
288 pub(crate) lhs: Expr<'hir>,
290 pub(crate) rhs: Expr<'hir>,
292}
293
294#[derive(Debug, TryClone, Clone, Copy)]
296#[try_clone(copy)]
297#[non_exhaustive]
298pub(crate) struct ExprLoop<'hir> {
299 pub(crate) label: Option<&'hir str>,
301 pub(crate) condition: Option<&'hir Condition<'hir>>,
303 pub(crate) body: Block<'hir>,
305 #[allow(unused)]
307 pub(crate) drop: &'hir [Variable],
308}
309
310#[derive(Debug, TryClone, Clone, Copy)]
312#[try_clone(copy)]
313#[non_exhaustive]
314pub(crate) struct ExprFor<'hir> {
315 pub(crate) label: Option<&'hir str>,
317 pub(crate) binding: PatBinding<'hir>,
320 pub(crate) iter: Expr<'hir>,
322 pub(crate) body: Block<'hir>,
324 #[allow(unused)]
326 pub(crate) drop: &'hir [Variable],
327}
328
329#[derive(Debug, TryClone, Clone, Copy, Spanned)]
331#[try_clone(copy)]
332#[non_exhaustive]
333pub(crate) struct ExprLet<'hir> {
334 pub(crate) pat: PatBinding<'hir>,
336 pub(crate) expr: Expr<'hir>,
338}
339
340#[derive(Debug, TryClone, Clone, Copy)]
348#[try_clone(copy)]
349#[non_exhaustive]
350pub(crate) struct Conditional<'hir> {
351 pub(crate) branches: &'hir [ConditionalBranch<'hir>],
353 pub(crate) fallback: Option<&'hir Block<'hir>>,
355}
356
357#[derive(Debug, TryClone, Clone, Copy, Spanned)]
359#[try_clone(copy)]
360#[non_exhaustive]
361pub(crate) struct ConditionalBranch<'hir> {
362 #[rune(span)]
364 pub(crate) span: Span,
365 pub(crate) condition: &'hir Condition<'hir>,
368 pub(crate) block: Block<'hir>,
370 #[allow(unused)]
372 pub(crate) drop: &'hir [Variable],
373}
374
375#[derive(Debug, TryClone, Clone, Copy)]
377#[try_clone(copy)]
378#[non_exhaustive]
379pub(crate) struct ExprMatch<'hir> {
380 pub(crate) expr: &'hir Expr<'hir>,
382 pub(crate) branches: &'hir [ExprMatchBranch<'hir>],
384}
385
386#[derive(Debug, TryClone, Clone, Copy, Spanned)]
388#[try_clone(copy)]
389#[non_exhaustive]
390pub(crate) struct ExprMatchBranch<'hir> {
391 #[rune(span)]
393 pub(crate) span: Span,
394 pub(crate) pat: PatBinding<'hir>,
396 pub(crate) condition: Option<&'hir Expr<'hir>>,
398 pub(crate) body: Expr<'hir>,
400 #[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 name: Variable,
412 },
413 Associated {
414 target: &'hir Expr<'hir>,
416 hash: Hash,
418 },
419 Meta {
420 hash: Hash,
422 },
423 Expr { expr: &'hir Expr<'hir> },
425 ConstFn {
427 from_module: ModId,
429 from_item: ItemId,
431 id: ItemId,
433 },
434}
435
436#[derive(Debug, TryClone, Clone, Copy)]
438#[try_clone(copy)]
439#[non_exhaustive]
440pub(crate) struct ExprCall<'hir> {
441 pub(crate) call: Call<'hir>,
443 pub(crate) args: &'hir [Expr<'hir>],
445}
446
447#[derive(Debug, TryClone, Clone, Copy)]
449#[try_clone(copy)]
450#[non_exhaustive]
451pub(crate) struct ExprFieldAccess<'hir> {
452 pub(crate) expr: Expr<'hir>,
454 pub(crate) expr_field: ExprField<'hir>,
456}
457
458#[derive(Debug, TryClone, Clone, Copy)]
460#[try_clone(copy)]
461#[non_exhaustive]
462pub(crate) enum ExprField<'hir> {
463 Index(usize),
469 Ident(&'hir str),
475 IdentGenerics(&'hir str, Hash),
481}
482
483#[derive(Debug, TryClone, Clone, Copy)]
485#[try_clone(copy)]
486#[non_exhaustive]
487pub(crate) struct ExprBinary<'hir> {
488 pub(crate) lhs: Expr<'hir>,
490 pub(crate) op: ast::BinOp,
492 pub(crate) rhs: Expr<'hir>,
494}
495
496#[derive(Debug, TryClone, Clone, Copy)]
498#[try_clone(copy)]
499#[non_exhaustive]
500pub(crate) struct ExprUnary<'hir> {
501 pub(crate) op: ast::UnOp,
503 pub(crate) expr: Expr<'hir>,
505}
506
507#[derive(Debug, TryClone, Clone, Copy)]
509#[try_clone(copy)]
510#[non_exhaustive]
511pub(crate) struct ExprIndex<'hir> {
512 pub(crate) target: Expr<'hir>,
514 pub(crate) index: Expr<'hir>,
516}
517
518#[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 pub(crate) label: Option<&'hir str>,
533 pub(crate) expr: Option<&'hir Expr<'hir>>,
535 #[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 pub(crate) label: Option<&'hir str>,
545 #[allow(unused)]
547 pub(crate) drop: &'hir [Variable],
548}
549
550#[derive(Debug, TryClone, Clone, Copy)]
552#[try_clone(copy)]
553#[non_exhaustive]
554pub(crate) struct ExprSelect<'hir> {
555 pub(crate) exprs: &'hir [Expr<'hir>],
557 pub(crate) branches: &'hir [ExprSelectBranch<'hir>],
559 pub(crate) default: Option<&'hir Expr<'hir>>,
561}
562
563#[derive(Debug, TryClone, Clone, Copy)]
565#[try_clone(copy)]
566#[non_exhaustive]
567pub(crate) struct ExprSelectBranch<'hir> {
568 pub(crate) pat: PatBinding<'hir>,
570 pub(crate) body: Expr<'hir>,
572 #[allow(unused)]
574 pub(crate) drop: &'hir [Variable],
575}
576
577#[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#[derive(Debug, TryClone, Clone, Copy, Spanned)]
589#[try_clone(copy)]
590#[non_exhaustive]
591pub(crate) struct ExprClosure<'hir> {
592 pub(crate) args: &'hir [FnArg<'hir>],
594 #[rune(span)]
596 pub(crate) body: &'hir Expr<'hir>,
597 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#[derive(Debug, TryClone, Clone, Copy)]
611#[try_clone(copy)]
612#[non_exhaustive]
613pub(crate) struct ExprObject<'hir> {
614 pub(crate) kind: ExprObjectKind,
616 pub(crate) assignments: &'hir [FieldAssign<'hir>],
618}
619
620#[derive(Debug, TryClone, Clone, Copy)]
622#[try_clone(copy)]
623#[non_exhaustive]
624pub(crate) struct FieldAssign<'hir> {
625 pub(crate) key: (Span, &'hir str),
627 pub(crate) assign: Expr<'hir>,
629 pub(crate) position: Option<usize>,
631}
632
633#[derive(Debug, TryClone, Clone, Copy)]
635#[try_clone(copy)]
636#[non_exhaustive]
637pub(crate) struct ExprSeq<'hir> {
638 pub(crate) items: &'hir [Expr<'hir>],
640}
641
642#[derive(Debug, TryClone, Clone, Copy)]
644#[try_clone(copy)]
645#[non_exhaustive]
646pub(crate) enum ExprRange<'hir> {
647 RangeFrom { start: Expr<'hir> },
649 RangeFull,
651 RangeInclusive { start: Expr<'hir>, end: Expr<'hir> },
653 RangeToInclusive { end: Expr<'hir> },
655 RangeTo { end: Expr<'hir> },
657 Range { start: Expr<'hir>, end: Expr<'hir> },
659}
660
661#[derive(Debug, TryClone, Clone, Copy, Spanned)]
663#[try_clone(copy)]
664#[non_exhaustive]
665pub(crate) enum Condition<'hir> {
666 Expr(&'hir Expr<'hir>),
668 ExprLet(&'hir ExprLet<'hir>),
670}
671
672impl Condition<'_> {
673 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 #[rune(span)]
688 pub(crate) span: Span,
689 pub(crate) args: &'hir [FnArg<'hir>],
691 pub(crate) body: Block<'hir>,
693}
694
695#[derive(Debug, TryClone, Clone, Copy, Spanned)]
697#[try_clone(copy)]
698#[non_exhaustive]
699pub(crate) enum FnArg<'hir> {
700 SelfValue(#[rune(span)] Span, Variable),
702 Pat(&'hir PatBinding<'hir>),
704}
705
706#[derive(Debug, TryClone, Clone, Copy, Spanned)]
708#[try_clone(copy)]
709#[non_exhaustive]
710pub(crate) struct Block<'hir> {
711 #[rune(span)]
713 pub(crate) span: Span,
714 pub(crate) label: Option<&'hir str>,
716 pub(crate) statements: &'hir [Stmt<'hir>],
718 pub(crate) value: Option<&'hir Expr<'hir>>,
720 #[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#[derive(Debug, TryClone, Clone, Copy, Spanned)]
735#[try_clone(copy)]
736#[non_exhaustive]
737pub(crate) enum Stmt<'hir> {
738 Local(&'hir Local<'hir>),
740 Expr(&'hir Expr<'hir>),
742}
743
744#[derive(Debug, TryClone, Clone, Copy, Spanned)]
746#[try_clone(copy)]
747#[non_exhaustive]
748pub(crate) struct Local<'hir> {
749 #[rune(span)]
751 pub(crate) span: Span,
752 pub(crate) pat: PatBinding<'hir>,
754 pub(crate) expr: Expr<'hir>,
756}