Lint for decreasing var scope

Hi all, There isn't lint that would warn about unnecessary scope increase in which variable has been declared. I believe such lint would be very helfpul. Any opinions?

fn main() {
    {
        let is_true = false;
        {
            {
                //here is the scope into which that variables declaration could be safely moved into,
                if is_true {
                    drop(1);
                }
            }
        }
    }
}

Seems like a reasonable opt-in (allow-by-default and/or Clippy) lint to me, provided it only takes into account trivial scopes (unless the expression were to be const-constructible), and I guess that the types also need to feature no drop-glue.

See for instance, the following "counter-examples":

- let is_true = compute_initial_value();
  if some_condition() {
+     let is_true = compute_initial_value();
      if is_true { /* … */ }
  }
  • Change of semantics: now compute_initial_value() only happens when some_condition()
- let is_true = ::scopeguard::guard(false, |_| stuff());
  {
+     let is_true = ::scopeguard::guard(false, |_| stuff());
      if *is_true { /* … */ }
+     /* is_true is implicitly dropped here, running stuff() */
  }
  other_stuff()
- /* is_true is implicitly dropped after this point, running stuff() */
  • Change of semantics: now other_stuff() observes the state after stuff() has run, rather than before.

Note that regarding the drop glue thing, it may actually be even easier to lint this way, it would just be a matter of counting the implicit drop calls in the MIR as points of use, which automatically leads to the scope being appropriate.

2 Likes