title: Using the Rust compiler to prevent forgetting to call a method
body: <p>I have some code like this:</p>
  
  <pre><code>foo.move_right_by(10);
  //do some stuff
  foo.move_left_by(10);
  </code></pre>
  
  <p>It's really important that I perform both of those operations <em>eventually</em>, but I often forget to do the second one after the first. It causes a lot of bugs and I'm wondering if there is an idiomatic Rust way to avoid this problem. Is there a way to get the rust compiler to let me know when I forget?</p>
  
  <p>My idea was to maybe somehow have something like this:</p>
  
  <pre><code>// must_use will prevent us from forgetting this if it is returned by a function
  #[must_use]
  pub struct MustGoLeft {
      steps: usize;
  }
  
  impl MustGoLeft {
      fn move(&amp;self, foo: &amp;mut Foo) {
          foo.move_left_by(self.steps);
      }
  }
  
  // If we don't use left, we'll get a warning about an unused variable
  let left = foo.move_left_by(10);
  
  // Downside: move() can be called multiple times which is still a bug
  // Downside: left is still available after this call, it would be nice if it could be dropped when move is called
  left.move();
  </code></pre>
  
  <p>Is there a better way to accomplish this?</p>
  
  <p>Another idea is to implement <code>Drop</code> and <code>panic!</code> if the struct is dropped without having called that method. This isn't as good though because it's a runtime check and that is highly undesirable. </p>
  
  <p><strong>Edit:</strong> I realized my example may have been too simple. The logic involved can get quite complex. For example, we have something like this:</p>
  
  <pre><code>foo.move_right_by(10);
  foo.open_box(); // like a cardboard box, nothing to do with Box&lt;T&gt;
  foo.move_left_by(10);
  // do more stuff...
  foo.close_box();
  </code></pre>
  
  <p>Notice how the operations aren't performed in a nice, properly nested order. The only thing that's important is that the inverse operation is always called afterwards. The order sometimes needs to be specified in a certain way in order to make the code work as expected.</p>
  
  <p>We can even have something like this:</p>
  
  <pre><code>foo.move_right_by(10);
  foo.open_box(); // like a cardboard box, nothing to do with Box&lt;T&gt;
  foo.move_left_by(10);
  // do more stuff...
  foo.move_right_by(10);
  foo.close_box();
  foo.move_left_by(10);
  // do more stuff...
  </code></pre>