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

Configure Feed

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

gleam / compiler-core / src / cranelift / mir / lower.rs
28 kB 697 lines
1use std::collections::{HashMap, HashSet, VecDeque}; 2 3use ecow::EcoString; 4 5use crate::cranelift::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: 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}