Skip to content

Commit 39f1b46

Browse files
committed
Rollup merge of rust-lang#53932 - matthewjasper:remove-base-path, r=nikomatsakis
[NLL] Remove base_place This function was supposed to make `Box` less special. But * I think that the consensus is that MIR borrowck is going to fully special case `Box` * It wasn't implemented correctly, it's looking at the type of the wrong `Place`, resulting in weird behaviour: ```rust #![feature(nll)] type A = Box<i32>; // If this is changed to another type then this will compile. pub fn foo(x: Box<(String, A)>) { let a = x.0; // This will compile if these lines are swapped let b = x.1; } ``` r? @nikomatsakis
2 parents d3b9ec5 + faf80ad commit 39f1b46

File tree

3 files changed

+18
-70
lines changed

3 files changed

+18
-70
lines changed

src/librustc_mir/borrow_check/mod.rs

+4-46
Original file line numberDiff line numberDiff line change
@@ -1605,10 +1605,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
16051605
place_span: (&Place<'tcx>, Span),
16061606
flow_state: &Flows<'cx, 'gcx, 'tcx>,
16071607
) {
1608-
// FIXME: analogous code in check_loans first maps `place` to
1609-
// its base_path ... but is that what we want here?
1610-
let place = self.base_path(place_span.0);
1611-
16121608
let maybe_uninits = &flow_state.uninits;
16131609

16141610
// Bad scenarios:
@@ -1646,8 +1642,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
16461642
//
16471643
// This code covers scenarios 1, 2, and 3.
16481644

1649-
debug!("check_if_full_path_is_moved place: {:?}", place);
1650-
match self.move_path_closest_to(place) {
1645+
debug!("check_if_full_path_is_moved place: {:?}", place_span.0);
1646+
match self.move_path_closest_to(place_span.0) {
16511647
Ok(mpi) => {
16521648
if maybe_uninits.contains(&mpi) {
16531649
self.report_use_of_moved_or_uninitialized(
@@ -1677,10 +1673,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
16771673
place_span: (&Place<'tcx>, Span),
16781674
flow_state: &Flows<'cx, 'gcx, 'tcx>,
16791675
) {
1680-
// FIXME: analogous code in check_loans first maps `place` to
1681-
// its base_path ... but is that what we want here?
1682-
let place = self.base_path(place_span.0);
1683-
16841676
let maybe_uninits = &flow_state.uninits;
16851677

16861678
// Bad scenarios:
@@ -1709,8 +1701,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
17091701
//
17101702
// This code covers scenario 1.
17111703

1712-
debug!("check_if_path_or_subpath_is_moved place: {:?}", place);
1713-
if let Some(mpi) = self.move_path_for_place(place) {
1704+
debug!("check_if_path_or_subpath_is_moved place: {:?}", place_span.0);
1705+
if let Some(mpi) = self.move_path_for_place(place_span.0) {
17141706
if let Some(child_mpi) = maybe_uninits.has_any_child_of(mpi) {
17151707
self.report_use_of_moved_or_uninitialized(
17161708
context,
@@ -1813,11 +1805,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
18131805
let tcx = self.tcx;
18141806
match base.ty(self.mir, tcx).to_ty(tcx).sty {
18151807
ty::Adt(def, _) if def.has_dtor(tcx) => {
1816-
1817-
// FIXME: analogous code in
1818-
// check_loans.rs first maps
1819-
// `base` to its base_path.
1820-
18211808
self.check_if_path_or_subpath_is_moved(
18221809
context, InitializationRequiringAction::Assignment,
18231810
(base, span), flow_state);
@@ -2190,35 +2177,6 @@ enum Overlap {
21902177
Disjoint,
21912178
}
21922179

2193-
impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
2194-
// FIXME (#16118): function intended to allow the borrow checker
2195-
// to be less precise in its handling of Box while still allowing
2196-
// moves out of a Box. They should be removed when/if we stop
2197-
// treating Box specially (e.g. when/if DerefMove is added...)
2198-
2199-
fn base_path<'d>(&self, place: &'d Place<'tcx>) -> &'d Place<'tcx> {
2200-
//! Returns the base of the leftmost (deepest) dereference of an
2201-
//! Box in `place`. If there is no dereference of an Box
2202-
//! in `place`, then it just returns `place` itself.
2203-
2204-
let mut cursor = place;
2205-
let mut deepest = place;
2206-
loop {
2207-
let proj = match *cursor {
2208-
Place::Promoted(_) |
2209-
Place::Local(..) | Place::Static(..) => return deepest,
2210-
Place::Projection(ref proj) => proj,
2211-
};
2212-
if proj.elem == ProjectionElem::Deref
2213-
&& place.ty(self.mir, self.tcx).to_ty(self.tcx).is_box()
2214-
{
2215-
deepest = &proj.base;
2216-
}
2217-
cursor = &proj.base;
2218-
}
2219-
}
2220-
}
2221-
22222180
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
22232181
struct Context {
22242182
kind: ContextKind,
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,14 @@
1-
error[E0382]: use of moved value: `a.y`
2-
--> $DIR/borrowck-box-insensitivity.rs:46:14
3-
|
4-
LL | let _x = a.x;
5-
| --- value moved here
6-
LL | //~^ value moved here
7-
LL | let _y = a.y; //~ ERROR use of moved
8-
| ^^^ value used here after move
9-
|
10-
= note: move occurs because `a.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
11-
12-
error[E0382]: use of moved value: `a.y`
13-
--> $DIR/borrowck-box-insensitivity.rs:108:14
14-
|
15-
LL | let _x = a.x.x;
16-
| ----- value moved here
17-
LL | //~^ value moved here
18-
LL | let _y = a.y; //~ ERROR use of collaterally moved
19-
| ^^^ value used here after move
20-
|
21-
= note: move occurs because `a.x.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
1+
error: compilation successful
2+
--> $DIR/borrowck-box-insensitivity.rs:160:1
3+
|
4+
LL | / fn main() {
5+
LL | | copy_after_move();
6+
LL | | move_after_move();
7+
LL | | borrow_after_move();
8+
... |
9+
LL | | mut_borrow_after_borrow_nested();
10+
LL | | }
11+
| |_^
2212

23-
error: aborting due to 2 previous errors
13+
error: aborting due to previous error
2414

25-
For more information about this error, try `rustc --explain E0382`.

src/test/ui/borrowck/borrowck-box-insensitivity.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#![feature(box_syntax)]
11+
#![feature(box_syntax, rustc_attrs)]
1212

1313
struct A {
1414
x: Box<isize>,
@@ -156,6 +156,7 @@ fn mut_borrow_after_borrow_nested() {
156156
//~^ mutable borrow occurs here
157157
}
158158

159+
#[rustc_error]
159160
fn main() {
160161
copy_after_move();
161162
move_after_move();

0 commit comments

Comments
 (0)