Comment by jason_oster

11 days ago

Therefore explaining why the bug hadn't been hit in practice for 11 years.

On further reading, the Drop impl is a red herring. The bug is unrelated to Drop. It's there in the repro to show the effects of invalid assignment, but even without impl Drop the bug is still there.

The bug in the OP is about UNconditional impl. And honestly, looks like very standard code, definitely something that could've been written for real. I can't even explain why it passes checks, it clearly shouldn't.

  • This code, from the bug submission?

      impl<T: 'static + Send> Drop for Q<T> {
          fn drop(&mut self) { if let Some(t) = self.0.take() { KEPT.lock().unwrap().push(Box::new(t)); } }
      }
    

    The bound on T in the Drop impl means Drop is not implemented for all T, only where T: 'static + Send. Q<T> also having the same bound doesn't make a difference to the Drop impl.

    • You cannot write a type which conditionally implements Drop: https://play.rust-lang.org/?version=stable&mode=debug&editio...

          struct Q<T>(Option<T>);
      
          impl<T: 'static> Drop for Q<T> {
              fn drop(&mut self) {}
          }
      
      
          error[E0367]: `Drop` impl requires `T: 'static` but the struct it is implemented for does not
           --> src/main.rs:3:9
            |
          3 | impl<T: 'static> Drop for Q<T> {
            |         ^^^^^^^
            |
          note: the implementor must specify the same requirement
           --> src/main.rs:1:1
            |
          1 | struct Q<T>(Option<T>);
            | ^^^^^^^^^^^

      7 replies →