You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When implementing Drop on a type that has type parameters (which requires #[unsafe_destructor]), if the Drop impl is specialized to some concrete type parameter, the specialization is ignored in the drop glue and the Drop impl is instead run on all values of the outer type regardless of type parameters.
Example:
#![feature(unsafe_destructor)]externcrate debug;structDropMe<T>{_x:T}structImplDrop;#[unsafe_destructor]implDropforDropMe<ImplDrop>{fndrop(&mutself){println!("DropMe<ImplDrop>.Drop: {:?}",*self);}}fnmain(){let x = DropMe::<ImplDrop>{_x:ImplDrop};println!("Dropping DropMe<ImplDrop>");drop(x);let y = DropMe::<int>{_x:32};println!("Dropping DropMe<int>");drop(y);}
It gets worse. If you use a type parameter with bounds, it incorrectly believes that it needs to call the Drop impl regardless of parameterization (as it did before), even though it knows that the type doesn't conform to the bounds. At least this time it's a compile-time error:
#![feature(unsafe_destructor)]externcrate debug;structDropMe<T>{_x:T}structImplDrop;traitFoo{}implFooforImplDrop{}#[unsafe_destructor]impl<T:Foo>DropforDropMe<T>{fndrop(&mutself){println!("DropMe<T: Foo>.Drop: {:?}",*self);}}fnmain(){let x = DropMe::<int>{_x:32};println!("Dropping DropMe<int>");drop(x);let y = DropMe::<ImplDrop>{_x:ImplDrop};println!("Dropping DropMe<ImplDrop>");drop(y);}
unnamed.rs:15:5: 17:6 error: failed to find an implementation of trait Foo for int
unnamed.rs:15 fn drop(&mut self) {
unnamed.rs:16 println!("DropMe<T: Foo>.Drop: {:?}", *self);
unnamed.rs:17 }
And of course if you add an impl Drop for DropMe<int> then it complains about duplicate implementations.
The text was updated successfully, but these errors were encountered:
Hrm, no wonder I couldn't find it, I only looked for open issues.
I was under the impression that there was some plan that would fix the lifetime issue and thus cause #[unsafe_destructor] to no longer be necessary?
In any case, if this doesn't work, then either a ticket should remain open to document it (such as this one), or the compiler should actually throw an error upon encountering the unsupported Drop impls.
@kballard I believe our planned fix is outlined on the updated description on #8142. (Note that it e.g. requires the ability to put bounds on type parameters in structs themselves, so that instead of having type-specialized Drop impls, you instead embed the desired constraints in the struct definition itself.)
Perhaps instead of closing that ticket after the addition of #14988, we instead should have just taken it off the P-backcompat-lang list and 1.0 milestone, but still left it open. I will go address that there.
When implementing
Drop
on a type that has type parameters (which requires#[unsafe_destructor])
, if theDrop
impl is specialized to some concrete type parameter, the specialization is ignored in the drop glue and theDrop
impl is instead run on all values of the outer type regardless of type parameters.Example:
This should print
Instead it prints
Note that it's calling the
Drop
impl onDropMe<int>
, even though theDrop
impl itself believes that the receiver type isDropMe<ImplDrop>
.It gets worse. If you add a second specialized
Drop
impl, that completely overrides the first:This prints:
It gets worse. If you use a type parameter with bounds, it incorrectly believes that it needs to call the
Drop
impl regardless of parameterization (as it did before), even though it knows that the type doesn't conform to the bounds. At least this time it's a compile-time error:And of course if you add an
impl Drop for DropMe<int>
then it complains about duplicate implementations.The text was updated successfully, but these errors were encountered: