Perform inference across the entire definition of `func`, including all the instructions in its body, and either store the resulting `Replacements` in its `Generic` (if `func` is "generic"), or return them otherwise.
(&mut self, func: &Function)
| 650 | /// the instructions in its body, and either store the resulting `Replacements` |
| 651 | /// in its `Generic` (if `func` is "generic"), or return them otherwise. |
| 652 | fn infer_function(&mut self, func: &Function) -> Option<Replacements> { |
| 653 | let func_id = func.def_id().unwrap(); |
| 654 | |
| 655 | let param_count = self |
| 656 | .generics |
| 657 | .get(&func_id) |
| 658 | .map_or(0, |generic| generic.param_count); |
| 659 | |
| 660 | let (param_values, replacements) = { |
| 661 | let mut infer_cx = InferCx::new(self); |
| 662 | infer_cx.instantiate_function(func); |
| 663 | |
| 664 | // FIXME(eddyb) dedup this with `collect_generics`. |
| 665 | let param_values = infer_cx.infer_var_values[..param_count as usize] |
| 666 | .iter() |
| 667 | .map(|v| v.map_var(|InferVar(i)| Param(i))); |
| 668 | // Only allocate `param_values` if they constrain parameters. |
| 669 | let param_values = if param_values.clone().any(|v| v != Value::Unknown) { |
| 670 | Some(param_values.collect()) |
| 671 | } else { |
| 672 | None |
| 673 | }; |
| 674 | |
| 675 | ( |
| 676 | param_values, |
| 677 | infer_cx.into_replacements(..Param(param_count)), |
| 678 | ) |
| 679 | }; |
| 680 | |
| 681 | if let Some(generic) = self.generics.get_mut(&func_id) { |
| 682 | // All constraints `func` could have from `collect_generics` |
| 683 | // would have to come from its `OpTypeFunction`, but types don't have |
| 684 | // internal constraints like e.g. `OpConstant*` and `OpVariable` do. |
| 685 | assert!(generic.param_values.is_none()); |
| 686 | |
| 687 | generic.param_values = param_values; |
| 688 | generic.replacements = replacements; |
| 689 | |
| 690 | None |
| 691 | } else { |
| 692 | Some(replacements) |
| 693 | } |
| 694 | } |
| 695 | } |
| 696 | |
| 697 | /// Newtype'd inference variable index. |
no test coverage detected