Comment by Xirdus

11 days ago

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>);
          | ^^^^^^^^^^^

    • Even if the bounds are the same on the struct and the impl, it's still true that placing bounds on the Drop impl means it's not implemented for all T (just all T that also satisfy Q).

      You also don't have to place those bounds on the Drop impl just because they're on Q, that's not an error.

      6 replies →