-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Rc
runs destructors twice on trait objects
#25515
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Doesn't occur in 1.0 stable thankfully... |
I'll ask this just as a control question, but it's kind of important. Is it sound that we allow simultaneous access to a value through both |
If a 'normal' Rc is dropped last the problem goes away: // This works:
let _: Rc<Send> = Rc::new(Bass(37)).clone();
// This also works:
let a: Rc<Bass> = Rc::new(Bass(37));
let _: Rc<Send> = a.clone();
// This triggers the bug:
let a: Rc<Bass> = Rc::new(Bass(37));
let b: Rc<Send> = a.clone();
drop(a);
drop(b); |
The bug also occurs when you use an unsized type that isn't a trait: // Same bug.
let _: Rc<[Bass]> = Rc::new([Bass(37)]); |
It looks like the problem is with #![feature(core)]
struct Foo(u8);
impl Drop for Foo {
fn drop(&mut self) { println!("Dropped Foo({})", self.0); self.0 += 1; }
}
struct Holder<T: ?Sized>(T);
fn main() {
unsafe {
let ptr = std::mem::transmute::<_, *mut Holder<[Foo; 1]>>(Box::new(Holder([Foo(0)])));
let big_ptr: *mut Holder<[Foo]> = ptr;
std::intrinsics::drop_in_place(&mut (*big_ptr).0 as *mut _);
// leak box memory here :(
}
} The same thing happens when we use the following unsafe block in main: let ptr = std::mem::transmute::<_, *mut Holder<Foo>>(Box::new(Holder(Foo(0))));
let big_ptr: *mut Holder<Send> = ptr;
std::intrinsics::drop_in_place(&mut (*big_ptr).0 as *mut _); |
cc me |
This bug is hilarious: #![feature(core)]
struct Foo(u8);
impl Drop for Foo {
fn drop(&mut self) { println!("Dropped Foo({})", self.0); self.0 += 1; }
}
struct Holder<T: ?Sized>(T);
fn main() {
unsafe {
let mut foo = Holder(Foo(0));
&(*(&mut foo as &mut Holder<Send>)).0;
&(*(&mut foo as &mut Holder<Send>)).0;
&(*(&mut foo as &mut Holder<Send>)).0;
std::mem::forget(foo);
}
} This prints:
Yes, we dropped the same Foo three times. The problem is not in Edit: so the bug appeared to be in |
Looks like this also applies to |
I believe so, since it’s always been possible to do so with |
prints:
(Playpen)
The text was updated successfully, but these errors were encountered: