Repository: HigherOrderCO/Bend
File: src/fun/transform/desugar_match_defs.rs (Rust)

Code before:
          let mut body = rule.body.clone();
          if let Some(var) = var {
            body = Term::Use {
              nam: Some(var.clone()),
              val: Box::new(Term::Num { val: Num::U24(*num) }),
              nxt: Box::new(std::mem::take(&mut body)),
            };
          }
          let rule = Rule { pats: rule.pats[1..].to_vec(), body };
          new_rules.push(rule);
        }
        _ => (),
      }
    }
    let body = simplify_rule_match(args.clone(), new_rules, with.clone(), ctrs, adts)?;
    num_bodies.push(body);
  }

  // Default case
  let mut new_rules = vec![];
  for rule in rules {
    if let Pattern::Var(var) = &rule.pats[0] {
      let mut body = rule.body.clone();
      if let Some(var) = var {
        let last_num = *nums.last().unwrap();
        let curr_num = 1 + last_num;
        let var_recovered = Term::add_num(Term::Var { nam: pred_var.clone() }, Num::U24(curr_num));
        body = Term::Use { nam: Some(var.clone()), val: Box::new(var_recovered), nxt: Box::new(body) };
        fast_pred_access(&mut body, curr_num, var, &pred_var);
      }
      let rule = Rule { pats: rule.pats[1..].to_vec(), body };
      new_rules.push(rule);
    }
  }
  let mut default_with = with.clone();
  default_with.push(pred_var.clone());
  let default_body = simplify_rule_match(args.clone(), new_rules, default_with, ctrs, adts)?;

  // Linearize previously matched vars and current args.
  let with = with.into_iter().chain(args).collect::<Vec<_>>();
  let with_bnd = with.iter().cloned().map(Some).collect::<Vec<_>>();
  let with_arg = with.iter().cloned().map(|nam| Term::Var { nam }).collect::<Vec<_>>();

  let term = num_bodies.into_iter().enumerate().rfold(default_body, |term, (i, body)| {
    let val = if i > 0 {
      //  switch arg = (pred +1 +num_i-1 - num_i) { 0: body_i; _: acc }
      // nums[i] >= nums[i-1]+1, so we do a sub here.
      Term::sub_num(Term::Var { nam: pred_var.clone() }, Num::U24(nums[i] - 1 - nums[i - 1]))
    } else {
      //  switch arg = (arg -num_0) { 0: body_0; _: acc}
      Term::sub_num(Term::Var { nam: arg.clone() }, Num::U24(nums[i]))

Review comment (suggestion):
```suggestion
        let cur_num = 1 + last_num;
```
Let's go with `cur` to mean "current" everywhere in the repo. (this is the only place that uses `curr`)

Code after:
          let mut body = rule.body.clone();
          if let Some(var) = var {
            body = Term::Use {
              nam: Some(var.clone()),
              val: Box::new(Term::Num { val: Num::U24(*num) }),
              nxt: Box::new(std::mem::take(&mut body)),
            };
          }
          let rule = Rule { pats: rule.pats[1..].to_vec(), body };
          new_rules.push(rule);
        }
        _ => (),
      }
    }
    let body = simplify_rule_match(args.clone(), new_rules, with.clone(), ctrs, adts)?;
    num_bodies.push(body);
  }

  // Default case
  let mut new_rules = vec![];
  for rule in rules {
    if let Pattern::Var(var) = &rule.pats[0] {
      let mut body = rule.body.clone();
      if let Some(var) = var {
        let last_num = *nums.last().unwrap();
        let cur_num = 1 + last_num;
        let var_recovered = Term::add_num(Term::Var { nam: pred_var.clone() }, Num::U24(cur_num));
        body = Term::Use { nam: Some(var.clone()), val: Box::new(var_recovered), nxt: Box::new(body) };
        fast_pred_access(&mut body, cur_num, var, &pred_var);
      }
      let rule = Rule { pats: rule.pats[1..].to_vec(), body };
      new_rules.push(rule);
    }
  }
  let mut default_with = with.clone();
  default_with.push(pred_var.clone());
  let default_body = simplify_rule_match(args.clone(), new_rules, default_with, ctrs, adts)?;

  // Linearize previously matched vars and current args.
  let with = with.into_iter().chain(args).collect::<Vec<_>>();
  let with_bnd = with.iter().cloned().map(Some).collect::<Vec<_>>();
  let with_arg = with.iter().cloned().map(|nam| Term::Var { nam }).collect::<Vec<_>>();

  let term = num_bodies.into_iter().enumerate().rfold(default_body, |term, (i, body)| {
    let val = if i > 0 {
      //  switch arg = (pred +1 +num_i-1 - num_i) { 0: body_i; _: acc }
      // nums[i] >= nums[i-1]+1, so we do a sub here.
      Term::sub_num(Term::Var { nam: pred_var.clone() }, Num::U24(nums[i] - 1 - nums[i - 1]))
    } else {
      //  switch arg = (arg -num_0) { 0: body_0; _: acc}
      Term::sub_num(Term::Var { nam: arg.clone() }, Num::U24(nums[i]))