1mod function;
2mod list;
3
4use super::{
5 BitArrayBitsSize, BitArrayExpr, BitArrayFunctionExpr, BitArrayListExpr, BitArrayListItem,
6 BitArraySegment, BoolExpr, BoolFunctionExpr, BoolListExpr, BoolListItem, CustomConstruction,
7 CustomConstructor, CustomExpr, CustomFunctionExpr, CustomListExpr, CustomListItem, Expr,
8 ExternalFunctionExpr, ExternalListExpr, ExternalListItem, FloatExpr, FloatFunctionExpr,
9 FloatListExpr, FloatListItem, FunctionExpr, FunctionFunctionExpr, FunctionListExpr,
10 FunctionListItem, FunctionReference, GenericFunctionExpr, GenericListExpr, GenericListItem,
11 IntExpr, IntFunctionExpr, IntListExpr, IntListItem, ListExpr, ListFunctionExpr, ListListExpr,
12 ListListItem, NilExpr, NilFunctionExpr, NilListExpr, NilListItem, ParameterListListExpr,
13 ParameterListListItem, StoredListExpr, StringExpr, StringFunctionExpr, StringListExpr,
14 StringListItem, TupleExpr, TupleFunctionExpr, TupleListExpr, TupleListItem, TypeScheme,
15 TypeSubstitution, TypedFunctionReference, UtfCodepointFunctionExpr, UtfCodepointListExpr,
16 UtfCodepointListItem,
17};
18use crate::plan::{
19 CustomValueShape, Endianness, ExternalValueShape, FloatBitSize, FunctionShape, PanicSite,
20 StringEncoding, ValueShape, ValueType,
21};
22use ecow::EcoString;
23use num_bigint::BigInt;
24
25pub(crate) use function::{
26 ConstantBitArrayFunctionInstantiation, ConstantBoolFunctionInstantiation,
27 ConstantCustomFunctionInstantiation, ConstantExternalFunctionInstantiation,
28 ConstantFloatFunctionInstantiation, ConstantFunctionFunctionInstantiation,
29 ConstantFunctionInstantiation, ConstantFunctionTemplateSource,
30 ConstantGenericFunctionInstantiation, ConstantIntFunctionInstantiation,
31 ConstantListFunctionInstantiation, ConstantNilFunctionInstantiation,
32 ConstantStringFunctionInstantiation, ConstantTupleFunctionInstantiation,
33 ConstantUtfCodepointFunctionInstantiation,
34};
35use function::{
36 ConstantBitArrayFunctionTemplateId, ConstantBitArrayFunctionValue,
37 ConstantBoolFunctionTemplateId, ConstantBoolFunctionValue, ConstantCustomFunctionTarget,
38 ConstantCustomFunctionTemplateId, ConstantCustomFunctionValue,
39 ConstantExternalFunctionTemplateId, ConstantExternalFunctionValue,
40 ConstantFloatFunctionTemplateId, ConstantFloatFunctionValue,
41 ConstantFunctionFunctionTemplateId, ConstantFunctionFunctionValue, ConstantFunctionTemplate,
42 ConstantFunctionValue, ConstantGenericFunctionTemplateId, ConstantGenericFunctionValue,
43 ConstantIntFunctionTemplateId, ConstantIntFunctionValue, ConstantListFunctionTemplateId,
44 ConstantListFunctionValue, ConstantNilFunctionTemplateId, ConstantNilFunctionValue,
45 ConstantStringFunctionTemplateId, ConstantStringFunctionValue, ConstantTupleFunctionTemplateId,
46 ConstantTupleFunctionValue, ConstantUtfCodepointFunctionTemplateId,
47 ConstantUtfCodepointFunctionValue, TypedConstantFunctionValueKind,
48};
49
50pub(crate) use list::{
51 ConstantBitArrayListInstantiation, ConstantBitArrayListTemplateId,
52 ConstantBoolListInstantiation, ConstantBoolListTemplateId, ConstantCustomListInstantiation,
53 ConstantCustomListTemplateId, ConstantExternalListInstantiation,
54 ConstantExternalListTemplateId, ConstantFloatListInstantiation, ConstantFloatListTemplateId,
55 ConstantFunctionListInstantiation, ConstantFunctionListTemplateId,
56 ConstantGenericListInstantiation, ConstantGenericListTemplateId, ConstantIntListInstantiation,
57 ConstantIntListTemplateId, ConstantListInstantiation, ConstantListListInstantiation,
58 ConstantListListTemplateId, ConstantListTemplateSource, ConstantNestedListTemplateSource,
59 ConstantNilListInstantiation, ConstantNilListTemplateId,
60 ConstantParameterListListInstantiation, ConstantParameterListListTemplateId,
61 ConstantStringListInstantiation, ConstantStringListTemplateId, ConstantTupleListInstantiation,
62 ConstantTupleListTemplateId, ConstantUtfCodepointListInstantiation,
63 ConstantUtfCodepointListTemplateId,
64};
65use list::{
66 ConstantBitArrayListValue, ConstantBoolListValue, ConstantCustomListValue,
67 ConstantExternalListValue, ConstantExternalListValueKind, ConstantFloatListValue,
68 ConstantFunctionListValue, ConstantGenericListValue, ConstantGenericListValueKind,
69 ConstantIntListValue, ConstantListListValue, ConstantListParts, ConstantListTemplate,
70 ConstantListValue, ConstantNilListValue, ConstantParameterListListValue,
71 ConstantStoredListValue, ConstantStringListValue, ConstantTupleListValue,
72 ConstantUtfCodepointListValue, ConstantUtfCodepointListValueKind, TypedConstantListValueKind,
73};
74
75#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
76pub struct ConstantTemplateId {
77 module: crate::plan::ModuleId,
78 index: usize,
79}
80
81#[derive(Debug, Clone, PartialEq)]
82pub struct ConstantTemplate {
83 signature: ConstantTemplateSignature,
84 name: EcoString,
85}
86
87#[derive(Debug, Clone, PartialEq)]
88pub(crate) struct ConstantTemplates {
89 module: crate::plan::ModuleId,
90 headers: Vec<ConstantTemplate>,
91 generic_lists: Vec<ConstantGenericListValue>,
92 ints: Vec<ConstantIntValue>,
93 strings: Vec<ConstantStringValue>,
94 bit_arrays: Vec<ConstantBitArrayValue>,
95 custom_values: Vec<ConstantCustomValue>,
96 floats: Vec<ConstantFloatValue>,
97 bools: Vec<ConstantBoolValue>,
98 nils: Vec<ConstantNilValue>,
99 tuples: Vec<ConstantTupleValue>,
100 int_lists: Vec<ConstantIntListValue>,
101 string_lists: Vec<ConstantStringListValue>,
102 bit_array_lists: Vec<ConstantBitArrayListValue>,
103 utf_codepoint_lists: Vec<ConstantUtfCodepointListValue>,
104 custom_lists: Vec<ConstantCustomListValue>,
105 external_lists: Vec<ConstantExternalListValue>,
106 float_lists: Vec<ConstantFloatListValue>,
107 bool_lists: Vec<ConstantBoolListValue>,
108 nil_lists: Vec<ConstantNilListValue>,
109 tuple_lists: Vec<ConstantTupleListValue>,
110 parameter_list_lists: Vec<ConstantParameterListListValue>,
111 list_lists: Vec<ConstantListListValue>,
112 function_lists: Vec<ConstantFunctionListValue>,
113 generic_functions: Vec<ConstantGenericFunctionValue>,
114 int_functions: Vec<ConstantIntFunctionValue>,
115 string_functions: Vec<ConstantStringFunctionValue>,
116 bit_array_functions: Vec<ConstantBitArrayFunctionValue>,
117 utf_codepoint_functions: Vec<ConstantUtfCodepointFunctionValue>,
118 custom_functions: Vec<ConstantCustomFunctionValue>,
119 external_functions: Vec<ConstantExternalFunctionValue>,
120 float_functions: Vec<ConstantFloatFunctionValue>,
121 bool_functions: Vec<ConstantBoolFunctionValue>,
122 nil_functions: Vec<ConstantNilFunctionValue>,
123 tuple_functions: Vec<ConstantTupleFunctionValue>,
124 list_functions: Vec<ConstantListFunctionValue>,
125 function_functions: Vec<ConstantFunctionFunctionValue>,
126}
127
128#[derive(Debug, Clone, PartialEq, Eq)]
129pub(crate) struct ConstantTemplateSignature {
130 id: ConstantTemplateId,
131 scheme: TypeScheme,
132 shape: ValueShape,
133 kind: ConstantTemplateSignatureKind,
134}
135
136#[derive(Debug, Clone, PartialEq, Eq)]
137enum ConstantTemplateSignatureKind {
138 Int(ConstantIntTemplateId),
139 String(ConstantStringTemplateId),
140 BitArray(ConstantBitArrayTemplateId),
141 Custom {
142 template: ConstantCustomTemplateId,
143 shape: CustomValueShape,
144 },
145 Float(ConstantFloatTemplateId),
146 Bool(ConstantBoolTemplateId),
147 Nil(ConstantNilTemplateId),
148 Tuple {
149 template: ConstantTupleTemplateId,
150 shape: Box<[ValueShape]>,
151 },
152 List(ConstantListTemplate),
153 Function {
154 template: ConstantFunctionTemplate,
155 shape: FunctionShape,
156 },
157}
158
159#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
160pub(crate) struct ConstantIntTemplateId(pub(crate) usize);
161
162#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
163pub(crate) struct ConstantStringTemplateId(pub(crate) usize);
164
165#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
166pub(crate) struct ConstantBitArrayTemplateId(pub(crate) usize);
167
168#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
169pub(crate) struct ConstantCustomTemplateId(pub(crate) usize);
170
171#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
172pub(crate) struct ConstantFloatTemplateId(pub(crate) usize);
173
174#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
175pub(crate) struct ConstantBoolTemplateId(pub(crate) usize);
176
177#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
178pub(crate) struct ConstantNilTemplateId(pub(crate) usize);
179
180#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
181pub(crate) struct ConstantTupleTemplateId(pub(crate) usize);
182
183#[derive(Debug, Clone, PartialEq, Eq, Hash)]
184pub(crate) struct TypedConstantInstantiation<Id, Shape> {
185 module: crate::plan::ModuleId,
186 template: Id,
187 substitution: TypeSubstitution,
188 shape: Shape,
189}
190
191pub(crate) type ConstantIntInstantiation = TypedConstantInstantiation<ConstantIntTemplateId, ()>;
192pub(crate) type ConstantStringInstantiation =
193 TypedConstantInstantiation<ConstantStringTemplateId, ()>;
194pub(crate) type ConstantBitArrayInstantiation =
195 TypedConstantInstantiation<ConstantBitArrayTemplateId, ()>;
196pub(crate) type ConstantCustomInstantiation =
197 TypedConstantInstantiation<ConstantCustomTemplateId, CustomValueShape>;
198pub(crate) type ConstantFloatInstantiation =
199 TypedConstantInstantiation<ConstantFloatTemplateId, ()>;
200pub(crate) type ConstantBoolInstantiation = TypedConstantInstantiation<ConstantBoolTemplateId, ()>;
201pub(crate) type ConstantNilInstantiation = TypedConstantInstantiation<ConstantNilTemplateId, ()>;
202pub(crate) type ConstantTupleInstantiation =
203 TypedConstantInstantiation<ConstantTupleTemplateId, Box<[ValueShape]>>;
204
205#[derive(Debug, Clone, PartialEq, Eq, Hash)]
206pub(crate) struct ConstantInstantiation {
207 kind: ConstantInstantiationKind,
208}
209
210#[derive(Debug, Clone, PartialEq, Eq, Hash)]
211enum ConstantInstantiationKind {
212 Int(ConstantIntInstantiation),
213 String(ConstantStringInstantiation),
214 BitArray(ConstantBitArrayInstantiation),
215 Custom(ConstantCustomInstantiation),
216 Float(ConstantFloatInstantiation),
217 Bool(ConstantBoolInstantiation),
218 Nil(ConstantNilInstantiation),
219 Tuple(ConstantTupleInstantiation),
220 List(ConstantListInstantiation),
221 Function(ConstantFunctionInstantiation),
222}
223
224#[derive(Debug, Clone, PartialEq, Eq, Hash)]
225pub(crate) struct ConstantIntReference(ConstantIntInstantiation);
226
227#[derive(Debug, Clone, PartialEq, Eq, Hash)]
228pub(crate) struct ConstantStringReference(ConstantStringInstantiation);
229
230#[derive(Debug, Clone, PartialEq, Eq, Hash)]
231pub(crate) struct ConstantBitArrayReference(ConstantBitArrayInstantiation);
232
233#[derive(Debug, Clone, PartialEq, Eq, Hash)]
234pub(crate) struct ConstantCustomReference(ConstantCustomInstantiation);
235
236#[derive(Debug, Clone, PartialEq, Eq, Hash)]
237pub(crate) struct ConstantFloatReference(ConstantFloatInstantiation);
238
239#[derive(Debug, Clone, PartialEq, Eq, Hash)]
240pub(crate) struct ConstantBoolReference(ConstantBoolInstantiation);
241
242#[derive(Debug, Clone, PartialEq, Eq, Hash)]
243pub(crate) struct ConstantNilReference(ConstantNilInstantiation);
244
245#[derive(Debug, Clone, PartialEq, Eq, Hash)]
246pub(crate) struct ConstantTupleReference(ConstantTupleInstantiation);
247
248impl ConstantCustomReference {
249 pub(crate) fn instantiation(&self) -> &ConstantCustomInstantiation {
250 &self.0
251 }
252
253 pub(crate) fn shape(&self) -> &CustomValueShape {
254 self.0.shape()
255 }
256}
257
258impl ConstantTupleReference {
259 pub(crate) fn instantiation(&self) -> &ConstantTupleInstantiation {
260 &self.0
261 }
262
263 pub(crate) fn shape(&self) -> &[ValueShape] {
264 self.0.shape()
265 }
266}
267
268impl ConstantIntReference {
269 pub(crate) fn instantiation(&self) -> &ConstantIntInstantiation {
270 &self.0
271 }
272}
273
274impl ConstantStringReference {
275 pub(crate) fn instantiation(&self) -> &ConstantStringInstantiation {
276 &self.0
277 }
278}
279
280impl ConstantBitArrayReference {
281 pub(crate) fn instantiation(&self) -> &ConstantBitArrayInstantiation {
282 &self.0
283 }
284}
285
286impl ConstantFloatReference {
287 pub(crate) fn instantiation(&self) -> &ConstantFloatInstantiation {
288 &self.0
289 }
290}
291
292impl ConstantBoolReference {
293 pub(crate) fn instantiation(&self) -> &ConstantBoolInstantiation {
294 &self.0
295 }
296}
297
298impl ConstantNilReference {
299 pub(crate) fn instantiation(&self) -> &ConstantNilInstantiation {
300 &self.0
301 }
302}
303
304impl ConstantInstantiation {
305 pub(crate) fn from_int(value: ConstantIntInstantiation) -> Self {
306 Self {
307 kind: ConstantInstantiationKind::Int(value),
308 }
309 }
310
311 pub(crate) fn from_string(value: ConstantStringInstantiation) -> Self {
312 Self {
313 kind: ConstantInstantiationKind::String(value),
314 }
315 }
316
317 pub(crate) fn from_bit_array(value: ConstantBitArrayInstantiation) -> Self {
318 Self {
319 kind: ConstantInstantiationKind::BitArray(value),
320 }
321 }
322
323 pub(crate) fn from_custom(value: ConstantCustomInstantiation) -> Self {
324 Self {
325 kind: ConstantInstantiationKind::Custom(value),
326 }
327 }
328
329 pub(crate) fn from_float(value: ConstantFloatInstantiation) -> Self {
330 Self {
331 kind: ConstantInstantiationKind::Float(value),
332 }
333 }
334
335 pub(crate) fn from_bool(value: ConstantBoolInstantiation) -> Self {
336 Self {
337 kind: ConstantInstantiationKind::Bool(value),
338 }
339 }
340
341 pub(crate) fn from_nil(value: ConstantNilInstantiation) -> Self {
342 Self {
343 kind: ConstantInstantiationKind::Nil(value),
344 }
345 }
346
347 pub(crate) fn from_tuple(value: ConstantTupleInstantiation) -> Self {
348 Self {
349 kind: ConstantInstantiationKind::Tuple(value),
350 }
351 }
352
353 pub(crate) fn from_list(value: ConstantListInstantiation) -> Self {
354 Self {
355 kind: ConstantInstantiationKind::List(value),
356 }
357 }
358
359 pub(crate) fn from_function(value: ConstantFunctionInstantiation) -> Self {
360 Self {
361 kind: ConstantInstantiationKind::Function(value),
362 }
363 }
364
365 pub(crate) fn module(&self) -> crate::plan::ModuleId {
366 match &self.kind {
367 ConstantInstantiationKind::Int(value) => value.module(),
368 ConstantInstantiationKind::String(value) => value.module(),
369 ConstantInstantiationKind::BitArray(value) => value.module(),
370 ConstantInstantiationKind::Custom(value) => value.module(),
371 ConstantInstantiationKind::Float(value) => value.module(),
372 ConstantInstantiationKind::Bool(value) => value.module(),
373 ConstantInstantiationKind::Nil(value) => value.module(),
374 ConstantInstantiationKind::Tuple(value) => value.module(),
375 ConstantInstantiationKind::List(value) => value.module(),
376 ConstantInstantiationKind::Function(value) => value.module(),
377 }
378 }
379
380 pub(crate) fn substitute(&self, outer: &TypeSubstitution) -> Self {
381 let kind = match &self.kind {
382 ConstantInstantiationKind::Int(value) => {
383 ConstantInstantiationKind::Int(value.substitute_leaf(outer))
384 }
385 ConstantInstantiationKind::String(value) => {
386 ConstantInstantiationKind::String(value.substitute_leaf(outer))
387 }
388 ConstantInstantiationKind::BitArray(value) => {
389 ConstantInstantiationKind::BitArray(value.substitute_leaf(outer))
390 }
391 ConstantInstantiationKind::Custom(value) => {
392 ConstantInstantiationKind::Custom(value.substitute_custom(outer))
393 }
394 ConstantInstantiationKind::Float(value) => {
395 ConstantInstantiationKind::Float(value.substitute_leaf(outer))
396 }
397 ConstantInstantiationKind::Bool(value) => {
398 ConstantInstantiationKind::Bool(value.substitute_leaf(outer))
399 }
400 ConstantInstantiationKind::Nil(value) => {
401 ConstantInstantiationKind::Nil(value.substitute_leaf(outer))
402 }
403 ConstantInstantiationKind::Tuple(value) => {
404 ConstantInstantiationKind::Tuple(value.substitute_tuple(outer))
405 }
406 ConstantInstantiationKind::List(value) => {
407 ConstantInstantiationKind::List(value.substitute(outer))
408 }
409 ConstantInstantiationKind::Function(value) => {
410 ConstantInstantiationKind::Function(value.substitute(outer))
411 }
412 };
413 Self { kind }
414 }
415}
416
417#[derive(Debug, Clone, PartialEq)]
418pub(crate) enum ConstantIntValue {
419 Value(BigInt),
420 Reference(ConstantIntInstantiation),
421}
422
423#[derive(Debug, Clone, PartialEq)]
424pub(crate) enum ConstantFloatValue {
425 Value(f64),
426 Reference(ConstantFloatInstantiation),
427}
428
429#[derive(Debug, Clone, PartialEq)]
430pub(crate) enum ConstantStringValue {
431 Value(EcoString),
432 Concatenation {
433 left: Box<ConstantStringValue>,
434 right: Box<ConstantStringValue>,
435 },
436 Reference(ConstantStringInstantiation),
437}
438
439#[derive(Debug, Clone, PartialEq)]
440pub(crate) enum ConstantBoolValue {
441 Value(bool),
442 Reference(ConstantBoolInstantiation),
443}
444
445#[derive(Debug, Clone, PartialEq)]
446pub(crate) enum ConstantNilValue {
447 Value,
448 Reference(ConstantNilInstantiation),
449}
450
451#[derive(Debug, Clone, PartialEq)]
452pub(crate) struct ConstantTupleValue {
453 shape: Box<[ValueShape]>,
454 kind: ConstantTupleValueKind,
455}
456
457#[derive(Debug, Clone, PartialEq)]
458pub(crate) enum ConstantTupleValueKind {
459 Value(Box<[ConstantValue]>),
460 Reference(ConstantTupleInstantiation),
461}
462
463#[derive(Debug, Clone, PartialEq)]
464pub(crate) struct ConstantBitArrayValue {
465 kind: ConstantBitArrayValueKind,
466}
467
468#[derive(Debug, Clone, PartialEq)]
469pub(crate) enum ConstantBitArrayValueKind {
470 Value(Box<[ConstantBitArraySegment]>),
471 Reference(ConstantBitArrayInstantiation),
472}
473
474#[derive(Debug, Clone, PartialEq)]
475pub(crate) struct ConstantCustomValue {
476 shape: CustomValueShape,
477 kind: ConstantCustomValueKind,
478}
479
480#[derive(Debug, Clone, PartialEq)]
481pub(crate) enum ConstantCustomValueKind {
482 Construction(ConstantCustomConstruction),
483 Reference(ConstantCustomInstantiation),
484}
485
486#[derive(Debug, Clone, PartialEq)]
487pub(crate) struct ConstantCustomConstruction {
488 constructor: CustomConstructor,
489 fields: Box<[ConstantValue]>,
490}
491
492#[derive(Debug)]
493pub(crate) struct MaterializedConstantCustomConstruction {
494 constructor: CustomConstructor,
495 fields: Box<[super::Expr]>,
496}
497
498#[derive(Debug, Clone, PartialEq)]
499pub(crate) struct ConstantValue {
500 kind: ConstantValueKind,
501}
502
503#[derive(Debug, Clone, PartialEq)]
504enum ConstantValueKind {
505 Int(ConstantIntValue),
506 Float(ConstantFloatValue),
507 String(ConstantStringValue),
508 Bool(ConstantBoolValue),
509 Nil(ConstantNilValue),
510 Tuple(ConstantTupleValue),
511 List(ConstantListValue),
512 BitArray(ConstantBitArrayValue),
513 Custom(ConstantCustomValue),
514 Function(ConstantFunctionValue),
515}
516
517#[derive(Debug, Clone, PartialEq, Eq)]
518pub(crate) enum ConstantListConstructionError {
519 TypeMismatch {
520 expected: ValueType,
521 actual: ValueType,
522 },
523 SpreadWithoutElements,
524}
525
526#[derive(Debug, Clone, PartialEq)]
527pub(crate) enum ConstantBitArraySegment {
528 Int {
529 value: ConstantIntValue,
530 bit_size: usize,
531 endianness: Endianness,
532 },
533 Float {
534 value: ConstantFloatValue,
535 bit_size: FloatBitSize,
536 endianness: Endianness,
537 },
538 String {
539 value: ConstantStringValue,
540 encoding: StringEncoding,
541 },
542 Bits(ConstantBitArrayValue),
543 SizedBits {
544 value: ConstantBitArrayValue,
545 bit_size: usize,
546 site: PanicSite,
547 },
548}
549
550impl ConstantTemplateId {
551 #[cfg(test)]
552 pub(crate) fn new(index: usize) -> Self {
553 Self::in_module(crate::plan::ModuleId::root(), index)
554 }
555
556 pub(crate) fn in_module(module: crate::plan::ModuleId, index: usize) -> Self {
557 Self { module, index }
558 }
559
560 pub fn module(self) -> crate::plan::ModuleId {
561 self.module
562 }
563
564 pub(crate) fn index(self) -> usize {
565 self.index
566 }
567}
568
569impl ConstantTemplate {
570 pub(crate) fn new(signature: ConstantTemplateSignature, name: EcoString) -> Self {
571 Self { signature, name }
572 }
573
574 pub fn id(&self) -> ConstantTemplateId {
575 self.signature.id()
576 }
577
578 pub fn name(&self) -> &EcoString {
579 &self.name
580 }
581
582 pub fn scheme(&self) -> &TypeScheme {
583 self.signature.scheme()
584 }
585
586 #[cfg(test)]
587 pub(crate) fn signature(&self) -> &ConstantTemplateSignature {
588 &self.signature
589 }
590}
591
592impl ConstantTemplates {
593 pub(crate) fn from_module_entries(
594 module: crate::plan::ModuleId,
595 entries: Vec<(ConstantTemplate, ConstantValue)>,
596 ) -> Self {
597 let mut templates = Self {
598 module,
599 headers: Vec::with_capacity(entries.len()),
600 generic_lists: Vec::new(),
601 ints: Vec::new(),
602 strings: Vec::new(),
603 bit_arrays: Vec::new(),
604 custom_values: Vec::new(),
605 floats: Vec::new(),
606 bools: Vec::new(),
607 nils: Vec::new(),
608 tuples: Vec::new(),
609 int_lists: Vec::new(),
610 string_lists: Vec::new(),
611 bit_array_lists: Vec::new(),
612 utf_codepoint_lists: Vec::new(),
613 custom_lists: Vec::new(),
614 external_lists: Vec::new(),
615 float_lists: Vec::new(),
616 bool_lists: Vec::new(),
617 nil_lists: Vec::new(),
618 tuple_lists: Vec::new(),
619 parameter_list_lists: Vec::new(),
620 list_lists: Vec::new(),
621 function_lists: Vec::new(),
622 generic_functions: Vec::new(),
623 int_functions: Vec::new(),
624 string_functions: Vec::new(),
625 bit_array_functions: Vec::new(),
626 utf_codepoint_functions: Vec::new(),
627 custom_functions: Vec::new(),
628 external_functions: Vec::new(),
629 float_functions: Vec::new(),
630 bool_functions: Vec::new(),
631 nil_functions: Vec::new(),
632 tuple_functions: Vec::new(),
633 list_functions: Vec::new(),
634 function_functions: Vec::new(),
635 };
636 for (template, value) in entries {
637 templates.headers.push(template);
638 templates.push_value(value);
639 }
640 templates
641 }
642
643 fn push_value(&mut self, value: ConstantValue) {
644 match value.kind {
645 ConstantValueKind::Int(value) => self.ints.push(value),
646 ConstantValueKind::Float(value) => self.floats.push(value),
647 ConstantValueKind::String(value) => self.strings.push(value),
648 ConstantValueKind::Bool(value) => self.bools.push(value),
649 ConstantValueKind::Nil(value) => self.nils.push(value),
650 ConstantValueKind::Tuple(value) => self.tuples.push(value),
651 ConstantValueKind::List(value) => match value {
652 ConstantListValue::Generic(value) => self.generic_lists.push(value),
653 ConstantListValue::ParameterList(value) => self.parameter_list_lists.push(value),
654 ConstantListValue::Int(value) => self.int_lists.push(value),
655 ConstantListValue::String(value) => self.string_lists.push(value),
656 ConstantListValue::BitArray(value) => self.bit_array_lists.push(value),
657 ConstantListValue::UtfCodepoint(value) => self.utf_codepoint_lists.push(value),
658 ConstantListValue::Custom(value) => self.custom_lists.push(value),
659 ConstantListValue::External(value) => self.external_lists.push(value),
660 ConstantListValue::Float(value) => self.float_lists.push(value),
661 ConstantListValue::Bool(value) => self.bool_lists.push(value),
662 ConstantListValue::Nil(value) => self.nil_lists.push(value),
663 ConstantListValue::Tuple(value) => self.tuple_lists.push(value),
664 ConstantListValue::List(value) => self.list_lists.push(value),
665 ConstantListValue::Function(value) => self.function_lists.push(value),
666 },
667 ConstantValueKind::BitArray(value) => self.bit_arrays.push(value),
668 ConstantValueKind::Custom(value) => self.custom_values.push(value),
669 ConstantValueKind::Function(value) => match value {
670 ConstantFunctionValue::Generic(value) => self.generic_functions.push(value),
671 ConstantFunctionValue::Int(value) => self.int_functions.push(value),
672 ConstantFunctionValue::String(value) => self.string_functions.push(value),
673 ConstantFunctionValue::BitArray(value) => self.bit_array_functions.push(value),
674 ConstantFunctionValue::UtfCodepoint(value) => {
675 self.utf_codepoint_functions.push(value)
676 }
677 ConstantFunctionValue::Custom(value) => self.custom_functions.push(value),
678 ConstantFunctionValue::External(value) => self.external_functions.push(value),
679 ConstantFunctionValue::Float(value) => self.float_functions.push(value),
680 ConstantFunctionValue::Bool(value) => self.bool_functions.push(value),
681 ConstantFunctionValue::Nil(value) => self.nil_functions.push(value),
682 ConstantFunctionValue::Tuple(value) => self.tuple_functions.push(value),
683 ConstantFunctionValue::List(value) => self.list_functions.push(value),
684 ConstantFunctionValue::Function(value) => self.function_functions.push(value),
685 },
686 }
687 }
688
689 #[cfg(test)]
690 pub(crate) fn from_entries(entries: Vec<(ConstantTemplate, ConstantValue)>) -> Self {
691 Self::from_module_entries(crate::plan::ModuleId::root(), entries)
692 }
693
694 #[cfg(test)]
695 pub(crate) fn empty() -> Self {
696 Self::from_entries(Vec::new())
697 }
698
699 fn owns(&self, module: crate::plan::ModuleId) -> bool {
700 self.module == module
701 }
702
703 pub(crate) fn headers(&self) -> &[ConstantTemplate] {
704 &self.headers
705 }
706
707 #[cfg(test)]
708 pub(crate) fn header(&self, id: ConstantTemplateId) -> &ConstantTemplate {
709 &self.headers[id.index()]
710 }
711
712 pub(crate) fn int(&self, id: ConstantIntTemplateId) -> &ConstantIntValue {
713 &self.ints[id.0]
714 }
715
716 pub(crate) fn string(&self, id: ConstantStringTemplateId) -> &ConstantStringValue {
717 &self.strings[id.0]
718 }
719
720 pub(crate) fn bit_array(&self, id: ConstantBitArrayTemplateId) -> &ConstantBitArrayValue {
721 &self.bit_arrays[id.0]
722 }
723
724 pub(crate) fn custom(&self, id: ConstantCustomTemplateId) -> &ConstantCustomValue {
725 &self.custom_values[id.0]
726 }
727
728 pub(crate) fn float(&self, id: ConstantFloatTemplateId) -> &ConstantFloatValue {
729 &self.floats[id.0]
730 }
731
732 pub(crate) fn bool(&self, id: ConstantBoolTemplateId) -> &ConstantBoolValue {
733 &self.bools[id.0]
734 }
735
736 pub(crate) fn nil(&self, id: ConstantNilTemplateId) -> &ConstantNilValue {
737 &self.nils[id.0]
738 }
739
740 pub(crate) fn tuple(&self, id: ConstantTupleTemplateId) -> &ConstantTupleValue {
741 &self.tuples[id.0]
742 }
743
744 fn generic_list(&self, id: ConstantGenericListTemplateId) -> &ConstantGenericListValue {
745 &self.generic_lists[id.0]
746 }
747
748 fn int_list(&self, id: ConstantIntListTemplateId) -> &ConstantIntListValue {
749 &self.int_lists[id.0]
750 }
751
752 fn string_list(&self, id: ConstantStringListTemplateId) -> &ConstantStringListValue {
753 &self.string_lists[id.0]
754 }
755
756 fn bit_array_list(&self, id: ConstantBitArrayListTemplateId) -> &ConstantBitArrayListValue {
757 &self.bit_array_lists[id.0]
758 }
759
760 fn utf_codepoint_list(
761 &self,
762 id: ConstantUtfCodepointListTemplateId,
763 ) -> &ConstantUtfCodepointListValue {
764 &self.utf_codepoint_lists[id.0]
765 }
766
767 fn custom_list(&self, id: ConstantCustomListTemplateId) -> &ConstantCustomListValue {
768 &self.custom_lists[id.0]
769 }
770
771 fn external_list(&self, id: ConstantExternalListTemplateId) -> &ConstantExternalListValue {
772 &self.external_lists[id.0]
773 }
774
775 fn float_list(&self, id: ConstantFloatListTemplateId) -> &ConstantFloatListValue {
776 &self.float_lists[id.0]
777 }
778
779 fn bool_list(&self, id: ConstantBoolListTemplateId) -> &ConstantBoolListValue {
780 &self.bool_lists[id.0]
781 }
782
783 fn nil_list(&self, id: ConstantNilListTemplateId) -> &ConstantNilListValue {
784 &self.nil_lists[id.0]
785 }
786
787 fn tuple_list(&self, id: ConstantTupleListTemplateId) -> &ConstantTupleListValue {
788 &self.tuple_lists[id.0]
789 }
790
791 fn list_list(&self, id: ConstantListListTemplateId) -> &ConstantListListValue {
792 &self.list_lists[id.0]
793 }
794
795 fn parameter_list_list(
796 &self,
797 id: ConstantParameterListListTemplateId,
798 ) -> &ConstantParameterListListValue {
799 &self.parameter_list_lists[id.0]
800 }
801
802 fn function_list(&self, id: ConstantFunctionListTemplateId) -> &ConstantFunctionListValue {
803 &self.function_lists[id.0]
804 }
805
806 fn generic_function(
807 &self,
808 id: ConstantGenericFunctionTemplateId,
809 ) -> &ConstantGenericFunctionValue {
810 &self.generic_functions[id.0]
811 }
812
813 fn int_function(&self, id: ConstantIntFunctionTemplateId) -> &ConstantIntFunctionValue {
814 &self.int_functions[id.0]
815 }
816
817 fn string_function(
818 &self,
819 id: ConstantStringFunctionTemplateId,
820 ) -> &ConstantStringFunctionValue {
821 &self.string_functions[id.0]
822 }
823
824 fn bit_array_function(
825 &self,
826 id: ConstantBitArrayFunctionTemplateId,
827 ) -> &ConstantBitArrayFunctionValue {
828 &self.bit_array_functions[id.0]
829 }
830
831 fn utf_codepoint_function(
832 &self,
833 id: ConstantUtfCodepointFunctionTemplateId,
834 ) -> &ConstantUtfCodepointFunctionValue {
835 &self.utf_codepoint_functions[id.0]
836 }
837
838 fn custom_function(
839 &self,
840 id: ConstantCustomFunctionTemplateId,
841 ) -> &ConstantCustomFunctionValue {
842 &self.custom_functions[id.0]
843 }
844
845 fn external_function(
846 &self,
847 id: ConstantExternalFunctionTemplateId,
848 ) -> &ConstantExternalFunctionValue {
849 &self.external_functions[id.0]
850 }
851
852 fn float_function(&self, id: ConstantFloatFunctionTemplateId) -> &ConstantFloatFunctionValue {
853 &self.float_functions[id.0]
854 }
855
856 fn bool_function(&self, id: ConstantBoolFunctionTemplateId) -> &ConstantBoolFunctionValue {
857 &self.bool_functions[id.0]
858 }
859
860 fn nil_function(&self, id: ConstantNilFunctionTemplateId) -> &ConstantNilFunctionValue {
861 &self.nil_functions[id.0]
862 }
863
864 fn tuple_function(&self, id: ConstantTupleFunctionTemplateId) -> &ConstantTupleFunctionValue {
865 &self.tuple_functions[id.0]
866 }
867
868 fn list_function(&self, id: ConstantListFunctionTemplateId) -> &ConstantListFunctionValue {
869 &self.list_functions[id.0]
870 }
871
872 fn function_function(
873 &self,
874 id: ConstantFunctionFunctionTemplateId,
875 ) -> &ConstantFunctionFunctionValue {
876 &self.function_functions[id.0]
877 }
878
879 pub(crate) fn reference(instantiation: ConstantInstantiation) -> Expr {
880 match instantiation.kind {
881 ConstantInstantiationKind::Int(value) => {
882 Expr::int(IntExpr::constant(ConstantIntReference(value)))
883 }
884 ConstantInstantiationKind::String(value) => {
885 Expr::string(StringExpr::constant(ConstantStringReference(value)))
886 }
887 ConstantInstantiationKind::BitArray(value) => {
888 Expr::bit_array(BitArrayExpr::constant(ConstantBitArrayReference(value)))
889 }
890 ConstantInstantiationKind::Custom(value) => {
891 Expr::custom(CustomExpr::constant(ConstantCustomReference(value)))
892 }
893 ConstantInstantiationKind::Float(value) => {
894 Expr::float(FloatExpr::constant(ConstantFloatReference(value)))
895 }
896 ConstantInstantiationKind::Bool(value) => {
897 Expr::bool(BoolExpr::constant(ConstantBoolReference(value)))
898 }
899 ConstantInstantiationKind::Nil(value) => {
900 Expr::nil(NilExpr::constant(ConstantNilReference(value)))
901 }
902 ConstantInstantiationKind::Tuple(value) => {
903 Expr::tuple(TupleExpr::constant(ConstantTupleReference(value)))
904 }
905 ConstantInstantiationKind::List(value) => Expr::list(ListExpr::constant(value)),
906 ConstantInstantiationKind::Function(value) => {
907 Expr::function(FunctionExpr::constant(value.clone()))
908 }
909 }
910 }
911
912 fn materialize_value(&self, value: &ConstantValue, substitution: &TypeSubstitution) -> Expr {
913 match &value.kind {
914 ConstantValueKind::Int(value) => {
915 Expr::int(self.materialize_int_value(value, substitution))
916 }
917 ConstantValueKind::Float(value) => {
918 Expr::float(self.materialize_float_value(value, substitution))
919 }
920 ConstantValueKind::String(value) => {
921 Expr::string(self.materialize_string_value(value, substitution))
922 }
923 ConstantValueKind::Bool(value) => {
924 Expr::bool(self.materialize_bool_value(value, substitution))
925 }
926 ConstantValueKind::Nil(value) => {
927 Expr::nil(self.materialize_nil_value(value, substitution))
928 }
929 ConstantValueKind::Tuple(value) => {
930 Expr::tuple(self.materialize_tuple_value(value, substitution))
931 }
932 ConstantValueKind::List(value) => {
933 Expr::list(self.materialize_list_value(value, substitution))
934 }
935 ConstantValueKind::BitArray(value) => {
936 Expr::bit_array(self.materialize_bit_array_value(value, substitution))
937 }
938 ConstantValueKind::Custom(value) => {
939 Expr::custom(self.materialize_custom_value(value, substitution))
940 }
941 ConstantValueKind::Function(value) => {
942 Expr::function(self.materialize_function_value(value, substitution))
943 }
944 }
945 }
946
947 pub(crate) fn materialize_int(&self, value: &ConstantIntInstantiation) -> IntExpr {
948 if !self.owns(value.module()) {
949 return IntExpr::constant(ConstantIntReference(value.clone()));
950 }
951 self.materialize_int_value(self.int(value.template()), value.substitution())
952 }
953
954 fn materialize_int_value(
955 &self,
956 value: &ConstantIntValue,
957 substitution: &TypeSubstitution,
958 ) -> IntExpr {
959 match value {
960 ConstantIntValue::Value(value) => IntExpr::value(value.clone()),
961 ConstantIntValue::Reference(value) => {
962 self.materialize_int(&value.substitute_leaf(substitution))
963 }
964 }
965 }
966
967 pub(crate) fn materialize_float(&self, value: &ConstantFloatInstantiation) -> FloatExpr {
968 if !self.owns(value.module()) {
969 return FloatExpr::constant(ConstantFloatReference(value.clone()));
970 }
971 self.materialize_float_value(self.float(value.template()), value.substitution())
972 }
973
974 fn materialize_float_value(
975 &self,
976 value: &ConstantFloatValue,
977 substitution: &TypeSubstitution,
978 ) -> FloatExpr {
979 match value {
980 ConstantFloatValue::Value(value) => FloatExpr::value(*value),
981 ConstantFloatValue::Reference(value) => {
982 self.materialize_float(&value.substitute_leaf(substitution))
983 }
984 }
985 }
986
987 pub(crate) fn materialize_string(&self, value: &ConstantStringInstantiation) -> StringExpr {
988 if !self.owns(value.module()) {
989 return StringExpr::constant(ConstantStringReference(value.clone()));
990 }
991 self.materialize_string_value(self.string(value.template()), value.substitution())
992 }
993
994 fn materialize_string_value(
995 &self,
996 value: &ConstantStringValue,
997 substitution: &TypeSubstitution,
998 ) -> StringExpr {
999 match value {
1000 ConstantStringValue::Value(value) => StringExpr::value(value.clone()),
1001 ConstantStringValue::Concatenation { left, right } => StringExpr::concatenate(
1002 self.materialize_string_value(left, substitution),
1003 self.materialize_string_value(right, substitution),
1004 ),
1005 ConstantStringValue::Reference(value) => {
1006 self.materialize_string(&value.substitute_leaf(substitution))
1007 }
1008 }
1009 }
1010
1011 pub(crate) fn materialize_bool(&self, value: &ConstantBoolInstantiation) -> BoolExpr {
1012 if !self.owns(value.module()) {
1013 return BoolExpr::constant(ConstantBoolReference(value.clone()));
1014 }
1015 self.materialize_bool_value(self.bool(value.template()), value.substitution())
1016 }
1017
1018 fn materialize_bool_value(
1019 &self,
1020 value: &ConstantBoolValue,
1021 substitution: &TypeSubstitution,
1022 ) -> BoolExpr {
1023 match value {
1024 ConstantBoolValue::Value(value) => BoolExpr::value(*value),
1025 ConstantBoolValue::Reference(value) => {
1026 self.materialize_bool(&value.substitute_leaf(substitution))
1027 }
1028 }
1029 }
1030
1031 pub(crate) fn materialize_nil(&self, value: &ConstantNilInstantiation) -> NilExpr {
1032 if !self.owns(value.module()) {
1033 return NilExpr::constant(ConstantNilReference(value.clone()));
1034 }
1035 self.materialize_nil_value(self.nil(value.template()), value.substitution())
1036 }
1037
1038 fn materialize_nil_value(
1039 &self,
1040 value: &ConstantNilValue,
1041 substitution: &TypeSubstitution,
1042 ) -> NilExpr {
1043 match value {
1044 ConstantNilValue::Value => NilExpr::value(),
1045 ConstantNilValue::Reference(value) => {
1046 self.materialize_nil(&value.substitute_leaf(substitution))
1047 }
1048 }
1049 }
1050
1051 pub(crate) fn materialize_tuple(&self, value: &ConstantTupleInstantiation) -> TupleExpr {
1052 if !self.owns(value.module()) {
1053 return TupleExpr::constant(ConstantTupleReference(value.clone()));
1054 }
1055 self.materialize_tuple_value(self.tuple(value.template()), value.substitution())
1056 }
1057
1058 fn materialize_tuple_value(
1059 &self,
1060 value: &ConstantTupleValue,
1061 substitution: &TypeSubstitution,
1062 ) -> TupleExpr {
1063 match value.kind() {
1064 ConstantTupleValueKind::Value(elements) => {
1065 let shape = value
1066 .shape()
1067 .iter()
1068 .map(|shape| shape.substitute(substitution))
1069 .collect::<Vec<_>>()
1070 .into_boxed_slice();
1071 TupleExpr::value(
1072 elements
1073 .iter()
1074 .map(|element| self.materialize_value(element, substitution))
1075 .collect(),
1076 shape.iter().map(ValueShape::value_type).collect(),
1077 )
1078 .with_shape(shape)
1079 }
1080 ConstantTupleValueKind::Reference(value) => {
1081 self.materialize_tuple(&value.substitute_tuple(substitution))
1082 }
1083 }
1084 }
1085
1086 pub(crate) fn materialize_bit_array(
1087 &self,
1088 value: &ConstantBitArrayInstantiation,
1089 ) -> BitArrayExpr {
1090 if !self.owns(value.module()) {
1091 return BitArrayExpr::constant(ConstantBitArrayReference(value.clone()));
1092 }
1093 self.materialize_bit_array_value(self.bit_array(value.template()), value.substitution())
1094 }
1095
1096 fn materialize_bit_array_value(
1097 &self,
1098 value: &ConstantBitArrayValue,
1099 substitution: &TypeSubstitution,
1100 ) -> BitArrayExpr {
1101 match value.kind() {
1102 ConstantBitArrayValueKind::Value(segments) => BitArrayExpr::value(
1103 segments
1104 .iter()
1105 .map(|segment| self.materialize_bit_array_segment(segment, substitution))
1106 .collect(),
1107 ),
1108 ConstantBitArrayValueKind::Reference(value) => {
1109 self.materialize_bit_array(&value.substitute_leaf(substitution))
1110 }
1111 }
1112 }
1113
1114 fn materialize_bit_array_segment(
1115 &self,
1116 segment: &ConstantBitArraySegment,
1117 substitution: &TypeSubstitution,
1118 ) -> BitArraySegment {
1119 match segment {
1120 ConstantBitArraySegment::Int {
1121 value,
1122 bit_size,
1123 endianness,
1124 } => BitArraySegment::Int {
1125 value: self.materialize_int_value(value, substitution),
1126 bit_size: *bit_size,
1127 endianness: *endianness,
1128 },
1129 ConstantBitArraySegment::Float {
1130 value,
1131 bit_size,
1132 endianness,
1133 } => BitArraySegment::Float {
1134 value: self.materialize_float_value(value, substitution),
1135 bit_size: *bit_size,
1136 endianness: *endianness,
1137 },
1138 ConstantBitArraySegment::String { value, encoding } => BitArraySegment::String {
1139 value: self.materialize_string_value(value, substitution),
1140 encoding: *encoding,
1141 },
1142 ConstantBitArraySegment::Bits(value) => {
1143 BitArraySegment::Bits(self.materialize_bit_array_value(value, substitution))
1144 }
1145 ConstantBitArraySegment::SizedBits {
1146 value,
1147 bit_size,
1148 site,
1149 } => BitArraySegment::SizedBits {
1150 value: self.materialize_bit_array_value(value, substitution),
1151 size: BitArrayBitsSize::Fixed(*bit_size),
1152 site: site.clone(),
1153 },
1154 }
1155 }
1156
1157 pub(crate) fn materialize_custom(&self, value: &ConstantCustomInstantiation) -> CustomExpr {
1158 if !self.owns(value.module()) {
1159 return CustomExpr::constant(ConstantCustomReference(value.clone()));
1160 }
1161 self.materialize_custom_value(self.custom(value.template()), value.substitution())
1162 }
1163
1164 fn materialize_custom_value(
1165 &self,
1166 value: &ConstantCustomValue,
1167 substitution: &TypeSubstitution,
1168 ) -> CustomExpr {
1169 match value.kind() {
1170 ConstantCustomValueKind::Construction(construction) => {
1171 let construction = MaterializedConstantCustomConstruction::new(
1172 construction.constructor().substitute(substitution),
1173 construction
1174 .fields()
1175 .iter()
1176 .map(|field| self.materialize_value(field, substitution))
1177 .collect(),
1178 );
1179 CustomExpr::from_construction(
1180 value.shape().substitute(substitution),
1181 CustomConstruction::from_constant(construction),
1182 )
1183 }
1184 ConstantCustomValueKind::Reference(value) => {
1185 self.materialize_custom(&value.substitute_custom(substitution))
1186 }
1187 }
1188 }
1189
1190 fn materialize_function_value(
1191 &self,
1192 value: &ConstantFunctionValue,
1193 substitution: &TypeSubstitution,
1194 ) -> FunctionExpr {
1195 match value {
1196 ConstantFunctionValue::Generic(value) => match value.kind() {
1197 TypedConstantFunctionValueKind::Target(reference) => {
1198 FunctionExpr::reference(reference.substitute(substitution))
1199 }
1200 TypedConstantFunctionValueKind::Reference(reference) => FunctionExpr::constant(
1201 ConstantFunctionInstantiation::Generic(reference.clone())
1202 .substitute(substitution),
1203 ),
1204 },
1205 ConstantFunctionValue::Int(value) => match value.kind() {
1206 TypedConstantFunctionValueKind::Target(reference) => {
1207 FunctionExpr::reference(reference.substitute(substitution))
1208 }
1209 TypedConstantFunctionValueKind::Reference(reference) => FunctionExpr::constant(
1210 ConstantFunctionInstantiation::Int(reference.substitute(substitution)),
1211 ),
1212 },
1213 ConstantFunctionValue::String(value) => match value.kind() {
1214 TypedConstantFunctionValueKind::Target(reference) => {
1215 FunctionExpr::reference(reference.substitute(substitution))
1216 }
1217 TypedConstantFunctionValueKind::Reference(reference) => FunctionExpr::constant(
1218 ConstantFunctionInstantiation::String(reference.substitute(substitution)),
1219 ),
1220 },
1221 ConstantFunctionValue::BitArray(value) => match value.kind() {
1222 TypedConstantFunctionValueKind::Target(reference) => {
1223 FunctionExpr::reference(reference.substitute(substitution))
1224 }
1225 TypedConstantFunctionValueKind::Reference(reference) => FunctionExpr::constant(
1226 ConstantFunctionInstantiation::BitArray(reference.substitute(substitution)),
1227 ),
1228 },
1229 ConstantFunctionValue::UtfCodepoint(value) => match value.kind() {
1230 TypedConstantFunctionValueKind::Target(reference) => {
1231 FunctionExpr::reference(reference.substitute(substitution))
1232 }
1233 TypedConstantFunctionValueKind::Reference(reference) => FunctionExpr::constant(
1234 ConstantFunctionInstantiation::UtfCodepoint(reference.substitute(substitution)),
1235 ),
1236 },
1237 ConstantFunctionValue::Custom(value) => match value.kind() {
1238 TypedConstantFunctionValueKind::Target(
1239 ConstantCustomFunctionTarget::Reference(reference),
1240 ) => FunctionExpr::reference(reference.substitute(substitution)),
1241 TypedConstantFunctionValueKind::Target(
1242 ConstantCustomFunctionTarget::Constructor(constructor),
1243 ) => FunctionExpr::custom(CustomFunctionExpr::constructor(
1244 constructor.substitute(substitution),
1245 )),
1246 TypedConstantFunctionValueKind::Reference(reference) => FunctionExpr::constant(
1247 ConstantFunctionInstantiation::Custom(reference.substitute(substitution)),
1248 ),
1249 },
1250 ConstantFunctionValue::External(value) => match value.kind() {
1251 TypedConstantFunctionValueKind::Target(reference) => {
1252 FunctionExpr::reference(reference.substitute(substitution))
1253 }
1254 TypedConstantFunctionValueKind::Reference(reference) => FunctionExpr::constant(
1255 ConstantFunctionInstantiation::External(reference.substitute(substitution)),
1256 ),
1257 },
1258 ConstantFunctionValue::Float(value) => match value.kind() {
1259 TypedConstantFunctionValueKind::Target(reference) => {
1260 FunctionExpr::reference(reference.substitute(substitution))
1261 }
1262 TypedConstantFunctionValueKind::Reference(reference) => FunctionExpr::constant(
1263 ConstantFunctionInstantiation::Float(reference.substitute(substitution)),
1264 ),
1265 },
1266 ConstantFunctionValue::Bool(value) => match value.kind() {
1267 TypedConstantFunctionValueKind::Target(reference) => {
1268 FunctionExpr::reference(reference.substitute(substitution))
1269 }
1270 TypedConstantFunctionValueKind::Reference(reference) => FunctionExpr::constant(
1271 ConstantFunctionInstantiation::Bool(reference.substitute(substitution)),
1272 ),
1273 },
1274 ConstantFunctionValue::Nil(value) => match value.kind() {
1275 TypedConstantFunctionValueKind::Target(reference) => {
1276 FunctionExpr::reference(reference.substitute(substitution))
1277 }
1278 TypedConstantFunctionValueKind::Reference(reference) => FunctionExpr::constant(
1279 ConstantFunctionInstantiation::Nil(reference.substitute(substitution)),
1280 ),
1281 },
1282 ConstantFunctionValue::Tuple(value) => match value.kind() {
1283 TypedConstantFunctionValueKind::Target(reference) => {
1284 FunctionExpr::reference(reference.substitute(substitution))
1285 }
1286 TypedConstantFunctionValueKind::Reference(reference) => FunctionExpr::constant(
1287 ConstantFunctionInstantiation::Tuple(reference.substitute(substitution)),
1288 ),
1289 },
1290 ConstantFunctionValue::List(value) => match value.kind() {
1291 TypedConstantFunctionValueKind::Target(reference) => {
1292 FunctionExpr::reference(reference.substitute(substitution))
1293 }
1294 TypedConstantFunctionValueKind::Reference(reference) => FunctionExpr::constant(
1295 ConstantFunctionInstantiation::List(reference.substitute(substitution)),
1296 ),
1297 },
1298 ConstantFunctionValue::Function(value) => match value.kind() {
1299 TypedConstantFunctionValueKind::Target(reference) => {
1300 FunctionExpr::reference(reference.substitute(substitution))
1301 }
1302 TypedConstantFunctionValueKind::Reference(reference) => FunctionExpr::constant(
1303 ConstantFunctionInstantiation::Function(reference.substitute(substitution)),
1304 ),
1305 },
1306 }
1307 }
1308
1309 fn typed_function_reference<Function>(
1310 reference: &FunctionReference,
1311 substitution: &TypeSubstitution,
1312 ) -> TypedFunctionReference<Function> {
1313 TypedFunctionReference::new(reference.substitute(substitution).into_instantiation())
1314 }
1315
1316 pub(crate) fn materialize_generic_function(
1317 &self,
1318 value: &ConstantGenericFunctionInstantiation,
1319 ) -> GenericFunctionExpr {
1320 let type_ = crate::plan::GenericFunctionType::new(
1321 value.shape().argument_shapes().to_vec(),
1322 *value.return_(),
1323 );
1324 match self.generic_function(*value.source()).kind() {
1325 TypedConstantFunctionValueKind::Target(reference) => GenericFunctionExpr::reference(
1326 Self::typed_function_reference(reference, value.substitution()),
1327 type_,
1328 ),
1329 TypedConstantFunctionValueKind::Reference(reference) => GenericFunctionExpr::constant(
1330 reference.substitute_generic(value.substitution(), *value.return_()),
1331 type_,
1332 ),
1333 }
1334 }
1335
1336 pub(crate) fn materialize_int_function(
1337 &self,
1338 value: &ConstantIntFunctionInstantiation,
1339 ) -> IntFunctionExpr {
1340 let type_ = value.shape().type_();
1341 match value.source() {
1342 ConstantFunctionTemplateSource::Generic(source) => {
1343 match self.generic_function(*source).kind() {
1344 TypedConstantFunctionValueKind::Target(reference) => {
1345 IntFunctionExpr::reference(Self::typed_function_reference(
1346 reference,
1347 value.substitution(),
1348 ))
1349 }
1350 TypedConstantFunctionValueKind::Reference(reference) => {
1351 IntFunctionExpr::constant(
1352 reference.specialize(value.substitution(), ()),
1353 type_,
1354 )
1355 }
1356 }
1357 }
1358 ConstantFunctionTemplateSource::Exact(source) => {
1359 match self.int_function(*source).kind() {
1360 TypedConstantFunctionValueKind::Target(reference) => {
1361 IntFunctionExpr::reference(Self::typed_function_reference(
1362 reference,
1363 value.substitution(),
1364 ))
1365 }
1366 TypedConstantFunctionValueKind::Reference(reference) => {
1367 let reference = reference.substitute(value.substitution());
1368 let type_ = reference.shape().type_();
1369 IntFunctionExpr::constant(reference, type_)
1370 }
1371 }
1372 }
1373 }
1374 }
1375
1376 pub(crate) fn materialize_string_function(
1377 &self,
1378 value: &ConstantStringFunctionInstantiation,
1379 ) -> StringFunctionExpr {
1380 let type_ = value.shape().type_();
1381 match value.source() {
1382 ConstantFunctionTemplateSource::Generic(source) => {
1383 match self.generic_function(*source).kind() {
1384 TypedConstantFunctionValueKind::Target(reference) => {
1385 StringFunctionExpr::reference(Self::typed_function_reference(
1386 reference,
1387 value.substitution(),
1388 ))
1389 }
1390 TypedConstantFunctionValueKind::Reference(reference) => {
1391 StringFunctionExpr::constant(
1392 reference.specialize(value.substitution(), ()),
1393 type_,
1394 )
1395 }
1396 }
1397 }
1398 ConstantFunctionTemplateSource::Exact(source) => {
1399 match self.string_function(*source).kind() {
1400 TypedConstantFunctionValueKind::Target(reference) => {
1401 StringFunctionExpr::reference(Self::typed_function_reference(
1402 reference,
1403 value.substitution(),
1404 ))
1405 }
1406 TypedConstantFunctionValueKind::Reference(reference) => {
1407 let reference = reference.substitute(value.substitution());
1408 let type_ = reference.shape().type_();
1409 StringFunctionExpr::constant(reference, type_)
1410 }
1411 }
1412 }
1413 }
1414 }
1415
1416 pub(crate) fn materialize_bit_array_function(
1417 &self,
1418 value: &ConstantBitArrayFunctionInstantiation,
1419 ) -> BitArrayFunctionExpr {
1420 let type_ = value.shape().type_();
1421 match value.source() {
1422 ConstantFunctionTemplateSource::Generic(source) => {
1423 match self.generic_function(*source).kind() {
1424 TypedConstantFunctionValueKind::Target(reference) => {
1425 BitArrayFunctionExpr::reference(Self::typed_function_reference(
1426 reference,
1427 value.substitution(),
1428 ))
1429 }
1430 TypedConstantFunctionValueKind::Reference(reference) => {
1431 BitArrayFunctionExpr::constant(
1432 reference.specialize(value.substitution(), ()),
1433 type_,
1434 )
1435 }
1436 }
1437 }
1438 ConstantFunctionTemplateSource::Exact(source) => {
1439 match self.bit_array_function(*source).kind() {
1440 TypedConstantFunctionValueKind::Target(reference) => {
1441 BitArrayFunctionExpr::reference(Self::typed_function_reference(
1442 reference,
1443 value.substitution(),
1444 ))
1445 }
1446 TypedConstantFunctionValueKind::Reference(reference) => {
1447 let reference = reference.substitute(value.substitution());
1448 let type_ = reference.shape().type_();
1449 BitArrayFunctionExpr::constant(reference, type_)
1450 }
1451 }
1452 }
1453 }
1454 }
1455
1456 pub(crate) fn materialize_utf_codepoint_function(
1457 &self,
1458 value: &ConstantUtfCodepointFunctionInstantiation,
1459 ) -> UtfCodepointFunctionExpr {
1460 let type_ = value.shape().type_();
1461 match value.source() {
1462 ConstantFunctionTemplateSource::Generic(source) => {
1463 match self.generic_function(*source).kind() {
1464 TypedConstantFunctionValueKind::Target(reference) => {
1465 UtfCodepointFunctionExpr::reference(Self::typed_function_reference(
1466 reference,
1467 value.substitution(),
1468 ))
1469 }
1470 TypedConstantFunctionValueKind::Reference(reference) => {
1471 UtfCodepointFunctionExpr::constant(
1472 reference.specialize(value.substitution(), ()),
1473 type_,
1474 )
1475 }
1476 }
1477 }
1478 ConstantFunctionTemplateSource::Exact(source) => {
1479 match self.utf_codepoint_function(*source).kind() {
1480 TypedConstantFunctionValueKind::Target(reference) => {
1481 UtfCodepointFunctionExpr::reference(Self::typed_function_reference(
1482 reference,
1483 value.substitution(),
1484 ))
1485 }
1486 TypedConstantFunctionValueKind::Reference(reference) => {
1487 let reference = reference.substitute(value.substitution());
1488 let type_ = reference.shape().type_();
1489 UtfCodepointFunctionExpr::constant(reference, type_)
1490 }
1491 }
1492 }
1493 }
1494 }
1495
1496 pub(crate) fn materialize_float_function(
1497 &self,
1498 value: &ConstantFloatFunctionInstantiation,
1499 ) -> FloatFunctionExpr {
1500 let type_ = value.shape().type_();
1501 match value.source() {
1502 ConstantFunctionTemplateSource::Generic(source) => {
1503 match self.generic_function(*source).kind() {
1504 TypedConstantFunctionValueKind::Target(reference) => {
1505 FloatFunctionExpr::reference(Self::typed_function_reference(
1506 reference,
1507 value.substitution(),
1508 ))
1509 }
1510 TypedConstantFunctionValueKind::Reference(reference) => {
1511 FloatFunctionExpr::constant(
1512 reference.specialize(value.substitution(), ()),
1513 type_,
1514 )
1515 }
1516 }
1517 }
1518 ConstantFunctionTemplateSource::Exact(source) => {
1519 match self.float_function(*source).kind() {
1520 TypedConstantFunctionValueKind::Target(reference) => {
1521 FloatFunctionExpr::reference(Self::typed_function_reference(
1522 reference,
1523 value.substitution(),
1524 ))
1525 }
1526 TypedConstantFunctionValueKind::Reference(reference) => {
1527 let reference = reference.substitute(value.substitution());
1528 let type_ = reference.shape().type_();
1529 FloatFunctionExpr::constant(reference, type_)
1530 }
1531 }
1532 }
1533 }
1534 }
1535
1536 pub(crate) fn materialize_bool_function(
1537 &self,
1538 value: &ConstantBoolFunctionInstantiation,
1539 ) -> BoolFunctionExpr {
1540 let type_ = value.shape().type_();
1541 match value.source() {
1542 ConstantFunctionTemplateSource::Generic(source) => {
1543 match self.generic_function(*source).kind() {
1544 TypedConstantFunctionValueKind::Target(reference) => {
1545 BoolFunctionExpr::reference(Self::typed_function_reference(
1546 reference,
1547 value.substitution(),
1548 ))
1549 }
1550 TypedConstantFunctionValueKind::Reference(reference) => {
1551 BoolFunctionExpr::constant(
1552 reference.specialize(value.substitution(), ()),
1553 type_,
1554 )
1555 }
1556 }
1557 }
1558 ConstantFunctionTemplateSource::Exact(source) => {
1559 match self.bool_function(*source).kind() {
1560 TypedConstantFunctionValueKind::Target(reference) => {
1561 BoolFunctionExpr::reference(Self::typed_function_reference(
1562 reference,
1563 value.substitution(),
1564 ))
1565 }
1566 TypedConstantFunctionValueKind::Reference(reference) => {
1567 let reference = reference.substitute(value.substitution());
1568 let type_ = reference.shape().type_();
1569 BoolFunctionExpr::constant(reference, type_)
1570 }
1571 }
1572 }
1573 }
1574 }
1575
1576 pub(crate) fn materialize_nil_function(
1577 &self,
1578 value: &ConstantNilFunctionInstantiation,
1579 ) -> NilFunctionExpr {
1580 let type_ = value.shape().type_();
1581 match value.source() {
1582 ConstantFunctionTemplateSource::Generic(source) => {
1583 match self.generic_function(*source).kind() {
1584 TypedConstantFunctionValueKind::Target(reference) => {
1585 NilFunctionExpr::reference(Self::typed_function_reference(
1586 reference,
1587 value.substitution(),
1588 ))
1589 }
1590 TypedConstantFunctionValueKind::Reference(reference) => {
1591 NilFunctionExpr::constant(
1592 reference.specialize(value.substitution(), ()),
1593 type_,
1594 )
1595 }
1596 }
1597 }
1598 ConstantFunctionTemplateSource::Exact(source) => {
1599 match self.nil_function(*source).kind() {
1600 TypedConstantFunctionValueKind::Target(reference) => {
1601 NilFunctionExpr::reference(Self::typed_function_reference(
1602 reference,
1603 value.substitution(),
1604 ))
1605 }
1606 TypedConstantFunctionValueKind::Reference(reference) => {
1607 let reference = reference.substitute(value.substitution());
1608 let type_ = reference.shape().type_();
1609 NilFunctionExpr::constant(reference, type_)
1610 }
1611 }
1612 }
1613 }
1614 }
1615
1616 pub(crate) fn materialize_tuple_function(
1617 &self,
1618 value: &ConstantTupleFunctionInstantiation,
1619 ) -> TupleFunctionExpr {
1620 let type_ = value.shape().type_();
1621 match value.source() {
1622 ConstantFunctionTemplateSource::Generic(source) => {
1623 match self.generic_function(*source).kind() {
1624 TypedConstantFunctionValueKind::Target(reference) => {
1625 TupleFunctionExpr::reference(Self::typed_function_reference(
1626 reference,
1627 value.substitution(),
1628 ))
1629 }
1630 TypedConstantFunctionValueKind::Reference(reference) => {
1631 TupleFunctionExpr::constant(
1632 reference.specialize(value.substitution(), value.return_().clone()),
1633 type_,
1634 )
1635 }
1636 }
1637 }
1638 ConstantFunctionTemplateSource::Exact(source) => {
1639 match self.tuple_function(*source).kind() {
1640 TypedConstantFunctionValueKind::Target(reference) => {
1641 TupleFunctionExpr::reference(Self::typed_function_reference(
1642 reference,
1643 value.substitution(),
1644 ))
1645 }
1646 TypedConstantFunctionValueKind::Reference(reference) => {
1647 let reference = reference.substitute(value.substitution());
1648 let type_ = reference.shape().type_();
1649 TupleFunctionExpr::constant(reference, type_)
1650 }
1651 }
1652 }
1653 }
1654 }
1655
1656 pub(crate) fn materialize_list_function(
1657 &self,
1658 value: &ConstantListFunctionInstantiation,
1659 ) -> ListFunctionExpr {
1660 let type_ = value.shape().type_();
1661 let item_type = value.return_().value_type();
1662 match value.source() {
1663 ConstantFunctionTemplateSource::Generic(source) => {
1664 match self.generic_function(*source).kind() {
1665 TypedConstantFunctionValueKind::Target(reference) => {
1666 ListFunctionExpr::reference(
1667 Self::typed_function_reference(reference, value.substitution()),
1668 item_type,
1669 )
1670 }
1671 TypedConstantFunctionValueKind::Reference(reference) => {
1672 ListFunctionExpr::constant(
1673 reference.specialize(value.substitution(), value.return_().clone()),
1674 type_,
1675 item_type,
1676 )
1677 }
1678 }
1679 }
1680 ConstantFunctionTemplateSource::Exact(source) => {
1681 match self.list_function(*source).kind() {
1682 TypedConstantFunctionValueKind::Target(reference) => {
1683 ListFunctionExpr::reference(
1684 Self::typed_function_reference(reference, value.substitution()),
1685 item_type,
1686 )
1687 }
1688 TypedConstantFunctionValueKind::Reference(reference) => {
1689 let reference = reference.substitute(value.substitution());
1690 let type_ = reference.shape().type_();
1691 let item_type = reference.return_().value_type();
1692 ListFunctionExpr::constant(reference, type_, item_type)
1693 }
1694 }
1695 }
1696 }
1697 }
1698
1699 pub(crate) fn materialize_custom_function(
1700 &self,
1701 value: &ConstantCustomFunctionInstantiation,
1702 ) -> CustomFunctionExpr {
1703 let type_ = crate::plan::CustomFunctionType::from_shapes(
1704 value.shape().argument_shapes().to_vec(),
1705 value.return_().clone(),
1706 );
1707 match value.source() {
1708 ConstantFunctionTemplateSource::Generic(source) => {
1709 match self.generic_function(*source).kind() {
1710 TypedConstantFunctionValueKind::Target(reference) => {
1711 CustomFunctionExpr::reference(
1712 Self::typed_function_reference(reference, value.substitution()),
1713 value.return_().clone(),
1714 )
1715 }
1716 TypedConstantFunctionValueKind::Reference(reference) => {
1717 CustomFunctionExpr::constant(
1718 reference.specialize(value.substitution(), value.return_().clone()),
1719 type_,
1720 )
1721 }
1722 }
1723 }
1724 ConstantFunctionTemplateSource::Exact(source) => {
1725 match self.custom_function(*source).kind() {
1726 TypedConstantFunctionValueKind::Target(
1727 ConstantCustomFunctionTarget::Reference(reference),
1728 ) => CustomFunctionExpr::reference(
1729 Self::typed_function_reference(reference, value.substitution()),
1730 value.return_().clone(),
1731 ),
1732 TypedConstantFunctionValueKind::Target(
1733 ConstantCustomFunctionTarget::Constructor(constructor),
1734 ) => CustomFunctionExpr::constructor(
1735 constructor.substitute(value.substitution()),
1736 ),
1737 TypedConstantFunctionValueKind::Reference(reference) => {
1738 let reference = reference.substitute(value.substitution());
1739 let type_ = crate::plan::CustomFunctionType::from_shapes(
1740 reference.shape().argument_shapes().to_vec(),
1741 reference.return_().clone(),
1742 );
1743 CustomFunctionExpr::constant(reference, type_)
1744 }
1745 }
1746 }
1747 }
1748 }
1749
1750 pub(crate) fn materialize_external_function(
1751 &self,
1752 value: &ConstantExternalFunctionInstantiation,
1753 ) -> ExternalFunctionExpr {
1754 let type_ = crate::plan::ExternalFunctionType::from_shapes(
1755 value.shape().argument_shapes().to_vec(),
1756 value.return_().clone(),
1757 );
1758 match value.source() {
1759 ConstantFunctionTemplateSource::Generic(source) => {
1760 match self.generic_function(*source).kind() {
1761 TypedConstantFunctionValueKind::Target(reference) => {
1762 ExternalFunctionExpr::reference(
1763 Self::typed_function_reference(reference, value.substitution()),
1764 value.return_().clone(),
1765 )
1766 }
1767 TypedConstantFunctionValueKind::Reference(reference) => {
1768 ExternalFunctionExpr::constant(
1769 reference.specialize(value.substitution(), value.return_().clone()),
1770 type_,
1771 )
1772 }
1773 }
1774 }
1775 ConstantFunctionTemplateSource::Exact(source) => {
1776 match self.external_function(*source).kind() {
1777 TypedConstantFunctionValueKind::Target(reference) => {
1778 ExternalFunctionExpr::reference(
1779 Self::typed_function_reference(reference, value.substitution()),
1780 value.return_().clone(),
1781 )
1782 }
1783 TypedConstantFunctionValueKind::Reference(reference) => {
1784 let reference = reference.substitute(value.substitution());
1785 let type_ = crate::plan::ExternalFunctionType::from_shapes(
1786 reference.shape().argument_shapes().to_vec(),
1787 reference.return_().clone(),
1788 );
1789 ExternalFunctionExpr::constant(reference, type_)
1790 }
1791 }
1792 }
1793 }
1794 }
1795
1796 pub(crate) fn materialize_function_function(
1797 &self,
1798 value: &ConstantFunctionFunctionInstantiation,
1799 ) -> FunctionFunctionExpr {
1800 let type_ = crate::plan::FunctionFunctionType::from_shapes(
1801 value.shape().argument_shapes().to_vec(),
1802 value.return_().as_ref().clone(),
1803 );
1804 match value.source() {
1805 ConstantFunctionTemplateSource::Generic(source) => {
1806 match self.generic_function(*source).kind() {
1807 TypedConstantFunctionValueKind::Target(reference) => {
1808 FunctionFunctionExpr::reference(
1809 Self::typed_function_reference(reference, value.substitution()),
1810 value.return_().type_(),
1811 )
1812 }
1813 TypedConstantFunctionValueKind::Reference(reference) => {
1814 FunctionFunctionExpr::constant(
1815 reference.specialize(value.substitution(), value.return_().clone()),
1816 type_,
1817 )
1818 }
1819 }
1820 }
1821 ConstantFunctionTemplateSource::Exact(source) => {
1822 match self.function_function(*source).kind() {
1823 TypedConstantFunctionValueKind::Target(reference) => {
1824 FunctionFunctionExpr::reference(
1825 Self::typed_function_reference(reference, value.substitution()),
1826 value.return_().type_(),
1827 )
1828 }
1829 TypedConstantFunctionValueKind::Reference(reference) => {
1830 let reference = reference.substitute(value.substitution());
1831 let type_ = crate::plan::FunctionFunctionType::from_shapes(
1832 reference.shape().argument_shapes().to_vec(),
1833 reference.return_().as_ref().clone(),
1834 );
1835 FunctionFunctionExpr::constant(reference, type_)
1836 }
1837 }
1838 }
1839 }
1840 }
1841
1842 pub(crate) fn materialize_generic_list(
1843 &self,
1844 value: &ConstantGenericListInstantiation,
1845 ) -> GenericListExpr {
1846 if !self.owns(value.module()) {
1847 let parameter = *value.item_shape();
1848 return GenericListExpr::constant(
1849 ValueShape::Parameter(parameter),
1850 GenericListItem::new(parameter),
1851 value.clone(),
1852 );
1853 }
1854 self.materialize_generic_parameter_list(
1855 self.generic_list(*value.source()),
1856 value.substitution(),
1857 *value.item_shape(),
1858 )
1859 }
1860
1861 fn materialize_list_value(
1862 &self,
1863 value: &ConstantListValue,
1864 substitution: &TypeSubstitution,
1865 ) -> ListExpr {
1866 match value {
1867 ConstantListValue::Generic(value) => {
1868 let item_shape = ValueShape::Parameter(value.parameter()).substitute(substitution);
1869 self.materialize_generic_list_value(value, substitution, &item_shape)
1870 }
1871 ConstantListValue::ParameterList(value) => {
1872 match ValueShape::Parameter(*value.item_shape())
1873 .substitute(substitution)
1874 .representation()
1875 {
1876 crate::plan::ValueRepresentation::Uninhabited(parameter) => {
1877 ListExpr::ParameterList(self.materialize_parameter_list_list_value(
1878 value,
1879 substitution,
1880 parameter,
1881 ))
1882 }
1883 crate::plan::ValueRepresentation::Stored(shape) => {
1884 ListExpr::List(self.materialize_parameter_list_list_value_as_stored(
1885 value,
1886 substitution,
1887 &shape,
1888 ))
1889 }
1890 }
1891 }
1892 ConstantListValue::Int(value) => {
1893 ListExpr::Int(self.materialize_int_list_value(value, substitution))
1894 }
1895 ConstantListValue::String(value) => {
1896 ListExpr::String(self.materialize_string_list_value(value, substitution))
1897 }
1898 ConstantListValue::BitArray(value) => {
1899 ListExpr::BitArray(self.materialize_bit_array_list_value(value, substitution))
1900 }
1901 ConstantListValue::UtfCodepoint(value) => ListExpr::UtfCodepoint(
1902 self.materialize_utf_codepoint_list_value(value, substitution),
1903 ),
1904 ConstantListValue::Custom(value) => {
1905 ListExpr::Custom(self.materialize_custom_list_value(value, substitution))
1906 }
1907 ConstantListValue::External(value) => {
1908 ListExpr::External(self.materialize_external_list_value(value, substitution))
1909 }
1910 ConstantListValue::Float(value) => {
1911 ListExpr::Float(self.materialize_float_list_value(value, substitution))
1912 }
1913 ConstantListValue::Bool(value) => {
1914 ListExpr::Bool(self.materialize_bool_list_value(value, substitution))
1915 }
1916 ConstantListValue::Nil(value) => {
1917 ListExpr::Nil(self.materialize_nil_list_value(value, substitution))
1918 }
1919 ConstantListValue::Tuple(value) => {
1920 ListExpr::Tuple(self.materialize_tuple_list_value(value, substitution))
1921 }
1922 ConstantListValue::List(value) => {
1923 ListExpr::List(self.materialize_list_list_value(value, substitution))
1924 }
1925 ConstantListValue::Function(value) => {
1926 ListExpr::Function(self.materialize_function_list_value(value, substitution))
1927 }
1928 }
1929 }
1930
1931 fn materialize_generic_list_value(
1932 &self,
1933 value: &ConstantGenericListValue,
1934 substitution: &TypeSubstitution,
1935 item_shape: &ValueShape,
1936 ) -> ListExpr {
1937 match item_shape {
1938 ValueShape::Parameter(parameter) => ListExpr::Generic(
1939 self.materialize_generic_parameter_list(value, substitution, *parameter),
1940 ),
1941 ValueShape::Int => {
1942 ListExpr::Int(self.materialize_generic_int_list(value, substitution))
1943 }
1944 ValueShape::String => {
1945 ListExpr::String(self.materialize_generic_string_list(value, substitution))
1946 }
1947 ValueShape::BitArray => {
1948 ListExpr::BitArray(self.materialize_generic_bit_array_list(value, substitution))
1949 }
1950 ValueShape::UtfCodepoint => ListExpr::UtfCodepoint(
1951 self.materialize_generic_utf_codepoint_list(value, substitution),
1952 ),
1953 ValueShape::Custom(shape) => {
1954 ListExpr::Custom(self.materialize_generic_custom_list(value, substitution, shape))
1955 }
1956 ValueShape::External(shape) => ListExpr::External(
1957 self.materialize_generic_external_list(value, substitution, shape),
1958 ),
1959 ValueShape::Float => {
1960 ListExpr::Float(self.materialize_generic_float_list(value, substitution))
1961 }
1962 ValueShape::Bool => {
1963 ListExpr::Bool(self.materialize_generic_bool_list(value, substitution))
1964 }
1965 ValueShape::Nil => {
1966 ListExpr::Nil(self.materialize_generic_nil_list(value, substitution))
1967 }
1968 ValueShape::Tuple(shape) => {
1969 ListExpr::Tuple(self.materialize_generic_tuple_list(value, substitution, shape))
1970 }
1971 ValueShape::List(shape) => match shape.representation() {
1972 crate::plan::ValueRepresentation::Uninhabited(parameter) => {
1973 ListExpr::ParameterList(self.materialize_generic_parameter_list_list(
1974 value,
1975 substitution,
1976 parameter,
1977 ))
1978 }
1979 crate::plan::ValueRepresentation::Stored(item_shape) => ListExpr::List(
1980 self.materialize_generic_list_list(value, substitution, &item_shape),
1981 ),
1982 },
1983 ValueShape::Function(shape) => ListExpr::Function(
1984 self.materialize_generic_function_list(value, substitution, shape),
1985 ),
1986 }
1987 }
1988
1989 fn materialize_generic_stored_list_value(
1990 &self,
1991 value: &ConstantGenericListValue,
1992 substitution: &TypeSubstitution,
1993 shape: &crate::plan::ValueStorageShape,
1994 ) -> StoredListExpr {
1995 match shape {
1996 crate::plan::ValueStorageShape::Int => {
1997 StoredListExpr::Int(self.materialize_generic_int_list(value, substitution))
1998 }
1999 crate::plan::ValueStorageShape::Float => {
2000 StoredListExpr::Float(self.materialize_generic_float_list(value, substitution))
2001 }
2002 crate::plan::ValueStorageShape::String => {
2003 StoredListExpr::String(self.materialize_generic_string_list(value, substitution))
2004 }
2005 crate::plan::ValueStorageShape::BitArray => StoredListExpr::BitArray(
2006 self.materialize_generic_bit_array_list(value, substitution),
2007 ),
2008 crate::plan::ValueStorageShape::UtfCodepoint => StoredListExpr::UtfCodepoint(
2009 self.materialize_generic_utf_codepoint_list(value, substitution),
2010 ),
2011 crate::plan::ValueStorageShape::Custom(shape) => StoredListExpr::Custom(
2012 self.materialize_generic_custom_list(value, substitution, shape),
2013 ),
2014 crate::plan::ValueStorageShape::External(shape) => StoredListExpr::External(
2015 self.materialize_generic_external_list(value, substitution, shape),
2016 ),
2017 crate::plan::ValueStorageShape::Bool => {
2018 StoredListExpr::Bool(self.materialize_generic_bool_list(value, substitution))
2019 }
2020 crate::plan::ValueStorageShape::Nil => {
2021 StoredListExpr::Nil(self.materialize_generic_nil_list(value, substitution))
2022 }
2023 crate::plan::ValueStorageShape::Tuple(shape) => StoredListExpr::Tuple(
2024 self.materialize_generic_tuple_list(value, substitution, shape),
2025 ),
2026 crate::plan::ValueStorageShape::List(shape) => match shape.representation() {
2027 crate::plan::ValueRepresentation::Uninhabited(parameter) => {
2028 StoredListExpr::ParameterList(self.materialize_generic_parameter_list_list(
2029 value,
2030 substitution,
2031 parameter,
2032 ))
2033 }
2034 crate::plan::ValueRepresentation::Stored(shape) => StoredListExpr::List(
2035 self.materialize_generic_list_list(value, substitution, &shape),
2036 ),
2037 },
2038 crate::plan::ValueStorageShape::Function(shape) => StoredListExpr::Function(
2039 self.materialize_generic_function_list(value, substitution, shape),
2040 ),
2041 }
2042 }
2043
2044 fn materialize_generic_parameter_list(
2045 &self,
2046 value: &ConstantGenericListValue,
2047 substitution: &TypeSubstitution,
2048 parameter: crate::plan::TypeParameterId,
2049 ) -> GenericListExpr {
2050 match value.kind() {
2051 ConstantGenericListValueKind::Empty => {
2052 GenericListExpr::value(GenericListItem::new(parameter), Vec::new())
2053 .with_item_shape(ValueShape::Parameter(parameter))
2054 }
2055 ConstantGenericListValueKind::Reference(value) => {
2056 self.materialize_generic_list(&value.retarget_generic(substitution, parameter))
2057 }
2058 }
2059 }
2060
2061 fn materialize_generic_int_list(
2062 &self,
2063 value: &ConstantGenericListValue,
2064 substitution: &TypeSubstitution,
2065 ) -> IntListExpr {
2066 match value.kind() {
2067 ConstantGenericListValueKind::Empty => {
2068 IntListExpr::value(IntListItem, Vec::new()).with_item_shape(ValueShape::Int)
2069 }
2070 ConstantGenericListValueKind::Reference(value) => {
2071 self.materialize_int_list(&value.retarget(substitution, ()))
2072 }
2073 }
2074 }
2075
2076 fn materialize_generic_string_list(
2077 &self,
2078 value: &ConstantGenericListValue,
2079 substitution: &TypeSubstitution,
2080 ) -> StringListExpr {
2081 match value.kind() {
2082 ConstantGenericListValueKind::Empty => {
2083 StringListExpr::value(StringListItem, Vec::new())
2084 .with_item_shape(ValueShape::String)
2085 }
2086 ConstantGenericListValueKind::Reference(value) => {
2087 self.materialize_string_list(&value.retarget(substitution, ()))
2088 }
2089 }
2090 }
2091
2092 fn materialize_generic_bit_array_list(
2093 &self,
2094 value: &ConstantGenericListValue,
2095 substitution: &TypeSubstitution,
2096 ) -> BitArrayListExpr {
2097 match value.kind() {
2098 ConstantGenericListValueKind::Empty => {
2099 BitArrayListExpr::value(BitArrayListItem, Vec::new())
2100 .with_item_shape(ValueShape::BitArray)
2101 }
2102 ConstantGenericListValueKind::Reference(value) => {
2103 self.materialize_bit_array_list(&value.retarget(substitution, ()))
2104 }
2105 }
2106 }
2107
2108 fn materialize_generic_utf_codepoint_list(
2109 &self,
2110 value: &ConstantGenericListValue,
2111 substitution: &TypeSubstitution,
2112 ) -> UtfCodepointListExpr {
2113 match value.kind() {
2114 ConstantGenericListValueKind::Empty => {
2115 UtfCodepointListExpr::value(UtfCodepointListItem, Vec::new())
2116 .with_item_shape(ValueShape::UtfCodepoint)
2117 }
2118 ConstantGenericListValueKind::Reference(value) => {
2119 self.materialize_utf_codepoint_list(&value.retarget(substitution, ()))
2120 }
2121 }
2122 }
2123
2124 fn materialize_generic_custom_list(
2125 &self,
2126 value: &ConstantGenericListValue,
2127 substitution: &TypeSubstitution,
2128 shape: &CustomValueShape,
2129 ) -> CustomListExpr {
2130 match value.kind() {
2131 ConstantGenericListValueKind::Empty => {
2132 CustomListExpr::value(CustomListItem::new(shape.type_().clone()), Vec::new())
2133 .with_item_shape(ValueShape::Custom(shape.clone()))
2134 }
2135 ConstantGenericListValueKind::Reference(value) => {
2136 self.materialize_custom_list(&value.retarget(substitution, shape.clone()))
2137 }
2138 }
2139 }
2140
2141 fn materialize_generic_external_list(
2142 &self,
2143 value: &ConstantGenericListValue,
2144 substitution: &TypeSubstitution,
2145 shape: &ExternalValueShape,
2146 ) -> ExternalListExpr {
2147 match value.kind() {
2148 ConstantGenericListValueKind::Empty => {
2149 ExternalListExpr::value(ExternalListItem::new(shape.type_().clone()), Vec::new())
2150 .with_item_shape(ValueShape::External(shape.clone()))
2151 }
2152 ConstantGenericListValueKind::Reference(value) => {
2153 self.materialize_external_list(&value.retarget(substitution, shape.clone()))
2154 }
2155 }
2156 }
2157
2158 fn materialize_generic_float_list(
2159 &self,
2160 value: &ConstantGenericListValue,
2161 substitution: &TypeSubstitution,
2162 ) -> FloatListExpr {
2163 match value.kind() {
2164 ConstantGenericListValueKind::Empty => {
2165 FloatListExpr::value(FloatListItem, Vec::new()).with_item_shape(ValueShape::Float)
2166 }
2167 ConstantGenericListValueKind::Reference(value) => {
2168 self.materialize_float_list(&value.retarget(substitution, ()))
2169 }
2170 }
2171 }
2172
2173 fn materialize_generic_bool_list(
2174 &self,
2175 value: &ConstantGenericListValue,
2176 substitution: &TypeSubstitution,
2177 ) -> BoolListExpr {
2178 match value.kind() {
2179 ConstantGenericListValueKind::Empty => {
2180 BoolListExpr::value(BoolListItem, Vec::new()).with_item_shape(ValueShape::Bool)
2181 }
2182 ConstantGenericListValueKind::Reference(value) => {
2183 self.materialize_bool_list(&value.retarget(substitution, ()))
2184 }
2185 }
2186 }
2187
2188 fn materialize_generic_nil_list(
2189 &self,
2190 value: &ConstantGenericListValue,
2191 substitution: &TypeSubstitution,
2192 ) -> NilListExpr {
2193 match value.kind() {
2194 ConstantGenericListValueKind::Empty => {
2195 NilListExpr::value(NilListItem, Vec::new()).with_item_shape(ValueShape::Nil)
2196 }
2197 ConstantGenericListValueKind::Reference(value) => {
2198 self.materialize_nil_list(&value.retarget(substitution, ()))
2199 }
2200 }
2201 }
2202
2203 fn materialize_generic_tuple_list(
2204 &self,
2205 value: &ConstantGenericListValue,
2206 substitution: &TypeSubstitution,
2207 shape: &[ValueShape],
2208 ) -> TupleListExpr {
2209 match value.kind() {
2210 ConstantGenericListValueKind::Empty => TupleListExpr::value(
2211 TupleListItem::new(shape.iter().map(ValueShape::value_type).collect()),
2212 Vec::new(),
2213 )
2214 .with_item_shape(ValueShape::Tuple(shape.to_vec().into_boxed_slice())),
2215 ConstantGenericListValueKind::Reference(value) => self.materialize_tuple_list(
2216 &value.retarget(substitution, shape.to_vec().into_boxed_slice()),
2217 ),
2218 }
2219 }
2220
2221 fn materialize_generic_list_list(
2222 &self,
2223 value: &ConstantGenericListValue,
2224 substitution: &TypeSubstitution,
2225 shape: &crate::plan::ValueStorageShape,
2226 ) -> ListListExpr {
2227 match value.kind() {
2228 ConstantGenericListValueKind::Empty => {
2229 ListListExpr::value(ListListItem::new(shape.clone()), Vec::new())
2230 .with_item_shape(ValueShape::List(Box::new(shape.to_value_shape())))
2231 }
2232 ConstantGenericListValueKind::Reference(value) => {
2233 self.materialize_list_list(&value.retarget_nested(substitution, shape.clone()))
2234 }
2235 }
2236 }
2237
2238 fn materialize_generic_parameter_list_list(
2239 &self,
2240 value: &ConstantGenericListValue,
2241 substitution: &TypeSubstitution,
2242 parameter: crate::plan::TypeParameterId,
2243 ) -> crate::plan::ParameterListListExpr {
2244 match value.kind() {
2245 ConstantGenericListValueKind::Empty => crate::plan::ParameterListListExpr::value(
2246 crate::plan::ParameterListListItem::new(parameter),
2247 Vec::new(),
2248 )
2249 .with_item_shape(ValueShape::List(Box::new(ValueShape::Parameter(parameter)))),
2250 ConstantGenericListValueKind::Reference(value) => {
2251 self.materialize_parameter_list_list(&value.retarget(substitution, parameter))
2252 }
2253 }
2254 }
2255
2256 fn materialize_generic_function_list(
2257 &self,
2258 value: &ConstantGenericListValue,
2259 substitution: &TypeSubstitution,
2260 shape: &FunctionShape,
2261 ) -> FunctionListExpr {
2262 match value.kind() {
2263 ConstantGenericListValueKind::Empty => {
2264 FunctionListExpr::value(FunctionListItem::new(shape.type_()), Vec::new())
2265 .with_item_shape(ValueShape::Function(Box::new(shape.clone())))
2266 }
2267 ConstantGenericListValueKind::Reference(value) => {
2268 self.materialize_function_list(&value.retarget(substitution, shape.clone()))
2269 }
2270 }
2271 }
2272
2273 pub(crate) fn materialize_int_list(&self, value: &ConstantIntListInstantiation) -> IntListExpr {
2274 if !self.owns(value.module()) {
2275 return IntListExpr::constant(ValueShape::Int, IntListItem, value.clone());
2276 }
2277 match value.source() {
2278 ConstantListTemplateSource::Generic(source) => {
2279 self.materialize_generic_int_list(self.generic_list(*source), value.substitution())
2280 }
2281 ConstantListTemplateSource::Exact(source) => {
2282 self.materialize_int_list_value(self.int_list(*source), value.substitution())
2283 }
2284 }
2285 }
2286
2287 fn materialize_int_list_value(
2288 &self,
2289 value: &ConstantIntListValue,
2290 substitution: &TypeSubstitution,
2291 ) -> IntListExpr {
2292 match value.kind() {
2293 TypedConstantListValueKind::Value(elements) => IntListExpr::value(
2294 IntListItem,
2295 elements
2296 .iter()
2297 .map(|value| self.materialize_int_value(value, substitution))
2298 .collect(),
2299 ),
2300 TypedConstantListValueKind::Spread { elements, tail } => IntListExpr::spread(
2301 elements.mapped_ref(|value| self.materialize_int_value(value, substitution)),
2302 self.materialize_int_list_value(tail, substitution),
2303 ),
2304 TypedConstantListValueKind::Reference(value) => {
2305 self.materialize_int_list(&value.substitute_leaf(substitution))
2306 }
2307 }
2308 }
2309
2310 pub(crate) fn materialize_string_list(
2311 &self,
2312 value: &ConstantStringListInstantiation,
2313 ) -> StringListExpr {
2314 if !self.owns(value.module()) {
2315 return StringListExpr::constant(ValueShape::String, StringListItem, value.clone());
2316 }
2317 match value.source() {
2318 ConstantListTemplateSource::Generic(source) => self
2319 .materialize_generic_string_list(self.generic_list(*source), value.substitution()),
2320 ConstantListTemplateSource::Exact(source) => {
2321 self.materialize_string_list_value(self.string_list(*source), value.substitution())
2322 }
2323 }
2324 }
2325
2326 fn materialize_string_list_value(
2327 &self,
2328 value: &ConstantStringListValue,
2329 substitution: &TypeSubstitution,
2330 ) -> StringListExpr {
2331 match value.kind() {
2332 TypedConstantListValueKind::Value(elements) => StringListExpr::value(
2333 StringListItem,
2334 elements
2335 .iter()
2336 .map(|value| self.materialize_string_value(value, substitution))
2337 .collect(),
2338 ),
2339 TypedConstantListValueKind::Spread { elements, tail } => StringListExpr::spread(
2340 elements.mapped_ref(|value| self.materialize_string_value(value, substitution)),
2341 self.materialize_string_list_value(tail, substitution),
2342 ),
2343 TypedConstantListValueKind::Reference(value) => {
2344 self.materialize_string_list(&value.substitute_leaf(substitution))
2345 }
2346 }
2347 }
2348
2349 pub(crate) fn materialize_bit_array_list(
2350 &self,
2351 value: &ConstantBitArrayListInstantiation,
2352 ) -> BitArrayListExpr {
2353 if !self.owns(value.module()) {
2354 return BitArrayListExpr::constant(
2355 ValueShape::BitArray,
2356 BitArrayListItem,
2357 value.clone(),
2358 );
2359 }
2360 match value.source() {
2361 ConstantListTemplateSource::Generic(source) => self.materialize_generic_bit_array_list(
2362 self.generic_list(*source),
2363 value.substitution(),
2364 ),
2365 ConstantListTemplateSource::Exact(source) => self.materialize_bit_array_list_value(
2366 self.bit_array_list(*source),
2367 value.substitution(),
2368 ),
2369 }
2370 }
2371
2372 fn materialize_bit_array_list_value(
2373 &self,
2374 value: &ConstantBitArrayListValue,
2375 substitution: &TypeSubstitution,
2376 ) -> BitArrayListExpr {
2377 match value.kind() {
2378 TypedConstantListValueKind::Value(elements) => BitArrayListExpr::value(
2379 BitArrayListItem,
2380 elements
2381 .iter()
2382 .map(|value| self.materialize_bit_array_value(value, substitution))
2383 .collect(),
2384 ),
2385 TypedConstantListValueKind::Spread { elements, tail } => BitArrayListExpr::spread(
2386 elements.mapped_ref(|value| self.materialize_bit_array_value(value, substitution)),
2387 self.materialize_bit_array_list_value(tail, substitution),
2388 ),
2389 TypedConstantListValueKind::Reference(value) => {
2390 self.materialize_bit_array_list(&value.substitute_leaf(substitution))
2391 }
2392 }
2393 }
2394
2395 pub(crate) fn materialize_utf_codepoint_list(
2396 &self,
2397 value: &ConstantUtfCodepointListInstantiation,
2398 ) -> UtfCodepointListExpr {
2399 if !self.owns(value.module()) {
2400 return UtfCodepointListExpr::constant(
2401 ValueShape::UtfCodepoint,
2402 UtfCodepointListItem,
2403 value.clone(),
2404 );
2405 }
2406 match value.source() {
2407 ConstantListTemplateSource::Generic(source) => self
2408 .materialize_generic_utf_codepoint_list(
2409 self.generic_list(*source),
2410 value.substitution(),
2411 ),
2412 ConstantListTemplateSource::Exact(source) => self.materialize_utf_codepoint_list_value(
2413 self.utf_codepoint_list(*source),
2414 value.substitution(),
2415 ),
2416 }
2417 }
2418
2419 fn materialize_utf_codepoint_list_value(
2420 &self,
2421 value: &ConstantUtfCodepointListValue,
2422 substitution: &TypeSubstitution,
2423 ) -> UtfCodepointListExpr {
2424 match value.kind() {
2425 ConstantUtfCodepointListValueKind::Empty => {
2426 UtfCodepointListExpr::value(UtfCodepointListItem, Vec::new())
2427 }
2428 ConstantUtfCodepointListValueKind::Reference(value) => {
2429 self.materialize_utf_codepoint_list(&value.substitute_leaf(substitution))
2430 }
2431 }
2432 }
2433
2434 pub(crate) fn materialize_custom_list(
2435 &self,
2436 value: &ConstantCustomListInstantiation,
2437 ) -> CustomListExpr {
2438 if !self.owns(value.module()) {
2439 let shape = value.item_shape().clone();
2440 return CustomListExpr::constant(
2441 ValueShape::Custom(shape.clone()),
2442 CustomListItem::new(shape.type_().clone()),
2443 value.clone(),
2444 );
2445 }
2446 match value.source() {
2447 ConstantListTemplateSource::Generic(source) => self.materialize_generic_custom_list(
2448 self.generic_list(*source),
2449 value.substitution(),
2450 value.item_shape(),
2451 ),
2452 ConstantListTemplateSource::Exact(source) => {
2453 self.materialize_custom_list_value(self.custom_list(*source), value.substitution())
2454 }
2455 }
2456 }
2457
2458 fn materialize_custom_list_value(
2459 &self,
2460 value: &ConstantCustomListValue,
2461 substitution: &TypeSubstitution,
2462 ) -> CustomListExpr {
2463 let shape = value.item_shape().substitute(substitution);
2464 match value.kind() {
2465 TypedConstantListValueKind::Value(elements) => CustomListExpr::value(
2466 CustomListItem::new(shape.type_().clone()),
2467 elements
2468 .iter()
2469 .map(|value| self.materialize_custom_value(value, substitution))
2470 .collect(),
2471 )
2472 .with_item_shape(ValueShape::Custom(shape)),
2473 TypedConstantListValueKind::Spread { elements, tail } => CustomListExpr::spread(
2474 elements.mapped_ref(|value| self.materialize_custom_value(value, substitution)),
2475 self.materialize_custom_list_value(tail, substitution),
2476 )
2477 .with_item_shape(ValueShape::Custom(shape)),
2478 TypedConstantListValueKind::Reference(value) => {
2479 self.materialize_custom_list(&value.substitute_custom(substitution))
2480 }
2481 }
2482 }
2483
2484 pub(crate) fn materialize_external_list(
2485 &self,
2486 value: &ConstantExternalListInstantiation,
2487 ) -> ExternalListExpr {
2488 if !self.owns(value.module()) {
2489 let shape = value.item_shape().clone();
2490 return ExternalListExpr::constant(
2491 ValueShape::External(shape.clone()),
2492 ExternalListItem::new(shape.type_().clone()),
2493 value.clone(),
2494 );
2495 }
2496 match value.source() {
2497 ConstantListTemplateSource::Generic(source) => self.materialize_generic_external_list(
2498 self.generic_list(*source),
2499 value.substitution(),
2500 value.item_shape(),
2501 ),
2502 ConstantListTemplateSource::Exact(source) => self
2503 .materialize_external_list_value(self.external_list(*source), value.substitution()),
2504 }
2505 }
2506
2507 fn materialize_external_list_value(
2508 &self,
2509 value: &ConstantExternalListValue,
2510 substitution: &TypeSubstitution,
2511 ) -> ExternalListExpr {
2512 let shape = value.item_shape().substitute(substitution);
2513 match value.kind() {
2514 ConstantExternalListValueKind::Empty => {
2515 ExternalListExpr::value(ExternalListItem::new(shape.type_().clone()), Vec::new())
2516 .with_item_shape(ValueShape::External(shape))
2517 }
2518 ConstantExternalListValueKind::Reference(value) => {
2519 self.materialize_external_list(&value.substitute_external(substitution))
2520 }
2521 }
2522 }
2523
2524 pub(crate) fn materialize_float_list(
2525 &self,
2526 value: &ConstantFloatListInstantiation,
2527 ) -> FloatListExpr {
2528 if !self.owns(value.module()) {
2529 return FloatListExpr::constant(ValueShape::Float, FloatListItem, value.clone());
2530 }
2531 match value.source() {
2532 ConstantListTemplateSource::Generic(source) => self
2533 .materialize_generic_float_list(self.generic_list(*source), value.substitution()),
2534 ConstantListTemplateSource::Exact(source) => {
2535 self.materialize_float_list_value(self.float_list(*source), value.substitution())
2536 }
2537 }
2538 }
2539
2540 fn materialize_float_list_value(
2541 &self,
2542 value: &ConstantFloatListValue,
2543 substitution: &TypeSubstitution,
2544 ) -> FloatListExpr {
2545 match value.kind() {
2546 TypedConstantListValueKind::Value(elements) => FloatListExpr::value(
2547 FloatListItem,
2548 elements
2549 .iter()
2550 .map(|value| self.materialize_float_value(value, substitution))
2551 .collect(),
2552 ),
2553 TypedConstantListValueKind::Spread { elements, tail } => FloatListExpr::spread(
2554 elements.mapped_ref(|value| self.materialize_float_value(value, substitution)),
2555 self.materialize_float_list_value(tail, substitution),
2556 ),
2557 TypedConstantListValueKind::Reference(value) => {
2558 self.materialize_float_list(&value.substitute_leaf(substitution))
2559 }
2560 }
2561 }
2562
2563 pub(crate) fn materialize_bool_list(
2564 &self,
2565 value: &ConstantBoolListInstantiation,
2566 ) -> BoolListExpr {
2567 if !self.owns(value.module()) {
2568 return BoolListExpr::constant(ValueShape::Bool, BoolListItem, value.clone());
2569 }
2570 match value.source() {
2571 ConstantListTemplateSource::Generic(source) => {
2572 self.materialize_generic_bool_list(self.generic_list(*source), value.substitution())
2573 }
2574 ConstantListTemplateSource::Exact(source) => {
2575 self.materialize_bool_list_value(self.bool_list(*source), value.substitution())
2576 }
2577 }
2578 }
2579
2580 fn materialize_bool_list_value(
2581 &self,
2582 value: &ConstantBoolListValue,
2583 substitution: &TypeSubstitution,
2584 ) -> BoolListExpr {
2585 match value.kind() {
2586 TypedConstantListValueKind::Value(elements) => BoolListExpr::value(
2587 BoolListItem,
2588 elements
2589 .iter()
2590 .map(|value| self.materialize_bool_value(value, substitution))
2591 .collect(),
2592 ),
2593 TypedConstantListValueKind::Spread { elements, tail } => BoolListExpr::spread(
2594 elements.mapped_ref(|value| self.materialize_bool_value(value, substitution)),
2595 self.materialize_bool_list_value(tail, substitution),
2596 ),
2597 TypedConstantListValueKind::Reference(value) => {
2598 self.materialize_bool_list(&value.substitute_leaf(substitution))
2599 }
2600 }
2601 }
2602
2603 pub(crate) fn materialize_nil_list(&self, value: &ConstantNilListInstantiation) -> NilListExpr {
2604 if !self.owns(value.module()) {
2605 return NilListExpr::constant(ValueShape::Nil, NilListItem, value.clone());
2606 }
2607 match value.source() {
2608 ConstantListTemplateSource::Generic(source) => {
2609 self.materialize_generic_nil_list(self.generic_list(*source), value.substitution())
2610 }
2611 ConstantListTemplateSource::Exact(source) => {
2612 self.materialize_nil_list_value(self.nil_list(*source), value.substitution())
2613 }
2614 }
2615 }
2616
2617 fn materialize_nil_list_value(
2618 &self,
2619 value: &ConstantNilListValue,
2620 substitution: &TypeSubstitution,
2621 ) -> NilListExpr {
2622 match value.kind() {
2623 TypedConstantListValueKind::Value(elements) => NilListExpr::value(
2624 NilListItem,
2625 elements
2626 .iter()
2627 .map(|value| self.materialize_nil_value(value, substitution))
2628 .collect(),
2629 ),
2630 TypedConstantListValueKind::Spread { elements, tail } => NilListExpr::spread(
2631 elements.mapped_ref(|value| self.materialize_nil_value(value, substitution)),
2632 self.materialize_nil_list_value(tail, substitution),
2633 ),
2634 TypedConstantListValueKind::Reference(value) => {
2635 self.materialize_nil_list(&value.substitute_leaf(substitution))
2636 }
2637 }
2638 }
2639
2640 pub(crate) fn materialize_tuple_list(
2641 &self,
2642 value: &ConstantTupleListInstantiation,
2643 ) -> TupleListExpr {
2644 if !self.owns(value.module()) {
2645 let shape = value.item_shape().clone();
2646 return TupleListExpr::constant(
2647 ValueShape::Tuple(shape.clone()),
2648 TupleListItem::new(shape.iter().map(ValueShape::value_type).collect()),
2649 value.clone(),
2650 );
2651 }
2652 match value.source() {
2653 ConstantListTemplateSource::Generic(source) => self.materialize_generic_tuple_list(
2654 self.generic_list(*source),
2655 value.substitution(),
2656 value.item_shape(),
2657 ),
2658 ConstantListTemplateSource::Exact(source) => {
2659 self.materialize_tuple_list_value(self.tuple_list(*source), value.substitution())
2660 }
2661 }
2662 }
2663
2664 fn materialize_tuple_list_value(
2665 &self,
2666 value: &ConstantTupleListValue,
2667 substitution: &TypeSubstitution,
2668 ) -> TupleListExpr {
2669 let shape = value
2670 .item_shape()
2671 .iter()
2672 .map(|shape| shape.substitute(substitution))
2673 .collect::<Vec<_>>()
2674 .into_boxed_slice();
2675 let item = TupleListItem::new(shape.iter().map(ValueShape::value_type).collect());
2676 match value.kind() {
2677 TypedConstantListValueKind::Value(elements) => TupleListExpr::value(
2678 item,
2679 elements
2680 .iter()
2681 .map(|value| self.materialize_tuple_value(value, substitution))
2682 .collect(),
2683 )
2684 .with_item_shape(ValueShape::Tuple(shape)),
2685 TypedConstantListValueKind::Spread { elements, tail } => TupleListExpr::spread(
2686 elements.mapped_ref(|value| self.materialize_tuple_value(value, substitution)),
2687 self.materialize_tuple_list_value(tail, substitution),
2688 )
2689 .with_item_shape(ValueShape::Tuple(shape)),
2690 TypedConstantListValueKind::Reference(value) => {
2691 self.materialize_tuple_list(&value.substitute_tuple(substitution))
2692 }
2693 }
2694 }
2695
2696 pub(crate) fn materialize_parameter_list_list(
2697 &self,
2698 value: &ConstantParameterListListInstantiation,
2699 ) -> ParameterListListExpr {
2700 if !self.owns(value.module()) {
2701 let parameter = *value.item_shape();
2702 return ParameterListListExpr::constant(
2703 ValueShape::List(Box::new(ValueShape::Parameter(parameter))),
2704 ParameterListListItem::new(parameter),
2705 value.clone(),
2706 );
2707 }
2708 match value.source() {
2709 ConstantListTemplateSource::Generic(source) => self
2710 .materialize_generic_parameter_list_list(
2711 self.generic_list(*source),
2712 value.substitution(),
2713 *value.item_shape(),
2714 ),
2715 ConstantListTemplateSource::Exact(source) => self
2716 .materialize_parameter_list_list_value(
2717 self.parameter_list_list(*source),
2718 value.substitution(),
2719 *value.item_shape(),
2720 ),
2721 }
2722 }
2723
2724 fn materialize_parameter_list_list_value(
2725 &self,
2726 value: &ConstantParameterListListValue,
2727 substitution: &TypeSubstitution,
2728 parameter: crate::plan::TypeParameterId,
2729 ) -> ParameterListListExpr {
2730 match value.kind() {
2731 TypedConstantListValueKind::Value(elements) => ParameterListListExpr::value(
2732 ParameterListListItem::new(parameter),
2733 elements
2734 .iter()
2735 .map(|value| {
2736 self.materialize_generic_parameter_list(value, substitution, parameter)
2737 })
2738 .collect(),
2739 )
2740 .with_item_shape(ValueShape::List(Box::new(ValueShape::Parameter(parameter)))),
2741 TypedConstantListValueKind::Spread { elements, tail } => ParameterListListExpr::spread(
2742 elements.mapped_ref(|value| {
2743 self.materialize_generic_parameter_list(value, substitution, parameter)
2744 }),
2745 self.materialize_parameter_list_list_value(tail, substitution, parameter),
2746 )
2747 .with_item_shape(ValueShape::List(Box::new(ValueShape::Parameter(parameter)))),
2748 TypedConstantListValueKind::Reference(value) => self.materialize_parameter_list_list(
2749 &value.retarget_parameter(substitution, parameter),
2750 ),
2751 }
2752 }
2753
2754 fn materialize_parameter_list_list_value_as_stored(
2755 &self,
2756 value: &ConstantParameterListListValue,
2757 substitution: &TypeSubstitution,
2758 shape: &crate::plan::ValueStorageShape,
2759 ) -> ListListExpr {
2760 match value.kind() {
2761 TypedConstantListValueKind::Value(elements) => ListListExpr::value(
2762 ListListItem::new(shape.clone()),
2763 elements
2764 .iter()
2765 .map(|value| {
2766 self.materialize_generic_stored_list_value(value, substitution, shape)
2767 })
2768 .collect(),
2769 )
2770 .with_item_shape(ValueShape::List(Box::new(shape.to_value_shape()))),
2771 TypedConstantListValueKind::Spread { elements, tail } => ListListExpr::spread(
2772 elements.mapped_ref(|value| {
2773 self.materialize_generic_stored_list_value(value, substitution, shape)
2774 }),
2775 self.materialize_parameter_list_list_value_as_stored(tail, substitution, shape),
2776 )
2777 .with_item_shape(ValueShape::List(Box::new(shape.to_value_shape()))),
2778 TypedConstantListValueKind::Reference(value) => {
2779 self.materialize_list_list(&value.retarget_stored(substitution, shape.clone()))
2780 }
2781 }
2782 }
2783
2784 fn materialize_stored_list_value(
2785 &self,
2786 value: &ConstantStoredListValue,
2787 substitution: &TypeSubstitution,
2788 ) -> StoredListExpr {
2789 match value {
2790 ConstantStoredListValue::ParameterList(value) => {
2791 match ValueShape::Parameter(*value.item_shape())
2792 .substitute(substitution)
2793 .representation()
2794 {
2795 crate::plan::ValueRepresentation::Uninhabited(parameter) => {
2796 StoredListExpr::ParameterList(self.materialize_parameter_list_list_value(
2797 value,
2798 substitution,
2799 parameter,
2800 ))
2801 }
2802 crate::plan::ValueRepresentation::Stored(shape) => {
2803 StoredListExpr::List(self.materialize_parameter_list_list_value_as_stored(
2804 value,
2805 substitution,
2806 &shape,
2807 ))
2808 }
2809 }
2810 }
2811 ConstantStoredListValue::Int(value) => {
2812 StoredListExpr::Int(self.materialize_int_list_value(value, substitution))
2813 }
2814 ConstantStoredListValue::String(value) => {
2815 StoredListExpr::String(self.materialize_string_list_value(value, substitution))
2816 }
2817 ConstantStoredListValue::BitArray(value) => {
2818 StoredListExpr::BitArray(self.materialize_bit_array_list_value(value, substitution))
2819 }
2820 ConstantStoredListValue::UtfCodepoint(value) => StoredListExpr::UtfCodepoint(
2821 self.materialize_utf_codepoint_list_value(value, substitution),
2822 ),
2823 ConstantStoredListValue::Custom(value) => {
2824 StoredListExpr::Custom(self.materialize_custom_list_value(value, substitution))
2825 }
2826 ConstantStoredListValue::External(value) => {
2827 StoredListExpr::External(self.materialize_external_list_value(value, substitution))
2828 }
2829 ConstantStoredListValue::Float(value) => {
2830 StoredListExpr::Float(self.materialize_float_list_value(value, substitution))
2831 }
2832 ConstantStoredListValue::Bool(value) => {
2833 StoredListExpr::Bool(self.materialize_bool_list_value(value, substitution))
2834 }
2835 ConstantStoredListValue::Nil(value) => {
2836 StoredListExpr::Nil(self.materialize_nil_list_value(value, substitution))
2837 }
2838 ConstantStoredListValue::Tuple(value) => {
2839 StoredListExpr::Tuple(self.materialize_tuple_list_value(value, substitution))
2840 }
2841 ConstantStoredListValue::List(value) => {
2842 StoredListExpr::List(self.materialize_list_list_value(value, substitution))
2843 }
2844 ConstantStoredListValue::Function(value) => {
2845 StoredListExpr::Function(self.materialize_function_list_value(value, substitution))
2846 }
2847 }
2848 }
2849
2850 pub(crate) fn materialize_list_list(
2851 &self,
2852 value: &ConstantListListInstantiation,
2853 ) -> ListListExpr {
2854 if !self.owns(value.module()) {
2855 let shape = value.item_shape().clone();
2856 return ListListExpr::constant(
2857 ValueShape::List(Box::new(shape.to_value_shape())),
2858 ListListItem::new(shape),
2859 value.clone(),
2860 );
2861 }
2862 match value.source() {
2863 ConstantNestedListTemplateSource::Generic(source) => self
2864 .materialize_generic_list_list(
2865 self.generic_list(*source),
2866 value.substitution(),
2867 value.item_shape(),
2868 ),
2869 ConstantNestedListTemplateSource::ParameterList(source) => self
2870 .materialize_parameter_list_list_value_as_stored(
2871 self.parameter_list_list(*source),
2872 value.substitution(),
2873 value.item_shape(),
2874 ),
2875 ConstantNestedListTemplateSource::Exact(source) => {
2876 self.materialize_list_list_value(self.list_list(*source), value.substitution())
2877 }
2878 }
2879 }
2880
2881 fn materialize_list_list_value(
2882 &self,
2883 value: &ConstantListListValue,
2884 substitution: &TypeSubstitution,
2885 ) -> ListListExpr {
2886 let shape = value.item_shape().substitute(substitution);
2887 match value.kind() {
2888 TypedConstantListValueKind::Value(elements) => ListListExpr::value(
2889 ListListItem::new(shape.clone()),
2890 elements
2891 .iter()
2892 .map(|value| self.materialize_stored_list_value(value, substitution))
2893 .collect(),
2894 )
2895 .with_item_shape(ValueShape::List(Box::new(shape.to_value_shape()))),
2896 TypedConstantListValueKind::Spread { elements, tail } => ListListExpr::spread(
2897 elements
2898 .mapped_ref(|value| self.materialize_stored_list_value(value, substitution)),
2899 self.materialize_list_list_value(tail, substitution),
2900 )
2901 .with_item_shape(ValueShape::List(Box::new(shape.to_value_shape()))),
2902 TypedConstantListValueKind::Reference(value) => {
2903 self.materialize_list_list(&value.substitute_list(substitution))
2904 }
2905 }
2906 }
2907
2908 pub(crate) fn materialize_function_list(
2909 &self,
2910 value: &ConstantFunctionListInstantiation,
2911 ) -> FunctionListExpr {
2912 if !self.owns(value.module()) {
2913 let shape = value.item_shape().clone();
2914 return FunctionListExpr::constant(
2915 ValueShape::Function(Box::new(shape.clone())),
2916 FunctionListItem::new(shape.type_()),
2917 value.clone(),
2918 );
2919 }
2920 match value.source() {
2921 ConstantListTemplateSource::Generic(source) => self.materialize_generic_function_list(
2922 self.generic_list(*source),
2923 value.substitution(),
2924 value.item_shape(),
2925 ),
2926 ConstantListTemplateSource::Exact(source) => self
2927 .materialize_function_list_value(self.function_list(*source), value.substitution()),
2928 }
2929 }
2930
2931 fn materialize_function_list_value(
2932 &self,
2933 value: &ConstantFunctionListValue,
2934 substitution: &TypeSubstitution,
2935 ) -> FunctionListExpr {
2936 let shape = value.item_shape().substitute(substitution);
2937 match value.kind() {
2938 TypedConstantListValueKind::Value(elements) => FunctionListExpr::value(
2939 FunctionListItem::new(shape.type_()),
2940 elements
2941 .iter()
2942 .map(|value| self.materialize_function_value(value, substitution))
2943 .collect(),
2944 )
2945 .with_item_shape(ValueShape::Function(Box::new(shape))),
2946 TypedConstantListValueKind::Spread { elements, tail } => FunctionListExpr::spread(
2947 elements.mapped_ref(|value| self.materialize_function_value(value, substitution)),
2948 self.materialize_function_list_value(tail, substitution),
2949 )
2950 .with_item_shape(ValueShape::Function(Box::new(shape))),
2951 TypedConstantListValueKind::Reference(value) => {
2952 self.materialize_function_list(&value.substitute_function(substitution))
2953 }
2954 }
2955 }
2956}
2957
2958impl ConstantTemplateSignature {
2959 pub(crate) fn int(id: ConstantTemplateId, storage_index: usize, scheme: TypeScheme) -> Self {
2960 Self::new(
2961 id,
2962 scheme,
2963 ValueShape::Int,
2964 ConstantTemplateSignatureKind::Int(ConstantIntTemplateId(storage_index)),
2965 )
2966 }
2967
2968 pub(crate) fn string(id: ConstantTemplateId, storage_index: usize, scheme: TypeScheme) -> Self {
2969 Self::new(
2970 id,
2971 scheme,
2972 ValueShape::String,
2973 ConstantTemplateSignatureKind::String(ConstantStringTemplateId(storage_index)),
2974 )
2975 }
2976
2977 pub(crate) fn bit_array(
2978 id: ConstantTemplateId,
2979 storage_index: usize,
2980 scheme: TypeScheme,
2981 ) -> Self {
2982 Self::new(
2983 id,
2984 scheme,
2985 ValueShape::BitArray,
2986 ConstantTemplateSignatureKind::BitArray(ConstantBitArrayTemplateId(storage_index)),
2987 )
2988 }
2989
2990 pub(crate) fn custom(
2991 id: ConstantTemplateId,
2992 storage_index: usize,
2993 scheme: TypeScheme,
2994 shape: CustomValueShape,
2995 ) -> Self {
2996 let kind_shape = shape.clone();
2997 Self::new(
2998 id,
2999 scheme,
3000 ValueShape::Custom(shape),
3001 ConstantTemplateSignatureKind::Custom {
3002 template: ConstantCustomTemplateId(storage_index),
3003 shape: kind_shape,
3004 },
3005 )
3006 }
3007
3008 pub(crate) fn float(id: ConstantTemplateId, storage_index: usize, scheme: TypeScheme) -> Self {
3009 Self::new(
3010 id,
3011 scheme,
3012 ValueShape::Float,
3013 ConstantTemplateSignatureKind::Float(ConstantFloatTemplateId(storage_index)),
3014 )
3015 }
3016
3017 pub(crate) fn bool(id: ConstantTemplateId, storage_index: usize, scheme: TypeScheme) -> Self {
3018 Self::new(
3019 id,
3020 scheme,
3021 ValueShape::Bool,
3022 ConstantTemplateSignatureKind::Bool(ConstantBoolTemplateId(storage_index)),
3023 )
3024 }
3025
3026 pub(crate) fn nil(id: ConstantTemplateId, storage_index: usize, scheme: TypeScheme) -> Self {
3027 Self::new(
3028 id,
3029 scheme,
3030 ValueShape::Nil,
3031 ConstantTemplateSignatureKind::Nil(ConstantNilTemplateId(storage_index)),
3032 )
3033 }
3034
3035 pub(crate) fn tuple(
3036 id: ConstantTemplateId,
3037 storage_index: usize,
3038 scheme: TypeScheme,
3039 shape: Box<[ValueShape]>,
3040 ) -> Self {
3041 let kind_shape = shape.clone();
3042 Self::new(
3043 id,
3044 scheme,
3045 ValueShape::Tuple(shape),
3046 ConstantTemplateSignatureKind::Tuple {
3047 template: ConstantTupleTemplateId(storage_index),
3048 shape: kind_shape,
3049 },
3050 )
3051 }
3052
3053 pub(crate) fn list(
3054 id: ConstantTemplateId,
3055 storage_index: usize,
3056 scheme: TypeScheme,
3057 item_shape: ValueShape,
3058 ) -> Self {
3059 let template = ConstantListTemplate::from_item_shape(item_shape, storage_index);
3060 let item_shape = template.item_shape();
3061 Self::new(
3062 id,
3063 scheme,
3064 ValueShape::List(Box::new(item_shape)),
3065 ConstantTemplateSignatureKind::List(template),
3066 )
3067 }
3068
3069 pub(crate) fn function(
3070 id: ConstantTemplateId,
3071 storage_index: usize,
3072 scheme: TypeScheme,
3073 shape: FunctionShape,
3074 ) -> Self {
3075 let template = ConstantFunctionTemplate::from_shape(&shape, storage_index);
3076 let kind_shape = shape.clone();
3077 Self::new(
3078 id,
3079 scheme,
3080 ValueShape::Function(Box::new(shape)),
3081 ConstantTemplateSignatureKind::Function {
3082 template,
3083 shape: kind_shape,
3084 },
3085 )
3086 }
3087
3088 fn new(
3089 id: ConstantTemplateId,
3090 scheme: TypeScheme,
3091 shape: ValueShape,
3092 kind: ConstantTemplateSignatureKind,
3093 ) -> Self {
3094 Self {
3095 id,
3096 scheme,
3097 shape,
3098 kind,
3099 }
3100 }
3101
3102 pub(crate) fn id(&self) -> ConstantTemplateId {
3103 self.id
3104 }
3105
3106 pub(crate) fn scheme(&self) -> &TypeScheme {
3107 &self.scheme
3108 }
3109
3110 pub(crate) fn shape(&self) -> &ValueShape {
3111 &self.shape
3112 }
3113
3114 pub(crate) fn try_instantiate(
3115 &self,
3116 arguments: Vec<ValueShape>,
3117 ) -> Option<ConstantInstantiation> {
3118 let substitution = self.scheme.try_substitution(arguments)?;
3119 let kind = match &self.kind {
3120 ConstantTemplateSignatureKind::Int(template) => {
3121 ConstantInstantiationKind::Int(TypedConstantInstantiation::in_module(
3122 self.id.module(),
3123 *template,
3124 substitution,
3125 (),
3126 ))
3127 }
3128 ConstantTemplateSignatureKind::String(template) => {
3129 ConstantInstantiationKind::String(TypedConstantInstantiation::in_module(
3130 self.id.module(),
3131 *template,
3132 substitution,
3133 (),
3134 ))
3135 }
3136 ConstantTemplateSignatureKind::BitArray(template) => {
3137 ConstantInstantiationKind::BitArray(TypedConstantInstantiation::in_module(
3138 self.id.module(),
3139 *template,
3140 substitution,
3141 (),
3142 ))
3143 }
3144 ConstantTemplateSignatureKind::Custom { template, shape } => {
3145 let shape = shape.substitute(&substitution);
3146 ConstantInstantiationKind::Custom(TypedConstantInstantiation::in_module(
3147 self.id.module(),
3148 *template,
3149 substitution,
3150 shape,
3151 ))
3152 }
3153 ConstantTemplateSignatureKind::Float(template) => {
3154 ConstantInstantiationKind::Float(TypedConstantInstantiation::in_module(
3155 self.id.module(),
3156 *template,
3157 substitution,
3158 (),
3159 ))
3160 }
3161 ConstantTemplateSignatureKind::Bool(template) => {
3162 ConstantInstantiationKind::Bool(TypedConstantInstantiation::in_module(
3163 self.id.module(),
3164 *template,
3165 substitution,
3166 (),
3167 ))
3168 }
3169 ConstantTemplateSignatureKind::Nil(template) => {
3170 ConstantInstantiationKind::Nil(TypedConstantInstantiation::in_module(
3171 self.id.module(),
3172 *template,
3173 substitution,
3174 (),
3175 ))
3176 }
3177 ConstantTemplateSignatureKind::Tuple { template, shape } => {
3178 let shape = shape
3179 .iter()
3180 .map(|shape| shape.substitute(&substitution))
3181 .collect::<Vec<_>>()
3182 .into_boxed_slice();
3183 ConstantInstantiationKind::Tuple(TypedConstantInstantiation::in_module(
3184 self.id.module(),
3185 *template,
3186 substitution,
3187 shape,
3188 ))
3189 }
3190 ConstantTemplateSignatureKind::List(template) => ConstantInstantiationKind::List(
3191 template.instantiate(self.id.module(), substitution),
3192 ),
3193 ConstantTemplateSignatureKind::Function { template, shape } => {
3194 let shape = shape.substitute(&substitution);
3195 ConstantInstantiationKind::Function(template.instantiate(
3196 self.id.module(),
3197 substitution,
3198 shape,
3199 ))
3200 }
3201 };
3202 Some(ConstantInstantiation { kind })
3203 }
3204}
3205
3206impl<Id: Copy, Shape> TypedConstantInstantiation<Id, Shape> {
3207 #[cfg(test)]
3208 fn new(template: Id, substitution: TypeSubstitution, shape: Shape) -> Self {
3209 Self::in_module(crate::plan::ModuleId::root(), template, substitution, shape)
3210 }
3211
3212 fn in_module(
3213 module: crate::plan::ModuleId,
3214 template: Id,
3215 substitution: TypeSubstitution,
3216 shape: Shape,
3217 ) -> Self {
3218 Self {
3219 module,
3220 template,
3221 substitution,
3222 shape,
3223 }
3224 }
3225
3226 pub(crate) fn template(&self) -> Id {
3227 self.template
3228 }
3229
3230 pub(crate) fn module(&self) -> crate::plan::ModuleId {
3231 self.module
3232 }
3233
3234 pub(crate) fn substitution(&self) -> &TypeSubstitution {
3235 &self.substitution
3236 }
3237
3238 pub(crate) fn shape(&self) -> &Shape {
3239 &self.shape
3240 }
3241}
3242
3243impl<Id: Copy> TypedConstantInstantiation<Id, ()> {
3244 fn substitute_leaf(&self, outer: &TypeSubstitution) -> Self {
3245 Self::in_module(
3246 self.module,
3247 self.template,
3248 self.substitution.substitute(outer),
3249 (),
3250 )
3251 }
3252}
3253
3254impl TypedConstantInstantiation<ConstantCustomTemplateId, CustomValueShape> {
3255 fn substitute_custom(&self, outer: &TypeSubstitution) -> Self {
3256 Self::in_module(
3257 self.module,
3258 self.template,
3259 self.substitution.substitute(outer),
3260 self.shape.substitute(outer),
3261 )
3262 }
3263}
3264
3265impl TypedConstantInstantiation<ConstantTupleTemplateId, Box<[ValueShape]>> {
3266 fn substitute_tuple(&self, outer: &TypeSubstitution) -> Self {
3267 Self::in_module(
3268 self.module,
3269 self.template,
3270 self.substitution.substitute(outer),
3271 self.shape
3272 .iter()
3273 .map(|shape| shape.substitute(outer))
3274 .collect::<Vec<_>>()
3275 .into_boxed_slice(),
3276 )
3277 }
3278}
3279
3280impl ConstantValue {
3281 pub(crate) fn int(value: BigInt) -> Self {
3282 Self {
3283 kind: ConstantValueKind::Int(ConstantIntValue::Value(value)),
3284 }
3285 }
3286
3287 pub(crate) fn float(value: f64) -> Self {
3288 Self {
3289 kind: ConstantValueKind::Float(ConstantFloatValue::Value(value)),
3290 }
3291 }
3292
3293 pub(crate) fn string(value: EcoString) -> Self {
3294 Self {
3295 kind: ConstantValueKind::String(ConstantStringValue::Value(value)),
3296 }
3297 }
3298
3299 pub(crate) fn string_concatenation(
3300 left: ConstantStringValue,
3301 right: ConstantStringValue,
3302 ) -> Self {
3303 Self {
3304 kind: ConstantValueKind::String(ConstantStringValue::Concatenation {
3305 left: Box::new(left),
3306 right: Box::new(right),
3307 }),
3308 }
3309 }
3310
3311 pub(crate) fn bool(value: bool) -> Self {
3312 Self {
3313 kind: ConstantValueKind::Bool(ConstantBoolValue::Value(value)),
3314 }
3315 }
3316
3317 pub(crate) fn nil() -> Self {
3318 Self {
3319 kind: ConstantValueKind::Nil(ConstantNilValue::Value),
3320 }
3321 }
3322
3323 pub(crate) fn tuple(element_shapes: Box<[ValueShape]>, elements: Box<[Self]>) -> Self {
3324 Self {
3325 kind: ConstantValueKind::Tuple(ConstantTupleValue {
3326 shape: element_shapes,
3327 kind: ConstantTupleValueKind::Value(elements),
3328 }),
3329 }
3330 }
3331
3332 pub(crate) fn try_list(
3333 item_shape: ValueShape,
3334 elements: Vec<Self>,
3335 tail: Option<Self>,
3336 ) -> Result<Self, ConstantListConstructionError> {
3337 let tail = tail
3338 .map(|tail| {
3339 let actual = tail.shape();
3340 match tail.into_list() {
3341 Some(tail) => Ok(tail),
3342 None => Err(constant_list_tail_mismatch(&item_shape, actual)),
3343 }
3344 })
3345 .transpose()?;
3346 let parts = ConstantListParts::try_from_parts(elements, tail)?;
3347
3348 let value = match &item_shape {
3349 ValueShape::Parameter(parameter) => {
3350 match parts {
3351 ConstantListParts::Value(elements) if elements.is_empty() => {}
3352 ConstantListParts::Value(elements) => {
3353 return Err(constant_list_element_mismatch(
3354 &item_shape,
3355 elements[0].shape(),
3356 ));
3357 }
3358 ConstantListParts::Spread { elements, .. } => {
3359 return Err(constant_list_element_mismatch(
3360 &item_shape,
3361 elements.first().shape(),
3362 ));
3363 }
3364 }
3365 ConstantListValue::generic(*parameter)
3366 }
3367 ValueShape::Int => ConstantListValue::int(parts.try_map(
3368 |value| {
3369 let actual = value.shape();
3370 match value.into_int() {
3371 Some(value) => Ok(value),
3372 None => Err(constant_list_element_mismatch(&item_shape, actual)),
3373 }
3374 },
3375 |tail| {
3376 let actual = tail.shape();
3377 match tail.into_int() {
3378 Some(tail) => Ok(tail),
3379 None => Err(constant_list_tail_mismatch(&item_shape, actual)),
3380 }
3381 },
3382 )?),
3383 ValueShape::String => ConstantListValue::string(parts.try_map(
3384 |value| {
3385 let actual = value.shape();
3386 match value.into_string() {
3387 Some(value) => Ok(value),
3388 None => Err(constant_list_element_mismatch(&item_shape, actual)),
3389 }
3390 },
3391 |tail| {
3392 let actual = tail.shape();
3393 match tail.into_string() {
3394 Some(tail) => Ok(tail),
3395 None => Err(constant_list_tail_mismatch(&item_shape, actual)),
3396 }
3397 },
3398 )?),
3399 ValueShape::BitArray => ConstantListValue::bit_array(parts.try_map(
3400 |value| {
3401 let actual = value.shape();
3402 match value.into_bit_array() {
3403 Some(value) => Ok(value),
3404 None => Err(constant_list_element_mismatch(&item_shape, actual)),
3405 }
3406 },
3407 |tail| {
3408 let actual = tail.shape();
3409 match tail.into_bit_array() {
3410 Some(tail) => Ok(tail),
3411 None => Err(constant_list_tail_mismatch(&item_shape, actual)),
3412 }
3413 },
3414 )?),
3415 ValueShape::UtfCodepoint => {
3416 match parts {
3417 ConstantListParts::Value(elements) if elements.is_empty() => {}
3418 ConstantListParts::Value(elements) => {
3419 return Err(constant_list_element_mismatch(
3420 &item_shape,
3421 elements[0].shape(),
3422 ));
3423 }
3424 ConstantListParts::Spread { elements, .. } => {
3425 return Err(constant_list_element_mismatch(
3426 &item_shape,
3427 elements.first().shape(),
3428 ));
3429 }
3430 }
3431 ConstantListValue::utf_codepoint()
3432 }
3433 ValueShape::Custom(shape) => ConstantListValue::custom(
3434 shape.clone(),
3435 parts.try_map(
3436 |value| {
3437 let actual = value.shape();
3438 match value.kind {
3439 ConstantValueKind::Custom(value) if actual.can_flow_to(&item_shape) => {
3440 Ok(value)
3441 }
3442 _ => Err(constant_list_element_mismatch(&item_shape, actual)),
3443 }
3444 },
3445 |tail| {
3446 let actual = tail.shape();
3447 match tail {
3448 ConstantListValue::Custom(value)
3449 if actual.can_flow_to(&ValueShape::List(Box::new(
3450 item_shape.clone(),
3451 ))) =>
3452 {
3453 Ok(value)
3454 }
3455 _ => Err(constant_list_tail_mismatch(&item_shape, actual)),
3456 }
3457 },
3458 )?,
3459 ),
3460 ValueShape::External(shape) => {
3461 match parts {
3462 ConstantListParts::Value(elements) if elements.is_empty() => {}
3463 ConstantListParts::Value(elements) => {
3464 return Err(constant_list_element_mismatch(
3465 &item_shape,
3466 elements[0].shape(),
3467 ));
3468 }
3469 ConstantListParts::Spread { elements, .. } => {
3470 return Err(constant_list_element_mismatch(
3471 &item_shape,
3472 elements.first().shape(),
3473 ));
3474 }
3475 }
3476 ConstantListValue::external(shape.clone())
3477 }
3478 ValueShape::Float => ConstantListValue::float(parts.try_map(
3479 |value| {
3480 let actual = value.shape();
3481 match value.into_float() {
3482 Some(value) => Ok(value),
3483 None => Err(constant_list_element_mismatch(&item_shape, actual)),
3484 }
3485 },
3486 |tail| {
3487 let actual = tail.shape();
3488 match tail.into_float() {
3489 Some(tail) => Ok(tail),
3490 None => Err(constant_list_tail_mismatch(&item_shape, actual)),
3491 }
3492 },
3493 )?),
3494 ValueShape::Bool => ConstantListValue::bool(parts.try_map(
3495 |value| {
3496 let actual = value.shape();
3497 match value.into_bool() {
3498 Some(value) => Ok(value),
3499 None => Err(constant_list_element_mismatch(&item_shape, actual)),
3500 }
3501 },
3502 |tail| {
3503 let actual = tail.shape();
3504 match tail.into_bool() {
3505 Some(tail) => Ok(tail),
3506 None => Err(constant_list_tail_mismatch(&item_shape, actual)),
3507 }
3508 },
3509 )?),
3510 ValueShape::Nil => ConstantListValue::nil(parts.try_map(
3511 |value| {
3512 let actual = value.shape();
3513 match value.into_nil() {
3514 Some(value) => Ok(value),
3515 None => Err(constant_list_element_mismatch(&item_shape, actual)),
3516 }
3517 },
3518 |tail| {
3519 let actual = tail.shape();
3520 match tail.into_nil() {
3521 Some(tail) => Ok(tail),
3522 None => Err(constant_list_tail_mismatch(&item_shape, actual)),
3523 }
3524 },
3525 )?),
3526 ValueShape::Tuple(shape) => ConstantListValue::tuple(
3527 shape.clone(),
3528 parts.try_map(
3529 |value| {
3530 let actual = value.shape();
3531 match value.kind {
3532 ConstantValueKind::Tuple(value) if actual.can_flow_to(&item_shape) => {
3533 Ok(value)
3534 }
3535 _ => Err(constant_list_element_mismatch(&item_shape, actual)),
3536 }
3537 },
3538 |tail| {
3539 let actual = tail.shape();
3540 match tail {
3541 ConstantListValue::Tuple(value)
3542 if actual.can_flow_to(&ValueShape::List(Box::new(
3543 item_shape.clone(),
3544 ))) =>
3545 {
3546 Ok(value)
3547 }
3548 _ => Err(constant_list_tail_mismatch(&item_shape, actual)),
3549 }
3550 },
3551 )?,
3552 ),
3553 ValueShape::List(shape) => match shape.representation() {
3554 crate::plan::ValueRepresentation::Uninhabited(parameter) => {
3555 ConstantListValue::parameter_list(
3556 parameter,
3557 parts.try_map(
3558 |value| {
3559 let actual = value.shape();
3560 match value.kind {
3561 ConstantValueKind::List(ConstantListValue::Generic(value))
3562 if actual.can_flow_to(&item_shape) =>
3563 {
3564 Ok(value)
3565 }
3566 _ => Err(constant_list_element_mismatch(&item_shape, actual)),
3567 }
3568 },
3569 |tail| {
3570 let actual = tail.shape();
3571 match tail {
3572 ConstantListValue::ParameterList(value)
3573 if actual.can_flow_to(&ValueShape::List(Box::new(
3574 item_shape.clone(),
3575 ))) =>
3576 {
3577 Ok(value)
3578 }
3579 _ => Err(constant_list_tail_mismatch(&item_shape, actual)),
3580 }
3581 },
3582 )?,
3583 )
3584 }
3585 crate::plan::ValueRepresentation::Stored(shape) => ConstantListValue::list(
3586 shape,
3587 parts.try_map(
3588 |value| {
3589 let actual = value.shape();
3590 let value = match value.kind {
3591 ConstantValueKind::List(ConstantListValue::ParameterList(
3592 value,
3593 )) => ConstantStoredListValue::ParameterList(value),
3594 ConstantValueKind::List(ConstantListValue::Int(value)) => {
3595 ConstantStoredListValue::Int(value)
3596 }
3597 ConstantValueKind::List(ConstantListValue::String(value)) => {
3598 ConstantStoredListValue::String(value)
3599 }
3600 ConstantValueKind::List(ConstantListValue::BitArray(value)) => {
3601 ConstantStoredListValue::BitArray(value)
3602 }
3603 ConstantValueKind::List(ConstantListValue::UtfCodepoint(value)) => {
3604 ConstantStoredListValue::UtfCodepoint(value)
3605 }
3606 ConstantValueKind::List(ConstantListValue::Custom(value)) => {
3607 ConstantStoredListValue::Custom(value)
3608 }
3609 ConstantValueKind::List(ConstantListValue::External(value)) => {
3610 ConstantStoredListValue::External(value)
3611 }
3612 ConstantValueKind::List(ConstantListValue::Float(value)) => {
3613 ConstantStoredListValue::Float(value)
3614 }
3615 ConstantValueKind::List(ConstantListValue::Bool(value)) => {
3616 ConstantStoredListValue::Bool(value)
3617 }
3618 ConstantValueKind::List(ConstantListValue::Nil(value)) => {
3619 ConstantStoredListValue::Nil(value)
3620 }
3621 ConstantValueKind::List(ConstantListValue::Tuple(value)) => {
3622 ConstantStoredListValue::Tuple(value)
3623 }
3624 ConstantValueKind::List(ConstantListValue::List(value)) => {
3625 ConstantStoredListValue::List(value)
3626 }
3627 ConstantValueKind::List(ConstantListValue::Function(value)) => {
3628 ConstantStoredListValue::Function(value)
3629 }
3630 _ => {
3631 return Err(constant_list_element_mismatch(
3632 &item_shape,
3633 actual,
3634 ));
3635 }
3636 };
3637 if actual.can_flow_to(&item_shape) {
3638 Ok(value)
3639 } else {
3640 Err(constant_list_element_mismatch(&item_shape, actual))
3641 }
3642 },
3643 |tail| {
3644 let actual = tail.shape();
3645 match tail {
3646 ConstantListValue::List(value)
3647 if actual.can_flow_to(&ValueShape::List(Box::new(
3648 item_shape.clone(),
3649 ))) =>
3650 {
3651 Ok(value)
3652 }
3653 _ => Err(constant_list_tail_mismatch(&item_shape, actual)),
3654 }
3655 },
3656 )?,
3657 ),
3658 },
3659 ValueShape::Function(shape) => ConstantListValue::function(
3660 (**shape).clone(),
3661 parts.try_map(
3662 |value| {
3663 let actual = value.shape();
3664 match value.kind {
3665 ConstantValueKind::Function(value)
3666 if actual.can_flow_to(&item_shape) =>
3667 {
3668 Ok(value)
3669 }
3670 _ => Err(constant_list_element_mismatch(&item_shape, actual)),
3671 }
3672 },
3673 |tail| {
3674 let actual = tail.shape();
3675 match tail {
3676 ConstantListValue::Function(value)
3677 if actual.can_flow_to(&ValueShape::List(Box::new(
3678 item_shape.clone(),
3679 ))) =>
3680 {
3681 Ok(value)
3682 }
3683 _ => Err(constant_list_tail_mismatch(&item_shape, actual)),
3684 }
3685 },
3686 )?,
3687 ),
3688 };
3689
3690 Ok(Self {
3691 kind: ConstantValueKind::List(value),
3692 })
3693 }
3694
3695 pub(crate) fn bit_array(segments: Box<[ConstantBitArraySegment]>) -> Self {
3696 Self {
3697 kind: ConstantValueKind::BitArray(ConstantBitArrayValue {
3698 kind: ConstantBitArrayValueKind::Value(segments),
3699 }),
3700 }
3701 }
3702
3703 pub(crate) fn custom(
3704 shape: CustomValueShape,
3705 constructor: CustomConstructor,
3706 fields: Box<[Self]>,
3707 ) -> Self {
3708 Self {
3709 kind: ConstantValueKind::Custom(ConstantCustomValue {
3710 shape,
3711 kind: ConstantCustomValueKind::Construction(ConstantCustomConstruction {
3712 constructor,
3713 fields,
3714 }),
3715 }),
3716 }
3717 }
3718
3719 pub(crate) fn function(shape: FunctionShape, reference: FunctionReference) -> Self {
3720 let value = ConstantFunctionValue::function_reference(shape, reference);
3721 Self {
3722 kind: ConstantValueKind::Function(value),
3723 }
3724 }
3725
3726 pub(crate) fn constructor_function(
3727 shape: FunctionShape,
3728 return_: CustomValueShape,
3729 constructor: CustomConstructor,
3730 ) -> Self {
3731 let value = ConstantFunctionValue::constructor(shape, return_, constructor);
3732 Self {
3733 kind: ConstantValueKind::Function(value),
3734 }
3735 }
3736
3737 pub(crate) fn reference(instantiation: ConstantInstantiation) -> Self {
3738 let kind = match instantiation.kind {
3739 ConstantInstantiationKind::Int(value) => {
3740 ConstantValueKind::Int(ConstantIntValue::Reference(value))
3741 }
3742 ConstantInstantiationKind::String(value) => {
3743 ConstantValueKind::String(ConstantStringValue::Reference(value))
3744 }
3745 ConstantInstantiationKind::BitArray(value) => {
3746 ConstantValueKind::BitArray(ConstantBitArrayValue {
3747 kind: ConstantBitArrayValueKind::Reference(value),
3748 })
3749 }
3750 ConstantInstantiationKind::Custom(value) => {
3751 ConstantValueKind::Custom(ConstantCustomValue {
3752 shape: value.shape().clone(),
3753 kind: ConstantCustomValueKind::Reference(value),
3754 })
3755 }
3756 ConstantInstantiationKind::Float(value) => {
3757 ConstantValueKind::Float(ConstantFloatValue::Reference(value))
3758 }
3759 ConstantInstantiationKind::Bool(value) => {
3760 ConstantValueKind::Bool(ConstantBoolValue::Reference(value))
3761 }
3762 ConstantInstantiationKind::Nil(value) => {
3763 ConstantValueKind::Nil(ConstantNilValue::Reference(value))
3764 }
3765 ConstantInstantiationKind::Tuple(value) => {
3766 ConstantValueKind::Tuple(ConstantTupleValue {
3767 shape: value.shape().clone(),
3768 kind: ConstantTupleValueKind::Reference(value),
3769 })
3770 }
3771 ConstantInstantiationKind::List(value) => {
3772 ConstantValueKind::List(ConstantListValue::reference(value))
3773 }
3774 ConstantInstantiationKind::Function(value) => {
3775 ConstantValueKind::Function(ConstantFunctionValue::reference(value))
3776 }
3777 };
3778 Self { kind }
3779 }
3780
3781 pub(crate) fn shape(&self) -> ValueShape {
3782 match &self.kind {
3783 ConstantValueKind::Int(_) => ValueShape::Int,
3784 ConstantValueKind::Float(_) => ValueShape::Float,
3785 ConstantValueKind::String(_) => ValueShape::String,
3786 ConstantValueKind::Bool(_) => ValueShape::Bool,
3787 ConstantValueKind::Nil(_) => ValueShape::Nil,
3788 ConstantValueKind::Tuple(value) => ValueShape::Tuple(value.shape.clone()),
3789 ConstantValueKind::List(value) => value.shape(),
3790 ConstantValueKind::BitArray(_) => ValueShape::BitArray,
3791 ConstantValueKind::Custom(value) => ValueShape::Custom(value.shape.clone()),
3792 ConstantValueKind::Function(value) => {
3793 ValueShape::Function(Box::new(value.shape().clone()))
3794 }
3795 }
3796 }
3797
3798 pub(crate) fn into_int(self) -> Option<ConstantIntValue> {
3799 match self.kind {
3800 ConstantValueKind::Int(value) => Some(value),
3801 _ => None,
3802 }
3803 }
3804
3805 pub(crate) fn into_float(self) -> Option<ConstantFloatValue> {
3806 match self.kind {
3807 ConstantValueKind::Float(value) => Some(value),
3808 _ => None,
3809 }
3810 }
3811
3812 pub(crate) fn into_string(self) -> Option<ConstantStringValue> {
3813 match self.kind {
3814 ConstantValueKind::String(value) => Some(value),
3815 _ => None,
3816 }
3817 }
3818
3819 pub(crate) fn into_bit_array(self) -> Option<ConstantBitArrayValue> {
3820 match self.kind {
3821 ConstantValueKind::BitArray(value) => Some(value),
3822 _ => None,
3823 }
3824 }
3825
3826 pub(crate) fn into_bool(self) -> Option<ConstantBoolValue> {
3827 match self.kind {
3828 ConstantValueKind::Bool(value) => Some(value),
3829 _ => None,
3830 }
3831 }
3832
3833 pub(crate) fn into_nil(self) -> Option<ConstantNilValue> {
3834 match self.kind {
3835 ConstantValueKind::Nil(value) => Some(value),
3836 _ => None,
3837 }
3838 }
3839
3840 fn into_list(self) -> Option<ConstantListValue> {
3841 match self.kind {
3842 ConstantValueKind::List(value) => Some(value),
3843 _ => None,
3844 }
3845 }
3846}
3847
3848impl ConstantTupleValue {
3849 pub(crate) fn shape(&self) -> &[ValueShape] {
3850 &self.shape
3851 }
3852
3853 pub(crate) fn kind(&self) -> &ConstantTupleValueKind {
3854 &self.kind
3855 }
3856}
3857
3858impl ConstantBitArrayValue {
3859 pub(crate) fn kind(&self) -> &ConstantBitArrayValueKind {
3860 &self.kind
3861 }
3862}
3863
3864impl ConstantCustomValue {
3865 pub(crate) fn shape(&self) -> &CustomValueShape {
3866 &self.shape
3867 }
3868
3869 pub(crate) fn kind(&self) -> &ConstantCustomValueKind {
3870 &self.kind
3871 }
3872}
3873
3874impl ConstantCustomConstruction {
3875 pub(crate) fn constructor(&self) -> &CustomConstructor {
3876 &self.constructor
3877 }
3878
3879 pub(crate) fn fields(&self) -> &[ConstantValue] {
3880 &self.fields
3881 }
3882}
3883
3884impl MaterializedConstantCustomConstruction {
3885 pub(crate) fn new(constructor: CustomConstructor, fields: Vec<super::Expr>) -> Self {
3886 Self {
3887 constructor,
3888 fields: fields.into_boxed_slice(),
3889 }
3890 }
3891
3892 pub(crate) fn into_parts(self) -> (CustomConstructor, Box<[super::Expr]>) {
3893 (self.constructor, self.fields)
3894 }
3895}
3896
3897fn constant_list_element_mismatch(
3898 expected: &ValueShape,
3899 actual: ValueShape,
3900) -> ConstantListConstructionError {
3901 ConstantListConstructionError::TypeMismatch {
3902 expected: expected.value_type(),
3903 actual: actual.value_type(),
3904 }
3905}
3906
3907fn constant_list_tail_mismatch(
3908 expected: &ValueShape,
3909 actual: ValueShape,
3910) -> ConstantListConstructionError {
3911 ConstantListConstructionError::TypeMismatch {
3912 expected: ValueType::List(Box::new(expected.value_type())),
3913 actual: actual.value_type(),
3914 }
3915}
3916
3917#[cfg(test)]
3918mod tests {
3919 use super::function::ConstantFunctionTemplate;
3920 use super::list::{ConstantListTemplate, ConstantParameterListListTemplateId};
3921 use super::{
3922 ConstantBitArraySegment, ConstantBitArrayTemplateId, ConstantBoolTemplateId,
3923 ConstantCustomTemplateId, ConstantFloatTemplateId, ConstantInstantiation,
3924 ConstantInstantiationKind, ConstantIntTemplateId, ConstantListConstructionError,
3925 ConstantListInstantiation, ConstantListValue, ConstantNilTemplateId,
3926 ConstantStringTemplateId, ConstantTemplate, ConstantTemplateId, ConstantTemplateSignature,
3927 ConstantTemplates, ConstantTupleTemplateId, ConstantValue,
3928 MaterializedConstantCustomConstruction, TypedConstantInstantiation,
3929 };
3930 use crate::plan::module::{
3931 CustomListExpr, CustomListItem, ExternalListExpr, ExternalListItem, GenericListExpr,
3932 GenericListItem,
3933 };
3934 use crate::plan::{
3935 BitArrayExpr, BitArrayListExpr, BitArrayListItem, BitArraySegment, BoolExpr, BoolListExpr,
3936 BoolListItem, CustomConstruction, CustomConstructor, CustomConstructorField,
3937 CustomConstructorRefinement, CustomExpr, CustomTypeName, CustomValueShape, Endianness,
3938 Expr, ExternalTypeName, ExternalValueShape, FloatBitSize, FloatExpr, FloatListExpr,
3939 FloatListItem, FunctionExpr, FunctionListExpr, FunctionListItem, FunctionReference,
3940 FunctionShape, IntExpr, ListExpr, ListListExpr, ListListItem, ModuleId, NilExpr,
3941 NilListExpr, NilListItem, PanicSite, ParameterListListExpr, ParameterListListItem,
3942 StoredListExpr, StringEncoding, StringExpr, StringListExpr, StringListItem, TupleExpr,
3943 TupleListExpr, TupleListItem, TypeParameterId, TypeScheme, TypeSubstitution,
3944 UtfCodepointListExpr, UtfCodepointListItem, ValueShape, ValueStorageShape, ValueType,
3945 monomorphic_function_instantiation,
3946 };
3947
3948 #[test]
3949 fn local_constant_alias_materialization_preserves_foreign_owner() {
3950 let scheme = TypeScheme::new(0);
3951 let root_signature = ConstantTemplateSignature::int(
3952 ConstantTemplateId::in_module(ModuleId::root(), 0),
3953 0,
3954 scheme,
3955 );
3956 let foreign = TypedConstantInstantiation::in_module(
3957 ModuleId::new(1),
3958 ConstantIntTemplateId(0),
3959 TypeSubstitution::from_arguments(Vec::new()),
3960 (),
3961 );
3962 let local = TypedConstantInstantiation::in_module(
3963 ModuleId::root(),
3964 ConstantIntTemplateId(0),
3965 TypeSubstitution::from_arguments(Vec::new()),
3966 (),
3967 );
3968 let templates = ConstantTemplates::from_module_entries(
3969 ModuleId::root(),
3970 vec![(
3971 ConstantTemplate::new(root_signature, "alias".into()),
3972 ConstantValue::reference(ConstantInstantiation::from_int(foreign.clone())),
3973 )],
3974 );
3975
3976 assert_eq!(
3977 templates.materialize_int(&local),
3978 IntExpr::constant(super::ConstantIntReference(foreign)),
3979 );
3980 }
3981
3982 #[test]
3983 fn external_function_constants_materialize_targets_and_aliases() {
3984 let external = ExternalValueShape::new(
3985 ExternalTypeName::new("application".into(), "main".into(), "Resource".into()),
3986 Vec::new(),
3987 );
3988 let shape = FunctionShape::new(Vec::new(), ValueShape::External(external));
3989 let reference =
3990 FunctionReference::new(monomorphic_function_instantiation(0, shape.clone()));
3991 let scheme = TypeScheme::new(0);
3992 let base = ConstantTemplateSignature::function(
3993 ConstantTemplateId::new(0),
3994 0,
3995 scheme.clone(),
3996 shape.clone(),
3997 );
3998 let alias = ConstantTemplateSignature::function(
3999 ConstantTemplateId::new(1),
4000 1,
4001 scheme,
4002 shape.clone(),
4003 );
4004 let base_instantiation = base
4005 .try_instantiate(Vec::new())
4006 .expect("a monomorphic external function constant should instantiate");
4007 let alias_instantiation = alias
4008 .try_instantiate(Vec::new())
4009 .expect("a monomorphic external function alias should instantiate");
4010 let substitution = TypeSubstitution::from_arguments(Vec::new());
4011 let expected_alias = ConstantFunctionTemplate::from_shape(&shape, 1).instantiate(
4012 ModuleId::root(),
4013 substitution.clone(),
4014 shape.clone(),
4015 );
4016 let templates = ConstantTemplates::from_entries(vec![
4017 (
4018 ConstantTemplate::new(base, "resource".into()),
4019 ConstantValue::function(shape.clone(), reference.clone()),
4020 ),
4021 (
4022 ConstantTemplate::new(alias, "resource_alias".into()),
4023 ConstantValue::reference(base_instantiation),
4024 ),
4025 ]);
4026 let expected_target = Expr::function(FunctionExpr::reference(reference.clone()));
4027 let expected_alias = Expr::function(FunctionExpr::constant(expected_alias));
4028
4029 assert_eq!(
4030 templates.materialize_value(&ConstantValue::function(shape, reference), &substitution,),
4031 expected_target,
4032 );
4033 assert_eq!(
4034 templates.materialize_value(
4035 &ConstantValue::reference(alias_instantiation),
4036 &substitution,
4037 ),
4038 expected_alias,
4039 );
4040 }
4041
4042 #[test]
4043 fn constant_references_materialize_every_top_level_family() {
4044 let monomorphic = TypeScheme::new(0);
4045 let int_base =
4046 ConstantTemplateSignature::int(ConstantTemplateId::new(0), 0, monomorphic.clone());
4047 let int_alias =
4048 ConstantTemplateSignature::int(ConstantTemplateId::new(1), 1, monomorphic.clone());
4049 let int_reference = int_base
4050 .try_instantiate(Vec::new())
4051 .expect("a monomorphic Int constant should instantiate without arguments");
4052
4053 let string_base =
4054 ConstantTemplateSignature::string(ConstantTemplateId::new(2), 0, monomorphic.clone());
4055 let string_alias =
4056 ConstantTemplateSignature::string(ConstantTemplateId::new(3), 1, monomorphic.clone());
4057 let string_reference = string_base
4058 .try_instantiate(Vec::new())
4059 .expect("a monomorphic String constant should instantiate without arguments");
4060
4061 let float_base =
4062 ConstantTemplateSignature::float(ConstantTemplateId::new(4), 0, monomorphic.clone());
4063 let float_alias =
4064 ConstantTemplateSignature::float(ConstantTemplateId::new(5), 1, monomorphic.clone());
4065 let float_reference = float_base
4066 .try_instantiate(Vec::new())
4067 .expect("a monomorphic Float constant should instantiate without arguments");
4068
4069 let bool_base =
4070 ConstantTemplateSignature::bool(ConstantTemplateId::new(6), 0, monomorphic.clone());
4071 let bool_alias =
4072 ConstantTemplateSignature::bool(ConstantTemplateId::new(7), 1, monomorphic.clone());
4073 let bool_reference = bool_base
4074 .try_instantiate(Vec::new())
4075 .expect("a monomorphic Bool constant should instantiate without arguments");
4076
4077 let nil_base =
4078 ConstantTemplateSignature::nil(ConstantTemplateId::new(8), 0, monomorphic.clone());
4079 let nil_alias =
4080 ConstantTemplateSignature::nil(ConstantTemplateId::new(9), 1, monomorphic.clone());
4081 let nil_reference = nil_base
4082 .try_instantiate(Vec::new())
4083 .expect("a monomorphic Nil constant should instantiate without arguments");
4084
4085 let bit_array_base = ConstantTemplateSignature::bit_array(
4086 ConstantTemplateId::new(10),
4087 0,
4088 monomorphic.clone(),
4089 );
4090 let bit_array_alias = ConstantTemplateSignature::bit_array(
4091 ConstantTemplateId::new(11),
4092 1,
4093 monomorphic.clone(),
4094 );
4095 let bit_array_reference = bit_array_base
4096 .try_instantiate(Vec::new())
4097 .expect("a monomorphic BitArray constant should instantiate without arguments");
4098
4099 let custom_shape = CustomValueShape::new(
4100 CustomTypeName::new("geam".into(), "main".into(), "Token".into()),
4101 Vec::new(),
4102 CustomConstructorRefinement::Exact(0),
4103 );
4104 let constructor = CustomConstructor::new(
4105 custom_shape.type_().clone(),
4106 "Token".into(),
4107 0,
4108 vec![CustomConstructorField::new(None, ValueType::Int)],
4109 );
4110 let custom_base = ConstantTemplateSignature::custom(
4111 ConstantTemplateId::new(12),
4112 0,
4113 monomorphic.clone(),
4114 custom_shape.clone(),
4115 );
4116 let custom_alias = ConstantTemplateSignature::custom(
4117 ConstantTemplateId::new(13),
4118 1,
4119 monomorphic.clone(),
4120 custom_shape.clone(),
4121 );
4122 let custom_reference = custom_base
4123 .try_instantiate(Vec::new())
4124 .expect("a monomorphic custom constant should instantiate without arguments");
4125
4126 let tuple_shape = vec![ValueShape::Int, ValueShape::String].into_boxed_slice();
4127 let tuple_base = ConstantTemplateSignature::tuple(
4128 ConstantTemplateId::new(14),
4129 0,
4130 monomorphic.clone(),
4131 tuple_shape.clone(),
4132 );
4133 let tuple_alias = ConstantTemplateSignature::tuple(
4134 ConstantTemplateId::new(15),
4135 1,
4136 monomorphic.clone(),
4137 tuple_shape.clone(),
4138 );
4139 let tuple_reference = tuple_base
4140 .try_instantiate(Vec::new())
4141 .expect("a monomorphic tuple constant should instantiate without arguments");
4142
4143 let function_shape = FunctionShape::new(vec![ValueShape::Int], ValueShape::String);
4144 let function_reference = FunctionReference::new(monomorphic_function_instantiation(
4145 3,
4146 function_shape.clone(),
4147 ));
4148 let function_base = ConstantTemplateSignature::function(
4149 ConstantTemplateId::new(16),
4150 0,
4151 monomorphic.clone(),
4152 function_shape.clone(),
4153 );
4154 let function_alias = ConstantTemplateSignature::function(
4155 ConstantTemplateId::new(17),
4156 1,
4157 monomorphic.clone(),
4158 function_shape.clone(),
4159 );
4160 let function_reference_constant = function_base
4161 .try_instantiate(Vec::new())
4162 .expect("a monomorphic function constant should instantiate without arguments");
4163
4164 let constructor_function_shape = FunctionShape::new(
4165 vec![ValueShape::Int],
4166 ValueShape::Custom(custom_shape.clone()),
4167 );
4168 let constructor_function = ConstantTemplateSignature::function(
4169 ConstantTemplateId::new(18),
4170 0,
4171 monomorphic,
4172 constructor_function_shape.clone(),
4173 );
4174
4175 let empty_bits = ConstantValue::bit_array(Box::new([]));
4176 let empty_bits_value = empty_bits
4177 .clone()
4178 .into_bit_array()
4179 .expect("a BitArray constant should retain its family");
4180 let bit_array = ConstantValue::bit_array(
4181 vec![
4182 ConstantBitArraySegment::Int {
4183 value: ConstantValue::reference(int_reference.clone())
4184 .into_int()
4185 .expect("an Int reference should retain its family"),
4186 bit_size: 12,
4187 endianness: Endianness::Little,
4188 },
4189 ConstantBitArraySegment::Float {
4190 value: ConstantValue::reference(float_reference.clone())
4191 .into_float()
4192 .expect("a Float reference should retain its family"),
4193 bit_size: FloatBitSize::Sixteen,
4194 endianness: Endianness::Big,
4195 },
4196 ConstantBitArraySegment::String {
4197 value: ConstantValue::reference(string_reference.clone())
4198 .into_string()
4199 .expect("a String reference should retain its family"),
4200 encoding: StringEncoding::Utf16(Endianness::Little),
4201 },
4202 ConstantBitArraySegment::Bits(empty_bits_value.clone()),
4203 ConstantBitArraySegment::SizedBits {
4204 value: empty_bits_value,
4205 bit_size: 0,
4206 site: PanicSite::unknown(),
4207 },
4208 ]
4209 .into_boxed_slice(),
4210 );
4211
4212 let entries = vec![
4213 (
4214 ConstantTemplate::new(int_base.clone(), "int".into()),
4215 ConstantValue::int(7.into()),
4216 ),
4217 (
4218 ConstantTemplate::new(int_alias.clone(), "int_alias".into()),
4219 ConstantValue::reference(int_reference.clone()),
4220 ),
4221 (
4222 ConstantTemplate::new(string_base.clone(), "string".into()),
4223 ConstantValue::string_concatenation(
4224 ConstantValue::string("ge".into())
4225 .into_string()
4226 .expect("a String constant should retain its family"),
4227 ConstantValue::string("am".into())
4228 .into_string()
4229 .expect("a String constant should retain its family"),
4230 ),
4231 ),
4232 (
4233 ConstantTemplate::new(string_alias.clone(), "string_alias".into()),
4234 ConstantValue::reference(string_reference.clone()),
4235 ),
4236 (
4237 ConstantTemplate::new(float_base.clone(), "float".into()),
4238 ConstantValue::float(1.5),
4239 ),
4240 (
4241 ConstantTemplate::new(float_alias.clone(), "float_alias".into()),
4242 ConstantValue::reference(float_reference.clone()),
4243 ),
4244 (
4245 ConstantTemplate::new(bool_base.clone(), "bool".into()),
4246 ConstantValue::bool(true),
4247 ),
4248 (
4249 ConstantTemplate::new(bool_alias.clone(), "bool_alias".into()),
4250 ConstantValue::reference(bool_reference),
4251 ),
4252 (
4253 ConstantTemplate::new(nil_base.clone(), "nil".into()),
4254 ConstantValue::nil(),
4255 ),
4256 (
4257 ConstantTemplate::new(nil_alias.clone(), "nil_alias".into()),
4258 ConstantValue::reference(nil_reference),
4259 ),
4260 (
4261 ConstantTemplate::new(bit_array_base.clone(), "bits".into()),
4262 bit_array,
4263 ),
4264 (
4265 ConstantTemplate::new(bit_array_alias.clone(), "bits_alias".into()),
4266 ConstantValue::reference(bit_array_reference),
4267 ),
4268 (
4269 ConstantTemplate::new(custom_base.clone(), "token".into()),
4270 ConstantValue::custom(
4271 custom_shape.clone(),
4272 constructor.clone(),
4273 vec![ConstantValue::reference(int_reference.clone())].into_boxed_slice(),
4274 ),
4275 ),
4276 (
4277 ConstantTemplate::new(custom_alias.clone(), "token_alias".into()),
4278 ConstantValue::reference(custom_reference),
4279 ),
4280 (
4281 ConstantTemplate::new(tuple_base.clone(), "pair".into()),
4282 ConstantValue::tuple(
4283 tuple_shape,
4284 vec![
4285 ConstantValue::reference(int_reference),
4286 ConstantValue::reference(string_reference),
4287 ]
4288 .into_boxed_slice(),
4289 ),
4290 ),
4291 (
4292 ConstantTemplate::new(tuple_alias.clone(), "pair_alias".into()),
4293 ConstantValue::reference(tuple_reference),
4294 ),
4295 (
4296 ConstantTemplate::new(function_base.clone(), "function".into()),
4297 ConstantValue::function(function_shape.clone(), function_reference.clone()),
4298 ),
4299 (
4300 ConstantTemplate::new(function_alias.clone(), "function_alias".into()),
4301 ConstantValue::reference(function_reference_constant.clone()),
4302 ),
4303 (
4304 ConstantTemplate::new(constructor_function.clone(), "constructor".into()),
4305 ConstantValue::constructor_function(
4306 constructor_function_shape,
4307 custom_shape.clone(),
4308 constructor.clone(),
4309 ),
4310 ),
4311 ];
4312 let templates = ConstantTemplates::from_entries(entries);
4313 let empty = TypeSubstitution::from_arguments(Vec::new());
4314
4315 assert_eq!(
4316 templates.materialize_value(&ConstantValue::float(2.5), &empty),
4317 Expr::float(FloatExpr::value(2.5)),
4318 );
4319 assert_eq!(
4320 templates.materialize_value(&ConstantValue::bool(false), &empty),
4321 Expr::bool(BoolExpr::value(false)),
4322 );
4323 assert_eq!(
4324 templates.materialize_value(&ConstantValue::nil(), &empty),
4325 Expr::nil(NilExpr::value()),
4326 );
4327 assert_eq!(
4328 templates.materialize_value(
4329 &ConstantValue::tuple(
4330 vec![ValueShape::Int].into_boxed_slice(),
4331 vec![ConstantValue::int(9.into())].into_boxed_slice(),
4332 ),
4333 &empty,
4334 ),
4335 Expr::tuple(TupleExpr::value(
4336 vec![Expr::int(IntExpr::value(9.into()))],
4337 vec![ValueType::Int],
4338 )),
4339 );
4340 assert_eq!(
4341 templates.materialize_value(
4342 &ConstantValue::custom(
4343 custom_shape.clone(),
4344 constructor.clone(),
4345 vec![ConstantValue::int(9.into())].into_boxed_slice(),
4346 ),
4347 &empty,
4348 ),
4349 Expr::custom(CustomExpr::from_construction(
4350 custom_shape.clone(),
4351 CustomConstruction::from_constant(MaterializedConstantCustomConstruction::new(
4352 constructor.clone(),
4353 vec![Expr::int(IntExpr::value(9.into()))],
4354 )),
4355 )),
4356 );
4357 assert_eq!(
4358 templates.materialize_value(
4359 &ConstantValue::function(function_shape.clone(), function_reference.clone()),
4360 &empty,
4361 ),
4362 Expr::function(FunctionExpr::reference(function_reference.clone())),
4363 );
4364
4365 assert_eq!(templates.headers().len(), 19);
4366 assert_eq!(
4367 templates.header(ConstantTemplateId::new(18)).name(),
4368 "constructor"
4369 );
4370 let int_alias_instantiation =
4371 TypedConstantInstantiation::new(ConstantIntTemplateId(1), empty.clone(), ());
4372 assert_eq!(
4373 int_alias.try_instantiate(Vec::new()),
4374 Some(ConstantInstantiation {
4375 kind: ConstantInstantiationKind::Int(int_alias_instantiation.clone()),
4376 }),
4377 );
4378 assert_eq!(
4379 templates.materialize_int(&int_alias_instantiation),
4380 IntExpr::value(7.into()),
4381 );
4382 let string_alias_instantiation =
4383 TypedConstantInstantiation::new(ConstantStringTemplateId(1), empty.clone(), ());
4384 assert_eq!(
4385 string_alias.try_instantiate(Vec::new()),
4386 Some(ConstantInstantiation {
4387 kind: ConstantInstantiationKind::String(string_alias_instantiation.clone()),
4388 }),
4389 );
4390 assert_eq!(
4391 templates.materialize_string(&string_alias_instantiation),
4392 StringExpr::concatenate(
4393 StringExpr::value("ge".into()),
4394 StringExpr::value("am".into()),
4395 ),
4396 );
4397 let float_alias_instantiation =
4398 TypedConstantInstantiation::new(ConstantFloatTemplateId(1), empty.clone(), ());
4399 assert_eq!(
4400 float_alias.try_instantiate(Vec::new()),
4401 Some(ConstantInstantiation {
4402 kind: ConstantInstantiationKind::Float(float_alias_instantiation.clone()),
4403 }),
4404 );
4405 assert_eq!(
4406 templates.materialize_float(&float_alias_instantiation),
4407 FloatExpr::value(1.5),
4408 );
4409 let bool_alias_instantiation =
4410 TypedConstantInstantiation::new(ConstantBoolTemplateId(1), empty.clone(), ());
4411 assert_eq!(
4412 bool_alias.try_instantiate(Vec::new()),
4413 Some(ConstantInstantiation {
4414 kind: ConstantInstantiationKind::Bool(bool_alias_instantiation.clone()),
4415 }),
4416 );
4417 assert_eq!(
4418 templates.materialize_bool(&bool_alias_instantiation),
4419 BoolExpr::value(true),
4420 );
4421 let nil_alias_instantiation =
4422 TypedConstantInstantiation::new(ConstantNilTemplateId(1), empty.clone(), ());
4423 assert_eq!(
4424 nil_alias.try_instantiate(Vec::new()),
4425 Some(ConstantInstantiation {
4426 kind: ConstantInstantiationKind::Nil(nil_alias_instantiation.clone()),
4427 }),
4428 );
4429 assert_eq!(
4430 templates.materialize_nil(&nil_alias_instantiation),
4431 NilExpr::value(),
4432 );
4433 let bit_array_alias_instantiation =
4434 TypedConstantInstantiation::new(ConstantBitArrayTemplateId(1), empty.clone(), ());
4435 assert_eq!(
4436 bit_array_alias.try_instantiate(Vec::new()),
4437 Some(ConstantInstantiation {
4438 kind: ConstantInstantiationKind::BitArray(bit_array_alias_instantiation.clone()),
4439 }),
4440 );
4441 assert_eq!(
4442 templates.materialize_bit_array(&bit_array_alias_instantiation),
4443 BitArrayExpr::value(vec![
4444 BitArraySegment::Int {
4445 value: IntExpr::value(7.into()),
4446 bit_size: 12,
4447 endianness: Endianness::Little,
4448 },
4449 BitArraySegment::Float {
4450 value: FloatExpr::value(1.5),
4451 bit_size: FloatBitSize::Sixteen,
4452 endianness: Endianness::Big,
4453 },
4454 BitArraySegment::String {
4455 value: StringExpr::concatenate(
4456 StringExpr::value("ge".into()),
4457 StringExpr::value("am".into()),
4458 ),
4459 encoding: StringEncoding::Utf16(Endianness::Little),
4460 },
4461 BitArraySegment::Bits(BitArrayExpr::value(Vec::new())),
4462 BitArraySegment::SizedBits {
4463 value: BitArrayExpr::value(Vec::new()),
4464 size: crate::plan::BitArrayBitsSize::Fixed(0),
4465 site: PanicSite::unknown(),
4466 },
4467 ]),
4468 );
4469 let custom_alias_instantiation = TypedConstantInstantiation::new(
4470 ConstantCustomTemplateId(1),
4471 empty.clone(),
4472 custom_shape.clone(),
4473 );
4474 assert_eq!(
4475 custom_alias.try_instantiate(Vec::new()),
4476 Some(ConstantInstantiation {
4477 kind: ConstantInstantiationKind::Custom(custom_alias_instantiation.clone()),
4478 }),
4479 );
4480 assert_eq!(
4481 templates.materialize_custom(&custom_alias_instantiation),
4482 CustomExpr::from_construction(
4483 custom_shape.clone(),
4484 CustomConstruction::from_constant(MaterializedConstantCustomConstruction::new(
4485 constructor.clone(),
4486 vec![Expr::int(IntExpr::value(7.into()))],
4487 )),
4488 ),
4489 );
4490 let tuple_alias_instantiation = TypedConstantInstantiation::new(
4491 ConstantTupleTemplateId(1),
4492 empty.clone(),
4493 vec![ValueShape::Int, ValueShape::String].into_boxed_slice(),
4494 );
4495 assert_eq!(
4496 tuple_alias.try_instantiate(Vec::new()),
4497 Some(ConstantInstantiation {
4498 kind: ConstantInstantiationKind::Tuple(tuple_alias_instantiation.clone()),
4499 }),
4500 );
4501 assert_eq!(
4502 templates.materialize_tuple(&tuple_alias_instantiation),
4503 TupleExpr::value(
4504 vec![
4505 Expr::int(IntExpr::value(7.into())),
4506 Expr::string(StringExpr::concatenate(
4507 StringExpr::value("ge".into()),
4508 StringExpr::value("am".into()),
4509 )),
4510 ],
4511 vec![ValueType::Int, ValueType::String],
4512 ),
4513 );
4514 let function_alias_instantiation = ConstantFunctionTemplate::from_shape(&function_shape, 1)
4515 .instantiate(
4516 crate::plan::ModuleId::root(),
4517 empty.clone(),
4518 function_shape.clone(),
4519 );
4520 assert_eq!(
4521 function_alias.try_instantiate(Vec::new()),
4522 Some(ConstantInstantiation {
4523 kind: ConstantInstantiationKind::Function(function_alias_instantiation),
4524 }),
4525 );
4526 let constructor_function_shape =
4527 FunctionShape::new(vec![ValueShape::Int], ValueShape::Custom(custom_shape));
4528 let constructor_function_instantiation =
4529 ConstantFunctionTemplate::from_shape(&constructor_function_shape, 0).instantiate(
4530 crate::plan::ModuleId::root(),
4531 empty,
4532 constructor_function_shape,
4533 );
4534 assert_eq!(
4535 constructor_function.try_instantiate(Vec::new()),
4536 Some(ConstantInstantiation {
4537 kind: ConstantInstantiationKind::Function(constructor_function_instantiation),
4538 }),
4539 );
4540 }
4541
4542 #[test]
4543 fn function_constant_targets_and_references_materialize_every_return_family() {
4544 let source = r#"
4545pub type Token { Token(Int) }
4546
4547fn identity(value: value) { value }
4548fn int_value() { 1 }
4549fn float_value() { 1.5 }
4550fn string_value() { "one" }
4551fn bit_array_value() { <<1>> }
4552fn codepoint_value() {
4553 let assert <<value:utf8_codepoint>> = <<65>>
4554 value
4555}
4556fn custom_value() { Token(1) }
4557fn bool_value() { True }
4558fn nil_value() { Nil }
4559fn tuple_value() { #(1) }
4560fn list_value() { [1] }
4561fn function_value() { int_value }
4562
4563const generic_function = identity
4564const generic_alias = generic_function
4565const int_function = int_value
4566const int_alias = int_function
4567const float_function = float_value
4568const float_alias = float_function
4569const string_function = string_value
4570const string_alias = string_function
4571const bit_array_function = bit_array_value
4572const bit_array_alias = bit_array_function
4573const codepoint_function = codepoint_value
4574const codepoint_alias = codepoint_function
4575const custom_function = custom_value
4576const custom_alias = custom_function
4577const bool_function = bool_value
4578const bool_alias = bool_function
4579const nil_function = nil_value
4580const nil_alias = nil_function
4581const tuple_function = tuple_value
4582const tuple_alias = tuple_function
4583const list_function = list_value
4584const list_alias = list_function
4585const function_function = function_value
4586const function_alias = function_function
4587const constructor_function = Token
4588const constructor_alias = constructor_function
4589
4590pub fn main() {
4591 #(
4592 generic_alias == generic_alias,
4593 int_alias == int_alias,
4594 float_alias == float_alias,
4595 string_alias == string_alias,
4596 bit_array_alias == bit_array_alias,
4597 codepoint_alias == codepoint_alias,
4598 custom_alias == custom_alias,
4599 bool_alias == bool_alias,
4600 nil_alias == nil_alias,
4601 tuple_alias == tuple_alias,
4602 list_alias == list_alias,
4603 function_alias == function_alias,
4604 constructor_alias == constructor_alias,
4605 )
4606}
4607"#;
4608 let typed = crate::compile_typed_module("main", "main.gleam", source)
4609 .expect("function constant fixture should compile");
4610 let module = crate::plan_module(typed).expect("function constant fixture should plan");
4611 let plan = crate::ExecutionPlan::from_module_plan(module);
4612 let value = crate::run_main(&plan, &mut Vec::new())
4613 .expect("function constant fixture should execute");
4614
4615 assert_eq!(
4616 value,
4617 crate::Value::Tuple(vec![
4618 crate::Value::Bool(true),
4619 crate::Value::Bool(true),
4620 crate::Value::Bool(true),
4621 crate::Value::Bool(true),
4622 crate::Value::Bool(true),
4623 crate::Value::Bool(true),
4624 crate::Value::Bool(true),
4625 crate::Value::Bool(true),
4626 crate::Value::Bool(true),
4627 crate::Value::Bool(true),
4628 crate::Value::Bool(true),
4629 crate::Value::Bool(true),
4630 crate::Value::Bool(false),
4631 ]),
4632 );
4633 }
4634
4635 #[test]
4636 fn generic_empty_list_references_materialize_every_item_shape() {
4637 let parameter = TypeParameterId(0);
4638 let base_signature = ConstantTemplateSignature::list(
4639 ConstantTemplateId::new(0),
4640 0,
4641 TypeScheme::new(1),
4642 ValueShape::Parameter(parameter),
4643 );
4644 let alias_signature = ConstantTemplateSignature::list(
4645 ConstantTemplateId::new(1),
4646 1,
4647 TypeScheme::new(1),
4648 ValueShape::Parameter(parameter),
4649 );
4650 let identity = base_signature
4651 .try_instantiate(vec![ValueShape::Parameter(parameter)])
4652 .expect("one parameter should match the generic constant scheme");
4653 let templates = ConstantTemplates::from_entries(vec![
4654 (
4655 ConstantTemplate::new(base_signature, "empty".into()),
4656 ConstantValue::try_list(ValueShape::Parameter(parameter), Vec::new(), None)
4657 .expect("an uninhabited list constant may be empty"),
4658 ),
4659 (
4660 ConstantTemplate::new(alias_signature.clone(), "alias".into()),
4661 ConstantValue::reference(identity),
4662 ),
4663 ]);
4664
4665 let custom_shape = CustomValueShape::new(
4666 CustomTypeName::new("geam".into(), "main".into(), "Token".into()),
4667 Vec::new(),
4668 CustomConstructorRefinement::Exact(0),
4669 );
4670 let function_shape = FunctionShape::new(vec![ValueShape::Int], ValueShape::String);
4671 let external_shape = ExternalValueShape::new(
4672 ExternalTypeName::new("geam".into(), "main".into(), "Resource".into()),
4673 Vec::new(),
4674 );
4675 let item_shapes = vec![
4676 ValueShape::Parameter(parameter),
4677 ValueShape::Int,
4678 ValueShape::String,
4679 ValueShape::BitArray,
4680 ValueShape::UtfCodepoint,
4681 ValueShape::Custom(custom_shape),
4682 ValueShape::External(external_shape),
4683 ValueShape::Float,
4684 ValueShape::Bool,
4685 ValueShape::Nil,
4686 ValueShape::Tuple(vec![ValueShape::Int, ValueShape::String].into_boxed_slice()),
4687 ValueShape::List(Box::new(ValueShape::Parameter(TypeParameterId(1)))),
4688 ValueShape::List(Box::new(ValueShape::Bool)),
4689 ValueShape::Function(Box::new(function_shape)),
4690 ];
4691
4692 for item_shape in item_shapes {
4693 let arguments = vec![item_shape.clone()];
4694 let substitution = TypeSubstitution::from_arguments(arguments.clone());
4695 let instantiation =
4696 ConstantListTemplate::from_item_shape(ValueShape::Parameter(parameter), 1)
4697 .instantiate(crate::plan::ModuleId::root(), substitution.clone());
4698 assert_eq!(
4699 alias_signature.try_instantiate(arguments),
4700 Some(ConstantInstantiation {
4701 kind: ConstantInstantiationKind::List(instantiation.clone()),
4702 }),
4703 );
4704 let actual = match instantiation {
4705 ConstantListInstantiation::Generic(value) => {
4706 ListExpr::Generic(templates.materialize_generic_list(&value))
4707 }
4708 ConstantListInstantiation::ParameterList(value) => {
4709 ListExpr::ParameterList(templates.materialize_parameter_list_list(&value))
4710 }
4711 ConstantListInstantiation::Int(value) => {
4712 ListExpr::Int(templates.materialize_int_list(&value))
4713 }
4714 ConstantListInstantiation::String(value) => {
4715 ListExpr::String(templates.materialize_string_list(&value))
4716 }
4717 ConstantListInstantiation::BitArray(value) => {
4718 ListExpr::BitArray(templates.materialize_bit_array_list(&value))
4719 }
4720 ConstantListInstantiation::UtfCodepoint(value) => {
4721 ListExpr::UtfCodepoint(templates.materialize_utf_codepoint_list(&value))
4722 }
4723 ConstantListInstantiation::Custom(value) => {
4724 ListExpr::Custom(templates.materialize_custom_list(&value))
4725 }
4726 ConstantListInstantiation::External(value) => {
4727 ListExpr::External(templates.materialize_external_list(&value))
4728 }
4729 ConstantListInstantiation::Float(value) => {
4730 ListExpr::Float(templates.materialize_float_list(&value))
4731 }
4732 ConstantListInstantiation::Bool(value) => {
4733 ListExpr::Bool(templates.materialize_bool_list(&value))
4734 }
4735 ConstantListInstantiation::Nil(value) => {
4736 ListExpr::Nil(templates.materialize_nil_list(&value))
4737 }
4738 ConstantListInstantiation::Tuple(value) => {
4739 ListExpr::Tuple(templates.materialize_tuple_list(&value))
4740 }
4741 ConstantListInstantiation::List(value) => {
4742 ListExpr::List(templates.materialize_list_list(&value))
4743 }
4744 ConstantListInstantiation::Function(value) => {
4745 ListExpr::Function(templates.materialize_function_list(&value))
4746 }
4747 };
4748 assert_eq!(
4749 templates.materialize_list_value(
4750 &ConstantListValue::Generic(
4751 templates
4752 .generic_list(super::ConstantGenericListTemplateId(0))
4753 .clone(),
4754 ),
4755 &substitution,
4756 ),
4757 actual.clone(),
4758 );
4759 assert_eq!(
4760 actual,
4761 ListExpr::value(Vec::new(), item_shape.value_type()).with_item_shape(item_shape),
4762 );
4763 }
4764 }
4765
4766 #[test]
4767 fn nested_generic_list_values_materialize_parameter_and_stored_items() {
4768 let parameter = TypeParameterId(0);
4769 let nested_parameter = TypeParameterId(1);
4770 let templates = ConstantTemplates::from_entries(Vec::new());
4771 let generic = ConstantValue::try_list(ValueShape::Parameter(parameter), Vec::new(), None)
4772 .expect("a bare-parameter list constant may be empty")
4773 .into_list()
4774 .and_then(ConstantListValue::into_generic)
4775 .expect("the empty bare-parameter list should retain its generic storage");
4776
4777 let unresolved_nested_shape =
4778 ValueShape::List(Box::new(ValueShape::Parameter(nested_parameter)));
4779 assert_eq!(
4780 templates.materialize_list_value(
4781 &ConstantListValue::Generic(generic.clone()),
4782 &TypeSubstitution::from_arguments(vec![unresolved_nested_shape.clone()]),
4783 ),
4784 ListExpr::value(Vec::new(), unresolved_nested_shape.value_type())
4785 .with_item_shape(unresolved_nested_shape),
4786 );
4787 assert_eq!(
4788 templates.materialize_generic_stored_list_value(
4789 &generic,
4790 &TypeSubstitution::from_arguments(Vec::new()),
4791 &ValueStorageShape::List(Box::new(ValueShape::Parameter(nested_parameter))),
4792 ),
4793 StoredListExpr::ParameterList(ParameterListListExpr::value(
4794 ParameterListListItem::new(nested_parameter),
4795 Vec::new(),
4796 )),
4797 );
4798
4799 let nested = ConstantValue::try_list(
4800 ValueShape::List(Box::new(ValueShape::Parameter(parameter))),
4801 vec![
4802 ConstantValue::try_list(ValueShape::Parameter(parameter), Vec::new(), None)
4803 .expect("a nested bare-parameter list element may be empty"),
4804 ],
4805 None,
4806 )
4807 .expect("a list may contain an empty bare-parameter list")
4808 .into_list()
4809 .expect("the nested constant should retain its list family");
4810 let nested_stored = nested
4811 .clone()
4812 .into_stored()
4813 .expect("the nested list should have stored outer-list representation");
4814
4815 assert_eq!(
4816 templates
4817 .materialize_list_value(&nested, &TypeSubstitution::from_arguments(Vec::new()),),
4818 ListExpr::ParameterList(ParameterListListExpr::value(
4819 ParameterListListItem::new(parameter),
4820 vec![GenericListExpr::value(
4821 GenericListItem::new(parameter),
4822 Vec::new(),
4823 )],
4824 )),
4825 );
4826 assert_eq!(
4827 templates.materialize_stored_list_value(
4828 &nested_stored,
4829 &TypeSubstitution::from_arguments(Vec::new()),
4830 ),
4831 StoredListExpr::ParameterList(ParameterListListExpr::value(
4832 ParameterListListItem::new(parameter),
4833 vec![GenericListExpr::value(
4834 GenericListItem::new(parameter),
4835 Vec::new(),
4836 )],
4837 )),
4838 );
4839 assert_eq!(
4840 templates.materialize_list_value(
4841 &nested,
4842 &TypeSubstitution::from_arguments(vec![ValueShape::Int]),
4843 ),
4844 ListExpr::List(ListListExpr::value(
4845 ListListItem::new(ValueStorageShape::Int),
4846 vec![StoredListExpr::Int(crate::plan::IntListExpr::value(
4847 crate::plan::IntListItem,
4848 Vec::new(),
4849 ))],
4850 )),
4851 );
4852 assert_eq!(
4853 templates.materialize_stored_list_value(
4854 &nested_stored,
4855 &TypeSubstitution::from_arguments(vec![ValueShape::Int]),
4856 ),
4857 StoredListExpr::List(ListListExpr::value(
4858 ListListItem::new(ValueStorageShape::Int),
4859 vec![StoredListExpr::Int(crate::plan::IntListExpr::value(
4860 crate::plan::IntListItem,
4861 Vec::new(),
4862 ))],
4863 )),
4864 );
4865
4866 let custom_shape = CustomValueShape::new(
4867 CustomTypeName::new("geam".into(), "main".into(), "Token".into()),
4868 Vec::new(),
4869 CustomConstructorRefinement::Exact(0),
4870 );
4871 let tuple_shape = vec![ValueShape::Int, ValueShape::String].into_boxed_slice();
4872 let function_shape = FunctionShape::new(vec![ValueShape::Int], ValueShape::String);
4873 let external_shape = ExternalValueShape::new(
4874 ExternalTypeName::new("geam".into(), "main".into(), "Resource".into()),
4875 Vec::new(),
4876 );
4877 let stored = vec![
4878 (
4879 ValueStorageShape::Int,
4880 StoredListExpr::Int(crate::plan::IntListExpr::value(
4881 crate::plan::IntListItem,
4882 Vec::new(),
4883 )),
4884 ),
4885 (
4886 ValueStorageShape::Float,
4887 StoredListExpr::Float(FloatListExpr::value(FloatListItem, Vec::new())),
4888 ),
4889 (
4890 ValueStorageShape::String,
4891 StoredListExpr::String(StringListExpr::value(StringListItem, Vec::new())),
4892 ),
4893 (
4894 ValueStorageShape::BitArray,
4895 StoredListExpr::BitArray(BitArrayListExpr::value(BitArrayListItem, Vec::new())),
4896 ),
4897 (
4898 ValueStorageShape::UtfCodepoint,
4899 StoredListExpr::UtfCodepoint(UtfCodepointListExpr::value(
4900 UtfCodepointListItem,
4901 Vec::new(),
4902 )),
4903 ),
4904 (
4905 ValueStorageShape::Custom(custom_shape.clone()),
4906 StoredListExpr::Custom(
4907 CustomListExpr::value(
4908 CustomListItem::new(custom_shape.type_().clone()),
4909 Vec::new(),
4910 )
4911 .with_item_shape(ValueShape::Custom(custom_shape.clone())),
4912 ),
4913 ),
4914 (
4915 ValueStorageShape::External(external_shape.clone()),
4916 StoredListExpr::External(
4917 ExternalListExpr::value(
4918 ExternalListItem::new(external_shape.type_().clone()),
4919 Vec::new(),
4920 )
4921 .with_item_shape(ValueShape::External(external_shape.clone())),
4922 ),
4923 ),
4924 (
4925 ValueStorageShape::Bool,
4926 StoredListExpr::Bool(BoolListExpr::value(BoolListItem, Vec::new())),
4927 ),
4928 (
4929 ValueStorageShape::Nil,
4930 StoredListExpr::Nil(NilListExpr::value(NilListItem, Vec::new())),
4931 ),
4932 (
4933 ValueStorageShape::Tuple(tuple_shape.clone()),
4934 StoredListExpr::Tuple(TupleListExpr::value(
4935 TupleListItem::new(tuple_shape.iter().map(ValueShape::value_type).collect()),
4936 Vec::new(),
4937 )),
4938 ),
4939 (
4940 ValueStorageShape::List(Box::new(ValueShape::Bool)),
4941 StoredListExpr::List(ListListExpr::value(
4942 ListListItem::new(ValueStorageShape::Bool),
4943 Vec::new(),
4944 )),
4945 ),
4946 (
4947 ValueStorageShape::Function(Box::new(function_shape.clone())),
4948 StoredListExpr::Function(FunctionListExpr::value(
4949 FunctionListItem::new(function_shape.type_()),
4950 Vec::new(),
4951 )),
4952 ),
4953 ];
4954 for (shape, expected) in stored {
4955 let stored_value = ConstantValue::try_list(shape.to_value_shape(), Vec::new(), None)
4956 .expect("an empty list should accept every stored item family")
4957 .into_list()
4958 .expect("the empty constant should retain its list family")
4959 .into_stored()
4960 .expect("a stored item family should use stored list representation");
4961 assert_eq!(
4962 templates.materialize_generic_stored_list_value(
4963 &generic,
4964 &TypeSubstitution::from_arguments(Vec::new()),
4965 &shape,
4966 ),
4967 expected.clone(),
4968 );
4969 assert_eq!(
4970 templates.materialize_stored_list_value(
4971 &stored_value,
4972 &TypeSubstitution::from_arguments(Vec::new()),
4973 ),
4974 expected,
4975 );
4976 }
4977
4978 let external_list = ConstantValue::try_list(
4979 ValueShape::External(external_shape.clone()),
4980 Vec::new(),
4981 None,
4982 )
4983 .expect("an external constant list may be empty");
4984 let nested_external_list = ConstantValue::try_list(
4985 ValueShape::List(Box::new(ValueShape::External(external_shape.clone()))),
4986 vec![external_list],
4987 None,
4988 )
4989 .expect("a constant list may contain an external list")
4990 .into_list()
4991 .expect("the nested external constant should retain its list family");
4992 assert_eq!(
4993 templates.materialize_list_value(
4994 &nested_external_list,
4995 &TypeSubstitution::from_arguments(Vec::new()),
4996 ),
4997 ListExpr::List(ListListExpr::value(
4998 ListListItem::new(ValueStorageShape::External(external_shape.clone())),
4999 vec![StoredListExpr::External(
5000 ExternalListExpr::value(
5001 ExternalListItem::new(external_shape.type_().clone()),
5002 Vec::new(),
5003 )
5004 .with_item_shape(ValueShape::External(external_shape)),
5005 )],
5006 )),
5007 );
5008
5009 let deeply_nested = ConstantValue::try_list(
5010 ValueShape::List(Box::new(ValueShape::List(Box::new(ValueShape::Parameter(
5011 parameter,
5012 ))))),
5013 vec![
5014 ConstantValue::try_list(
5015 ValueShape::List(Box::new(ValueShape::Parameter(parameter))),
5016 vec![
5017 ConstantValue::try_list(ValueShape::Parameter(parameter), Vec::new(), None)
5018 .expect("a nested bare-parameter list element may be empty"),
5019 ],
5020 None,
5021 )
5022 .expect("an outer list may store a parameter-list payload"),
5023 ],
5024 None,
5025 )
5026 .expect("a deeply nested list may store an empty bare-parameter leaf");
5027 assert_eq!(
5028 deeply_nested.shape(),
5029 ValueShape::List(Box::new(ValueShape::List(Box::new(ValueShape::List(
5030 Box::new(ValueShape::Parameter(parameter)),
5031 ))))),
5032 );
5033 let deeply_nested = deeply_nested
5034 .into_list()
5035 .expect("the deeply nested constant should retain its list family");
5036 assert_eq!(
5037 templates.materialize_list_value(
5038 &deeply_nested,
5039 &TypeSubstitution::from_arguments(Vec::new()),
5040 ),
5041 ListExpr::List(ListListExpr::value(
5042 ListListItem::new(ValueStorageShape::List(Box::new(ValueShape::Parameter(
5043 parameter,
5044 )))),
5045 vec![StoredListExpr::ParameterList(ParameterListListExpr::value(
5046 ParameterListListItem::new(parameter),
5047 vec![GenericListExpr::value(
5048 GenericListItem::new(parameter),
5049 Vec::new(),
5050 )],
5051 ))],
5052 )),
5053 );
5054 assert_eq!(
5055 templates.materialize_list_value(
5056 &deeply_nested,
5057 &TypeSubstitution::from_arguments(vec![ValueShape::Int]),
5058 ),
5059 ListExpr::List(ListListExpr::value(
5060 ListListItem::new(ValueStorageShape::List(Box::new(ValueShape::Int))),
5061 vec![StoredListExpr::List(ListListExpr::value(
5062 ListListItem::new(ValueStorageShape::Int),
5063 vec![StoredListExpr::Int(crate::plan::IntListExpr::value(
5064 crate::plan::IntListItem,
5065 Vec::new(),
5066 ))],
5067 ))],
5068 )),
5069 );
5070 }
5071
5072 #[test]
5073 fn parameter_list_list_spread_reference_materializes_uninhabited_and_stored_items() {
5074 let parameter = TypeParameterId(0);
5075 let item_shape = ValueShape::List(Box::new(ValueShape::Parameter(parameter)));
5076 let generic_element = || {
5077 ConstantValue::try_list(ValueShape::Parameter(parameter), Vec::new(), None)
5078 .expect("a bare-parameter list element may be empty")
5079 };
5080 let tail = ConstantValue::try_list(item_shape.clone(), vec![generic_element()], None)
5081 .expect("a parameter-list tail should accept an empty generic list");
5082 let base = ConstantValue::try_list(item_shape.clone(), vec![generic_element()], Some(tail))
5083 .expect("a parameter-list spread should accept a matching tail");
5084 let base_signature = ConstantTemplateSignature::list(
5085 ConstantTemplateId::new(0),
5086 0,
5087 TypeScheme::new(1),
5088 item_shape.clone(),
5089 );
5090 let alias_signature = ConstantTemplateSignature::list(
5091 ConstantTemplateId::new(1),
5092 1,
5093 TypeScheme::new(1),
5094 item_shape,
5095 );
5096 let reference = base_signature
5097 .try_instantiate(vec![ValueShape::Parameter(parameter)])
5098 .expect("the parameter-list constant should accept its identity substitution");
5099 let templates = ConstantTemplates::from_entries(vec![
5100 (ConstantTemplate::new(base_signature, "base".into()), base),
5101 (
5102 ConstantTemplate::new(alias_signature, "alias".into()),
5103 ConstantValue::reference(reference),
5104 ),
5105 ]);
5106 let alias = ConstantListValue::ParameterList(
5107 templates
5108 .parameter_list_list(ConstantParameterListListTemplateId(1))
5109 .clone(),
5110 );
5111 let generic = GenericListExpr::value(GenericListItem::new(parameter), Vec::new());
5112
5113 assert_eq!(
5114 templates
5115 .materialize_list_value(&alias, &TypeSubstitution::from_arguments(Vec::new()),),
5116 ListExpr::ParameterList(ParameterListListExpr::spread(
5117 vec1::vec1![generic.clone()],
5118 ParameterListListExpr::value(ParameterListListItem::new(parameter), vec![generic],),
5119 )),
5120 );
5121
5122 let int_list = StoredListExpr::Int(crate::plan::IntListExpr::value(
5123 crate::plan::IntListItem,
5124 Vec::new(),
5125 ));
5126 assert_eq!(
5127 templates.materialize_list_value(
5128 &alias,
5129 &TypeSubstitution::from_arguments(vec![ValueShape::Int]),
5130 ),
5131 ListExpr::List(ListListExpr::spread(
5132 vec1::vec1![int_list.clone()],
5133 ListListExpr::value(ListListItem::new(ValueStorageShape::Int), vec![int_list],),
5134 )),
5135 );
5136 }
5137
5138 #[test]
5139 fn exact_list_references_materialize_every_item_family() {
5140 let monomorphic = TypeScheme::new(0);
5141 let custom_shape = CustomValueShape::new(
5142 CustomTypeName::new("geam".into(), "main".into(), "Token".into()),
5143 Vec::new(),
5144 CustomConstructorRefinement::Exact(0),
5145 );
5146 let constructor = CustomConstructor::new(
5147 custom_shape.type_().clone(),
5148 "Token".into(),
5149 0,
5150 vec![CustomConstructorField::new(None, ValueType::Int)],
5151 );
5152 let tuple_shape = vec![ValueShape::Int, ValueShape::String].into_boxed_slice();
5153 let function_shape = FunctionShape::new(vec![ValueShape::Int], ValueShape::String);
5154 let function_reference = FunctionReference::new(monomorphic_function_instantiation(
5155 5,
5156 function_shape.clone(),
5157 ));
5158
5159 let item_shapes = vec![
5160 ValueShape::Int,
5161 ValueShape::String,
5162 ValueShape::BitArray,
5163 ValueShape::UtfCodepoint,
5164 ValueShape::Custom(custom_shape.clone()),
5165 ValueShape::Float,
5166 ValueShape::Bool,
5167 ValueShape::Nil,
5168 ValueShape::Tuple(tuple_shape.clone()),
5169 ValueShape::List(Box::new(ValueShape::Int)),
5170 ValueShape::Function(Box::new(function_shape.clone())),
5171 ];
5172 let signatures = item_shapes
5173 .iter()
5174 .enumerate()
5175 .flat_map(|(index, shape)| {
5176 [
5177 ConstantTemplateSignature::list(
5178 ConstantTemplateId::new(index * 2),
5179 0,
5180 monomorphic.clone(),
5181 shape.clone(),
5182 ),
5183 ConstantTemplateSignature::list(
5184 ConstantTemplateId::new(index * 2 + 1),
5185 1,
5186 monomorphic.clone(),
5187 shape.clone(),
5188 ),
5189 ]
5190 })
5191 .collect::<Vec<_>>();
5192
5193 let int_tail =
5194 ConstantValue::try_list(ValueShape::Int, vec![ConstantValue::int(2.into())], None)
5195 .expect("an Int list tail should accept Int elements");
5196 let int_list = ConstantValue::try_list(
5197 ValueShape::Int,
5198 vec![ConstantValue::int(1.into())],
5199 Some(int_tail),
5200 )
5201 .expect("an Int list spread should accept an Int list tail");
5202
5203 let string_tail = ConstantValue::try_list(
5204 ValueShape::String,
5205 vec![ConstantValue::string("two".into())],
5206 None,
5207 )
5208 .expect("a String list tail should accept String elements");
5209 let string_list = ConstantValue::try_list(
5210 ValueShape::String,
5211 vec![ConstantValue::string("one".into())],
5212 Some(string_tail),
5213 )
5214 .expect("a String list spread should accept a String list tail");
5215
5216 let bit_array_tail = ConstantValue::try_list(
5217 ValueShape::BitArray,
5218 vec![ConstantValue::bit_array(Box::new([]))],
5219 None,
5220 )
5221 .expect("a BitArray list tail should accept BitArray elements");
5222 let bit_array_list = ConstantValue::try_list(
5223 ValueShape::BitArray,
5224 vec![ConstantValue::bit_array(Box::new([]))],
5225 Some(bit_array_tail),
5226 )
5227 .expect("a BitArray list spread should accept a BitArray list tail");
5228
5229 let utf_codepoint_list =
5230 ConstantValue::try_list(ValueShape::UtfCodepoint, Vec::new(), None)
5231 .expect("a UtfCodepoint constant list may be empty");
5232
5233 let token = |value: i64| {
5234 ConstantValue::custom(
5235 custom_shape.clone(),
5236 constructor.clone(),
5237 vec![ConstantValue::int(value.into())].into_boxed_slice(),
5238 )
5239 };
5240 let custom_tail = ConstantValue::try_list(
5241 ValueShape::Custom(custom_shape.clone()),
5242 vec![token(4)],
5243 None,
5244 )
5245 .expect("a custom list tail should accept matching custom elements");
5246 let custom_list = ConstantValue::try_list(
5247 ValueShape::Custom(custom_shape.clone()),
5248 vec![token(3)],
5249 Some(custom_tail),
5250 )
5251 .expect("a custom list spread should accept a matching custom list tail");
5252
5253 let float_tail =
5254 ConstantValue::try_list(ValueShape::Float, vec![ConstantValue::float(2.5)], None)
5255 .expect("a Float list tail should accept Float elements");
5256 let float_list = ConstantValue::try_list(
5257 ValueShape::Float,
5258 vec![ConstantValue::float(1.5)],
5259 Some(float_tail),
5260 )
5261 .expect("a Float list spread should accept a Float list tail");
5262
5263 let bool_tail =
5264 ConstantValue::try_list(ValueShape::Bool, vec![ConstantValue::bool(false)], None)
5265 .expect("a Bool list tail should accept Bool elements");
5266 let bool_list = ConstantValue::try_list(
5267 ValueShape::Bool,
5268 vec![ConstantValue::bool(true)],
5269 Some(bool_tail),
5270 )
5271 .expect("a Bool list spread should accept a Bool list tail");
5272
5273 let nil_tail = ConstantValue::try_list(ValueShape::Nil, vec![ConstantValue::nil()], None)
5274 .expect("a Nil list tail should accept Nil elements");
5275 let nil_list =
5276 ConstantValue::try_list(ValueShape::Nil, vec![ConstantValue::nil()], Some(nil_tail))
5277 .expect("a Nil list spread should accept a Nil list tail");
5278
5279 let pair = |number: i64, string: &str| {
5280 ConstantValue::tuple(
5281 tuple_shape.clone(),
5282 vec![
5283 ConstantValue::int(number.into()),
5284 ConstantValue::string(string.into()),
5285 ]
5286 .into_boxed_slice(),
5287 )
5288 };
5289 let tuple_tail = ConstantValue::try_list(
5290 ValueShape::Tuple(tuple_shape.clone()),
5291 vec![pair(2, "two")],
5292 None,
5293 )
5294 .expect("a tuple list tail should accept matching tuple elements");
5295 let tuple_list = ConstantValue::try_list(
5296 ValueShape::Tuple(tuple_shape.clone()),
5297 vec![pair(1, "one")],
5298 Some(tuple_tail),
5299 )
5300 .expect("a tuple list spread should accept a matching tuple list tail");
5301
5302 let int_element = |value: i64| {
5303 ConstantValue::try_list(
5304 ValueShape::Int,
5305 vec![ConstantValue::int(value.into())],
5306 None,
5307 )
5308 .expect("a nested Int list should accept Int elements")
5309 };
5310 let list_tail = ConstantValue::try_list(
5311 ValueShape::List(Box::new(ValueShape::Int)),
5312 vec![int_element(2)],
5313 None,
5314 )
5315 .expect("a nested list tail should accept matching lists");
5316 let list_list = ConstantValue::try_list(
5317 ValueShape::List(Box::new(ValueShape::Int)),
5318 vec![int_element(1)],
5319 Some(list_tail),
5320 )
5321 .expect("a nested list spread should accept a matching nested list tail");
5322
5323 let function_value =
5324 || ConstantValue::function(function_shape.clone(), function_reference.clone());
5325 let function_tail = ConstantValue::try_list(
5326 ValueShape::Function(Box::new(function_shape.clone())),
5327 vec![function_value()],
5328 None,
5329 )
5330 .expect("a function list tail should accept matching functions");
5331 let function_list = ConstantValue::try_list(
5332 ValueShape::Function(Box::new(function_shape.clone())),
5333 vec![function_value()],
5334 Some(function_tail),
5335 )
5336 .expect("a function list spread should accept a matching function list tail");
5337
5338 let base_values = vec![
5339 int_list,
5340 string_list,
5341 bit_array_list,
5342 utf_codepoint_list,
5343 custom_list,
5344 float_list,
5345 bool_list,
5346 nil_list,
5347 tuple_list,
5348 list_list,
5349 function_list,
5350 ];
5351 let mut entries = Vec::with_capacity(base_values.len() * 2);
5352 let mut aliases = Vec::with_capacity(base_values.len());
5353 for (index, value) in base_values.into_iter().enumerate() {
5354 let base_signature = signatures[index * 2].clone();
5355 let alias_signature = signatures[index * 2 + 1].clone();
5356 let reference = base_signature
5357 .try_instantiate(Vec::new())
5358 .expect("a monomorphic list constant should instantiate without arguments");
5359 let alias = ConstantValue::reference(reference);
5360 entries.push((
5361 ConstantTemplate::new(base_signature, format!("base_{index}").into()),
5362 value,
5363 ));
5364 entries.push((
5365 ConstantTemplate::new(alias_signature, format!("alias_{index}").into()),
5366 alias.clone(),
5367 ));
5368 aliases.push(alias);
5369 }
5370 let templates = ConstantTemplates::from_entries(entries);
5371
5372 let expected = vec![
5373 ListExpr::spread(
5374 vec![Expr::int(IntExpr::value(1.into()))],
5375 ListExpr::value(vec![Expr::int(IntExpr::value(2.into()))], ValueType::Int),
5376 ValueType::Int,
5377 ),
5378 ListExpr::spread(
5379 vec![Expr::string(StringExpr::value("one".into()))],
5380 ListExpr::value(
5381 vec![Expr::string(StringExpr::value("two".into()))],
5382 ValueType::String,
5383 ),
5384 ValueType::String,
5385 ),
5386 ListExpr::spread(
5387 vec![Expr::bit_array(BitArrayExpr::value(Vec::new()))],
5388 ListExpr::value(
5389 vec![Expr::bit_array(BitArrayExpr::value(Vec::new()))],
5390 ValueType::BitArray,
5391 ),
5392 ValueType::BitArray,
5393 ),
5394 ListExpr::value(Vec::new(), ValueType::UtfCodepoint),
5395 ListExpr::spread(
5396 vec![Expr::custom(
5397 CustomExpr::try_constructor(
5398 constructor.clone(),
5399 vec![Expr::int(IntExpr::value(3.into()))],
5400 )
5401 .expect("the custom element should match its constructor"),
5402 )],
5403 ListExpr::value(
5404 vec![Expr::custom(
5405 CustomExpr::try_constructor(
5406 constructor.clone(),
5407 vec![Expr::int(IntExpr::value(4.into()))],
5408 )
5409 .expect("the custom tail element should match its constructor"),
5410 )],
5411 ValueType::Custom(custom_shape.type_().clone()),
5412 )
5413 .with_item_shape(ValueShape::Custom(custom_shape.clone())),
5414 ValueType::Custom(custom_shape.type_().clone()),
5415 )
5416 .with_item_shape(ValueShape::Custom(custom_shape)),
5417 ListExpr::spread(
5418 vec![Expr::float(FloatExpr::value(1.5))],
5419 ListExpr::value(vec![Expr::float(FloatExpr::value(2.5))], ValueType::Float),
5420 ValueType::Float,
5421 ),
5422 ListExpr::spread(
5423 vec![Expr::bool(BoolExpr::value(true))],
5424 ListExpr::value(vec![Expr::bool(BoolExpr::value(false))], ValueType::Bool),
5425 ValueType::Bool,
5426 ),
5427 ListExpr::spread(
5428 vec![Expr::nil(NilExpr::value())],
5429 ListExpr::value(vec![Expr::nil(NilExpr::value())], ValueType::Nil),
5430 ValueType::Nil,
5431 ),
5432 ListExpr::spread(
5433 vec![Expr::tuple(TupleExpr::value(
5434 vec![
5435 Expr::int(IntExpr::value(1.into())),
5436 Expr::string(StringExpr::value("one".into())),
5437 ],
5438 vec![ValueType::Int, ValueType::String],
5439 ))],
5440 ListExpr::value(
5441 vec![Expr::tuple(TupleExpr::value(
5442 vec![
5443 Expr::int(IntExpr::value(2.into())),
5444 Expr::string(StringExpr::value("two".into())),
5445 ],
5446 vec![ValueType::Int, ValueType::String],
5447 ))],
5448 ValueType::Tuple(vec![ValueType::Int, ValueType::String]),
5449 ),
5450 ValueType::Tuple(vec![ValueType::Int, ValueType::String]),
5451 ),
5452 ListExpr::spread(
5453 vec![Expr::list(ListExpr::value(
5454 vec![Expr::int(IntExpr::value(1.into()))],
5455 ValueType::Int,
5456 ))],
5457 ListExpr::value(
5458 vec![Expr::list(ListExpr::value(
5459 vec![Expr::int(IntExpr::value(2.into()))],
5460 ValueType::Int,
5461 ))],
5462 ValueType::List(Box::new(ValueType::Int)),
5463 ),
5464 ValueType::List(Box::new(ValueType::Int)),
5465 ),
5466 ListExpr::spread(
5467 vec![Expr::function(FunctionExpr::reference(
5468 function_reference.clone(),
5469 ))],
5470 ListExpr::value(
5471 vec![Expr::function(FunctionExpr::reference(
5472 function_reference.clone(),
5473 ))],
5474 ValueType::Function(Box::new(function_shape.type_())),
5475 ),
5476 ValueType::Function(Box::new(function_shape.type_())),
5477 ),
5478 ];
5479
5480 for (index, expected) in expected.into_iter().enumerate() {
5481 let instantiation =
5482 ConstantListTemplate::from_item_shape(item_shapes[index].clone(), 1).instantiate(
5483 crate::plan::ModuleId::root(),
5484 TypeSubstitution::from_arguments(Vec::new()),
5485 );
5486 assert_eq!(
5487 signatures[index * 2 + 1].try_instantiate(Vec::new()),
5488 Some(ConstantInstantiation {
5489 kind: ConstantInstantiationKind::List(instantiation.clone()),
5490 }),
5491 );
5492 assert_eq!(
5493 templates.materialize_value(
5494 &aliases[index],
5495 &TypeSubstitution::from_arguments(Vec::new()),
5496 ),
5497 Expr::list(expected),
5498 );
5499 }
5500 }
5501
5502 #[test]
5503 fn constant_template_instantiation_rejects_wrong_argument_count() {
5504 let signature = ConstantTemplateSignature::list(
5505 ConstantTemplateId::new(3),
5506 0,
5507 TypeScheme::new(1),
5508 ValueShape::Parameter(TypeParameterId(0)),
5509 );
5510
5511 assert_eq!(signature.try_instantiate(Vec::new()), None);
5512 let instantiation = signature
5513 .try_instantiate(vec![ValueShape::String])
5514 .expect("one argument should match the constant scheme");
5515 assert_eq!(
5516 ConstantValue::reference(instantiation).shape(),
5517 ValueShape::List(Box::new(ValueShape::String)),
5518 );
5519 }
5520
5521 #[test]
5522 fn constant_instantiations_preserve_every_family_through_substitution() {
5523 let parameter = TypeParameterId(0);
5524 let replacement = ValueShape::String;
5525 let substitution = TypeSubstitution::from_arguments(vec![replacement.clone()]);
5526 let custom_shape = CustomValueShape::new(
5527 CustomTypeName::new("geam".into(), "main".into(), "Boxed".into()),
5528 vec![ValueShape::Parameter(parameter)],
5529 CustomConstructorRefinement::Exact(0),
5530 );
5531 let tuple_shape = vec![ValueShape::Parameter(parameter)].into_boxed_slice();
5532
5533 let int = TypedConstantInstantiation::new(
5534 ConstantIntTemplateId(0),
5535 TypeSubstitution::from_arguments(vec![ValueShape::Parameter(parameter)]),
5536 (),
5537 );
5538 let string = TypedConstantInstantiation::new(
5539 ConstantStringTemplateId(0),
5540 TypeSubstitution::from_arguments(vec![ValueShape::Parameter(parameter)]),
5541 (),
5542 );
5543 let float = TypedConstantInstantiation::new(
5544 ConstantFloatTemplateId(0),
5545 TypeSubstitution::from_arguments(vec![ValueShape::Parameter(parameter)]),
5546 (),
5547 );
5548 let bool_ = TypedConstantInstantiation::new(
5549 super::ConstantBoolTemplateId(0),
5550 TypeSubstitution::from_arguments(vec![ValueShape::Parameter(parameter)]),
5551 (),
5552 );
5553 let nil = TypedConstantInstantiation::new(
5554 ConstantNilTemplateId(0),
5555 TypeSubstitution::from_arguments(vec![ValueShape::Parameter(parameter)]),
5556 (),
5557 );
5558 let custom = TypedConstantInstantiation::new(
5559 ConstantCustomTemplateId(0),
5560 TypeSubstitution::from_arguments(vec![ValueShape::Parameter(parameter)]),
5561 custom_shape.clone(),
5562 );
5563 let tuple = TypedConstantInstantiation::new(
5564 ConstantTupleTemplateId(0),
5565 TypeSubstitution::from_arguments(vec![ValueShape::Parameter(parameter)]),
5566 tuple_shape,
5567 );
5568
5569 let cases = [
5570 ConstantInstantiation::from_int(int.clone()),
5571 ConstantInstantiation::from_string(string.clone()),
5572 ConstantInstantiation::from_custom(custom.clone()),
5573 ConstantInstantiation::from_float(float.clone()),
5574 ConstantInstantiation::from_bool(bool_.clone()),
5575 ConstantInstantiation::from_nil(nil.clone()),
5576 ];
5577 let expected = [
5578 ConstantInstantiation::from_int(int.substitute_leaf(&substitution)),
5579 ConstantInstantiation::from_string(string.substitute_leaf(&substitution)),
5580 ConstantInstantiation::from_custom(custom.substitute_custom(&substitution)),
5581 ConstantInstantiation::from_float(float.substitute_leaf(&substitution)),
5582 ConstantInstantiation::from_bool(bool_.substitute_leaf(&substitution)),
5583 ConstantInstantiation::from_nil(nil.substitute_leaf(&substitution)),
5584 ];
5585
5586 for (value, expected) in cases.iter().zip(expected) {
5587 assert_eq!(value.substitute(&substitution), expected);
5588 }
5589 assert_eq!(
5590 ConstantInstantiation::from_tuple(tuple.clone()).substitute(&substitution),
5591 ConstantInstantiation::from_tuple(tuple.substitute_tuple(&substitution)),
5592 );
5593
5594 assert_eq!(
5595 super::ConstantIntReference(int.clone()).instantiation(),
5596 &int
5597 );
5598 assert_eq!(
5599 super::ConstantStringReference(string.clone()).instantiation(),
5600 &string,
5601 );
5602 assert_eq!(
5603 super::ConstantCustomReference(custom.clone()).instantiation(),
5604 &custom,
5605 );
5606 assert_eq!(
5607 super::ConstantFloatReference(float.clone()).instantiation(),
5608 &float,
5609 );
5610 assert_eq!(
5611 super::ConstantBoolReference(bool_.clone()).instantiation(),
5612 &bool_,
5613 );
5614 assert_eq!(
5615 super::ConstantNilReference(nil.clone()).instantiation(),
5616 &nil
5617 );
5618
5619 assert_eq!(ConstantValue::string("not int".into()).into_int(), None);
5620 assert_eq!(ConstantValue::int(1.into()).into_float(), None);
5621 assert_eq!(ConstantValue::int(1.into()).into_string(), None);
5622 assert_eq!(ConstantValue::int(1.into()).into_bit_array(), None);
5623 assert_eq!(ConstantValue::int(1.into()).into_bool(), None);
5624 assert_eq!(ConstantValue::int(1.into()).into_nil(), None);
5625 assert_eq!(ConstantValue::int(1.into()).into_list(), None);
5626 }
5627
5628 #[test]
5629 fn list_construction_rejects_uninhabited_and_mismatched_payloads() {
5630 let int_list =
5631 ConstantValue::try_list(ValueShape::Int, vec![ConstantValue::int(1.into())], None)
5632 .expect("an Int list should accept Int elements");
5633 let string_list = ConstantValue::try_list(
5634 ValueShape::String,
5635 vec![ConstantValue::string("one".into())],
5636 None,
5637 )
5638 .expect("a String list should accept String elements");
5639 let generic_list =
5640 ConstantValue::try_list(ValueShape::Parameter(TypeParameterId(0)), Vec::new(), None)
5641 .expect("a bare-parameter list may be empty");
5642 let utf_codepoint_list =
5643 ConstantValue::try_list(ValueShape::UtfCodepoint, Vec::new(), None)
5644 .expect("a UtfCodepoint list may be empty");
5645 let external_shape = ExternalValueShape::new(
5646 ExternalTypeName::new("geam".into(), "main".into(), "Resource".into()),
5647 Vec::new(),
5648 );
5649 let external_list = ConstantValue::try_list(
5650 ValueShape::External(external_shape.clone()),
5651 Vec::new(),
5652 None,
5653 )
5654 .expect("an external constant list may be empty");
5655
5656 assert_eq!(
5657 ConstantValue::try_list(ValueShape::Int, Vec::new(), Some(int_list.clone())),
5658 Err(ConstantListConstructionError::SpreadWithoutElements),
5659 );
5660 assert_eq!(
5661 ConstantValue::try_list(
5662 ValueShape::Parameter(TypeParameterId(0)),
5663 Vec::new(),
5664 Some(generic_list.clone()),
5665 ),
5666 Err(ConstantListConstructionError::SpreadWithoutElements),
5667 );
5668 assert_eq!(
5669 ConstantValue::try_list(
5670 ValueShape::UtfCodepoint,
5671 Vec::new(),
5672 Some(utf_codepoint_list.clone()),
5673 ),
5674 Err(ConstantListConstructionError::SpreadWithoutElements),
5675 );
5676 assert_eq!(
5677 ConstantValue::try_list(
5678 ValueShape::External(external_shape.clone()),
5679 Vec::new(),
5680 Some(external_list.clone()),
5681 ),
5682 Err(ConstantListConstructionError::SpreadWithoutElements),
5683 );
5684 assert_eq!(
5685 ConstantValue::try_list(
5686 ValueShape::Parameter(TypeParameterId(0)),
5687 vec![ConstantValue::int(1.into())],
5688 None,
5689 ),
5690 Err(ConstantListConstructionError::TypeMismatch {
5691 expected: ValueType::Parameter(TypeParameterId(0)),
5692 actual: ValueType::Int,
5693 }),
5694 );
5695 assert_eq!(
5696 ConstantValue::try_list(
5697 ValueShape::External(external_shape.clone()),
5698 vec![ConstantValue::int(1.into())],
5699 None,
5700 ),
5701 Err(ConstantListConstructionError::TypeMismatch {
5702 expected: ValueType::External(external_shape.type_().clone()),
5703 actual: ValueType::Int,
5704 }),
5705 );
5706 assert_eq!(
5707 ConstantValue::try_list(
5708 ValueShape::External(external_shape.clone()),
5709 vec![ConstantValue::int(1.into())],
5710 Some(external_list),
5711 ),
5712 Err(ConstantListConstructionError::TypeMismatch {
5713 expected: ValueType::External(external_shape.type_().clone()),
5714 actual: ValueType::Int,
5715 }),
5716 );
5717 assert_eq!(
5718 ConstantValue::try_list(
5719 ValueShape::UtfCodepoint,
5720 vec![ConstantValue::int(1.into())],
5721 None,
5722 ),
5723 Err(ConstantListConstructionError::TypeMismatch {
5724 expected: ValueType::UtfCodepoint,
5725 actual: ValueType::Int,
5726 }),
5727 );
5728 assert_eq!(
5729 ConstantValue::try_list(
5730 ValueShape::Parameter(TypeParameterId(0)),
5731 vec![ConstantValue::int(1.into())],
5732 Some(generic_list.clone()),
5733 ),
5734 Err(ConstantListConstructionError::TypeMismatch {
5735 expected: ValueType::Parameter(TypeParameterId(0)),
5736 actual: ValueType::Int,
5737 }),
5738 );
5739 assert_eq!(
5740 ConstantValue::try_list(
5741 ValueShape::UtfCodepoint,
5742 vec![ConstantValue::int(1.into())],
5743 Some(utf_codepoint_list),
5744 ),
5745 Err(ConstantListConstructionError::TypeMismatch {
5746 expected: ValueType::UtfCodepoint,
5747 actual: ValueType::Int,
5748 }),
5749 );
5750
5751 assert_eq!(
5752 ConstantValue::try_list(
5753 ValueShape::Int,
5754 vec![ConstantValue::string("one".into())],
5755 None,
5756 ),
5757 Err(ConstantListConstructionError::TypeMismatch {
5758 expected: ValueType::Int,
5759 actual: ValueType::String,
5760 }),
5761 );
5762 assert_eq!(
5763 ConstantValue::try_list(ValueShape::Float, vec![ConstantValue::int(1.into())], None,),
5764 Err(ConstantListConstructionError::TypeMismatch {
5765 expected: ValueType::Float,
5766 actual: ValueType::Int,
5767 }),
5768 );
5769 assert_eq!(
5770 ConstantValue::try_list(ValueShape::String, vec![ConstantValue::int(1.into())], None,),
5771 Err(ConstantListConstructionError::TypeMismatch {
5772 expected: ValueType::String,
5773 actual: ValueType::Int,
5774 }),
5775 );
5776 assert_eq!(
5777 ConstantValue::try_list(
5778 ValueShape::BitArray,
5779 vec![ConstantValue::int(1.into())],
5780 None,
5781 ),
5782 Err(ConstantListConstructionError::TypeMismatch {
5783 expected: ValueType::BitArray,
5784 actual: ValueType::Int,
5785 }),
5786 );
5787 assert_eq!(
5788 ConstantValue::try_list(ValueShape::Bool, vec![ConstantValue::int(1.into())], None,),
5789 Err(ConstantListConstructionError::TypeMismatch {
5790 expected: ValueType::Bool,
5791 actual: ValueType::Int,
5792 }),
5793 );
5794 assert_eq!(
5795 ConstantValue::try_list(ValueShape::Nil, vec![ConstantValue::int(1.into())], None,),
5796 Err(ConstantListConstructionError::TypeMismatch {
5797 expected: ValueType::Nil,
5798 actual: ValueType::Int,
5799 }),
5800 );
5801
5802 let custom_shape = CustomValueShape::new(
5803 CustomTypeName::new("geam".into(), "main".into(), "Token".into()),
5804 Vec::new(),
5805 CustomConstructorRefinement::Exact(0),
5806 );
5807 let constructor =
5808 CustomConstructor::new(custom_shape.type_().clone(), "Token".into(), 0, Vec::new());
5809 let custom = ConstantValue::custom(custom_shape.clone(), constructor.clone(), Box::new([]));
5810 let tuple = ConstantValue::tuple(
5811 vec![ValueShape::Int].into_boxed_slice(),
5812 vec![ConstantValue::int(1.into())].into_boxed_slice(),
5813 );
5814 let function_shape =
5815 FunctionShape::new(Vec::new(), ValueShape::Custom(custom_shape.clone()));
5816 let function = ConstantValue::constructor_function(
5817 function_shape.clone(),
5818 custom_shape.clone(),
5819 constructor,
5820 );
5821
5822 assert_eq!(
5823 ConstantValue::try_list(
5824 ValueShape::Custom(custom_shape.clone()),
5825 vec![ConstantValue::int(1.into())],
5826 None,
5827 ),
5828 Err(ConstantListConstructionError::TypeMismatch {
5829 expected: ValueType::Custom(custom_shape.type_().clone()),
5830 actual: ValueType::Int,
5831 }),
5832 );
5833 assert_eq!(
5834 ConstantValue::try_list(
5835 ValueShape::Tuple(vec![ValueShape::Int].into_boxed_slice()),
5836 vec![ConstantValue::int(1.into())],
5837 None,
5838 ),
5839 Err(ConstantListConstructionError::TypeMismatch {
5840 expected: ValueType::Tuple(vec![ValueType::Int]),
5841 actual: ValueType::Int,
5842 }),
5843 );
5844 assert_eq!(
5845 ConstantValue::try_list(
5846 ValueShape::List(Box::new(ValueShape::Int)),
5847 vec![ConstantValue::int(1.into())],
5848 None,
5849 ),
5850 Err(ConstantListConstructionError::TypeMismatch {
5851 expected: ValueType::List(Box::new(ValueType::Int)),
5852 actual: ValueType::Int,
5853 }),
5854 );
5855 assert_eq!(
5856 ConstantValue::try_list(
5857 ValueShape::List(Box::new(ValueShape::Parameter(TypeParameterId(0)))),
5858 vec![int_list.clone()],
5859 None,
5860 ),
5861 Err(ConstantListConstructionError::TypeMismatch {
5862 expected: ValueType::List(Box::new(ValueType::Parameter(TypeParameterId(0)))),
5863 actual: ValueType::List(Box::new(ValueType::Int)),
5864 }),
5865 );
5866 assert_eq!(
5867 ConstantValue::try_list(
5868 ValueShape::List(Box::new(ValueShape::Parameter(TypeParameterId(0)))),
5869 vec![ConstantValue::int(1.into())],
5870 None,
5871 ),
5872 Err(ConstantListConstructionError::TypeMismatch {
5873 expected: ValueType::List(Box::new(ValueType::Parameter(TypeParameterId(0)))),
5874 actual: ValueType::Int,
5875 }),
5876 );
5877 assert_eq!(
5878 ConstantValue::try_list(
5879 ValueShape::List(Box::new(ValueShape::List(Box::new(ValueShape::Parameter(
5880 TypeParameterId(0)
5881 ),)))),
5882 vec![int_list.clone()],
5883 Some(int_list.clone()),
5884 ),
5885 Err(ConstantListConstructionError::TypeMismatch {
5886 expected: ValueType::List(Box::new(ValueType::List(Box::new(
5887 ValueType::Parameter(TypeParameterId(0)),
5888 )))),
5889 actual: ValueType::List(Box::new(ValueType::Int)),
5890 }),
5891 );
5892 assert_eq!(
5893 ConstantValue::try_list(
5894 ValueShape::List(Box::new(ValueShape::Parameter(TypeParameterId(0)))),
5895 vec![
5896 ConstantValue::try_list(
5897 ValueShape::Parameter(TypeParameterId(0)),
5898 Vec::new(),
5899 None,
5900 )
5901 .expect("a bare-parameter list may be empty")
5902 ],
5903 Some(int_list.clone()),
5904 ),
5905 Err(ConstantListConstructionError::TypeMismatch {
5906 expected: ValueType::List(Box::new(ValueType::List(Box::new(
5907 ValueType::Parameter(TypeParameterId(0)),
5908 )))),
5909 actual: ValueType::List(Box::new(ValueType::Int)),
5910 }),
5911 );
5912 assert_eq!(
5913 ConstantValue::try_list(
5914 ValueShape::List(Box::new(ValueShape::Int)),
5915 vec![generic_list],
5916 None,
5917 ),
5918 Err(ConstantListConstructionError::TypeMismatch {
5919 expected: ValueType::List(Box::new(ValueType::Int)),
5920 actual: ValueType::List(Box::new(ValueType::Parameter(TypeParameterId(0)))),
5921 }),
5922 );
5923 assert_eq!(
5924 ConstantValue::try_list(
5925 ValueShape::Function(Box::new(function_shape.clone())),
5926 vec![ConstantValue::int(1.into())],
5927 None,
5928 ),
5929 Err(ConstantListConstructionError::TypeMismatch {
5930 expected: ValueType::Function(Box::new(function_shape.type_())),
5931 actual: ValueType::Int,
5932 }),
5933 );
5934
5935 assert_eq!(
5936 ConstantValue::try_list(
5937 ValueShape::Int,
5938 vec![ConstantValue::int(1.into())],
5939 Some(ConstantValue::int(2.into())),
5940 ),
5941 Err(ConstantListConstructionError::TypeMismatch {
5942 expected: ValueType::List(Box::new(ValueType::Int)),
5943 actual: ValueType::Int,
5944 }),
5945 );
5946 assert_eq!(
5947 ConstantValue::try_list(
5948 ValueShape::Int,
5949 vec![ConstantValue::int(1.into())],
5950 Some(string_list.clone()),
5951 ),
5952 Err(ConstantListConstructionError::TypeMismatch {
5953 expected: ValueType::List(Box::new(ValueType::Int)),
5954 actual: ValueType::List(Box::new(ValueType::String)),
5955 }),
5956 );
5957 assert_eq!(
5958 ConstantValue::try_list(
5959 ValueShape::String,
5960 vec![ConstantValue::string("one".into())],
5961 Some(int_list.clone()),
5962 ),
5963 Err(ConstantListConstructionError::TypeMismatch {
5964 expected: ValueType::List(Box::new(ValueType::String)),
5965 actual: ValueType::List(Box::new(ValueType::Int)),
5966 }),
5967 );
5968 assert_eq!(
5969 ConstantValue::try_list(
5970 ValueShape::BitArray,
5971 vec![ConstantValue::bit_array(Box::new([]))],
5972 Some(int_list.clone()),
5973 ),
5974 Err(ConstantListConstructionError::TypeMismatch {
5975 expected: ValueType::List(Box::new(ValueType::BitArray)),
5976 actual: ValueType::List(Box::new(ValueType::Int)),
5977 }),
5978 );
5979 assert_eq!(
5980 ConstantValue::try_list(
5981 ValueShape::Float,
5982 vec![ConstantValue::float(1.5)],
5983 Some(int_list.clone()),
5984 ),
5985 Err(ConstantListConstructionError::TypeMismatch {
5986 expected: ValueType::List(Box::new(ValueType::Float)),
5987 actual: ValueType::List(Box::new(ValueType::Int)),
5988 }),
5989 );
5990 assert_eq!(
5991 ConstantValue::try_list(
5992 ValueShape::Bool,
5993 vec![ConstantValue::bool(true)],
5994 Some(int_list.clone()),
5995 ),
5996 Err(ConstantListConstructionError::TypeMismatch {
5997 expected: ValueType::List(Box::new(ValueType::Bool)),
5998 actual: ValueType::List(Box::new(ValueType::Int)),
5999 }),
6000 );
6001 assert_eq!(
6002 ConstantValue::try_list(
6003 ValueShape::Nil,
6004 vec![ConstantValue::nil()],
6005 Some(int_list.clone()),
6006 ),
6007 Err(ConstantListConstructionError::TypeMismatch {
6008 expected: ValueType::List(Box::new(ValueType::Nil)),
6009 actual: ValueType::List(Box::new(ValueType::Int)),
6010 }),
6011 );
6012 assert_eq!(
6013 ConstantValue::try_list(
6014 ValueShape::Custom(custom_shape.clone()),
6015 vec![custom],
6016 Some(int_list.clone()),
6017 ),
6018 Err(ConstantListConstructionError::TypeMismatch {
6019 expected: ValueType::List(Box::new(ValueType::Custom(
6020 custom_shape.type_().clone(),
6021 ))),
6022 actual: ValueType::List(Box::new(ValueType::Int)),
6023 }),
6024 );
6025 assert_eq!(
6026 ConstantValue::try_list(
6027 ValueShape::Tuple(vec![ValueShape::Int].into_boxed_slice()),
6028 vec![tuple],
6029 Some(int_list.clone()),
6030 ),
6031 Err(ConstantListConstructionError::TypeMismatch {
6032 expected: ValueType::List(Box::new(ValueType::Tuple(vec![ValueType::Int]))),
6033 actual: ValueType::List(Box::new(ValueType::Int)),
6034 }),
6035 );
6036 assert_eq!(
6037 ConstantValue::try_list(
6038 ValueShape::List(Box::new(ValueShape::Int)),
6039 vec![int_list.clone()],
6040 Some(int_list.clone()),
6041 ),
6042 Err(ConstantListConstructionError::TypeMismatch {
6043 expected: ValueType::List(Box::new(ValueType::List(Box::new(ValueType::Int)))),
6044 actual: ValueType::List(Box::new(ValueType::Int)),
6045 }),
6046 );
6047 assert_eq!(
6048 ConstantValue::try_list(
6049 ValueShape::Function(Box::new(function_shape.clone())),
6050 vec![function],
6051 Some(int_list),
6052 ),
6053 Err(ConstantListConstructionError::TypeMismatch {
6054 expected: ValueType::List(Box::new(ValueType::Function(Box::new(
6055 function_shape.type_(),
6056 )))),
6057 actual: ValueType::List(Box::new(ValueType::Int)),
6058 }),
6059 );
6060 }
6061}