(
&mut self,
ty: &Type,
blocks_with_type_have_result: bool,
cases: impl IntoIterator<Item = Option<&'b Type>>,
mut iter: impl FnMut(&mut Self, &Type),
)
| 1908 | } |
| 1909 | |
| 1910 | fn flat_for_each_variant_arm<'b>( |
| 1911 | &mut self, |
| 1912 | ty: &Type, |
| 1913 | blocks_with_type_have_result: bool, |
| 1914 | cases: impl IntoIterator<Item = Option<&'b Type>>, |
| 1915 | mut iter: impl FnMut(&mut Self, &Type), |
| 1916 | ) { |
| 1917 | let params = flat_types(self.resolve, ty, None).unwrap(); |
| 1918 | let mut casts = Vec::new(); |
| 1919 | let block_inputs = self |
| 1920 | .stack |
| 1921 | .drain(self.stack.len() + 1 - params.len()..) |
| 1922 | .collect::<Vec<_>>(); |
| 1923 | for ty in cases { |
| 1924 | self.push_block(); |
| 1925 | if let Some(ty) = ty { |
| 1926 | // Push only the values we need for this variant onto |
| 1927 | // the stack. |
| 1928 | let temp = flat_types(self.resolve, ty, None).unwrap(); |
| 1929 | self.stack |
| 1930 | .extend(block_inputs[..temp.len()].iter().cloned()); |
| 1931 | |
| 1932 | // Cast all the types we have on the stack to the actual |
| 1933 | // types needed for this variant, if necessary. |
| 1934 | casts.truncate(0); |
| 1935 | for (actual, expected) in temp.iter().zip(¶ms[1..]) { |
| 1936 | casts.push(cast(*expected, *actual)); |
| 1937 | } |
| 1938 | if casts.iter().any(|c| *c != Bitcast::None) { |
| 1939 | self.emit(&Instruction::Bitcasts { casts: &casts }); |
| 1940 | } |
| 1941 | |
| 1942 | // Then recursively lift this variant's payload. |
| 1943 | iter(self, ty); |
| 1944 | } |
| 1945 | self.finish_block(if blocks_with_type_have_result { |
| 1946 | ty.is_some() as usize |
| 1947 | } else { |
| 1948 | 0 |
| 1949 | }); |
| 1950 | } |
| 1951 | } |
| 1952 | |
| 1953 | fn write_to_memory(&mut self, ty: &Type, addr: B::Operand, offset: ArchitectureSize) { |
| 1954 | use Instruction::*; |
no test coverage detected