Fork of daniellemaywood.uk/gleam — Wasm codegen work
1

Configure Feed

Select the types of activity you want to include in your feed.

gleam / compiler-core / src / wasm / mir / lower.rs
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(&parameter.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}