(
&mut self,
subject: &ast::Expr,
cases: &[ast::MatchCase],
pattern_context: &mut PatternContext,
)
| 6796 | } |
| 6797 | |
| 6798 | fn compile_match_inner( |
| 6799 | &mut self, |
| 6800 | subject: &ast::Expr, |
| 6801 | cases: &[ast::MatchCase], |
| 6802 | pattern_context: &mut PatternContext, |
| 6803 | ) -> CompileResult<()> { |
| 6804 | self.compile_expression(subject)?; |
| 6805 | let end = self.new_block(); |
| 6806 | |
| 6807 | let num_cases = cases.len(); |
| 6808 | assert!(num_cases > 0); |
| 6809 | let has_default = cases.iter().last().unwrap().pattern.is_match_star() && num_cases > 1; |
| 6810 | |
| 6811 | let case_count = num_cases - if has_default { 1 } else { 0 }; |
| 6812 | for (i, m) in cases.iter().enumerate().take(case_count) { |
| 6813 | // Only copy the subject if not on the last case |
| 6814 | if i != case_count - 1 { |
| 6815 | emit!(self, Instruction::Copy { i: 1 }); |
| 6816 | } |
| 6817 | |
| 6818 | pattern_context.stores = Vec::with_capacity(1); |
| 6819 | pattern_context.allow_irrefutable = m.guard.is_some() || i == case_count - 1; |
| 6820 | pattern_context.fail_pop.clear(); |
| 6821 | pattern_context.on_top = 0; |
| 6822 | |
| 6823 | self.compile_pattern(&m.pattern, pattern_context)?; |
| 6824 | assert_eq!(pattern_context.on_top, 0); |
| 6825 | |
| 6826 | for name in &pattern_context.stores { |
| 6827 | self.compile_name(name, NameUsage::Store)?; |
| 6828 | } |
| 6829 | |
| 6830 | if let Some(ref guard) = m.guard { |
| 6831 | self.ensure_fail_pop(pattern_context, 0)?; |
| 6832 | // Compile the guard expression |
| 6833 | self.compile_expression(guard)?; |
| 6834 | emit!(self, Instruction::ToBool); |
| 6835 | emit!( |
| 6836 | self, |
| 6837 | Instruction::PopJumpIfFalse { |
| 6838 | delta: pattern_context.fail_pop[0] |
| 6839 | } |
| 6840 | ); |
| 6841 | } |
| 6842 | |
| 6843 | if i != case_count - 1 { |
| 6844 | emit!(self, Instruction::PopTop); |
| 6845 | } |
| 6846 | |
| 6847 | self.compile_statements(&m.body)?; |
| 6848 | emit!(self, PseudoInstruction::Jump { delta: end }); |
| 6849 | self.emit_and_reset_fail_pop(pattern_context)?; |
| 6850 | } |
| 6851 | |
| 6852 | if has_default { |
| 6853 | let m = &cases[num_cases - 1]; |
| 6854 | if num_cases == 1 { |
| 6855 | emit!(self, Instruction::PopTop); |
no test coverage detected