(
&self,
cx: &InferCx<'_, impl Specialization>,
)
| 873 | |
| 874 | impl<'a> InferOperandList<'a> { |
| 875 | fn split_first( |
| 876 | &self, |
| 877 | cx: &InferCx<'_, impl Specialization>, |
| 878 | ) -> Option<(InferOperand, InferOperandList<'a>)> { |
| 879 | let mut list = self.clone(); |
| 880 | loop { |
| 881 | let (first_operand, rest) = list.operands.split_first()?; |
| 882 | list.operands = rest; |
| 883 | |
| 884 | let (first, rest_args) = InferOperand::from_operand_and_generic_args( |
| 885 | first_operand, |
| 886 | list.all_generic_args.clone(), |
| 887 | cx, |
| 888 | ); |
| 889 | list.all_generic_args = rest_args; |
| 890 | |
| 891 | // Maybe filter this operand, but only *after* consuming the "generic" args for it. |
| 892 | match self.transform { |
| 893 | None => {} |
| 894 | |
| 895 | // Skip a non-ID operand. |
| 896 | Some(InferOperandListTransform::TypeOfId) => { |
| 897 | if first_operand.id_ref_any().is_none() { |
| 898 | continue; |
| 899 | } |
| 900 | } |
| 901 | } |
| 902 | |
| 903 | // Maybe replace this operand with a different one. |
| 904 | let first = match self.transform { |
| 905 | None => first, |
| 906 | |
| 907 | // Map `first` to its type. |
| 908 | Some(InferOperandListTransform::TypeOfId) => match first { |
| 909 | InferOperand::Concrete(CopyOperand::IdRef(id)) => cx |
| 910 | .type_of_result |
| 911 | .get(&id) |
| 912 | .cloned() |
| 913 | .unwrap_or(InferOperand::Unknown), |
| 914 | InferOperand::Unknown | InferOperand::Var(_) | InferOperand::Concrete(_) => { |
| 915 | InferOperand::Unknown |
| 916 | } |
| 917 | InferOperand::Instance(instance) => { |
| 918 | let generic = &cx.specializer.generics[&instance.generic_id]; |
| 919 | |
| 920 | // HACK(eddyb) work around the inexplicable fact that `OpFunction` is |
| 921 | // specified with a *Result Type* that isn't the type of its *Result*: |
| 922 | // > *Result Type* must be the same as the *Return Type* declared in *Function Type* |
| 923 | // So we use *Function Type* instead as the type of its *Result*, and |
| 924 | // we are helped by `instantiate_instruction`, which ensures that the |
| 925 | // "generic" args we have are specifically meant for *Function Type*. |
| 926 | let type_of_result = match generic.def.class.opcode { |
| 927 | Op::Function => Some(generic.def.operands[1].unwrap_id_ref()), |
| 928 | _ => generic.def.result_type, |
| 929 | }; |
| 930 | |
| 931 | match type_of_result { |
| 932 | Some(type_of_result) => { |
no test coverage detected