Fork of daniellemaywood.uk/gleam — Wasm codegen work
28 kB
704 lines
1use std::collections::{HashMap, HashSet, VecDeque};
2
3use ecow::EcoString;
4
5use crate::wasm::mir::{
6 ast::{CompleteType, Expression, Function, FunctionParameter, IncompleteType, Module, Var},
7 visit::Visit,
8};
9
10pub fn lower(modules: Vec<Module<IncompleteType>>) -> Vec<Module<CompleteType>> {
11 let (generics, functions): (HashMap<_, _>, HashMap<_, _>) = modules
12 .into_iter()
13 .flat_map(|module| {
14 module
15 .functions
16 .into_iter()
17 .map(|function| ((module.name.clone(), function.name.clone()), function))
18 .collect::<Vec<_>>()
19 })
20 .partition(|(_, function)| is_generic(function));
21
22 let mut functions = functions
23 .into_iter()
24 .map(|((module, name), function)| {
25 let function = Function::<CompleteType>::try_from(function)?;
26
27 let instantiation = Instantiation {
28 argument_types: function
29 .parameters
30 .iter()
31 .map(|parameter| parameter.type_.clone())
32 .collect(),
33 return_type: function.return_type.clone(),
34 };
35
36 Ok(((module, name, instantiation), function))
37 })
38 .collect::<Result<
39 HashMap<(EcoString, EcoString, Instantiation), Function<CompleteType>>,
40 NonGenericError,
41 >>()
42 .expect("expected all functions to be non-generic");
43
44 let mut monomorphizer = Monomorphizer::new(&generics);
45 for (_, function) in functions.iter_mut() {
46 monomorphizer.visit_function(function);
47 }
48
49 let mut queue: VecDeque<_> = monomorphizer.instantiations.into_iter().collect();
50
51 while let Some((module, name, instantiation)) = queue.pop_front() {
52 if let Some(function) = generics.get(&(module.clone(), name.clone())).cloned() {
53 let mut function = FunctionMonomorphizer::default()
54 .translate_function(function, instantiation.clone());
55
56 _ = functions.insert((module, name, instantiation), function.clone());
57
58 let mut monomorphizer = Monomorphizer::new(&generics);
59 monomorphizer.visit_function(&mut function);
60
61 for instantiation in monomorphizer.instantiations {
62 if !functions.contains_key(&instantiation) {
63 queue.push_back(instantiation);
64 }
65 }
66 }
67 }
68
69 let mut module_map: HashMap<EcoString, Vec<Function<CompleteType>>> = HashMap::new();
70 for ((module, _, _), function) in functions {
71 module_map
72 .entry(module)
73 .or_insert_with(Vec::new)
74 .push(function);
75 }
76
77 module_map
78 .into_iter()
79 .map(|(name, functions)| Module { name, functions })
80 .collect()
81}
82
83#[derive(Debug, Clone, PartialEq, Eq, Hash)]
84struct Instantiation {
85 argument_types: Vec<CompleteType>,
86 return_type: CompleteType,
87}
88
89#[derive(Default)]
90struct FunctionMonomorphizer {
91 generic_id_map: HashMap<u64, CompleteType>,
92}
93
94impl FunctionMonomorphizer {
95 fn collect_type_ids(&mut self, incomplete: &IncompleteType, complete: &CompleteType) {
96 match incomplete {
97 IncompleteType::Generic { id } => {
98 _ = self.generic_id_map.insert(*id, complete.clone());
99 }
100
101 IncompleteType::Func { arguments, returns } => {
102 let CompleteType::Func {
103 arguments: complete_arguments,
104 returns: complete_returns,
105 } = complete
106 else {
107 unreachable!("types should not be diverged")
108 };
109
110 for (argument, complete) in arguments.iter().zip(complete_arguments.iter()) {
111 self.collect_type_ids(argument, complete);
112 }
113
114 self.collect_type_ids(returns, complete_returns);
115 }
116 IncompleteType::Tuple { elements } => {
117 let CompleteType::Tuple { elements: complete } = complete else {
118 unreachable!("types should not be diverged")
119 };
120
121 for (element, complete) in elements.iter().zip(complete.iter()) {
122 self.collect_type_ids(element, complete);
123 }
124 }
125 IncompleteType::Struct { elements } => {
126 let CompleteType::Struct { elements: complete } = complete else {
127 unreachable!("types should not be diverged")
128 };
129
130 for (element, complete) in elements.iter().zip(complete.iter()) {
131 self.collect_type_ids(element, complete);
132 }
133 }
134 IncompleteType::List(element_type) => {
135 let CompleteType::List(complete) = complete else {
136 unreachable!("types should not be diverged")
137 };
138
139 self.collect_type_ids(element_type, complete);
140 }
141
142 IncompleteType::Int
143 | IncompleteType::Float
144 | IncompleteType::Bool
145 | IncompleteType::String => {}
146 }
147 }
148
149 fn translate_function(
150 mut self,
151 function: Function<IncompleteType>,
152 instantiation: Instantiation,
153 ) -> Function<CompleteType> {
154 for (parameter, argument_type) in function
155 .parameters
156 .iter()
157 .zip(instantiation.argument_types.iter())
158 {
159 self.collect_type_ids(¶meter.type_, argument_type);
160 }
161
162 self.collect_type_ids(&function.return_type, &instantiation.return_type);
163
164 Function {
165 name: function.name,
166 return_type: instantiation.return_type,
167 parameters: function
168 .parameters
169 .into_iter()
170 .zip(instantiation.argument_types.into_iter())
171 .map(|(parameter, argument_type)| FunctionParameter {
172 name: parameter.name,
173 type_: argument_type,
174 })
175 .collect(),
176 body: function
177 .body
178 .map(|body| self.translate_expression(body)),
179 external_wasm: function.external_wasm,
180 }
181 }
182
183 fn translate_expression(
184 &mut self,
185 expression: Expression<IncompleteType>,
186 ) -> Expression<CompleteType> {
187 match expression {
188 Expression::Block(expressions) => Expression::Block(
189 expressions
190 .into_iter()
191 .map(|expression| self.translate_expression(expression))
192 .collect(),
193 ),
194 Expression::FunctionRef {
195 module,
196 name,
197 arity,
198 type_,
199 } => Expression::FunctionRef {
200 module,
201 name,
202 arity,
203 type_: self.translate_type(type_),
204 },
205 Expression::Var(var) => Expression::Var(Var {
206 name: var.name,
207 type_: self.translate_type(var.type_),
208 }),
209 Expression::Int { value } => Expression::Int { value },
210 Expression::Float { value } => Expression::Float { value },
211 Expression::Bool { value } => Expression::Bool { value },
212 Expression::String { value } => Expression::String { value },
213 Expression::Equals { lhs, rhs } => Expression::Equals {
214 lhs: Box::new(self.translate_expression(*lhs)),
215 rhs: Box::new(self.translate_expression(*rhs)),
216 },
217 Expression::NotEquals { lhs, rhs } => Expression::NotEquals {
218 lhs: Box::new(self.translate_expression(*lhs)),
219 rhs: Box::new(self.translate_expression(*rhs)),
220 },
221 Expression::IntGt { lhs, rhs } => Expression::IntGt {
222 lhs: Box::new(self.translate_expression(*lhs)),
223 rhs: Box::new(self.translate_expression(*rhs)),
224 },
225 Expression::IntGtEq { lhs, rhs } => Expression::IntGtEq {
226 lhs: Box::new(self.translate_expression(*lhs)),
227 rhs: Box::new(self.translate_expression(*rhs)),
228 },
229 Expression::IntLt { lhs, rhs } => Expression::IntLt {
230 lhs: Box::new(self.translate_expression(*lhs)),
231 rhs: Box::new(self.translate_expression(*rhs)),
232 },
233 Expression::IntLtEq { lhs, rhs } => Expression::IntLtEq {
234 lhs: Box::new(self.translate_expression(*lhs)),
235 rhs: Box::new(self.translate_expression(*rhs)),
236 },
237 Expression::IntAdd { lhs, rhs } => Expression::IntAdd {
238 lhs: Box::new(self.translate_expression(*lhs)),
239 rhs: Box::new(self.translate_expression(*rhs)),
240 },
241 Expression::IntSub { lhs, rhs } => Expression::IntSub {
242 lhs: Box::new(self.translate_expression(*lhs)),
243 rhs: Box::new(self.translate_expression(*rhs)),
244 },
245 Expression::IntMul { lhs, rhs } => Expression::IntMul {
246 lhs: Box::new(self.translate_expression(*lhs)),
247 rhs: Box::new(self.translate_expression(*rhs)),
248 },
249 Expression::IntDiv { lhs, rhs } => Expression::IntDiv {
250 lhs: Box::new(self.translate_expression(*lhs)),
251 rhs: Box::new(self.translate_expression(*rhs)),
252 },
253 Expression::IntRem { lhs, rhs } => Expression::IntRem {
254 lhs: Box::new(self.translate_expression(*lhs)),
255 rhs: Box::new(self.translate_expression(*rhs)),
256 },
257 Expression::FloatGt { lhs, rhs } => Expression::FloatGt {
258 lhs: Box::new(self.translate_expression(*lhs)),
259 rhs: Box::new(self.translate_expression(*rhs)),
260 },
261 Expression::FloatGtEq { lhs, rhs } => Expression::FloatGtEq {
262 lhs: Box::new(self.translate_expression(*lhs)),
263 rhs: Box::new(self.translate_expression(*rhs)),
264 },
265 Expression::FloatLt { lhs, rhs } => Expression::FloatLt {
266 lhs: Box::new(self.translate_expression(*lhs)),
267 rhs: Box::new(self.translate_expression(*rhs)),
268 },
269 Expression::FloatLtEq { lhs, rhs } => Expression::FloatLtEq {
270 lhs: Box::new(self.translate_expression(*lhs)),
271 rhs: Box::new(self.translate_expression(*rhs)),
272 },
273 Expression::FloatAdd { lhs, rhs } => Expression::FloatAdd {
274 lhs: Box::new(self.translate_expression(*lhs)),
275 rhs: Box::new(self.translate_expression(*rhs)),
276 },
277 Expression::FloatSub { lhs, rhs } => Expression::FloatSub {
278 lhs: Box::new(self.translate_expression(*lhs)),
279 rhs: Box::new(self.translate_expression(*rhs)),
280 },
281 Expression::FloatMul { lhs, rhs } => Expression::FloatMul {
282 lhs: Box::new(self.translate_expression(*lhs)),
283 rhs: Box::new(self.translate_expression(*rhs)),
284 },
285 Expression::FloatDiv { lhs, rhs } => Expression::FloatDiv {
286 lhs: Box::new(self.translate_expression(*lhs)),
287 rhs: Box::new(self.translate_expression(*rhs)),
288 },
289 Expression::StringConcat { lhs, rhs } => Expression::StringConcat {
290 lhs: Box::new(self.translate_expression(*lhs)),
291 rhs: Box::new(self.translate_expression(*rhs)),
292 },
293 Expression::List { items, tail, type_ } => Expression::List {
294 items: items
295 .into_iter()
296 .map(|item| self.translate_expression(item))
297 .collect(),
298 tail: tail.map(|t| Box::new(self.translate_expression(*t))),
299 type_: self.translate_type(type_),
300 },
301 Expression::Tuple { items, type_ } => Expression::Tuple {
302 items: items
303 .into_iter()
304 .map(|item| self.translate_expression(item))
305 .collect(),
306 type_: self.translate_type(type_),
307 },
308 Expression::TupleAccess {
309 value,
310 index,
311 type_,
312 } => Expression::TupleAccess {
313 value: Box::new(self.translate_expression(*value)),
314 index,
315 type_: self.translate_type(type_),
316 },
317 Expression::Struct { tag, items, type_ } => Expression::Struct {
318 tag,
319 items: items
320 .into_iter()
321 .map(|item| self.translate_expression(item))
322 .collect(),
323 type_: self.translate_type(type_),
324 },
325 Expression::StructTag { value } => Expression::StructTag {
326 value: Box::new(self.translate_expression(*value)),
327 },
328 Expression::StructAccess {
329 value,
330 index,
331 type_,
332 } => Expression::StructAccess {
333 value: Box::new(self.translate_expression(*value)),
334 index,
335 type_: self.translate_type(type_),
336 },
337 Expression::Set { name, value } => Expression::Set {
338 name: Var {
339 name: name.name,
340 type_: self.translate_type(name.type_),
341 },
342 value: Box::new(self.translate_expression(*value)),
343 },
344 Expression::If { cond, then, else_ } => Expression::If {
345 cond: Box::new(self.translate_expression(*cond)),
346 then: Box::new(self.translate_expression(*then)),
347 else_: Box::new(self.translate_expression(*else_)),
348 },
349 Expression::Call {
350 target,
351 args,
352 type_,
353 } => Expression::Call {
354 target: Box::new(self.translate_expression(*target)),
355 args: args
356 .into_iter()
357 .map(|arg| self.translate_expression(arg))
358 .collect(),
359 type_: self.translate_type(type_),
360 },
361 Expression::Panic { type_ } => Expression::Panic {
362 type_: self.translate_type(type_),
363 },
364 }
365 }
366
367 fn translate_type(&mut self, type_: IncompleteType) -> CompleteType {
368 match type_ {
369 IncompleteType::Int => CompleteType::Int,
370 IncompleteType::Float => CompleteType::Float,
371 IncompleteType::Bool => CompleteType::Bool,
372 IncompleteType::String => CompleteType::String,
373 IncompleteType::Func { arguments, returns } => CompleteType::Func {
374 arguments: arguments
375 .into_iter()
376 .map(|argument| self.translate_type(argument))
377 .collect(),
378 returns: Box::new(self.translate_type(*returns)),
379 },
380 IncompleteType::Tuple { elements } => CompleteType::Tuple {
381 elements: elements
382 .into_iter()
383 .map(|element| self.translate_type(element))
384 .collect(),
385 },
386 IncompleteType::Struct { elements } => CompleteType::Struct {
387 elements: elements
388 .into_iter()
389 .map(|element| self.translate_type(element))
390 .collect(),
391 },
392 IncompleteType::List(element_type) => {
393 CompleteType::List(Box::new(self.translate_type(*element_type)))
394 }
395 IncompleteType::Generic { id } => self
396 .generic_id_map
397 .get(&id)
398 .cloned()
399 .expect("expected generic id to have a matching type"),
400 }
401 }
402}
403
404struct Monomorphizer<'g> {
405 generics: &'g HashMap<(EcoString, EcoString), Function<IncompleteType>>,
406 instantiations: HashSet<(EcoString, EcoString, Instantiation)>,
407}
408
409impl<'g> Monomorphizer<'g> {
410 fn new(generics: &'g HashMap<(EcoString, EcoString), Function<IncompleteType>>) -> Self {
411 Self {
412 generics,
413 instantiations: Default::default(),
414 }
415 }
416}
417
418impl<'mir, 'g> Visit<'mir, CompleteType> for Monomorphizer<'g> {
419 fn visit_expression_function_ref(
420 &mut self,
421 module: &mut EcoString,
422 name: &mut EcoString,
423 _arity: &mut usize,
424 type_: &mut CompleteType,
425 ) {
426 if !self.generics.contains_key(&(module.clone(), name.clone())) {
427 return;
428 }
429
430 let CompleteType::Func { arguments, returns } = type_ else {
431 unreachable!("a function ref should always have a func type")
432 };
433
434 let instantiation = Instantiation {
435 argument_types: arguments.clone(),
436 return_type: *returns.clone(),
437 };
438
439 _ = self
440 .instantiations
441 .insert((module.clone(), name.clone(), instantiation));
442 }
443}
444
445fn is_generic(function: &Function<IncompleteType>) -> bool {
446 let has_generic_parameter = function
447 .parameters
448 .iter()
449 .any(|parameter| matches!(parameter.type_, IncompleteType::Generic { .. }));
450
451 has_generic_parameter || matches!(function.return_type, IncompleteType::Generic { .. })
452}
453
454#[derive(Debug, Clone, Copy)]
455pub struct NonGenericError;
456
457impl TryFrom<Function<IncompleteType>> for Function<CompleteType> {
458 type Error = NonGenericError;
459
460 fn try_from(value: Function<IncompleteType>) -> Result<Self, Self::Error> {
461 Ok(Function {
462 name: value.name,
463 return_type: value.return_type.try_into()?,
464 parameters: value
465 .parameters
466 .into_iter()
467 .map(|parameter| {
468 Ok(FunctionParameter {
469 name: parameter.name,
470 type_: CompleteType::try_from(parameter.type_)?,
471 })
472 })
473 .collect::<Result<Vec<_>, _>>()?,
474 body: value
475 .body
476 .map(Expression::<CompleteType>::try_from)
477 .transpose()?,
478 external_wasm: value.external_wasm,
479 })
480 }
481}
482
483impl TryFrom<Expression<IncompleteType>> for Expression<CompleteType> {
484 type Error = NonGenericError;
485
486 fn try_from(value: Expression<IncompleteType>) -> Result<Self, Self::Error> {
487 match value {
488 Expression::Block(expressions) => Ok(Expression::Block(
489 expressions
490 .into_iter()
491 .map(Expression::try_from)
492 .collect::<Result<Vec<_>, _>>()?,
493 )),
494 Expression::FunctionRef {
495 module,
496 name,
497 arity,
498 type_,
499 } => Ok(Expression::FunctionRef {
500 module,
501 name,
502 arity,
503 type_: type_.try_into()?,
504 }),
505 Expression::Var(var) => Ok(Expression::Var(Var {
506 name: var.name,
507 type_: var.type_.try_into()?,
508 })),
509 Expression::Int { value } => Ok(Expression::Int { value }),
510 Expression::Float { value } => Ok(Expression::Float { value }),
511 Expression::Bool { value } => Ok(Expression::Bool { value }),
512 Expression::String { value } => Ok(Expression::String { value }),
513 Expression::Equals { lhs, rhs } => Ok(Expression::Equals {
514 lhs: Box::new(Expression::try_from(*lhs)?),
515 rhs: Box::new(Expression::try_from(*rhs)?),
516 }),
517 Expression::NotEquals { lhs, rhs } => Ok(Expression::NotEquals {
518 lhs: Box::new(Expression::try_from(*lhs)?),
519 rhs: Box::new(Expression::try_from(*rhs)?),
520 }),
521 Expression::IntGt { lhs, rhs } => Ok(Expression::IntGt {
522 lhs: Box::new(Expression::try_from(*lhs)?),
523 rhs: Box::new(Expression::try_from(*rhs)?),
524 }),
525 Expression::IntGtEq { lhs, rhs } => Ok(Expression::IntGtEq {
526 lhs: Box::new(Expression::try_from(*lhs)?),
527 rhs: Box::new(Expression::try_from(*rhs)?),
528 }),
529 Expression::IntLt { lhs, rhs } => Ok(Expression::IntLt {
530 lhs: Box::new(Expression::try_from(*lhs)?),
531 rhs: Box::new(Expression::try_from(*rhs)?),
532 }),
533 Expression::IntLtEq { lhs, rhs } => Ok(Expression::IntLtEq {
534 lhs: Box::new(Expression::try_from(*lhs)?),
535 rhs: Box::new(Expression::try_from(*rhs)?),
536 }),
537 Expression::IntAdd { lhs, rhs } => Ok(Expression::IntAdd {
538 lhs: Box::new(Expression::try_from(*lhs)?),
539 rhs: Box::new(Expression::try_from(*rhs)?),
540 }),
541 Expression::IntSub { lhs, rhs } => Ok(Expression::IntSub {
542 lhs: Box::new(Expression::try_from(*lhs)?),
543 rhs: Box::new(Expression::try_from(*rhs)?),
544 }),
545 Expression::IntMul { lhs, rhs } => Ok(Expression::IntMul {
546 lhs: Box::new(Expression::try_from(*lhs)?),
547 rhs: Box::new(Expression::try_from(*rhs)?),
548 }),
549 Expression::IntDiv { lhs, rhs } => Ok(Expression::IntDiv {
550 lhs: Box::new(Expression::try_from(*lhs)?),
551 rhs: Box::new(Expression::try_from(*rhs)?),
552 }),
553 Expression::IntRem { lhs, rhs } => Ok(Expression::IntRem {
554 lhs: Box::new(Expression::try_from(*lhs)?),
555 rhs: Box::new(Expression::try_from(*rhs)?),
556 }),
557 Expression::FloatGt { lhs, rhs } => Ok(Expression::FloatGt {
558 lhs: Box::new(Expression::try_from(*lhs)?),
559 rhs: Box::new(Expression::try_from(*rhs)?),
560 }),
561 Expression::FloatGtEq { lhs, rhs } => Ok(Expression::FloatGtEq {
562 lhs: Box::new(Expression::try_from(*lhs)?),
563 rhs: Box::new(Expression::try_from(*rhs)?),
564 }),
565 Expression::FloatLt { lhs, rhs } => Ok(Expression::FloatLt {
566 lhs: Box::new(Expression::try_from(*lhs)?),
567 rhs: Box::new(Expression::try_from(*rhs)?),
568 }),
569 Expression::FloatLtEq { lhs, rhs } => Ok(Expression::FloatLtEq {
570 lhs: Box::new(Expression::try_from(*lhs)?),
571 rhs: Box::new(Expression::try_from(*rhs)?),
572 }),
573 Expression::FloatAdd { lhs, rhs } => Ok(Expression::FloatAdd {
574 lhs: Box::new(Expression::try_from(*lhs)?),
575 rhs: Box::new(Expression::try_from(*rhs)?),
576 }),
577 Expression::FloatSub { lhs, rhs } => Ok(Expression::FloatSub {
578 lhs: Box::new(Expression::try_from(*lhs)?),
579 rhs: Box::new(Expression::try_from(*rhs)?),
580 }),
581 Expression::FloatMul { lhs, rhs } => Ok(Expression::FloatMul {
582 lhs: Box::new(Expression::try_from(*lhs)?),
583 rhs: Box::new(Expression::try_from(*rhs)?),
584 }),
585 Expression::FloatDiv { lhs, rhs } => Ok(Expression::FloatDiv {
586 lhs: Box::new(Expression::try_from(*lhs)?),
587 rhs: Box::new(Expression::try_from(*rhs)?),
588 }),
589 Expression::StringConcat { lhs, rhs } => Ok(Expression::StringConcat {
590 lhs: Box::new(Expression::try_from(*lhs)?),
591 rhs: Box::new(Expression::try_from(*rhs)?),
592 }),
593 Expression::List { items, tail, type_ } => Ok(Expression::List {
594 items: items
595 .into_iter()
596 .map(Expression::try_from)
597 .collect::<Result<Vec<_>, _>>()?,
598 tail: tail
599 .map(|t| Ok(Box::new(Expression::try_from(*t)?)))
600 .transpose()?,
601 type_: type_.try_into()?,
602 }),
603 Expression::Tuple { items, type_ } => Ok(Expression::Tuple {
604 items: items
605 .into_iter()
606 .map(Expression::try_from)
607 .collect::<Result<Vec<_>, _>>()?,
608 type_: type_.try_into()?,
609 }),
610 Expression::TupleAccess {
611 value,
612 index,
613 type_,
614 } => Ok(Expression::TupleAccess {
615 value: Box::new(Expression::try_from(*value)?),
616 index,
617 type_: type_.try_into()?,
618 }),
619 Expression::Struct { tag, items, type_ } => Ok(Expression::Struct {
620 tag,
621 items: items
622 .into_iter()
623 .map(Expression::try_from)
624 .collect::<Result<Vec<_>, _>>()?,
625 type_: type_.try_into()?,
626 }),
627 Expression::StructTag { value } => Ok(Expression::StructTag {
628 value: Box::new(Expression::try_from(*value)?),
629 }),
630 Expression::StructAccess {
631 value,
632 index,
633 type_,
634 } => Ok(Expression::StructAccess {
635 value: Box::new(Expression::try_from(*value)?),
636 index,
637 type_: type_.try_into()?,
638 }),
639 Expression::Set { name, value } => Ok(Expression::Set {
640 name: Var {
641 name: name.name,
642 type_: name.type_.try_into()?,
643 },
644 value: Box::new(Expression::try_from(*value)?),
645 }),
646 Expression::If { cond, then, else_ } => Ok(Expression::If {
647 cond: Box::new(Expression::try_from(*cond)?),
648 then: Box::new(Expression::try_from(*then)?),
649 else_: Box::new(Expression::try_from(*else_)?),
650 }),
651 Expression::Call {
652 target,
653 args,
654 type_,
655 } => Ok(Expression::Call {
656 target: Box::new(Expression::try_from(*target)?),
657 args: args
658 .into_iter()
659 .map(Expression::try_from)
660 .collect::<Result<Vec<_>, _>>()?,
661 type_: type_.try_into()?,
662 }),
663 Expression::Panic { type_ } => Ok(Expression::Panic {
664 type_: type_.try_into()?,
665 }),
666 }
667 }
668}
669
670impl TryFrom<IncompleteType> for CompleteType {
671 type Error = NonGenericError;
672
673 fn try_from(value: IncompleteType) -> Result<Self, Self::Error> {
674 match value {
675 IncompleteType::Int => Ok(Self::Int),
676 IncompleteType::Float => Ok(Self::Float),
677 IncompleteType::Bool => Ok(Self::Bool),
678 IncompleteType::String => Ok(Self::String),
679 IncompleteType::Func { arguments, returns } => Ok(Self::Func {
680 arguments: arguments
681 .into_iter()
682 .map(Self::try_from)
683 .collect::<Result<Vec<_>, _>>()?,
684 returns: Box::new(Self::try_from(*returns)?),
685 }),
686 IncompleteType::Tuple { elements } => Ok(Self::Tuple {
687 elements: elements
688 .into_iter()
689 .map(Self::try_from)
690 .collect::<Result<Vec<_>, _>>()?,
691 }),
692 IncompleteType::Struct { elements } => Ok(Self::Struct {
693 elements: elements
694 .into_iter()
695 .map(Self::try_from)
696 .collect::<Result<Vec<_>, _>>()?,
697 }),
698 IncompleteType::List(element_type) => {
699 Ok(Self::List(Box::new(Self::try_from(*element_type)?)))
700 }
701 IncompleteType::Generic { id: _ } => Err(NonGenericError),
702 }
703 }
704}