-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Uniformly prevent values with destructors from being disassembled/moved out of #4691
Comments
Has any of this been done? |
I actually this this is done. Let me double-check the tests. |
See e.g. compile-fail/borrowck-move-out-of-struct-with-dtor.rs |
Not sure about the FSU case, and the test doesn't cover the |
It occurs to me that this test is only present on the branch for PR #7262 |
@nikomatsakis: can this be closed now? |
@thestinger sounds like it needs tests. I will tag as such (and also poke around to check what the situation is with respect to the tests). |
Or rather, I think the first two bullets already have tests:
Now I'm just trying to understand what Niko was getting at about the functional struct update (FSU) case... |
Okay, the borrow checker currently does not prevent someone from doing this, but I think @nikomatsakis wants it to be prevented: use NC = std::util::NonCopyable;
#[cfg(version2)]
struct S { a: int, b: int, p: ~str, nc: NC }
#[cfg(version2)]
fn make_s(a: int) -> S { S{ a: a, b: 0, p: ~"A", nc: NC } }
#[cfg(version2)]
fn ownmut(s: &mut S) { s.b = 1; s.p.push_char('B'); }
#[cfg(not(version2))]
struct S { a: int, b: int, nc: NC }
#[cfg(not(version2))]
fn make_s(a: int) -> S { S{ a: a, b: 0, nc: NC } }
#[cfg(not(version2))]
fn ownmut(s: &mut S) { s.b = 1; }
impl ToStr for S {
#[cfg(version2)]
fn to_str(&self) -> ~str {
"S { a: "+ self.a.to_str() +
", b: "+ self.b.to_str() +
", p: "+ self.p + " (nc) }"
}
#[cfg(not(version2))]
fn to_str(&self) -> ~str {
"S { a: "+ self.a.to_str() +
", b: "+ self.b.to_str() + " (nc) }"
}
}
impl Drop for S {
fn drop(&mut self) {
println!("{} is dropped", self.to_str());
}
}
fn main() {
let s0 = make_s(0);
println!("s0: {}", s0.to_str());
// Shouldn't be allowed: A move out of value with a dtor via
// Functional Struct Update (FSU):
let mut s2 = S{a: 2, ..s0};
// Uncommenting below will fail to compile, b/c s0 has been moved
// println!("s0: {}", s0.to_str());
ownmut(&mut s2);
println!("s2: {}", s2.to_str());
} There seems like there's good reason for preventing this, at least in our current system, because its not clear how you should go about destructing instances of things like I put two versions of the code above. In one version, Here's the results:
So, yeah, this is not yet done, and its not just a matter of |
…ng-compute-moves, r=nikomatsakis Resolves third bullet of #4691: if the functional-struct-update (FSU) expression `{ a: b, ..s }` causes `s` to move and `s` has a destructor, then the expression is illegal. r? @nikomatsakis
We need to put in place three checks (at least?) to prevent values with destructors from being moved out of:
x.f
wherex
has a dtor). Right now the borrow checker doesn't allow such moves, but there is no deep reason why it shouldn't, and the rest of the code is kind of setup to allow them whenever borrow checker gives the nod.S { a, b, ..c }
wherec
has a dtor, even if this would otherwise be legalThe text was updated successfully, but these errors were encountered: