Skip to main content

geam_core/plan/module/
id.rs

1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2pub enum LocalId {
3    Generic(GenericLocal),
4    Int(IntLocalId),
5    Float(FloatLocalId),
6    String(StringLocalId),
7    BitArray(BitArrayLocalId),
8    UtfCodepoint(UtfCodepointLocalId),
9    Bool(BoolLocalId),
10    Nil(NilLocalId),
11}
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
14pub struct GenericLocalId(pub(crate) usize);
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
17pub struct GenericLocal {
18    id: GenericLocalId,
19    parameter: crate::plan::TypeParameterId,
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23pub struct IntLocalId(pub(crate) usize);
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq)]
26pub struct FloatLocalId(pub(crate) usize);
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub struct StringLocalId(pub(crate) usize);
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32pub struct BitArrayLocalId(pub(crate) usize);
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35pub struct UtfCodepointLocalId(pub(crate) usize);
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
38pub struct CustomLocalId(pub(crate) usize);
39
40#[derive(Debug, Clone, PartialEq, Eq, Hash)]
41pub(crate) struct CustomLocal {
42    id: CustomLocalId,
43    shape: crate::plan::CustomValueShape,
44}
45
46#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
47pub struct ExternalLocalId(pub(crate) usize);
48
49#[derive(Debug, Clone, PartialEq, Eq, Hash)]
50pub(crate) struct ExternalLocal {
51    id: ExternalLocalId,
52    shape: crate::plan::ExternalValueShape,
53}
54
55#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56pub struct BoolLocalId(pub(crate) usize);
57
58#[derive(Debug, Clone, Copy, PartialEq, Eq)]
59pub struct NilLocalId(pub(crate) usize);
60
61#[derive(Debug, Clone, Copy, PartialEq, Eq)]
62pub struct TupleLocalId(pub(crate) usize);
63
64#[derive(Debug, Clone, Copy, PartialEq, Eq)]
65pub struct IntListLocalId(pub(crate) usize);
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq)]
68pub struct StringListLocalId(pub(crate) usize);
69
70#[derive(Debug, Clone, Copy, PartialEq, Eq)]
71pub struct BitArrayListLocalId(pub(crate) usize);
72
73#[derive(Debug, Clone, Copy, PartialEq, Eq)]
74pub struct UtfCodepointListLocalId(pub(crate) usize);
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq)]
77pub struct CustomListLocalId(pub(crate) usize);
78
79#[derive(Debug, Clone, Copy, PartialEq, Eq)]
80pub struct ExternalListLocalId(pub(crate) usize);
81
82#[derive(Debug, Clone, Copy, PartialEq, Eq)]
83pub struct FloatListLocalId(pub(crate) usize);
84
85#[derive(Debug, Clone, Copy, PartialEq, Eq)]
86pub struct BoolListLocalId(pub(crate) usize);
87
88#[derive(Debug, Clone, Copy, PartialEq, Eq)]
89pub struct NilListLocalId(pub(crate) usize);
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq)]
92pub struct TupleListLocalId(pub(crate) usize);
93
94#[derive(Debug, Clone, Copy, PartialEq, Eq)]
95pub struct ListListLocalId(pub(crate) usize);
96
97#[derive(Debug, Clone, Copy, PartialEq, Eq)]
98pub struct FunctionListLocalId(pub(crate) usize);
99
100#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
101pub struct GenericListLocalId(pub(crate) usize);
102
103#[derive(Debug, Clone, PartialEq, Eq)]
104pub enum ListLocal {
105    Generic {
106        local: GenericListLocalId,
107        parameter: crate::plan::TypeParameterId,
108    },
109    Int(IntListLocalId),
110    String(StringListLocalId),
111    BitArray(BitArrayListLocalId),
112    UtfCodepoint(UtfCodepointListLocalId),
113    Custom {
114        local: CustomListLocalId,
115        item_type: crate::plan::CustomType,
116    },
117    External {
118        local: ExternalListLocalId,
119        item_type: crate::plan::ExternalType,
120    },
121    Float(FloatListLocalId),
122    Bool(BoolListLocalId),
123    Nil(NilListLocalId),
124    Tuple {
125        local: TupleListLocalId,
126        item_type: Vec<crate::plan::ValueType>,
127    },
128    List {
129        local: ListListLocalId,
130        item_type: Box<crate::plan::ValueType>,
131    },
132    Function {
133        local: FunctionListLocalId,
134        item_type: crate::plan::FunctionType,
135    },
136}
137
138#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
139pub struct IntFunctionLocalId(pub(crate) usize);
140
141#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
142pub struct FloatFunctionLocalId(pub(crate) usize);
143
144#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
145pub struct StringFunctionLocalId(pub(crate) usize);
146
147#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
148pub struct BitArrayFunctionLocalId(pub(crate) usize);
149
150#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
151pub struct UtfCodepointFunctionLocalId(pub(crate) usize);
152
153#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
154pub struct CustomFunctionLocalId(pub(crate) usize);
155
156#[derive(Debug, Clone, PartialEq, Eq, Hash)]
157pub(crate) struct CustomFunctionLocal {
158    id: CustomFunctionLocalId,
159    type_: crate::plan::CustomFunctionType,
160}
161
162#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
163pub struct ExternalFunctionLocalId(pub(crate) usize);
164
165#[derive(Debug, Clone, PartialEq, Eq, Hash)]
166pub(crate) struct ExternalFunctionLocal {
167    id: ExternalFunctionLocalId,
168    type_: crate::plan::ExternalFunctionType,
169}
170
171#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
172pub struct BoolFunctionLocalId(pub(crate) usize);
173
174#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
175pub struct NilFunctionLocalId(pub(crate) usize);
176
177#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
178pub struct TupleFunctionLocalId(pub(crate) usize);
179
180#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
181pub struct IntListFunctionLocalId(pub(crate) usize);
182
183#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
184pub struct StringListFunctionLocalId(pub(crate) usize);
185
186#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
187pub struct BitArrayListFunctionLocalId(pub(crate) usize);
188
189#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
190pub struct UtfCodepointListFunctionLocalId(pub(crate) usize);
191
192#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
193pub struct CustomListFunctionLocalId(pub(crate) usize);
194
195#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
196pub struct ExternalListFunctionLocalId(pub(crate) usize);
197
198#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
199pub struct FloatListFunctionLocalId(pub(crate) usize);
200
201#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
202pub struct BoolListFunctionLocalId(pub(crate) usize);
203
204#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
205pub struct NilListFunctionLocalId(pub(crate) usize);
206
207#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
208pub struct TupleListFunctionLocalId(pub(crate) usize);
209
210#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
211pub struct ListListFunctionLocalId(pub(crate) usize);
212
213#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
214pub struct FunctionListFunctionLocalId(pub(crate) usize);
215
216#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
217pub struct GenericListFunctionLocalId(pub(crate) usize);
218
219#[derive(Debug, Clone, PartialEq, Eq, Hash)]
220pub enum ListFunctionLocal {
221    Generic {
222        local: GenericListFunctionLocalId,
223        type_: crate::plan::FunctionType,
224        parameter: crate::plan::TypeParameterId,
225    },
226    Int {
227        local: IntListFunctionLocalId,
228        type_: crate::plan::FunctionType,
229    },
230    String {
231        local: StringListFunctionLocalId,
232        type_: crate::plan::FunctionType,
233    },
234    BitArray {
235        local: BitArrayListFunctionLocalId,
236        type_: crate::plan::FunctionType,
237    },
238    UtfCodepoint {
239        local: UtfCodepointListFunctionLocalId,
240        type_: crate::plan::FunctionType,
241    },
242    Custom {
243        local: CustomListFunctionLocalId,
244        type_: crate::plan::FunctionType,
245        item_type: crate::plan::CustomType,
246    },
247    External {
248        local: ExternalListFunctionLocalId,
249        type_: crate::plan::FunctionType,
250        item_type: crate::plan::ExternalType,
251    },
252    Float {
253        local: FloatListFunctionLocalId,
254        type_: crate::plan::FunctionType,
255    },
256    Bool {
257        local: BoolListFunctionLocalId,
258        type_: crate::plan::FunctionType,
259    },
260    Nil {
261        local: NilListFunctionLocalId,
262        type_: crate::plan::FunctionType,
263    },
264    Tuple {
265        local: TupleListFunctionLocalId,
266        type_: crate::plan::FunctionType,
267        item_type: Vec<crate::plan::ValueType>,
268    },
269    List {
270        local: ListListFunctionLocalId,
271        type_: crate::plan::FunctionType,
272        item_type: Box<crate::plan::ValueType>,
273    },
274    Function {
275        local: FunctionListFunctionLocalId,
276        type_: crate::plan::FunctionType,
277        item_type: Box<crate::plan::FunctionType>,
278    },
279}
280
281#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
282pub struct FunctionFunctionLocalId(pub(crate) usize);
283
284#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
285pub struct GenericFunctionLocalId(pub(crate) usize);
286
287#[derive(Debug, Clone, PartialEq, Eq, Hash)]
288pub(crate) struct FunctionFunctionLocal {
289    id: FunctionFunctionLocalId,
290    type_: crate::plan::FunctionFunctionType,
291}
292
293#[derive(Debug, Clone, PartialEq, Eq, Hash)]
294pub(crate) struct GenericFunctionLocal {
295    id: GenericFunctionLocalId,
296    type_: crate::plan::GenericFunctionType,
297}
298
299#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
300pub struct ModuleId(usize);
301
302#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
303pub struct FunctionTemplateId {
304    module: ModuleId,
305    index: usize,
306}
307
308#[cfg(test)]
309#[derive(Debug, Clone, PartialEq, Eq)]
310pub(crate) enum RuntimeFunctionId {
311    Int(IntFunctionId),
312    Float(FloatFunctionId),
313    String(StringFunctionId),
314    BitArray(BitArrayFunctionId),
315    UtfCodepoint(UtfCodepointFunctionId),
316    Custom(CustomFunctionId),
317    Bool(BoolFunctionId),
318    Nil(NilFunctionId),
319    Tuple {
320        id: TupleFunctionId,
321        return_type: Vec<crate::plan::ValueType>,
322    },
323    List(ListFunctionId),
324    Function {
325        id: FunctionFunctionId,
326        return_type: crate::plan::FunctionType,
327    },
328}
329
330#[cfg(test)]
331#[derive(Debug, Clone, Copy, PartialEq, Eq)]
332pub struct IntFunctionId(pub(crate) usize);
333
334#[cfg(test)]
335#[derive(Debug, Clone, Copy, PartialEq, Eq)]
336pub struct FloatFunctionId(pub(crate) usize);
337
338#[cfg(test)]
339#[derive(Debug, Clone, Copy, PartialEq, Eq)]
340pub struct StringFunctionId(pub(crate) usize);
341
342#[cfg(test)]
343#[derive(Debug, Clone, Copy, PartialEq, Eq)]
344pub struct BitArrayFunctionId(pub(crate) usize);
345
346#[cfg(test)]
347#[derive(Debug, Clone, Copy, PartialEq, Eq)]
348pub struct UtfCodepointFunctionId(pub(crate) usize);
349
350#[cfg(test)]
351#[derive(Debug, Clone, PartialEq, Eq)]
352pub struct CustomFunctionId {
353    index: usize,
354    return_shape: crate::plan::CustomValueShape,
355}
356
357#[cfg(test)]
358#[derive(Debug, Clone, Copy, PartialEq, Eq)]
359pub struct BoolFunctionId(pub(crate) usize);
360
361#[cfg(test)]
362#[derive(Debug, Clone, Copy, PartialEq, Eq)]
363pub struct NilFunctionId(pub(crate) usize);
364
365#[cfg(test)]
366#[derive(Debug, Clone, Copy, PartialEq, Eq)]
367pub struct TupleFunctionId(pub(crate) usize);
368
369#[cfg(test)]
370#[derive(Debug, Clone, Copy, PartialEq, Eq)]
371pub struct IntListFunctionId(pub(crate) usize);
372
373#[cfg(test)]
374#[derive(Debug, Clone, Copy, PartialEq, Eq)]
375pub struct StringListFunctionId(pub(crate) usize);
376
377#[cfg(test)]
378#[derive(Debug, Clone, Copy, PartialEq, Eq)]
379pub struct BitArrayListFunctionId(pub(crate) usize);
380
381#[cfg(test)]
382#[derive(Debug, Clone, Copy, PartialEq, Eq)]
383pub struct UtfCodepointListFunctionId(pub(crate) usize);
384
385#[cfg(test)]
386#[derive(Debug, Clone, Copy, PartialEq, Eq)]
387pub struct CustomListFunctionId(pub(crate) usize);
388
389#[cfg(test)]
390#[derive(Debug, Clone, Copy, PartialEq, Eq)]
391pub struct ExternalListFunctionId(pub(crate) usize);
392
393#[cfg(test)]
394#[derive(Debug, Clone, Copy, PartialEq, Eq)]
395pub struct FloatListFunctionId(pub(crate) usize);
396
397#[cfg(test)]
398#[derive(Debug, Clone, Copy, PartialEq, Eq)]
399pub struct BoolListFunctionId(pub(crate) usize);
400
401#[cfg(test)]
402#[derive(Debug, Clone, Copy, PartialEq, Eq)]
403pub struct NilListFunctionId(pub(crate) usize);
404
405#[cfg(test)]
406#[derive(Debug, Clone, Copy, PartialEq, Eq)]
407pub struct TupleListFunctionId(pub(crate) usize);
408
409#[cfg(test)]
410#[derive(Debug, Clone, Copy, PartialEq, Eq)]
411pub struct ListListFunctionId(pub(crate) usize);
412
413#[cfg(test)]
414#[derive(Debug, Clone, Copy, PartialEq, Eq)]
415pub struct FunctionListFunctionId(pub(crate) usize);
416
417#[cfg(test)]
418#[derive(Debug, Clone, PartialEq, Eq)]
419pub enum ListFunctionId {
420    Generic {
421        id: GenericListFunctionId,
422        parameter: crate::plan::TypeParameterId,
423    },
424    Int(IntListFunctionId),
425    String(StringListFunctionId),
426    BitArray(BitArrayListFunctionId),
427    UtfCodepoint(UtfCodepointListFunctionId),
428    Custom {
429        id: CustomListFunctionId,
430        item_type: crate::plan::CustomType,
431    },
432    External {
433        id: ExternalListFunctionId,
434        item_type: crate::plan::ExternalType,
435    },
436    Float(FloatListFunctionId),
437    Bool(BoolListFunctionId),
438    Nil(NilListFunctionId),
439    Tuple {
440        id: TupleListFunctionId,
441        item_type: Vec<crate::plan::ValueType>,
442    },
443    List {
444        id: ListListFunctionId,
445        item_type: Box<crate::plan::ValueType>,
446    },
447    Function {
448        id: FunctionListFunctionId,
449        item_type: crate::plan::FunctionType,
450    },
451}
452
453#[cfg(test)]
454#[derive(Debug, Clone, PartialEq, Eq)]
455pub(crate) enum FunctionFunctionId {
456    Int(IntFunctionFunctionId),
457    Float(FloatFunctionFunctionId),
458    String(StringFunctionFunctionId),
459    BitArray(BitArrayFunctionFunctionId),
460    UtfCodepoint(UtfCodepointFunctionFunctionId),
461    Custom(CustomFunctionFunctionId),
462    Bool(BoolFunctionFunctionId),
463    Nil(NilFunctionFunctionId),
464    Tuple(TupleFunctionFunctionId),
465    List(ListFunctionFunctionId),
466    Function(FunctionFunctionFunctionId),
467}
468
469#[derive(Debug, Clone, Copy, PartialEq, Eq)]
470pub enum FunctionReturnFamily {
471    Generic,
472    Int,
473    Float,
474    String,
475    BitArray,
476    UtfCodepoint,
477    Custom,
478    External,
479    Bool,
480    Nil,
481    Tuple,
482    List,
483    Function,
484}
485
486#[cfg(test)]
487#[derive(Debug, Clone, Copy, PartialEq, Eq)]
488pub struct GenericListFunctionId(pub(crate) usize);
489
490#[cfg(test)]
491#[derive(Debug, Clone, Copy, PartialEq, Eq)]
492pub struct IntFunctionFunctionId(pub(crate) usize);
493
494#[cfg(test)]
495#[derive(Debug, Clone, Copy, PartialEq, Eq)]
496pub struct FloatFunctionFunctionId(pub(crate) usize);
497
498#[cfg(test)]
499#[derive(Debug, Clone, Copy, PartialEq, Eq)]
500pub struct StringFunctionFunctionId(pub(crate) usize);
501
502#[cfg(test)]
503#[derive(Debug, Clone, Copy, PartialEq, Eq)]
504pub struct BitArrayFunctionFunctionId(pub(crate) usize);
505
506#[cfg(test)]
507#[derive(Debug, Clone, Copy, PartialEq, Eq)]
508pub struct UtfCodepointFunctionFunctionId(pub(crate) usize);
509
510#[cfg(test)]
511#[derive(Debug, Clone, PartialEq, Eq)]
512pub struct CustomFunctionFunctionId {
513    index: usize,
514    type_: crate::plan::CustomFunctionType,
515}
516
517#[cfg(test)]
518#[derive(Debug, Clone, Copy, PartialEq, Eq)]
519pub struct BoolFunctionFunctionId(pub(crate) usize);
520
521#[cfg(test)]
522#[derive(Debug, Clone, Copy, PartialEq, Eq)]
523pub struct NilFunctionFunctionId(pub(crate) usize);
524
525#[cfg(test)]
526#[derive(Debug, Clone, Copy, PartialEq, Eq)]
527pub struct TupleFunctionFunctionId(pub(crate) usize);
528
529#[cfg(test)]
530#[derive(Debug, Clone, Copy, PartialEq, Eq)]
531pub struct IntListFunctionFunctionId(pub(crate) usize);
532
533#[cfg(test)]
534#[derive(Debug, Clone, Copy, PartialEq, Eq)]
535pub struct StringListFunctionFunctionId(pub(crate) usize);
536
537#[cfg(test)]
538#[derive(Debug, Clone, Copy, PartialEq, Eq)]
539pub struct BitArrayListFunctionFunctionId(pub(crate) usize);
540
541#[cfg(test)]
542#[derive(Debug, Clone, Copy, PartialEq, Eq)]
543pub struct UtfCodepointListFunctionFunctionId(pub(crate) usize);
544
545#[cfg(test)]
546#[derive(Debug, Clone, Copy, PartialEq, Eq)]
547pub struct CustomListFunctionFunctionId(pub(crate) usize);
548
549#[cfg(test)]
550#[derive(Debug, Clone, Copy, PartialEq, Eq)]
551pub struct ExternalListFunctionFunctionId(pub(crate) usize);
552
553#[cfg(test)]
554#[derive(Debug, Clone, Copy, PartialEq, Eq)]
555pub struct FloatListFunctionFunctionId(pub(crate) usize);
556
557#[cfg(test)]
558#[derive(Debug, Clone, Copy, PartialEq, Eq)]
559pub struct BoolListFunctionFunctionId(pub(crate) usize);
560
561#[cfg(test)]
562#[derive(Debug, Clone, Copy, PartialEq, Eq)]
563pub struct NilListFunctionFunctionId(pub(crate) usize);
564
565#[cfg(test)]
566#[derive(Debug, Clone, Copy, PartialEq, Eq)]
567pub struct TupleListFunctionFunctionId(pub(crate) usize);
568
569#[cfg(test)]
570#[derive(Debug, Clone, Copy, PartialEq, Eq)]
571pub struct ListListFunctionFunctionId(pub(crate) usize);
572
573#[cfg(test)]
574#[derive(Debug, Clone, Copy, PartialEq, Eq)]
575pub struct FunctionListFunctionFunctionId(pub(crate) usize);
576
577#[cfg(test)]
578#[derive(Debug, Clone, Copy, PartialEq, Eq)]
579pub struct GenericListFunctionFunctionId(pub(crate) usize);
580
581#[cfg(test)]
582#[derive(Debug, Clone, PartialEq, Eq)]
583pub enum ListFunctionFunctionId {
584    Generic {
585        id: GenericListFunctionFunctionId,
586        type_: crate::plan::FunctionType,
587        parameter: crate::plan::TypeParameterId,
588    },
589    Int {
590        id: IntListFunctionFunctionId,
591        type_: crate::plan::FunctionType,
592    },
593    String {
594        id: StringListFunctionFunctionId,
595        type_: crate::plan::FunctionType,
596    },
597    BitArray {
598        id: BitArrayListFunctionFunctionId,
599        type_: crate::plan::FunctionType,
600    },
601    UtfCodepoint {
602        id: UtfCodepointListFunctionFunctionId,
603        type_: crate::plan::FunctionType,
604    },
605    Custom {
606        id: CustomListFunctionFunctionId,
607        type_: crate::plan::FunctionType,
608        item_type: crate::plan::CustomType,
609    },
610    External {
611        id: ExternalListFunctionFunctionId,
612        type_: crate::plan::FunctionType,
613        item_type: crate::plan::ExternalType,
614    },
615    Float {
616        id: FloatListFunctionFunctionId,
617        type_: crate::plan::FunctionType,
618    },
619    Bool {
620        id: BoolListFunctionFunctionId,
621        type_: crate::plan::FunctionType,
622    },
623    Nil {
624        id: NilListFunctionFunctionId,
625        type_: crate::plan::FunctionType,
626    },
627    Tuple {
628        id: TupleListFunctionFunctionId,
629        type_: crate::plan::FunctionType,
630        item_type: Vec<crate::plan::ValueType>,
631    },
632    List {
633        id: ListListFunctionFunctionId,
634        type_: crate::plan::FunctionType,
635        item_type: Box<crate::plan::ValueType>,
636    },
637    Function {
638        id: FunctionListFunctionFunctionId,
639        type_: crate::plan::FunctionType,
640        item_type: Box<crate::plan::FunctionType>,
641    },
642}
643
644#[cfg(test)]
645#[derive(Debug, Clone, PartialEq, Eq)]
646pub struct FunctionFunctionFunctionId {
647    index: usize,
648    type_: crate::plan::FunctionFunctionType,
649}
650
651impl CustomFunctionLocal {
652    pub(crate) fn new(id: CustomFunctionLocalId, type_: crate::plan::CustomFunctionType) -> Self {
653        Self { id, type_ }
654    }
655
656    pub(crate) fn id(&self) -> CustomFunctionLocalId {
657        self.id
658    }
659
660    pub(crate) fn type_(&self) -> &crate::plan::CustomFunctionType {
661        &self.type_
662    }
663}
664
665impl ExternalFunctionLocal {
666    pub(crate) fn new(
667        id: ExternalFunctionLocalId,
668        type_: crate::plan::ExternalFunctionType,
669    ) -> Self {
670        Self { id, type_ }
671    }
672
673    pub(crate) fn id(&self) -> ExternalFunctionLocalId {
674        self.id
675    }
676
677    pub(crate) fn type_(&self) -> &crate::plan::ExternalFunctionType {
678        &self.type_
679    }
680}
681
682impl GenericLocal {
683    pub(crate) fn new(id: GenericLocalId, parameter: crate::plan::TypeParameterId) -> Self {
684        Self { id, parameter }
685    }
686
687    pub fn id(self) -> GenericLocalId {
688        self.id
689    }
690
691    pub fn parameter(self) -> crate::plan::TypeParameterId {
692        self.parameter
693    }
694}
695
696impl GenericFunctionLocal {
697    pub(crate) fn new(id: GenericFunctionLocalId, type_: crate::plan::GenericFunctionType) -> Self {
698        Self { id, type_ }
699    }
700
701    pub(crate) fn id(&self) -> GenericFunctionLocalId {
702        self.id
703    }
704
705    pub(crate) fn type_(&self) -> &crate::plan::GenericFunctionType {
706        &self.type_
707    }
708}
709
710impl CustomLocal {
711    #[cfg(test)]
712    pub(crate) fn new(id: CustomLocalId, type_: crate::plan::CustomType) -> Self {
713        Self::from_shape(id, crate::plan::CustomValueShape::any(type_))
714    }
715
716    pub(crate) fn from_shape(id: CustomLocalId, shape: crate::plan::CustomValueShape) -> Self {
717        Self { id, shape }
718    }
719
720    pub(crate) fn id(&self) -> CustomLocalId {
721        self.id
722    }
723
724    pub(crate) fn type_(&self) -> &crate::plan::CustomType {
725        self.shape.type_()
726    }
727
728    pub(crate) fn shape(&self) -> &crate::plan::CustomValueShape {
729        &self.shape
730    }
731}
732
733impl ExternalLocal {
734    pub(crate) fn from_shape(id: ExternalLocalId, shape: crate::plan::ExternalValueShape) -> Self {
735        Self { id, shape }
736    }
737
738    pub(crate) fn id(&self) -> ExternalLocalId {
739        self.id
740    }
741
742    pub(crate) fn type_(&self) -> &crate::plan::ExternalType {
743        self.shape.type_()
744    }
745
746    pub(crate) fn shape(&self) -> &crate::plan::ExternalValueShape {
747        &self.shape
748    }
749}
750
751#[cfg(test)]
752impl CustomFunctionId {
753    pub(crate) fn new(index: usize, return_type: crate::plan::CustomType) -> Self {
754        Self::from_shape(index, crate::plan::CustomValueShape::any(return_type))
755    }
756
757    pub(crate) fn from_shape(index: usize, return_shape: crate::plan::CustomValueShape) -> Self {
758        Self {
759            index,
760            return_shape,
761        }
762    }
763
764    pub(crate) fn index(&self) -> usize {
765        self.index
766    }
767
768    pub(crate) fn return_type(&self) -> &crate::plan::CustomType {
769        self.return_shape.type_()
770    }
771
772    pub(crate) fn return_shape(&self) -> &crate::plan::CustomValueShape {
773        &self.return_shape
774    }
775
776    pub(crate) fn into_parts(self) -> (usize, crate::plan::CustomValueShape) {
777        (self.index, self.return_shape)
778    }
779}
780
781impl FunctionFunctionLocal {
782    pub(crate) fn new(
783        id: FunctionFunctionLocalId,
784        type_: crate::plan::FunctionFunctionType,
785    ) -> Self {
786        Self { id, type_ }
787    }
788
789    pub(crate) fn id(&self) -> FunctionFunctionLocalId {
790        self.id
791    }
792
793    pub(crate) fn type_(&self) -> &crate::plan::FunctionFunctionType {
794        &self.type_
795    }
796}
797
798#[cfg(test)]
799impl CustomFunctionFunctionId {
800    pub(crate) fn new(index: usize, type_: crate::plan::CustomFunctionType) -> Self {
801        Self { index, type_ }
802    }
803
804    pub(crate) fn index(&self) -> usize {
805        self.index
806    }
807}
808
809#[cfg(test)]
810impl FunctionFunctionFunctionId {
811    pub(crate) fn new(index: usize, type_: crate::plan::FunctionFunctionType) -> Self {
812        Self { index, type_ }
813    }
814
815    pub(crate) fn index(&self) -> usize {
816        self.index
817    }
818}
819
820impl LocalId {
821    pub(crate) fn value_type(self) -> crate::plan::ValueType {
822        match self {
823            Self::Generic(local) => crate::plan::ValueType::Parameter(local.parameter),
824            Self::Int(_) => crate::plan::ValueType::Int,
825            Self::Float(_) => crate::plan::ValueType::Float,
826            Self::String(_) => crate::plan::ValueType::String,
827            Self::BitArray(_) => crate::plan::ValueType::BitArray,
828            Self::UtfCodepoint(_) => crate::plan::ValueType::UtfCodepoint,
829            Self::Bool(_) => crate::plan::ValueType::Bool,
830            Self::Nil(_) => crate::plan::ValueType::Nil,
831        }
832    }
833}
834
835impl FunctionTemplateId {
836    #[cfg(test)]
837    pub(crate) fn new(index: usize) -> Self {
838        Self::in_module(ModuleId::root(), index)
839    }
840
841    pub(crate) fn in_module(module: ModuleId, index: usize) -> Self {
842        Self { module, index }
843    }
844
845    pub fn module(self) -> ModuleId {
846        self.module
847    }
848
849    pub(crate) fn index(self) -> usize {
850        self.index
851    }
852}
853
854impl ModuleId {
855    pub(crate) fn new(index: usize) -> Self {
856        Self(index)
857    }
858
859    pub(crate) fn root() -> Self {
860        Self(0)
861    }
862
863    pub fn index(self) -> usize {
864        self.0
865    }
866}
867
868#[cfg(test)]
869impl FunctionFunctionId {
870    pub(crate) fn family(&self) -> FunctionReturnFamily {
871        match self {
872            Self::Int(_) => FunctionReturnFamily::Int,
873            Self::Float(_) => FunctionReturnFamily::Float,
874            Self::String(_) => FunctionReturnFamily::String,
875            Self::BitArray(_) => FunctionReturnFamily::BitArray,
876            Self::UtfCodepoint(_) => FunctionReturnFamily::UtfCodepoint,
877            Self::Custom(_) => FunctionReturnFamily::Custom,
878            Self::Bool(_) => FunctionReturnFamily::Bool,
879            Self::Nil(_) => FunctionReturnFamily::Nil,
880            Self::Tuple(_) => FunctionReturnFamily::Tuple,
881            Self::List(_) => FunctionReturnFamily::List,
882            Self::Function(_) => FunctionReturnFamily::Function,
883        }
884    }
885
886    pub(crate) fn int(&self) -> Option<IntFunctionFunctionId> {
887        match self {
888            Self::Int(id) => Some(*id),
889            _ => None,
890        }
891    }
892
893    pub(crate) fn string(&self) -> Option<StringFunctionFunctionId> {
894        match self {
895            Self::String(id) => Some(*id),
896            _ => None,
897        }
898    }
899
900    pub(crate) fn bit_array(&self) -> Option<BitArrayFunctionFunctionId> {
901        match self {
902            Self::BitArray(id) => Some(*id),
903            _ => None,
904        }
905    }
906
907    pub(crate) fn utf_codepoint(&self) -> Option<UtfCodepointFunctionFunctionId> {
908        match self {
909            Self::UtfCodepoint(id) => Some(*id),
910            _ => None,
911        }
912    }
913
914    pub(crate) fn custom(&self) -> Option<CustomFunctionFunctionId> {
915        match self {
916            Self::Custom(id) => Some(id.clone()),
917            _ => None,
918        }
919    }
920
921    pub(crate) fn float(&self) -> Option<FloatFunctionFunctionId> {
922        match self {
923            Self::Float(id) => Some(*id),
924            _ => None,
925        }
926    }
927
928    pub(crate) fn bool(&self) -> Option<BoolFunctionFunctionId> {
929        match self {
930            Self::Bool(id) => Some(*id),
931            _ => None,
932        }
933    }
934
935    pub(crate) fn nil(&self) -> Option<NilFunctionFunctionId> {
936        match self {
937            Self::Nil(id) => Some(*id),
938            _ => None,
939        }
940    }
941
942    pub(crate) fn tuple(&self) -> Option<TupleFunctionFunctionId> {
943        match self {
944            Self::Tuple(id) => Some(*id),
945            _ => None,
946        }
947    }
948
949    pub(crate) fn list(&self) -> Option<ListFunctionFunctionId> {
950        match self {
951            Self::List(id) => Some(id.clone()),
952            _ => None,
953        }
954    }
955
956    pub(crate) fn function(&self) -> Option<FunctionFunctionFunctionId> {
957        match self {
958            Self::Function(id) => Some(id.clone()),
959            _ => None,
960        }
961    }
962}
963
964impl ListFunctionLocal {
965    pub(crate) fn from_item_type(
966        index: usize,
967        type_: crate::plan::FunctionType,
968        item_type: crate::plan::ValueType,
969    ) -> Self {
970        match item_type {
971            crate::plan::ValueType::Parameter(parameter) => Self::Generic {
972                local: GenericListFunctionLocalId(index),
973                type_,
974                parameter,
975            },
976            crate::plan::ValueType::Int => Self::int(IntListFunctionLocalId(index), type_),
977            crate::plan::ValueType::String => Self::string(StringListFunctionLocalId(index), type_),
978            crate::plan::ValueType::BitArray => {
979                Self::bit_array(BitArrayListFunctionLocalId(index), type_)
980            }
981            crate::plan::ValueType::UtfCodepoint => {
982                Self::utf_codepoint(UtfCodepointListFunctionLocalId(index), type_)
983            }
984            crate::plan::ValueType::Custom(item_type) => {
985                Self::custom(CustomListFunctionLocalId(index), type_, item_type)
986            }
987            crate::plan::ValueType::External(item_type) => {
988                Self::external(ExternalListFunctionLocalId(index), type_, item_type)
989            }
990            crate::plan::ValueType::Float => Self::float(FloatListFunctionLocalId(index), type_),
991            crate::plan::ValueType::Bool => Self::bool(BoolListFunctionLocalId(index), type_),
992            crate::plan::ValueType::Nil => Self::nil(NilListFunctionLocalId(index), type_),
993            crate::plan::ValueType::Tuple(item_type) => {
994                Self::tuple(TupleListFunctionLocalId(index), type_, item_type)
995            }
996            crate::plan::ValueType::List(item_type) => {
997                Self::list(ListListFunctionLocalId(index), type_, *item_type)
998            }
999            crate::plan::ValueType::Function(item_type) => {
1000                Self::function(FunctionListFunctionLocalId(index), type_, *item_type)
1001            }
1002        }
1003    }
1004
1005    pub(crate) fn int(local: IntListFunctionLocalId, type_: crate::plan::FunctionType) -> Self {
1006        Self::Int { local, type_ }
1007    }
1008
1009    pub(crate) fn string(
1010        local: StringListFunctionLocalId,
1011        type_: crate::plan::FunctionType,
1012    ) -> Self {
1013        Self::String { local, type_ }
1014    }
1015
1016    pub(crate) fn bit_array(
1017        local: BitArrayListFunctionLocalId,
1018        type_: crate::plan::FunctionType,
1019    ) -> Self {
1020        Self::BitArray { local, type_ }
1021    }
1022
1023    pub(crate) fn utf_codepoint(
1024        local: UtfCodepointListFunctionLocalId,
1025        type_: crate::plan::FunctionType,
1026    ) -> Self {
1027        Self::UtfCodepoint { local, type_ }
1028    }
1029
1030    pub(crate) fn custom(
1031        local: CustomListFunctionLocalId,
1032        type_: crate::plan::FunctionType,
1033        item_type: crate::plan::CustomType,
1034    ) -> Self {
1035        Self::Custom {
1036            local,
1037            type_,
1038            item_type,
1039        }
1040    }
1041
1042    pub(crate) fn external(
1043        local: ExternalListFunctionLocalId,
1044        type_: crate::plan::FunctionType,
1045        item_type: crate::plan::ExternalType,
1046    ) -> Self {
1047        Self::External {
1048            local,
1049            type_,
1050            item_type,
1051        }
1052    }
1053
1054    pub(crate) fn float(local: FloatListFunctionLocalId, type_: crate::plan::FunctionType) -> Self {
1055        Self::Float { local, type_ }
1056    }
1057
1058    pub(crate) fn bool(local: BoolListFunctionLocalId, type_: crate::plan::FunctionType) -> Self {
1059        Self::Bool { local, type_ }
1060    }
1061
1062    pub(crate) fn nil(local: NilListFunctionLocalId, type_: crate::plan::FunctionType) -> Self {
1063        Self::Nil { local, type_ }
1064    }
1065
1066    pub(crate) fn tuple(
1067        local: TupleListFunctionLocalId,
1068        type_: crate::plan::FunctionType,
1069        item_type: Vec<crate::plan::ValueType>,
1070    ) -> Self {
1071        Self::Tuple {
1072            local,
1073            type_,
1074            item_type,
1075        }
1076    }
1077
1078    pub(crate) fn list(
1079        local: ListListFunctionLocalId,
1080        type_: crate::plan::FunctionType,
1081        item_type: crate::plan::ValueType,
1082    ) -> Self {
1083        Self::List {
1084            local,
1085            type_,
1086            item_type: Box::new(item_type),
1087        }
1088    }
1089
1090    pub(crate) fn function(
1091        local: FunctionListFunctionLocalId,
1092        type_: crate::plan::FunctionType,
1093        item_type: crate::plan::FunctionType,
1094    ) -> Self {
1095        Self::Function {
1096            local,
1097            type_,
1098            item_type: Box::new(item_type),
1099        }
1100    }
1101
1102    pub(crate) fn type_(&self) -> &crate::plan::FunctionType {
1103        match self {
1104            Self::Generic { type_, .. }
1105            | Self::Int { type_, .. }
1106            | Self::String { type_, .. }
1107            | Self::BitArray { type_, .. }
1108            | Self::UtfCodepoint { type_, .. }
1109            | Self::Custom { type_, .. }
1110            | Self::External { type_, .. }
1111            | Self::Float { type_, .. }
1112            | Self::Bool { type_, .. }
1113            | Self::Nil { type_, .. }
1114            | Self::Tuple { type_, .. }
1115            | Self::List { type_, .. }
1116            | Self::Function { type_, .. } => type_,
1117        }
1118    }
1119
1120    pub(crate) fn value_type(&self) -> crate::plan::ValueType {
1121        crate::plan::ValueType::Function(Box::new(self.type_().clone()))
1122    }
1123
1124    pub(crate) fn item_type(&self) -> crate::plan::ValueType {
1125        match self {
1126            Self::Generic { parameter, .. } => crate::plan::ValueType::Parameter(*parameter),
1127            Self::Int { .. } => crate::plan::ValueType::Int,
1128            Self::String { .. } => crate::plan::ValueType::String,
1129            Self::BitArray { .. } => crate::plan::ValueType::BitArray,
1130            Self::UtfCodepoint { .. } => crate::plan::ValueType::UtfCodepoint,
1131            Self::Custom { item_type, .. } => crate::plan::ValueType::Custom(item_type.clone()),
1132            Self::External { item_type, .. } => crate::plan::ValueType::External(item_type.clone()),
1133            Self::Float { .. } => crate::plan::ValueType::Float,
1134            Self::Bool { .. } => crate::plan::ValueType::Bool,
1135            Self::Nil { .. } => crate::plan::ValueType::Nil,
1136            Self::Tuple { item_type, .. } => crate::plan::ValueType::Tuple(item_type.clone()),
1137            Self::List { item_type, .. } => crate::plan::ValueType::List(item_type.clone()),
1138            Self::Function { item_type, .. } => crate::plan::ValueType::Function(item_type.clone()),
1139        }
1140    }
1141
1142    pub(crate) fn index(&self) -> usize {
1143        match self {
1144            Self::Generic { local, .. } => local.0,
1145            Self::Int { local, .. } => local.0,
1146            Self::String { local, .. } => local.0,
1147            Self::BitArray { local, .. } => local.0,
1148            Self::UtfCodepoint { local, .. } => local.0,
1149            Self::Custom { local, .. } => local.0,
1150            Self::External { local, .. } => local.0,
1151            Self::Float { local, .. } => local.0,
1152            Self::Bool { local, .. } => local.0,
1153            Self::Nil { local, .. } => local.0,
1154            Self::Tuple { local, .. } => local.0,
1155            Self::List { local, .. } => local.0,
1156            Self::Function { local, .. } => local.0,
1157        }
1158    }
1159}
1160
1161#[cfg(test)]
1162impl ListFunctionId {
1163    pub(crate) fn from_item_type(index: usize, item_type: crate::plan::ValueType) -> Self {
1164        match item_type {
1165            crate::plan::ValueType::Parameter(parameter) => Self::Generic {
1166                id: GenericListFunctionId(index),
1167                parameter,
1168            },
1169            crate::plan::ValueType::Int => Self::Int(IntListFunctionId(index)),
1170            crate::plan::ValueType::String => Self::String(StringListFunctionId(index)),
1171            crate::plan::ValueType::BitArray => Self::BitArray(BitArrayListFunctionId(index)),
1172            crate::plan::ValueType::UtfCodepoint => {
1173                Self::UtfCodepoint(UtfCodepointListFunctionId(index))
1174            }
1175            crate::plan::ValueType::Custom(item_type) => Self::Custom {
1176                id: CustomListFunctionId(index),
1177                item_type,
1178            },
1179            crate::plan::ValueType::External(item_type) => Self::External {
1180                id: ExternalListFunctionId(index),
1181                item_type,
1182            },
1183            crate::plan::ValueType::Float => Self::Float(FloatListFunctionId(index)),
1184            crate::plan::ValueType::Bool => Self::Bool(BoolListFunctionId(index)),
1185            crate::plan::ValueType::Nil => Self::Nil(NilListFunctionId(index)),
1186            crate::plan::ValueType::Tuple(item_type) => Self::Tuple {
1187                id: TupleListFunctionId(index),
1188                item_type,
1189            },
1190            crate::plan::ValueType::List(item_type) => Self::List {
1191                id: ListListFunctionId(index),
1192                item_type,
1193            },
1194            crate::plan::ValueType::Function(item_type) => Self::Function {
1195                id: FunctionListFunctionId(index),
1196                item_type: *item_type,
1197            },
1198        }
1199    }
1200
1201    pub(crate) fn item_type(&self) -> crate::plan::ValueType {
1202        match self {
1203            Self::Generic { parameter, .. } => crate::plan::ValueType::Parameter(*parameter),
1204            Self::Int(_) => crate::plan::ValueType::Int,
1205            Self::String(_) => crate::plan::ValueType::String,
1206            Self::BitArray(_) => crate::plan::ValueType::BitArray,
1207            Self::UtfCodepoint(_) => crate::plan::ValueType::UtfCodepoint,
1208            Self::Custom { item_type, .. } => crate::plan::ValueType::Custom(item_type.clone()),
1209            Self::External { item_type, .. } => crate::plan::ValueType::External(item_type.clone()),
1210            Self::Float(_) => crate::plan::ValueType::Float,
1211            Self::Bool(_) => crate::plan::ValueType::Bool,
1212            Self::Nil(_) => crate::plan::ValueType::Nil,
1213            Self::Tuple { item_type, .. } => crate::plan::ValueType::Tuple(item_type.clone()),
1214            Self::List { item_type, .. } => crate::plan::ValueType::List(item_type.clone()),
1215            Self::Function { item_type, .. } => {
1216                crate::plan::ValueType::Function(Box::new(item_type.clone()))
1217            }
1218        }
1219    }
1220}
1221
1222#[cfg(test)]
1223impl ListFunctionFunctionId {
1224    pub(crate) fn from_item_type(
1225        index: usize,
1226        type_: crate::plan::FunctionType,
1227        item_type: crate::plan::ValueType,
1228    ) -> Self {
1229        match item_type {
1230            crate::plan::ValueType::Parameter(parameter) => Self::Generic {
1231                id: GenericListFunctionFunctionId(index),
1232                type_,
1233                parameter,
1234            },
1235            crate::plan::ValueType::Int => Self::Int {
1236                id: IntListFunctionFunctionId(index),
1237                type_,
1238            },
1239            crate::plan::ValueType::String => Self::String {
1240                id: StringListFunctionFunctionId(index),
1241                type_,
1242            },
1243            crate::plan::ValueType::BitArray => Self::BitArray {
1244                id: BitArrayListFunctionFunctionId(index),
1245                type_,
1246            },
1247            crate::plan::ValueType::UtfCodepoint => Self::UtfCodepoint {
1248                id: UtfCodepointListFunctionFunctionId(index),
1249                type_,
1250            },
1251            crate::plan::ValueType::Custom(item_type) => Self::Custom {
1252                id: CustomListFunctionFunctionId(index),
1253                type_,
1254                item_type,
1255            },
1256            crate::plan::ValueType::External(item_type) => Self::External {
1257                id: ExternalListFunctionFunctionId(index),
1258                type_,
1259                item_type,
1260            },
1261            crate::plan::ValueType::Float => Self::Float {
1262                id: FloatListFunctionFunctionId(index),
1263                type_,
1264            },
1265            crate::plan::ValueType::Bool => Self::Bool {
1266                id: BoolListFunctionFunctionId(index),
1267                type_,
1268            },
1269            crate::plan::ValueType::Nil => Self::Nil {
1270                id: NilListFunctionFunctionId(index),
1271                type_,
1272            },
1273            crate::plan::ValueType::Tuple(item_type) => Self::Tuple {
1274                id: TupleListFunctionFunctionId(index),
1275                type_,
1276                item_type,
1277            },
1278            crate::plan::ValueType::List(item_type) => Self::List {
1279                id: ListListFunctionFunctionId(index),
1280                type_,
1281                item_type,
1282            },
1283            crate::plan::ValueType::Function(item_type) => Self::Function {
1284                id: FunctionListFunctionFunctionId(index),
1285                type_,
1286                item_type,
1287            },
1288        }
1289    }
1290
1291    pub(crate) fn type_(&self) -> &crate::plan::FunctionType {
1292        match self {
1293            Self::Generic { type_, .. }
1294            | Self::Int { type_, .. }
1295            | Self::String { type_, .. }
1296            | Self::BitArray { type_, .. }
1297            | Self::UtfCodepoint { type_, .. }
1298            | Self::Custom { type_, .. }
1299            | Self::External { type_, .. }
1300            | Self::Float { type_, .. }
1301            | Self::Bool { type_, .. }
1302            | Self::Nil { type_, .. }
1303            | Self::Tuple { type_, .. }
1304            | Self::List { type_, .. }
1305            | Self::Function { type_, .. } => type_,
1306        }
1307    }
1308
1309    #[cfg(test)]
1310    pub(crate) fn item_type(&self) -> crate::plan::ValueType {
1311        match self {
1312            Self::Generic { parameter, .. } => crate::plan::ValueType::Parameter(*parameter),
1313            Self::Int { .. } => crate::plan::ValueType::Int,
1314            Self::String { .. } => crate::plan::ValueType::String,
1315            Self::BitArray { .. } => crate::plan::ValueType::BitArray,
1316            Self::UtfCodepoint { .. } => crate::plan::ValueType::UtfCodepoint,
1317            Self::Custom { item_type, .. } => crate::plan::ValueType::Custom(item_type.clone()),
1318            Self::External { item_type, .. } => crate::plan::ValueType::External(item_type.clone()),
1319            Self::Float { .. } => crate::plan::ValueType::Float,
1320            Self::Bool { .. } => crate::plan::ValueType::Bool,
1321            Self::Nil { .. } => crate::plan::ValueType::Nil,
1322            Self::Tuple { item_type, .. } => crate::plan::ValueType::Tuple(item_type.clone()),
1323            Self::List { item_type, .. } => crate::plan::ValueType::List(item_type.clone()),
1324            Self::Function { item_type, .. } => crate::plan::ValueType::Function(item_type.clone()),
1325        }
1326    }
1327}
1328
1329impl ListLocal {
1330    pub(crate) fn generic(
1331        local: GenericListLocalId,
1332        parameter: crate::plan::TypeParameterId,
1333    ) -> Self {
1334        Self::Generic { local, parameter }
1335    }
1336
1337    pub(crate) fn int(local: IntListLocalId) -> Self {
1338        Self::Int(local)
1339    }
1340
1341    pub(crate) fn string(local: StringListLocalId) -> Self {
1342        Self::String(local)
1343    }
1344
1345    pub(crate) fn bit_array(local: BitArrayListLocalId) -> Self {
1346        Self::BitArray(local)
1347    }
1348
1349    pub(crate) fn utf_codepoint(local: UtfCodepointListLocalId) -> Self {
1350        Self::UtfCodepoint(local)
1351    }
1352
1353    pub(crate) fn custom(local: CustomListLocalId, item_type: crate::plan::CustomType) -> Self {
1354        Self::Custom { local, item_type }
1355    }
1356
1357    pub(crate) fn external(
1358        local: ExternalListLocalId,
1359        item_type: crate::plan::ExternalType,
1360    ) -> Self {
1361        Self::External { local, item_type }
1362    }
1363
1364    pub(crate) fn float(local: FloatListLocalId) -> Self {
1365        Self::Float(local)
1366    }
1367
1368    pub(crate) fn bool(local: BoolListLocalId) -> Self {
1369        Self::Bool(local)
1370    }
1371
1372    pub(crate) fn nil(local: NilListLocalId) -> Self {
1373        Self::Nil(local)
1374    }
1375
1376    pub(crate) fn tuple(local: TupleListLocalId, item_type: Vec<crate::plan::ValueType>) -> Self {
1377        Self::Tuple { local, item_type }
1378    }
1379
1380    pub(crate) fn list(local: ListListLocalId, item_type: crate::plan::ValueType) -> Self {
1381        Self::List {
1382            local,
1383            item_type: Box::new(item_type),
1384        }
1385    }
1386
1387    pub(crate) fn function(
1388        local: FunctionListLocalId,
1389        item_type: crate::plan::FunctionType,
1390    ) -> Self {
1391        Self::Function { local, item_type }
1392    }
1393
1394    pub(crate) fn item_type(&self) -> crate::plan::ValueType {
1395        match self {
1396            Self::Generic { parameter, .. } => crate::plan::ValueType::Parameter(*parameter),
1397            Self::Int(_) => crate::plan::ValueType::Int,
1398            Self::String(_) => crate::plan::ValueType::String,
1399            Self::BitArray(_) => crate::plan::ValueType::BitArray,
1400            Self::UtfCodepoint(_) => crate::plan::ValueType::UtfCodepoint,
1401            Self::Custom { item_type, .. } => crate::plan::ValueType::Custom(item_type.clone()),
1402            Self::External { item_type, .. } => crate::plan::ValueType::External(item_type.clone()),
1403            Self::Float(_) => crate::plan::ValueType::Float,
1404            Self::Bool(_) => crate::plan::ValueType::Bool,
1405            Self::Nil(_) => crate::plan::ValueType::Nil,
1406            Self::Tuple { item_type, .. } => crate::plan::ValueType::Tuple(item_type.clone()),
1407            Self::List { item_type, .. } => crate::plan::ValueType::List(item_type.clone()),
1408            Self::Function { item_type, .. } => {
1409                crate::plan::ValueType::Function(Box::new(item_type.clone()))
1410            }
1411        }
1412    }
1413
1414    pub(crate) fn value_type(&self) -> crate::plan::ValueType {
1415        crate::plan::ValueType::List(Box::new(self.item_type()))
1416    }
1417
1418    pub(crate) fn family_name(&self) -> &'static str {
1419        match self {
1420            Self::Generic { .. } => "generic",
1421            Self::Int(_) => "int",
1422            Self::String(_) => "string",
1423            Self::BitArray(_) => "bit array",
1424            Self::UtfCodepoint(_) => "utf codepoint",
1425            Self::Custom { .. } => "custom",
1426            Self::External { .. } => "external",
1427            Self::Float(_) => "float",
1428            Self::Bool(_) => "bool",
1429            Self::Nil(_) => "nil",
1430            Self::Tuple { .. } => "tuple",
1431            Self::List { .. } => "list",
1432            Self::Function { .. } => "function",
1433        }
1434    }
1435
1436    pub(crate) fn index(&self) -> usize {
1437        match self {
1438            Self::Generic { local, .. } => local.0,
1439            Self::Int(local) => local.0,
1440            Self::String(local) => local.0,
1441            Self::BitArray(local) => local.0,
1442            Self::UtfCodepoint(local) => local.0,
1443            Self::Custom { local, .. } => local.0,
1444            Self::External { local, .. } => local.0,
1445            Self::Float(local) => local.0,
1446            Self::Bool(local) => local.0,
1447            Self::Nil(local) => local.0,
1448            Self::Tuple { local, .. } => local.0,
1449            Self::List { local, .. } => local.0,
1450            Self::Function { local, .. } => local.0,
1451        }
1452    }
1453}
1454
1455impl std::fmt::Display for FunctionReturnFamily {
1456    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1457        match self {
1458            Self::Generic => f.write_str("Generic"),
1459            Self::Int => f.write_str("Int"),
1460            Self::Float => f.write_str("Float"),
1461            Self::String => f.write_str("String"),
1462            Self::BitArray => f.write_str("BitArray"),
1463            Self::UtfCodepoint => f.write_str("UtfCodepoint"),
1464            Self::Custom => f.write_str("Custom"),
1465            Self::External => f.write_str("External"),
1466            Self::Bool => f.write_str("Bool"),
1467            Self::Nil => f.write_str("Nil"),
1468            Self::Tuple => f.write_str("Tuple"),
1469            Self::List => f.write_str("List"),
1470            Self::Function => f.write_str("Function"),
1471        }
1472    }
1473}
1474
1475#[cfg(test)]
1476mod tests {
1477    use super::{
1478        BitArrayFunctionFunctionId, BitArrayFunctionLocalId, BitArrayListFunctionFunctionId,
1479        BitArrayListFunctionId, BitArrayListFunctionLocalId, BitArrayListLocalId,
1480        BoolFunctionFunctionId, BoolFunctionLocalId, BoolListFunctionFunctionId,
1481        BoolListFunctionId, BoolListFunctionLocalId, CustomFunctionFunctionId, CustomFunctionId,
1482        CustomListFunctionFunctionId, CustomListFunctionId, CustomListFunctionLocalId,
1483        CustomListLocalId, ExternalListFunctionFunctionId, ExternalListFunctionId,
1484        ExternalListFunctionLocalId, ExternalListLocalId, FloatFunctionFunctionId,
1485        FloatFunctionLocalId, FloatListFunctionFunctionId, FloatListFunctionId,
1486        FloatListFunctionLocalId, FunctionFunctionFunctionId, FunctionFunctionId,
1487        FunctionFunctionLocalId, FunctionListFunctionFunctionId, FunctionListFunctionId,
1488        FunctionListFunctionLocalId, FunctionListLocalId, FunctionTemplateId,
1489        GenericListFunctionFunctionId, GenericListFunctionId, GenericListFunctionLocalId,
1490        GenericListLocalId, IntFunctionFunctionId, IntFunctionLocalId, IntListFunctionFunctionId,
1491        IntListFunctionId, IntListFunctionLocalId, IntListLocalId, ListFunctionFunctionId,
1492        ListFunctionId, ListFunctionLocal, ListListFunctionFunctionId, ListListFunctionId,
1493        ListListFunctionLocalId, ListListLocalId, ListLocal, NilFunctionFunctionId,
1494        NilFunctionLocalId, NilListFunctionFunctionId, NilListFunctionId, NilListFunctionLocalId,
1495        NilListLocalId, StringFunctionFunctionId, StringFunctionLocalId,
1496        StringListFunctionFunctionId, StringListFunctionId, StringListFunctionLocalId,
1497        StringListLocalId, TupleFunctionFunctionId, TupleFunctionLocalId,
1498        TupleListFunctionFunctionId, TupleListFunctionId, TupleListFunctionLocalId,
1499        TupleListLocalId, UtfCodepointFunctionFunctionId, UtfCodepointFunctionLocalId,
1500        UtfCodepointListFunctionFunctionId, UtfCodepointListFunctionId,
1501        UtfCodepointListFunctionLocalId, UtfCodepointListLocalId,
1502    };
1503    use crate::plan::{
1504        CustomFunctionType, CustomType, CustomTypeName, ExternalType, ExternalTypeName,
1505        FunctionFunctionType, FunctionType, ValueType,
1506    };
1507
1508    fn custom_type() -> CustomType {
1509        CustomType::new(
1510            CustomTypeName::new("geam".into(), "main".into(), "Boxed".into()),
1511            Vec::new(),
1512        )
1513    }
1514
1515    fn external_type() -> ExternalType {
1516        ExternalType::new(
1517            ExternalTypeName::new("geam".into(), "main".into(), "Resource".into()),
1518            Vec::new(),
1519        )
1520    }
1521
1522    #[test]
1523    fn function_id_index() {
1524        assert_eq!(FunctionTemplateId::new(5).index(), 5);
1525    }
1526
1527    #[test]
1528    fn custom_function_id_owns_its_return_type() {
1529        let type_ = custom_type();
1530        let id = CustomFunctionId::new(5, type_.clone());
1531
1532        assert_eq!(id.index(), 5);
1533        assert_eq!(id.return_type(), &type_);
1534        assert_eq!(
1535            id.into_parts(),
1536            (5, crate::plan::CustomValueShape::any(type_)),
1537        );
1538    }
1539
1540    #[test]
1541    fn function_local_id_debug_surface() {
1542        assert_eq!(
1543            format!("{:?}", IntFunctionLocalId(3)),
1544            "IntFunctionLocalId(3)"
1545        );
1546        assert_eq!(
1547            format!("{:?}", FloatFunctionLocalId(3)),
1548            "FloatFunctionLocalId(3)"
1549        );
1550        assert_eq!(
1551            format!("{:?}", StringFunctionLocalId(3)),
1552            "StringFunctionLocalId(3)"
1553        );
1554        assert_eq!(
1555            format!("{:?}", BitArrayFunctionLocalId(3)),
1556            "BitArrayFunctionLocalId(3)"
1557        );
1558        assert_eq!(
1559            format!("{:?}", UtfCodepointFunctionLocalId(3)),
1560            "UtfCodepointFunctionLocalId(3)"
1561        );
1562        assert_eq!(
1563            format!("{:?}", BoolFunctionLocalId(3)),
1564            "BoolFunctionLocalId(3)"
1565        );
1566        assert_eq!(
1567            format!("{:?}", NilFunctionLocalId(3)),
1568            "NilFunctionLocalId(3)"
1569        );
1570        assert_eq!(
1571            format!("{:?}", TupleFunctionLocalId(3)),
1572            "TupleFunctionLocalId(3)"
1573        );
1574        assert_eq!(
1575            format!(
1576                "{:?}",
1577                crate::plan::ListFunctionLocal::from_item_type(
1578                    3,
1579                    crate::plan::FunctionType::new(
1580                        Vec::new(),
1581                        crate::plan::ValueType::List(Box::new(crate::plan::ValueType::Int))
1582                    ),
1583                    crate::plan::ValueType::Int,
1584                )
1585            ),
1586            "Int { local: IntListFunctionLocalId(3), type_: FunctionType { arguments: [], return_: List(Int) } }"
1587        );
1588        assert_eq!(
1589            format!("{:?}", FunctionFunctionLocalId(3)),
1590            "FunctionFunctionLocalId(3)"
1591        );
1592    }
1593
1594    #[test]
1595    fn function_function_id_typed_projection() {
1596        let custom =
1597            CustomFunctionFunctionId::new(9, CustomFunctionType::new(Vec::new(), custom_type()));
1598        let function = FunctionFunctionFunctionId::new(
1599            6,
1600            FunctionFunctionType::new(Vec::new(), FunctionType::new(Vec::new(), ValueType::Int)),
1601        );
1602        assert_eq!(
1603            FunctionFunctionId::Int(IntFunctionFunctionId(1)).int(),
1604            Some(IntFunctionFunctionId(1)),
1605        );
1606        assert_eq!(
1607            FunctionFunctionId::Float(FloatFunctionFunctionId(6)).float(),
1608            Some(FloatFunctionFunctionId(6)),
1609        );
1610        assert_eq!(
1611            FunctionFunctionId::String(StringFunctionFunctionId(2)).string(),
1612            Some(StringFunctionFunctionId(2)),
1613        );
1614        assert_eq!(
1615            FunctionFunctionId::BitArray(BitArrayFunctionFunctionId(7)).bit_array(),
1616            Some(BitArrayFunctionFunctionId(7)),
1617        );
1618        assert_eq!(
1619            FunctionFunctionId::UtfCodepoint(UtfCodepointFunctionFunctionId(8)).utf_codepoint(),
1620            Some(UtfCodepointFunctionFunctionId(8)),
1621        );
1622        assert_eq!(
1623            FunctionFunctionId::Custom(custom.clone()).custom(),
1624            Some(custom),
1625        );
1626        assert_eq!(
1627            FunctionFunctionId::Bool(BoolFunctionFunctionId(3)).bool(),
1628            Some(BoolFunctionFunctionId(3)),
1629        );
1630        assert_eq!(
1631            FunctionFunctionId::Nil(NilFunctionFunctionId(4)).nil(),
1632            Some(NilFunctionFunctionId(4)),
1633        );
1634        assert_eq!(
1635            FunctionFunctionId::Tuple(TupleFunctionFunctionId(5)).tuple(),
1636            Some(TupleFunctionFunctionId(5)),
1637        );
1638        assert_eq!(
1639            FunctionFunctionId::List(ListFunctionFunctionId::from_item_type(
1640                6,
1641                crate::plan::FunctionType::new(
1642                    Vec::new(),
1643                    crate::plan::ValueType::List(Box::new(crate::plan::ValueType::Int))
1644                ),
1645                crate::plan::ValueType::Int
1646            ))
1647            .list(),
1648            Some(ListFunctionFunctionId::from_item_type(
1649                6,
1650                crate::plan::FunctionType::new(
1651                    Vec::new(),
1652                    crate::plan::ValueType::List(Box::new(crate::plan::ValueType::Int))
1653                ),
1654                crate::plan::ValueType::Int
1655            )),
1656        );
1657        assert_eq!(
1658            FunctionFunctionId::Function(function.clone()).function(),
1659            Some(function),
1660        );
1661    }
1662
1663    #[test]
1664    fn function_function_id_typed_projection_mismatch() {
1665        assert_eq!(
1666            FunctionFunctionId::String(StringFunctionFunctionId(1)).int(),
1667            None,
1668        );
1669        assert_eq!(
1670            FunctionFunctionId::Int(IntFunctionFunctionId(1)).string(),
1671            None,
1672        );
1673        assert_eq!(
1674            FunctionFunctionId::Int(IntFunctionFunctionId(1)).bit_array(),
1675            None,
1676        );
1677        assert_eq!(
1678            FunctionFunctionId::Int(IntFunctionFunctionId(1)).utf_codepoint(),
1679            None,
1680        );
1681        assert_eq!(
1682            FunctionFunctionId::Int(IntFunctionFunctionId(1)).custom(),
1683            None,
1684        );
1685        assert_eq!(
1686            FunctionFunctionId::Int(IntFunctionFunctionId(1)).float(),
1687            None,
1688        );
1689        assert_eq!(
1690            FunctionFunctionId::Int(IntFunctionFunctionId(1)).bool(),
1691            None,
1692        );
1693        assert_eq!(
1694            FunctionFunctionId::Int(IntFunctionFunctionId(1)).nil(),
1695            None
1696        );
1697        assert_eq!(
1698            FunctionFunctionId::Int(IntFunctionFunctionId(1)).tuple(),
1699            None,
1700        );
1701        assert_eq!(
1702            FunctionFunctionId::Int(IntFunctionFunctionId(1)).list(),
1703            None,
1704        );
1705        assert_eq!(
1706            FunctionFunctionId::Int(IntFunctionFunctionId(1)).function(),
1707            None,
1708        );
1709    }
1710
1711    #[test]
1712    fn function_function_id_family() {
1713        assert_eq!(
1714            FunctionFunctionId::Int(IntFunctionFunctionId(1)).family(),
1715            super::FunctionReturnFamily::Int,
1716        );
1717        assert_eq!(
1718            FunctionFunctionId::Float(FloatFunctionFunctionId(1)).family(),
1719            super::FunctionReturnFamily::Float,
1720        );
1721        assert_eq!(
1722            FunctionFunctionId::String(StringFunctionFunctionId(1)).family(),
1723            super::FunctionReturnFamily::String,
1724        );
1725        assert_eq!(
1726            FunctionFunctionId::BitArray(BitArrayFunctionFunctionId(1)).family(),
1727            super::FunctionReturnFamily::BitArray,
1728        );
1729        assert_eq!(
1730            FunctionFunctionId::UtfCodepoint(UtfCodepointFunctionFunctionId(1)).family(),
1731            super::FunctionReturnFamily::UtfCodepoint,
1732        );
1733        assert_eq!(
1734            FunctionFunctionId::Custom(CustomFunctionFunctionId::new(
1735                1,
1736                CustomFunctionType::new(Vec::new(), custom_type()),
1737            ))
1738            .family(),
1739            super::FunctionReturnFamily::Custom,
1740        );
1741        assert_eq!(
1742            FunctionFunctionId::Bool(BoolFunctionFunctionId(1)).family(),
1743            super::FunctionReturnFamily::Bool,
1744        );
1745        assert_eq!(
1746            FunctionFunctionId::Nil(NilFunctionFunctionId(1)).family(),
1747            super::FunctionReturnFamily::Nil,
1748        );
1749        assert_eq!(
1750            FunctionFunctionId::Tuple(TupleFunctionFunctionId(1)).family(),
1751            super::FunctionReturnFamily::Tuple,
1752        );
1753        assert_eq!(
1754            FunctionFunctionId::List(ListFunctionFunctionId::from_item_type(
1755                1,
1756                crate::plan::FunctionType::new(
1757                    Vec::new(),
1758                    crate::plan::ValueType::List(Box::new(crate::plan::ValueType::Int))
1759                ),
1760                crate::plan::ValueType::Int,
1761            ))
1762            .family(),
1763            super::FunctionReturnFamily::List,
1764        );
1765        assert_eq!(
1766            FunctionFunctionId::Function(FunctionFunctionFunctionId::new(
1767                1,
1768                FunctionFunctionType::new(
1769                    Vec::new(),
1770                    FunctionType::new(Vec::new(), ValueType::Int),
1771                ),
1772            ))
1773            .family(),
1774            super::FunctionReturnFamily::Function,
1775        );
1776    }
1777
1778    #[test]
1779    fn function_return_family_display() {
1780        assert_eq!(super::FunctionReturnFamily::Generic.to_string(), "Generic");
1781        assert_eq!(super::FunctionReturnFamily::Int.to_string(), "Int");
1782        assert_eq!(super::FunctionReturnFamily::Float.to_string(), "Float");
1783        assert_eq!(super::FunctionReturnFamily::String.to_string(), "String");
1784        assert_eq!(
1785            super::FunctionReturnFamily::BitArray.to_string(),
1786            "BitArray"
1787        );
1788        assert_eq!(
1789            super::FunctionReturnFamily::UtfCodepoint.to_string(),
1790            "UtfCodepoint"
1791        );
1792        assert_eq!(super::FunctionReturnFamily::Custom.to_string(), "Custom");
1793        assert_eq!(
1794            super::FunctionReturnFamily::External.to_string(),
1795            "External"
1796        );
1797        assert_eq!(super::FunctionReturnFamily::Bool.to_string(), "Bool");
1798        assert_eq!(super::FunctionReturnFamily::Nil.to_string(), "Nil");
1799        assert_eq!(super::FunctionReturnFamily::Tuple.to_string(), "Tuple");
1800        assert_eq!(super::FunctionReturnFamily::List.to_string(), "List");
1801        assert_eq!(
1802            super::FunctionReturnFamily::Function.to_string(),
1803            "Function"
1804        );
1805    }
1806
1807    #[test]
1808    fn list_locals_preserve_item_family() {
1809        let item_types = list_item_types();
1810        let locals = [
1811            ListLocal::int(IntListLocalId(3)),
1812            ListLocal::string(StringListLocalId(3)),
1813            ListLocal::bit_array(BitArrayListLocalId(3)),
1814            ListLocal::utf_codepoint(UtfCodepointListLocalId(3)),
1815            ListLocal::custom(CustomListLocalId(3), custom_type()),
1816            ListLocal::external(ExternalListLocalId(3), external_type()),
1817            ListLocal::float(super::FloatListLocalId(3)),
1818            ListLocal::bool(super::BoolListLocalId(3)),
1819            ListLocal::nil(NilListLocalId(3)),
1820            ListLocal::tuple(TupleListLocalId(3), vec![ValueType::Int, ValueType::String]),
1821            ListLocal::list(ListListLocalId(3), ValueType::Int),
1822            ListLocal::function(
1823                FunctionListLocalId(3),
1824                FunctionType::new(vec![ValueType::Int], ValueType::String),
1825            ),
1826            ListLocal::generic(GenericListLocalId(3), crate::plan::TypeParameterId(0)),
1827        ];
1828
1829        assert_eq!(
1830            locals.iter().map(ListLocal::item_type).collect::<Vec<_>>(),
1831            item_types,
1832        );
1833        assert_eq!(
1834            locals.iter().map(ListLocal::index).collect::<Vec<_>>(),
1835            vec![3; 13],
1836        );
1837    }
1838
1839    #[test]
1840    fn list_function_locals_preserve_item_family_and_type() {
1841        let cases = list_function_type_cases();
1842        let item_types = list_item_types();
1843        let locals = [
1844            ListFunctionLocal::from_item_type(3, cases[0].clone(), item_types[0].clone()),
1845            ListFunctionLocal::from_item_type(3, cases[1].clone(), item_types[1].clone()),
1846            ListFunctionLocal::from_item_type(3, cases[2].clone(), item_types[2].clone()),
1847            ListFunctionLocal::from_item_type(3, cases[3].clone(), item_types[3].clone()),
1848            ListFunctionLocal::from_item_type(3, cases[4].clone(), item_types[4].clone()),
1849            ListFunctionLocal::from_item_type(3, cases[5].clone(), item_types[5].clone()),
1850            ListFunctionLocal::from_item_type(3, cases[6].clone(), item_types[6].clone()),
1851            ListFunctionLocal::from_item_type(3, cases[7].clone(), item_types[7].clone()),
1852            ListFunctionLocal::from_item_type(3, cases[8].clone(), item_types[8].clone()),
1853            ListFunctionLocal::from_item_type(3, cases[9].clone(), item_types[9].clone()),
1854            ListFunctionLocal::from_item_type(3, cases[10].clone(), item_types[10].clone()),
1855            ListFunctionLocal::from_item_type(3, cases[11].clone(), item_types[11].clone()),
1856            ListFunctionLocal::from_item_type(3, cases[12].clone(), item_types[12].clone()),
1857        ];
1858
1859        assert_eq!(
1860            locals,
1861            [
1862                ListFunctionLocal::int(IntListFunctionLocalId(3), cases[0].clone()),
1863                ListFunctionLocal::string(StringListFunctionLocalId(3), cases[1].clone()),
1864                ListFunctionLocal::bit_array(BitArrayListFunctionLocalId(3), cases[2].clone(),),
1865                ListFunctionLocal::utf_codepoint(
1866                    UtfCodepointListFunctionLocalId(3),
1867                    cases[3].clone(),
1868                ),
1869                ListFunctionLocal::custom(
1870                    CustomListFunctionLocalId(3),
1871                    cases[4].clone(),
1872                    custom_type(),
1873                ),
1874                ListFunctionLocal::external(
1875                    ExternalListFunctionLocalId(3),
1876                    cases[5].clone(),
1877                    external_type(),
1878                ),
1879                ListFunctionLocal::float(FloatListFunctionLocalId(3), cases[6].clone()),
1880                ListFunctionLocal::bool(BoolListFunctionLocalId(3), cases[7].clone()),
1881                ListFunctionLocal::nil(NilListFunctionLocalId(3), cases[8].clone()),
1882                ListFunctionLocal::tuple(
1883                    TupleListFunctionLocalId(3),
1884                    cases[9].clone(),
1885                    vec![ValueType::Int, ValueType::String],
1886                ),
1887                ListFunctionLocal::list(
1888                    ListListFunctionLocalId(3),
1889                    cases[10].clone(),
1890                    ValueType::Int,
1891                ),
1892                ListFunctionLocal::function(
1893                    FunctionListFunctionLocalId(3),
1894                    cases[11].clone(),
1895                    FunctionType::new(vec![ValueType::Int], ValueType::String),
1896                ),
1897                ListFunctionLocal::Generic {
1898                    local: GenericListFunctionLocalId(3),
1899                    type_: cases[12].clone(),
1900                    parameter: crate::plan::TypeParameterId(0),
1901                },
1902            ],
1903        );
1904        assert_eq!(
1905            locals
1906                .iter()
1907                .map(ListFunctionLocal::value_type)
1908                .collect::<Vec<_>>(),
1909            cases
1910                .iter()
1911                .cloned()
1912                .map(|type_| ValueType::Function(Box::new(type_)))
1913                .collect::<Vec<_>>(),
1914        );
1915        assert_eq!(
1916            locals
1917                .iter()
1918                .map(ListFunctionLocal::item_type)
1919                .collect::<Vec<_>>(),
1920            item_types,
1921        );
1922        assert_eq!(
1923            locals
1924                .iter()
1925                .map(ListFunctionLocal::index)
1926                .collect::<Vec<_>>(),
1927            vec![3; 13],
1928        );
1929    }
1930
1931    #[test]
1932    fn list_function_ids_preserve_item_family() {
1933        let item_types = list_item_types();
1934        let ids = item_types
1935            .iter()
1936            .cloned()
1937            .map(|item_type| ListFunctionId::from_item_type(5, item_type))
1938            .collect::<Vec<_>>();
1939
1940        assert_eq!(
1941            ids,
1942            vec![
1943                ListFunctionId::Int(IntListFunctionId(5)),
1944                ListFunctionId::String(StringListFunctionId(5)),
1945                ListFunctionId::BitArray(BitArrayListFunctionId(5)),
1946                ListFunctionId::UtfCodepoint(UtfCodepointListFunctionId(5)),
1947                ListFunctionId::Custom {
1948                    id: CustomListFunctionId(5),
1949                    item_type: custom_type(),
1950                },
1951                ListFunctionId::External {
1952                    id: ExternalListFunctionId(5),
1953                    item_type: external_type(),
1954                },
1955                ListFunctionId::Float(FloatListFunctionId(5)),
1956                ListFunctionId::Bool(BoolListFunctionId(5)),
1957                ListFunctionId::Nil(NilListFunctionId(5)),
1958                ListFunctionId::Tuple {
1959                    id: TupleListFunctionId(5),
1960                    item_type: vec![ValueType::Int, ValueType::String],
1961                },
1962                ListFunctionId::List {
1963                    id: ListListFunctionId(5),
1964                    item_type: Box::new(ValueType::Int),
1965                },
1966                ListFunctionId::Function {
1967                    id: FunctionListFunctionId(5),
1968                    item_type: FunctionType::new(vec![ValueType::Int], ValueType::String),
1969                },
1970                ListFunctionId::Generic {
1971                    id: GenericListFunctionId(5),
1972                    parameter: crate::plan::TypeParameterId(0),
1973                },
1974            ],
1975        );
1976        assert_eq!(
1977            ids.iter()
1978                .map(ListFunctionId::item_type)
1979                .collect::<Vec<_>>(),
1980            item_types,
1981        );
1982    }
1983
1984    #[test]
1985    fn list_function_function_ids_preserve_item_family_and_type() {
1986        let cases = list_function_type_cases();
1987        let item_types = list_item_types();
1988        let ids = [
1989            ListFunctionFunctionId::from_item_type(7, cases[0].clone(), item_types[0].clone()),
1990            ListFunctionFunctionId::from_item_type(7, cases[1].clone(), item_types[1].clone()),
1991            ListFunctionFunctionId::from_item_type(7, cases[2].clone(), item_types[2].clone()),
1992            ListFunctionFunctionId::from_item_type(7, cases[3].clone(), item_types[3].clone()),
1993            ListFunctionFunctionId::from_item_type(7, cases[4].clone(), item_types[4].clone()),
1994            ListFunctionFunctionId::from_item_type(7, cases[5].clone(), item_types[5].clone()),
1995            ListFunctionFunctionId::from_item_type(7, cases[6].clone(), item_types[6].clone()),
1996            ListFunctionFunctionId::from_item_type(7, cases[7].clone(), item_types[7].clone()),
1997            ListFunctionFunctionId::from_item_type(7, cases[8].clone(), item_types[8].clone()),
1998            ListFunctionFunctionId::from_item_type(7, cases[9].clone(), item_types[9].clone()),
1999            ListFunctionFunctionId::from_item_type(7, cases[10].clone(), item_types[10].clone()),
2000            ListFunctionFunctionId::from_item_type(7, cases[11].clone(), item_types[11].clone()),
2001            ListFunctionFunctionId::from_item_type(7, cases[12].clone(), item_types[12].clone()),
2002        ];
2003
2004        assert_eq!(
2005            ids,
2006            [
2007                ListFunctionFunctionId::Int {
2008                    id: IntListFunctionFunctionId(7),
2009                    type_: cases[0].clone(),
2010                },
2011                ListFunctionFunctionId::String {
2012                    id: StringListFunctionFunctionId(7),
2013                    type_: cases[1].clone(),
2014                },
2015                ListFunctionFunctionId::BitArray {
2016                    id: BitArrayListFunctionFunctionId(7),
2017                    type_: cases[2].clone(),
2018                },
2019                ListFunctionFunctionId::UtfCodepoint {
2020                    id: UtfCodepointListFunctionFunctionId(7),
2021                    type_: cases[3].clone(),
2022                },
2023                ListFunctionFunctionId::Custom {
2024                    id: CustomListFunctionFunctionId(7),
2025                    type_: cases[4].clone(),
2026                    item_type: custom_type(),
2027                },
2028                ListFunctionFunctionId::External {
2029                    id: ExternalListFunctionFunctionId(7),
2030                    type_: cases[5].clone(),
2031                    item_type: external_type(),
2032                },
2033                ListFunctionFunctionId::Float {
2034                    id: FloatListFunctionFunctionId(7),
2035                    type_: cases[6].clone(),
2036                },
2037                ListFunctionFunctionId::Bool {
2038                    id: BoolListFunctionFunctionId(7),
2039                    type_: cases[7].clone(),
2040                },
2041                ListFunctionFunctionId::Nil {
2042                    id: NilListFunctionFunctionId(7),
2043                    type_: cases[8].clone(),
2044                },
2045                ListFunctionFunctionId::Tuple {
2046                    id: TupleListFunctionFunctionId(7),
2047                    type_: cases[9].clone(),
2048                    item_type: vec![ValueType::Int, ValueType::String],
2049                },
2050                ListFunctionFunctionId::List {
2051                    id: ListListFunctionFunctionId(7),
2052                    type_: cases[10].clone(),
2053                    item_type: Box::new(ValueType::Int),
2054                },
2055                ListFunctionFunctionId::Function {
2056                    id: FunctionListFunctionFunctionId(7),
2057                    type_: cases[11].clone(),
2058                    item_type: Box::new(FunctionType::new(vec![ValueType::Int], ValueType::String)),
2059                },
2060                ListFunctionFunctionId::Generic {
2061                    id: GenericListFunctionFunctionId(7),
2062                    type_: cases[12].clone(),
2063                    parameter: crate::plan::TypeParameterId(0),
2064                },
2065            ],
2066        );
2067        assert_eq!(
2068            ids.iter().map(|id| id.type_().clone()).collect::<Vec<_>>(),
2069            cases,
2070        );
2071        assert_eq!(
2072            ids.iter().map(|id| id.item_type()).collect::<Vec<_>>(),
2073            item_types,
2074        );
2075    }
2076
2077    fn list_function_type_cases() -> [FunctionType; 13] {
2078        list_item_types().map(list_function_type)
2079    }
2080
2081    fn list_item_types() -> [ValueType; 13] {
2082        [
2083            ValueType::Int,
2084            ValueType::String,
2085            ValueType::BitArray,
2086            ValueType::UtfCodepoint,
2087            ValueType::Custom(custom_type()),
2088            ValueType::External(external_type()),
2089            ValueType::Float,
2090            ValueType::Bool,
2091            ValueType::Nil,
2092            ValueType::Tuple(vec![ValueType::Int, ValueType::String]),
2093            ValueType::List(Box::new(ValueType::Int)),
2094            ValueType::Function(Box::new(FunctionType::new(
2095                vec![ValueType::Int],
2096                ValueType::String,
2097            ))),
2098            ValueType::Parameter(crate::plan::TypeParameterId(0)),
2099        ]
2100    }
2101
2102    fn list_function_type(item_type: ValueType) -> FunctionType {
2103        FunctionType::new(Vec::new(), ValueType::List(Box::new(item_type)))
2104    }
2105}