-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Soundness bug? (use after move) #42729
Comments
Seems safe. Moving 1. If you use an additional field, you can't read that field after struct MyObject {
text: String,
int: u32,
}
fn do_something_owned(_o: MyObject) {}
fn main() {
let mut my_object = MyObject { text: "1".into(), int: 2 };
do_something_owned(my_object);
my_object.text = "3".into();
println!("{:?}", my_object.int);
//~^ ERROR: use of moved value: `my_object.int`
} 2. If the type impl Drop, you can't use struct MyObject {
text: String,
}
impl Drop for MyObject {
fn drop(&mut self) {}
}
fn do_something_owned(_o: MyObject) {}
fn main() {
let mut my_object = MyObject { text: "1".into() };
do_something_owned(my_object);
my_object.text = "3".into();
//~^ ERROR: partial reinitialization of uninitialized structure `my_object`
} |
While it's safe, it doesn't seem to be a well looking behavior. Assigning all fields back doesn't create a working object (which is correct because structs can't be self referencing), and it's basically like an decomposed object. |
Not a bug, borrow and move/initialization checkers decompose structs/enums/unions into "elementary fragments" and analyze each of these fragments individually.
This is a limitation of the current implementation and it would be useful to fix it, especially for unions. Here's what happens in the example, step by step: fn main() {
// my_object becomes initialized
// ->
// my_object.text becomes initialized
let mut my_object = MyObject { text: String::from("sometest") };
// my_object becomes uninitialized
// ->
// my_object.text becomes uninitialized
do_something_owned(my_object);
// my_object.text becomes initialized
// ->
// my_object becomes initialized (UNIMPLEMENTED)
my_object.text = String::from("we're done");
} Note, that the last assignment to
I'm relatively sure this is an artificial restriction (probably to simplify implementation, especially dynamic drop flags), with general rule "every fully initialized fragment is dropped, all other fragments are not" it becomes redundant. |
I will point out here that whoever wrote the text for E0383 certainly thought this should fail to compile; maybe it did at some point:
This actually compiles today. On a side note - these examples in the error reference probably should be tested like doctests in every release! |
@djzin The error index does get doc-tested, but this example is
|
Given that this is not a bug, I'm giving it a close. Thanks! |
…bank Remove most "```ignore" doc tests. Unconditional ` ```ignore ` doc tests lead to outdated examples (e.g. rust-lang#42729 (comment)). This PR tries to change all existing ` ```ignore ` tests into one of the following: * Add import and declarations to ensure the code is run-pass * If the code is not Rust, change to ` ```text `/` ```sh `/` ```json `/` ```dot ` * If the code is expected compile-fail, change to ` ```compile_fail ` * If the code is expected run-fail, change to ` ```should_panic ` * If the code can type-check but cannot link/run, change to ` ```no_run ` * Otherwise, add an explanation after the ` ```ignore ` The `--explain` handling is changed to cope with hidden lines from the error index. Tidy is changed to reject any unexplained ` ```ignore ` and ` ```rust,ignore `.
…bank Remove most "```ignore" doc tests. Unconditional ` ```ignore ` doc tests lead to outdated examples (e.g. rust-lang#42729 (comment)). This PR tries to change all existing ` ```ignore ` tests into one of the following: * Add import and declarations to ensure the code is run-pass * If the code is not Rust, change to ` ```text `/` ```sh `/` ```json `/` ```dot ` * If the code is expected compile-fail, change to ` ```compile_fail ` * If the code is expected run-fail, change to ` ```should_panic ` * If the code can type-check but cannot link/run, change to ` ```no_run ` * Otherwise, add an explanation after the ` ```ignore ` The `--explain` handling is changed to cope with hidden lines from the error index. Tidy is changed to reject any unexplained ` ```ignore ` and ` ```rust,ignore `.
Remove most "```ignore" doc tests. Unconditional ` ```ignore ` doc tests lead to outdated examples (e.g. #42729 (comment)). This PR tries to change all existing ` ```ignore ` tests into one of the following: * Add import and declarations to ensure the code is run-pass * If the code is not Rust, change to ` ```text `/` ```sh `/` ```json `/` ```dot ` * If the code is expected compile-fail, change to ` ```compile_fail ` * If the code is expected run-fail, change to ` ```should_panic ` * If the code can type-check but cannot link/run, change to ` ```no_run ` * Otherwise, add an explanation after the ` ```ignore ` The `--explain` handling is changed to cope with hidden lines from the error index. Tidy is changed to reject any unexplained ` ```ignore ` and ` ```rust,ignore `.
Remove most "```ignore" doc tests. Unconditional ` ```ignore ` doc tests lead to outdated examples (e.g. #42729 (comment)). This PR tries to change all existing ` ```ignore ` tests into one of the following: * Add import and declarations to ensure the code is run-pass * If the code is not Rust, change to ` ```text `/` ```sh `/` ```json `/` ```dot ` * If the code is expected compile-fail, change to ` ```compile_fail ` * If the code is expected run-fail, change to ` ```should_panic ` * If the code can type-check but cannot link/run, change to ` ```no_run ` * Otherwise, add an explanation after the ` ```ignore ` The `--explain` handling is changed to cope with hidden lines from the error index. Tidy is changed to reject any unexplained ` ```ignore ` and ` ```rust,ignore `.
…bank Remove most "```ignore" doc tests. Unconditional ` ```ignore ` doc tests lead to outdated examples (e.g. rust-lang#42729 (comment)). This PR tries to change all existing ` ```ignore ` tests into one of the following: * Add import and declarations to ensure the code is run-pass * If the code is not Rust, change to ` ```text `/` ```sh `/` ```json `/` ```dot ` * If the code is expected compile-fail, change to ` ```compile_fail ` * If the code is expected run-fail, change to ` ```should_panic ` * If the code can type-check but cannot link/run, change to ` ```no_run ` * Otherwise, add an explanation after the ` ```ignore ` The `--explain` handling is changed to cope with hidden lines from the error index. Tidy is changed to reject any unexplained ` ```ignore ` and ` ```rust,ignore `.
…bank Remove most "```ignore" doc tests. Unconditional ` ```ignore ` doc tests lead to outdated examples (e.g. rust-lang#42729 (comment)). This PR tries to change all existing ` ```ignore ` tests into one of the following: * Add import and declarations to ensure the code is run-pass * If the code is not Rust, change to ` ```text `/` ```sh `/` ```json `/` ```dot ` * If the code is expected compile-fail, change to ` ```compile_fail ` * If the code is expected run-fail, change to ` ```should_panic ` * If the code can type-check but cannot link/run, change to ` ```no_run ` * Otherwise, add an explanation after the ` ```ignore ` The `--explain` handling is changed to cope with hidden lines from the error index. Tidy is changed to reject any unexplained ` ```ignore ` and ` ```rust,ignore `.
Remove most "```ignore" doc tests. Unconditional ` ```ignore ` doc tests lead to outdated examples (e.g. rust-lang/rust#42729 (comment)). This PR tries to change all existing ` ```ignore ` tests into one of the following: * Add import and declarations to ensure the code is run-pass * If the code is not Rust, change to ` ```text `/` ```sh `/` ```json `/` ```dot ` * If the code is expected compile-fail, change to ` ```compile_fail ` * If the code is expected run-fail, change to ` ```should_panic ` * If the code can type-check but cannot link/run, change to ` ```no_run ` * Otherwise, add an explanation after the ` ```ignore ` The `--explain` handling is changed to cope with hidden lines from the error index. Tidy is changed to reject any unexplained ` ```ignore ` and ` ```rust,ignore `.
Playground link: https://is.gd/3eEKsV
I would expect it to be a compile time error.
The text was updated successfully, but these errors were encountered: