Fork of daniellemaywood.uk/gleam — Wasm codegen work
28 kB
697 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: self.translate_expression(function.body),
177 }
178 }
179
180 fn translate_expression(
181 &mut self,
182 expression: Expression<IncompleteType>,
183 ) -> Expression<CompleteType> {
184 match expression {
185 Expression::Block(expressions) => Expression::Block(
186 expressions
187 .into_iter()
188 .map(|expression| self.translate_expression(expression))
189 .collect(),
190 ),
191 Expression::FunctionRef {
192 module,
193 name,
194 arity,
195 type_,
196 } => Expression::FunctionRef {
197 module,
198 name,
199 arity,
200 type_: self.translate_type(type_),
201 },
202 Expression::Var(var) => Expression::Var(Var {
203 name: var.name,
204 type_: self.translate_type(var.type_),
205 }),
206 Expression::Int { value } => Expression::Int { value },
207 Expression::Float { value } => Expression::Float { value },
208 Expression::Bool { value } => Expression::Bool { value },
209 Expression::String { value } => Expression::String { value },
210 Expression::Equals { lhs, rhs } => Expression::Equals {
211 lhs: Box::new(self.translate_expression(*lhs)),
212 rhs: Box::new(self.translate_expression(*rhs)),
213 },
214 Expression::NotEquals { lhs, rhs } => Expression::NotEquals {
215 lhs: Box::new(self.translate_expression(*lhs)),
216 rhs: Box::new(self.translate_expression(*rhs)),
217 },
218 Expression::IntGt { lhs, rhs } => Expression::IntGt {
219 lhs: Box::new(self.translate_expression(*lhs)),
220 rhs: Box::new(self.translate_expression(*rhs)),
221 },
222 Expression::IntGtEq { lhs, rhs } => Expression::IntGtEq {
223 lhs: Box::new(self.translate_expression(*lhs)),
224 rhs: Box::new(self.translate_expression(*rhs)),
225 },
226 Expression::IntLt { lhs, rhs } => Expression::IntLt {
227 lhs: Box::new(self.translate_expression(*lhs)),
228 rhs: Box::new(self.translate_expression(*rhs)),
229 },
230 Expression::IntLtEq { lhs, rhs } => Expression::IntLtEq {
231 lhs: Box::new(self.translate_expression(*lhs)),
232 rhs: Box::new(self.translate_expression(*rhs)),
233 },
234 Expression::IntAdd { lhs, rhs } => Expression::IntAdd {
235 lhs: Box::new(self.translate_expression(*lhs)),
236 rhs: Box::new(self.translate_expression(*rhs)),
237 },
238 Expression::IntSub { lhs, rhs } => Expression::IntSub {
239 lhs: Box::new(self.translate_expression(*lhs)),
240 rhs: Box::new(self.translate_expression(*rhs)),
241 },
242 Expression::IntMul { lhs, rhs } => Expression::IntMul {
243 lhs: Box::new(self.translate_expression(*lhs)),
244 rhs: Box::new(self.translate_expression(*rhs)),
245 },
246 Expression::IntDiv { lhs, rhs } => Expression::IntDiv {
247 lhs: Box::new(self.translate_expression(*lhs)),
248 rhs: Box::new(self.translate_expression(*rhs)),
249 },
250 Expression::IntRem { lhs, rhs } => Expression::IntRem {
251 lhs: Box::new(self.translate_expression(*lhs)),
252 rhs: Box::new(self.translate_expression(*rhs)),
253 },
254 Expression::FloatGt { lhs, rhs } => Expression::FloatGt {
255 lhs: Box::new(self.translate_expression(*lhs)),
256 rhs: Box::new(self.translate_expression(*rhs)),
257 },
258 Expression::FloatGtEq { lhs, rhs } => Expression::FloatGtEq {
259 lhs: Box::new(self.translate_expression(*lhs)),
260 rhs: Box::new(self.translate_expression(*rhs)),
261 },
262 Expression::FloatLt { lhs, rhs } => Expression::FloatLt {
263 lhs: Box::new(self.translate_expression(*lhs)),
264 rhs: Box::new(self.translate_expression(*rhs)),
265 },
266 Expression::FloatLtEq { lhs, rhs } => Expression::FloatLtEq {
267 lhs: Box::new(self.translate_expression(*lhs)),
268 rhs: Box::new(self.translate_expression(*rhs)),
269 },
270 Expression::FloatAdd { lhs, rhs } => Expression::FloatAdd {
271 lhs: Box::new(self.translate_expression(*lhs)),
272 rhs: Box::new(self.translate_expression(*rhs)),
273 },
274 Expression::FloatSub { lhs, rhs } => Expression::FloatSub {
275 lhs: Box::new(self.translate_expression(*lhs)),
276 rhs: Box::new(self.translate_expression(*rhs)),
277 },
278 Expression::FloatMul { lhs, rhs } => Expression::FloatMul {
279 lhs: Box::new(self.translate_expression(*lhs)),
280 rhs: Box::new(self.translate_expression(*rhs)),
281 },
282 Expression::FloatDiv { lhs, rhs } => Expression::FloatDiv {
283 lhs: Box::new(self.translate_expression(*lhs)),
284 rhs: Box::new(self.translate_expression(*rhs)),
285 },
286 Expression::StringConcat { lhs, rhs } => Expression::StringConcat {
287 lhs: Box::new(self.translate_expression(*lhs)),
288 rhs: Box::new(self.translate_expression(*rhs)),
289 },
290 Expression::List { items, tail, type_ } => Expression::List {
291 items: items
292 .into_iter()
293 .map(|item| self.translate_expression(item))
294 .collect(),
295 tail: tail.map(|t| Box::new(self.translate_expression(*t))),
296 type_: self.translate_type(type_),
297 },
298 Expression::Tuple { items, type_ } => Expression::Tuple {
299 items: items
300 .into_iter()
301 .map(|item| self.translate_expression(item))
302 .collect(),
303 type_: self.translate_type(type_),
304 },
305 Expression::TupleAccess {
306 value,
307 index,
308 type_,
309 } => Expression::TupleAccess {
310 value: Box::new(self.translate_expression(*value)),
311 index,
312 type_: self.translate_type(type_),
313 },
314 Expression::Struct { tag, items, type_ } => Expression::Struct {
315 tag,
316 items: items
317 .into_iter()
318 .map(|item| self.translate_expression(item))
319 .collect(),
320 type_: self.translate_type(type_),
321 },
322 Expression::StructTag { value } => Expression::StructTag {
323 value: Box::new(self.translate_expression(*value)),
324 },
325 Expression::StructAccess {
326 value,
327 index,
328 type_,
329 } => Expression::StructAccess {
330 value: Box::new(self.translate_expression(*value)),
331 index,
332 type_: self.translate_type(type_),
333 },
334 Expression::Set { name, value } => Expression::Set {
335 name: Var {
336 name: name.name,
337 type_: self.translate_type(name.type_),
338 },
339 value: Box::new(self.translate_expression(*value)),
340 },
341 Expression::If { cond, then, else_ } => Expression::If {
342 cond: Box::new(self.translate_expression(*cond)),
343 then: Box::new(self.translate_expression(*then)),
344 else_: Box::new(self.translate_expression(*else_)),
345 },
346 Expression::Call {
347 target,
348 args,
349 type_,
350 } => Expression::Call {
351 target: Box::new(self.translate_expression(*target)),
352 args: args
353 .into_iter()
354 .map(|arg| self.translate_expression(arg))
355 .collect(),
356 type_: self.translate_type(type_),
357 },
358 Expression::Panic { type_ } => Expression::Panic {
359 type_: self.translate_type(type_),
360 },
361 }
362 }
363
364 fn translate_type(&mut self, type_: IncompleteType) -> CompleteType {
365 match type_ {
366 IncompleteType::Int => CompleteType::Int,
367 IncompleteType::Float => CompleteType::Float,
368 IncompleteType::Bool => CompleteType::Bool,
369 IncompleteType::String => CompleteType::String,
370 IncompleteType::Func { arguments, returns } => CompleteType::Func {
371 arguments: arguments
372 .into_iter()
373 .map(|argument| self.translate_type(argument))
374 .collect(),
375 returns: Box::new(self.translate_type(*returns)),
376 },
377 IncompleteType::Tuple { elements } => CompleteType::Tuple {
378 elements: elements
379 .into_iter()
380 .map(|element| self.translate_type(element))
381 .collect(),
382 },
383 IncompleteType::Struct { elements } => CompleteType::Struct {
384 elements: elements
385 .into_iter()
386 .map(|element| self.translate_type(element))
387 .collect(),
388 },
389 IncompleteType::List(element_type) => {
390 CompleteType::List(Box::new(self.translate_type(*element_type)))
391 }
392 IncompleteType::Generic { id } => self
393 .generic_id_map
394 .get(&id)
395 .cloned()
396 .expect("expected generic id to have a matching type"),
397 }
398 }
399}
400
401struct Monomorphizer<'g> {
402 generics: &'g HashMap<(EcoString, EcoString), Function<IncompleteType>>,
403 instantiations: HashSet<(EcoString, EcoString, Instantiation)>,
404}
405
406impl<'g> Monomorphizer<'g> {
407 fn new(generics: &'g HashMap<(EcoString, EcoString), Function<IncompleteType>>) -> Self {
408 Self {
409 generics,
410 instantiations: Default::default(),
411 }
412 }
413}
414
415impl<'mir, 'g> Visit<'mir, CompleteType> for Monomorphizer<'g> {
416 fn visit_expression_function_ref(
417 &mut self,
418 module: &mut EcoString,
419 name: &mut EcoString,
420 _arity: &mut usize,
421 type_: &mut CompleteType,
422 ) {
423 if !self.generics.contains_key(&(module.clone(), name.clone())) {
424 return;
425 }
426
427 let CompleteType::Func { arguments, returns } = type_ else {
428 unreachable!("a function ref should always have a func type")
429 };
430
431 let instantiation = Instantiation {
432 argument_types: arguments.clone(),
433 return_type: *returns.clone(),
434 };
435
436 _ = self
437 .instantiations
438 .insert((module.clone(), name.clone(), instantiation));
439 }
440}
441
442fn is_generic(function: &Function<IncompleteType>) -> bool {
443 let has_generic_parameter = function
444 .parameters
445 .iter()
446 .any(|parameter| matches!(parameter.type_, IncompleteType::Generic { .. }));
447
448 has_generic_parameter || matches!(function.return_type, IncompleteType::Generic { .. })
449}
450
451#[derive(Debug, Clone, Copy)]
452pub struct NonGenericError;
453
454impl TryFrom<Function<IncompleteType>> for Function<CompleteType> {
455 type Error = NonGenericError;
456
457 fn try_from(value: Function<IncompleteType>) -> Result<Self, Self::Error> {
458 Ok(Function {
459 name: value.name,
460 return_type: value.return_type.try_into()?,
461 parameters: value
462 .parameters
463 .into_iter()
464 .map(|parameter| {
465 Ok(FunctionParameter {
466 name: parameter.name,
467 type_: CompleteType::try_from(parameter.type_)?,
468 })
469 })
470 .collect::<Result<Vec<_>, _>>()?,
471 body: Expression::<CompleteType>::try_from(value.body)?,
472 })
473 }
474}
475
476impl TryFrom<Expression<IncompleteType>> for Expression<CompleteType> {
477 type Error = NonGenericError;
478
479 fn try_from(value: Expression<IncompleteType>) -> Result<Self, Self::Error> {
480 match value {
481 Expression::Block(expressions) => Ok(Expression::Block(
482 expressions
483 .into_iter()
484 .map(Expression::try_from)
485 .collect::<Result<Vec<_>, _>>()?,
486 )),
487 Expression::FunctionRef {
488 module,
489 name,
490 arity,
491 type_,
492 } => Ok(Expression::FunctionRef {
493 module,
494 name,
495 arity,
496 type_: type_.try_into()?,
497 }),
498 Expression::Var(var) => Ok(Expression::Var(Var {
499 name: var.name,
500 type_: var.type_.try_into()?,
501 })),
502 Expression::Int { value } => Ok(Expression::Int { value }),
503 Expression::Float { value } => Ok(Expression::Float { value }),
504 Expression::Bool { value } => Ok(Expression::Bool { value }),
505 Expression::String { value } => Ok(Expression::String { value }),
506 Expression::Equals { lhs, rhs } => Ok(Expression::Equals {
507 lhs: Box::new(Expression::try_from(*lhs)?),
508 rhs: Box::new(Expression::try_from(*rhs)?),
509 }),
510 Expression::NotEquals { lhs, rhs } => Ok(Expression::NotEquals {
511 lhs: Box::new(Expression::try_from(*lhs)?),
512 rhs: Box::new(Expression::try_from(*rhs)?),
513 }),
514 Expression::IntGt { lhs, rhs } => Ok(Expression::IntGt {
515 lhs: Box::new(Expression::try_from(*lhs)?),
516 rhs: Box::new(Expression::try_from(*rhs)?),
517 }),
518 Expression::IntGtEq { lhs, rhs } => Ok(Expression::IntGtEq {
519 lhs: Box::new(Expression::try_from(*lhs)?),
520 rhs: Box::new(Expression::try_from(*rhs)?),
521 }),
522 Expression::IntLt { lhs, rhs } => Ok(Expression::IntLt {
523 lhs: Box::new(Expression::try_from(*lhs)?),
524 rhs: Box::new(Expression::try_from(*rhs)?),
525 }),
526 Expression::IntLtEq { lhs, rhs } => Ok(Expression::IntLtEq {
527 lhs: Box::new(Expression::try_from(*lhs)?),
528 rhs: Box::new(Expression::try_from(*rhs)?),
529 }),
530 Expression::IntAdd { lhs, rhs } => Ok(Expression::IntAdd {
531 lhs: Box::new(Expression::try_from(*lhs)?),
532 rhs: Box::new(Expression::try_from(*rhs)?),
533 }),
534 Expression::IntSub { lhs, rhs } => Ok(Expression::IntSub {
535 lhs: Box::new(Expression::try_from(*lhs)?),
536 rhs: Box::new(Expression::try_from(*rhs)?),
537 }),
538 Expression::IntMul { lhs, rhs } => Ok(Expression::IntMul {
539 lhs: Box::new(Expression::try_from(*lhs)?),
540 rhs: Box::new(Expression::try_from(*rhs)?),
541 }),
542 Expression::IntDiv { lhs, rhs } => Ok(Expression::IntDiv {
543 lhs: Box::new(Expression::try_from(*lhs)?),
544 rhs: Box::new(Expression::try_from(*rhs)?),
545 }),
546 Expression::IntRem { lhs, rhs } => Ok(Expression::IntRem {
547 lhs: Box::new(Expression::try_from(*lhs)?),
548 rhs: Box::new(Expression::try_from(*rhs)?),
549 }),
550 Expression::FloatGt { lhs, rhs } => Ok(Expression::FloatGt {
551 lhs: Box::new(Expression::try_from(*lhs)?),
552 rhs: Box::new(Expression::try_from(*rhs)?),
553 }),
554 Expression::FloatGtEq { lhs, rhs } => Ok(Expression::FloatGtEq {
555 lhs: Box::new(Expression::try_from(*lhs)?),
556 rhs: Box::new(Expression::try_from(*rhs)?),
557 }),
558 Expression::FloatLt { lhs, rhs } => Ok(Expression::FloatLt {
559 lhs: Box::new(Expression::try_from(*lhs)?),
560 rhs: Box::new(Expression::try_from(*rhs)?),
561 }),
562 Expression::FloatLtEq { lhs, rhs } => Ok(Expression::FloatLtEq {
563 lhs: Box::new(Expression::try_from(*lhs)?),
564 rhs: Box::new(Expression::try_from(*rhs)?),
565 }),
566 Expression::FloatAdd { lhs, rhs } => Ok(Expression::FloatAdd {
567 lhs: Box::new(Expression::try_from(*lhs)?),
568 rhs: Box::new(Expression::try_from(*rhs)?),
569 }),
570 Expression::FloatSub { lhs, rhs } => Ok(Expression::FloatSub {
571 lhs: Box::new(Expression::try_from(*lhs)?),
572 rhs: Box::new(Expression::try_from(*rhs)?),
573 }),
574 Expression::FloatMul { lhs, rhs } => Ok(Expression::FloatMul {
575 lhs: Box::new(Expression::try_from(*lhs)?),
576 rhs: Box::new(Expression::try_from(*rhs)?),
577 }),
578 Expression::FloatDiv { lhs, rhs } => Ok(Expression::FloatDiv {
579 lhs: Box::new(Expression::try_from(*lhs)?),
580 rhs: Box::new(Expression::try_from(*rhs)?),
581 }),
582 Expression::StringConcat { lhs, rhs } => Ok(Expression::StringConcat {
583 lhs: Box::new(Expression::try_from(*lhs)?),
584 rhs: Box::new(Expression::try_from(*rhs)?),
585 }),
586 Expression::List { items, tail, type_ } => Ok(Expression::List {
587 items: items
588 .into_iter()
589 .map(Expression::try_from)
590 .collect::<Result<Vec<_>, _>>()?,
591 tail: tail
592 .map(|t| Ok(Box::new(Expression::try_from(*t)?)))
593 .transpose()?,
594 type_: type_.try_into()?,
595 }),
596 Expression::Tuple { items, type_ } => Ok(Expression::Tuple {
597 items: items
598 .into_iter()
599 .map(Expression::try_from)
600 .collect::<Result<Vec<_>, _>>()?,
601 type_: type_.try_into()?,
602 }),
603 Expression::TupleAccess {
604 value,
605 index,
606 type_,
607 } => Ok(Expression::TupleAccess {
608 value: Box::new(Expression::try_from(*value)?),
609 index,
610 type_: type_.try_into()?,
611 }),
612 Expression::Struct { tag, items, type_ } => Ok(Expression::Struct {
613 tag,
614 items: items
615 .into_iter()
616 .map(Expression::try_from)
617 .collect::<Result<Vec<_>, _>>()?,
618 type_: type_.try_into()?,
619 }),
620 Expression::StructTag { value } => Ok(Expression::StructTag {
621 value: Box::new(Expression::try_from(*value)?),
622 }),
623 Expression::StructAccess {
624 value,
625 index,
626 type_,
627 } => Ok(Expression::StructAccess {
628 value: Box::new(Expression::try_from(*value)?),
629 index,
630 type_: type_.try_into()?,
631 }),
632 Expression::Set { name, value } => Ok(Expression::Set {
633 name: Var {
634 name: name.name,
635 type_: name.type_.try_into()?,
636 },
637 value: Box::new(Expression::try_from(*value)?),
638 }),
639 Expression::If { cond, then, else_ } => Ok(Expression::If {
640 cond: Box::new(Expression::try_from(*cond)?),
641 then: Box::new(Expression::try_from(*then)?),
642 else_: Box::new(Expression::try_from(*else_)?),
643 }),
644 Expression::Call {
645 target,
646 args,
647 type_,
648 } => Ok(Expression::Call {
649 target: Box::new(Expression::try_from(*target)?),
650 args: args
651 .into_iter()
652 .map(Expression::try_from)
653 .collect::<Result<Vec<_>, _>>()?,
654 type_: type_.try_into()?,
655 }),
656 Expression::Panic { type_ } => Ok(Expression::Panic {
657 type_: type_.try_into()?,
658 }),
659 }
660 }
661}
662
663impl TryFrom<IncompleteType> for CompleteType {
664 type Error = NonGenericError;
665
666 fn try_from(value: IncompleteType) -> Result<Self, Self::Error> {
667 match value {
668 IncompleteType::Int => Ok(Self::Int),
669 IncompleteType::Float => Ok(Self::Float),
670 IncompleteType::Bool => Ok(Self::Bool),
671 IncompleteType::String => Ok(Self::String),
672 IncompleteType::Func { arguments, returns } => Ok(Self::Func {
673 arguments: arguments
674 .into_iter()
675 .map(Self::try_from)
676 .collect::<Result<Vec<_>, _>>()?,
677 returns: Box::new(Self::try_from(*returns)?),
678 }),
679 IncompleteType::Tuple { elements } => Ok(Self::Tuple {
680 elements: elements
681 .into_iter()
682 .map(Self::try_from)
683 .collect::<Result<Vec<_>, _>>()?,
684 }),
685 IncompleteType::Struct { elements } => Ok(Self::Struct {
686 elements: elements
687 .into_iter()
688 .map(Self::try_from)
689 .collect::<Result<Vec<_>, _>>()?,
690 }),
691 IncompleteType::List(element_type) => {
692 Ok(Self::List(Box::new(Self::try_from(*element_type)?)))
693 }
694 IncompleteType::Generic { id: _ } => Err(NonGenericError),
695 }
696 }
697}