forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of rust-lang#90788 - ecstatic-morse:issue-90752, r=wesleyw…
…iser Mark places as initialized when mutably borrowed Fixes the example in rust-lang#90752, but does not handle some corner cases involving raw pointers and unsafe. See [this comment](rust-lang#90752 (comment)) for more information, or the second test. Although I talked about both `MaybeUninitializedPlaces` and `MaybeInitializedPlaces` in rust-lang#90752, this PR only changes the latter. That's because "maybe uninitialized" is the conservative choice, and marking them as definitely initialized (`!maybe_uninitialized`) when a mutable borrow is created could lead to problems if `addr_of_mut` to an uninitialized local is allowed. Additionally, places cannot become uninitialized via a mutable reference, so if a place is definitely initialized, taking a mutable reference to it should not change that. I think it's correct to ignore interior mutability as nbdd0121 suggests below. Their analysis doesn't work inside of `core::cell`, which *does* have access to `UnsafeCell`'s field, but that won't be an issue unless we explicitly instantiate one with an `enum` within that module. r? `@wesleywiser`
- Loading branch information
Showing
5 changed files
with
163 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// run-pass | ||
|
||
use std::cell::RefCell; | ||
|
||
struct S<'a>(i32, &'a RefCell<Vec<i32>>); | ||
|
||
impl<'a> Drop for S<'a> { | ||
fn drop(&mut self) { | ||
self.1.borrow_mut().push(self.0); | ||
} | ||
} | ||
|
||
fn test(drops: &RefCell<Vec<i32>>) { | ||
let mut foo = None; | ||
let pfoo: *mut _ = &mut foo; | ||
|
||
match foo { | ||
None => (), | ||
_ => return, | ||
} | ||
|
||
// Both S(0) and S(1) should be dropped, but aren't. | ||
unsafe { *pfoo = Some((S(0, drops), S(1, drops))); } | ||
|
||
match foo { | ||
Some((_x, _)) => {} | ||
_ => {} | ||
} | ||
} | ||
|
||
fn main() { | ||
let drops = RefCell::new(Vec::new()); | ||
test(&drops); | ||
|
||
// Ideally, we want this... | ||
//assert_eq!(*drops.borrow(), &[0, 1]); | ||
|
||
// But the delayed access through the raw pointer confuses drop elaboration, | ||
// causing S(1) to be leaked. | ||
assert_eq!(*drops.borrow(), &[0]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// run-pass | ||
|
||
use std::cell::RefCell; | ||
|
||
struct S<'a>(i32, &'a RefCell<Vec<i32>>); | ||
|
||
impl<'a> Drop for S<'a> { | ||
fn drop(&mut self) { | ||
self.1.borrow_mut().push(self.0); | ||
} | ||
} | ||
|
||
fn test(drops: &RefCell<Vec<i32>>) { | ||
let mut foo = None; | ||
match foo { | ||
None => (), | ||
_ => return, | ||
} | ||
|
||
*(&mut foo) = Some((S(0, drops), S(1, drops))); // Both S(0) and S(1) should be dropped | ||
|
||
match foo { | ||
Some((_x, _)) => {} | ||
_ => {} | ||
} | ||
} | ||
|
||
fn main() { | ||
let drops = RefCell::new(Vec::new()); | ||
test(&drops); | ||
assert_eq!(*drops.borrow(), &[0, 1]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// Ensure that taking a mutable raw ptr to an uninitialized variable does not change its | ||
// initializedness. | ||
|
||
struct S; | ||
|
||
fn main() { | ||
let mut x: S; | ||
std::ptr::addr_of_mut!(x); //~ borrow of | ||
|
||
let y = x; // Should error here if `addr_of_mut` is ever allowed on uninitialized variables | ||
drop(y); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
error[E0381]: borrow of possibly-uninitialized variable: `x` | ||
--> $DIR/move-of-addr-of-mut.rs:8:5 | ||
| | ||
LL | std::ptr::addr_of_mut!(x); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `x` | ||
| | ||
= note: this error originates in the macro `std::ptr::addr_of_mut` (in Nightly builds, run with -Z macro-backtrace for more info) | ||
|
||
error: aborting due to previous error | ||
|
||
For more information about this error, try `rustc --explain E0381`. |