-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Use EverInit instead of MaybeInit to determine initialization #50697
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
Conversation
r? @estebank (rust_highfive has picked a reviewer for you, use r? to override) |
r? @pnkfelix or @nikomatsakis |
lgtm |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
@TimNN Looks like that if there's a timeout, the logs above say nothing about it. |
@KiChjang the change to the compiler functionality looks fine to me but since it seems like you made what look like two independent changes, I would imagine we need more than the single small unit test that you have here. In particular, I suspect you need a test to check the change where you added unused mut logic for reservations or writes of (Let us know if you want help constructing such a test!) |
@jonhoo I'm already looking into it; the problem is I don't know how to construct a test for that functionality. |
@KiChjang Okay so here's the deal Unique borrows (sometimes called They largely arise from closures which
You can see some high-level discussion of the matter at the following (old!) blog post by @nikomatsakis : http://smallcultfollowing.com/babysteps/blog/2014/05/13/focusing-on-ownership/
Here (under the details) are some examples of where the construct arises mod mutate_deref {
fn foo(a: &mut i32) { // note: *not* `mut a: &mut i32`
{
let _closure = || { *a = 3; }; // mutates deref of `&uniq` borrowed `a`
}
*a = 4; // (this proves `a` was reborrowed for limited time, not moved)
}
}
mod mut_borrow {
fn inside_closure(_x: &mut i32) { }
fn foo(a: &mut i32) { // note: *not* `mut a: &mut i32`
let _closure = || { inside_closure(a) }; // `&uniq` reborrow `a` w/o mutating local
}
}
mod mutate_field {
fn foo(a: &mut (i32, i32)) { // note: *not* `mut a`
{
let _closure = || { a.0 = 3; }; // mutates deref of `&uniq` borrowed `a`
}
a.0 = 4; // (this proves `a` was reborrowed for limited time, not moved)
}
} For comparison's sake, here (under the details) are some cases that look similar but where the mod generic {
fn inside_closure<X>(_x: X) { }
fn foo(a: &mut i32) {
let _closure = || { inside_closure(a) }; // *moves* `a` due to above signature
}
}
mod shared_borrow {
fn inside_closure(_x: &i32) { }
fn foo(a: &mut i32) {
{
println!("we can read a: {:?}", a);
let _closure = || { inside_closure(a) }; // a shared reborrow; not unique.
println!("we can read a: {:?}", a);
}
*a = 4; // this proves we had shared reborrow for more limited time
}
}
mod mutate_local {
fn foo<'r>(mut a: &'r mut i32, b: Option<&'r mut i32>) {
let _closure = || { a = b.unwrap(); }; // mutates local `a` (via implicit `&mut` borrow)
}
} If my memory is right, the main reason why we distinguish unique borrows from mutable borrows is precisely so that one does not have to mark those locals as mutable. I think the mental model is that you are not mutating the local, but rather than thing it points to, and that does not require a Looking at this again, I am now even more curious to understand the actual net-effect of adding the
FYI, the quickest way I've found, at least in terms of developer effort, to "discover" how to reconstruct a case like this when you're starting from nothing: Just make a build of src/librustc_mir/borrow_check/mod.rs
--- INDEX:/src/librustc_mir/borrow_check/mod.rs
+++ WORKDIR:/src/librustc_mir/borrow_check/mod.rs
@@ -1711,7 +1711,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
Reservation(WriteKind::MutableBorrow(BorrowKind::Unique))
| Write(WriteKind::MutableBorrow(BorrowKind::Unique)) => {
match self.is_mutable(place, LocalMutationIsAllowed::Yes) {
- Ok(root_place) => self.add_used_mut(root_place, flow_state),
+ Ok(root_place) => {
+ self.add_used_mut(root_place, flow_state);
+ panic!("this is what we're looking for.");
+ }
Err(_place_err) => {
span_bug!(span, "&unique borrow for {:?} should not fail", place);
} And then run the test suite: That should yield a collection of instances of input .rs files that exercise the code in question. (Of course this technique needs to be adapted slightly if the code in question is executed during bootstrap itself; in that case you can e.g. make the panic dependent on an environment variable.) Here's my suggestion at this point: If you cannot identify (via a concrete test input) what bug is fixed by your addition of the (But double check first if you can find a concrete test input after considering the examples I provided above! I assume you had some initial motivation for adding that line!) |
Ok, for the sake of a timely fix, I've removed the check under |
@bors r+ |
📌 Commit 8b24644 has been approved by |
☀️ Test successful - status-appveyor, status-travis |
Fixes #50461.
Fixes #50463.