Skip to content

Commit ef236e4

Browse files
committed
Disable certain code on nll runs, update constraint generation to fix bugs, and update tests based on feedback
1 parent e966e8c commit ef236e4

File tree

5 files changed

+63
-99
lines changed

5 files changed

+63
-99
lines changed

src/librustc_mir/borrow_check/mod.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,13 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
8181
// contain non-lexical lifetimes. It will have a lifetime tied
8282
// to the inference context.
8383
let mut mir: Mir<'tcx> = input_mir.clone();
84-
let free_regions = {
84+
let free_regions = if !tcx.sess.opts.debugging_opts.nll {
85+
None
86+
} else {
8587
let mir = &mut mir;
8688

8789
// Replace all regions with fresh inference variables.
88-
nll::replace_regions_in_mir(infcx, src, mir)
90+
Some(nll::replace_regions_in_mir(infcx, src, mir))
8991
};
9092
let mir = &mir;
9193

@@ -119,7 +121,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
119121

120122
let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env };
121123
let dead_unwinds = IdxSetBuf::new_empty(mir.basic_blocks().len());
122-
let flow_inits = FlowInProgress::new(do_dataflow(tcx, mir, id, &attributes, &dead_unwinds,
124+
let mut flow_inits = FlowInProgress::new(do_dataflow(tcx, mir, id, &attributes, &dead_unwinds,
123125
MaybeInitializedLvals::new(tcx, mir, &mdpe),
124126
|bd, i| &bd.move_data().move_paths[i]));
125127
let flow_uninits = FlowInProgress::new(do_dataflow(tcx, mir, id, &attributes, &dead_unwinds,
@@ -133,13 +135,14 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
133135
Some(nll::compute_regions(
134136
infcx,
135137
src,
136-
&free_regions,
138+
&free_regions.unwrap(),
137139
mir,
138140
param_env,
139-
&flow_inits,
141+
&mut flow_inits,
140142
&mdpe.move_data
141143
))
142144
};
145+
let flow_inits = flow_inits; // remove mut
143146

144147
let mut mbcx = MirBorrowckCtxt {
145148
tcx: tcx,

src/librustc_mir/borrow_check/nll/constraint_generation.rs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc::mir::{Location, Lvalue, Mir, Rvalue};
1313
use rustc::mir::transform::MirSource;
1414
use rustc::mir::visit::Visitor;
1515
use rustc::mir::Lvalue::Projection;
16-
use rustc::mir::{LvalueProjection, ProjectionElem};
16+
use rustc::mir::{LvalueProjection, ProjectionElem, Local};
1717
use rustc::infer::InferCtxt;
1818
use rustc::traits::{self, ObligationCause};
1919
use rustc::ty::{self, Ty};
@@ -35,7 +35,7 @@ pub(super) fn generate_constraints<'cx, 'gcx, 'tcx>(
3535
mir: &Mir<'tcx>,
3636
mir_source: MirSource,
3737
liveness: &LivenessResults,
38-
flow_inits: &FlowInProgress<MaybeInitializedLvals<'cx, 'gcx, 'tcx>>,
38+
flow_inits: &mut FlowInProgress<MaybeInitializedLvals<'cx, 'gcx, 'tcx>>,
3939
move_data: &MoveData<'tcx>,
4040
) {
4141
ConstraintGeneration {
@@ -56,7 +56,7 @@ struct ConstraintGeneration<'cg, 'cx: 'cg, 'gcx: 'tcx, 'tcx: 'cx> {
5656
mir: &'cg Mir<'tcx>,
5757
liveness: &'cg LivenessResults,
5858
mir_source: MirSource,
59-
flow_inits: &'cg FlowInProgress<MaybeInitializedLvals<'cx, 'gcx, 'tcx>>,
59+
flow_inits: &'cg mut FlowInProgress<MaybeInitializedLvals<'cx, 'gcx, 'tcx>>,
6060
move_data: &'cg MoveData<'tcx>,
6161
}
6262

@@ -84,19 +84,27 @@ impl<'cx, 'cg, 'gcx, 'tcx> ConstraintGeneration<'cx, 'cg, 'gcx, 'tcx> {
8484
}
8585
});
8686

87-
self.liveness.drop.simulate_block(
88-
self.mir,
89-
bb,
90-
|location, live_locals| {
91-
for live_local in live_locals.iter() {
92-
let mpi = self.move_data.rev_lookup.find_local(live_local);
93-
if self.flow_inits.has_any_child_of(mpi).is_some() {
94-
let live_local_ty = self.mir.local_decls[live_local].ty;
95-
self.add_drop_live_constraint(live_local_ty, location);
96-
}
87+
let mut all_live_locals: Vec<(Location, Vec<Local>)> = vec![];
88+
self.liveness.drop.simulate_block(self.mir, bb, |location, live_locals| {
89+
all_live_locals.push((location, live_locals.iter().collect()));
90+
});
91+
92+
self.flow_inits.reset_to_entry_of(bb);
93+
for index in 0 .. self.mir.basic_blocks()[bb].statements.len() {
94+
let location = Location { block: bb, statement_index: index };
95+
let (location2, live_locals) = all_live_locals.pop().unwrap();
96+
assert_eq!(location, location2);
97+
98+
for live_local in live_locals {
99+
let mpi = self.move_data.rev_lookup.find_local(live_local);
100+
if self.flow_inits.has_any_child_of(mpi).is_some() {
101+
let live_local_ty = self.mir.local_decls[live_local].ty;
102+
self.add_drop_live_constraint(live_local_ty, location);
97103
}
98-
},
99-
);
104+
}
105+
106+
self.flow_inits.reconstruct_statement_effect(location);
107+
}
100108
}
101109
}
102110

src/librustc_mir/borrow_check/nll/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ mod renumber;
3737
/// scraping out the set of free regions (e.g., region parameters)
3838
/// declared on the function. That set will need to be given to
3939
/// `compute_regions`.
40-
pub(super) fn replace_regions_in_mir<'a, 'gcx, 'tcx>(
41-
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
40+
pub(super) fn replace_regions_in_mir<'cx, 'gcx, 'tcx>(
41+
infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
4242
source: MirSource,
4343
mir: &mut Mir<'tcx>
4444
) -> FreeRegions<'tcx> {
@@ -54,13 +54,13 @@ pub(super) fn replace_regions_in_mir<'a, 'gcx, 'tcx>(
5454
/// Computes the (non-lexical) regions from the input MIR.
5555
///
5656
/// This may result in errors being reported.
57-
pub(super) fn compute_regions<'a, 'gcx, 'tcx>(
58-
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
57+
pub(super) fn compute_regions<'cx, 'gcx, 'tcx>(
58+
infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
5959
source: MirSource,
6060
free_regions: &FreeRegions<'tcx>,
6161
mir: &Mir<'tcx>,
6262
param_env: ty::ParamEnv<'gcx>,
63-
flow_inits: &FlowInProgress<MaybeInitializedLvals<'a, 'gcx, 'tcx>>,
63+
flow_inits: &mut FlowInProgress<MaybeInitializedLvals<'cx, 'gcx, 'tcx>>,
6464
move_data: &MoveData<'tcx>,
6565
) -> RegionInferenceContext<'tcx> {
6666
// Run the MIR type-checker.

src/test/ui/nll/maybe-initialized-drop.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
10-
// revisions: mir
11-
//[mir]compile-flags: -Z emit-end-regions -Z borrowck-mir
10+
11+
//compile-flags: -Z emit-end-regions -Z borrowck-mir -Z nll
1212

1313
struct Wrap<'p> { p: &'p mut i32 }
1414

@@ -43,6 +43,7 @@ fn baz_a() {
4343
let s = String::from("str");
4444
let foo = Foo { a: s, b: wrap };
4545
move_string(foo.a);
46+
x += 1; //~ ERROR because of Foo.b's Wrap dtor
4647
}
4748

4849
fn baz_a_b() {
@@ -52,6 +53,7 @@ fn baz_a_b() {
5253
let foo = Foo { a: s, b: wrap };
5354
move_string(foo.a);
5455
move_wrap(foo.b);
56+
x += 1; // OK, drops are inert
5557
}
5658

5759
fn baz_b() {
@@ -60,6 +62,8 @@ fn baz_b() {
6062
let s = String::from("str");
6163
let foo = Foo { a: s, b: wrap };
6264
move_wrap(foo.b);
65+
x += 1; //~ ERROR because of Foo.a's implicit dtor
66+
// FIXME ^ Should not error in the future with implicit dtors, only manually implemented ones
6367
}
6468

6569
fn main() { }
Lines changed: 21 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,46 @@
11
error[E0506]: cannot assign to `x` because it is borrowed (Ast)
2-
--> /home/paulf/rust/src/test/ui/nll/maybe-initialized-drop.rs:24:5
2+
--> $DIR/maybe-initialized-drop.rs:24:5
33
|
44
23 | let wrap = Wrap { p: &mut x };
55
| - borrow of `x` occurs here
66
24 | x += 1; //~ ERROR because of dtor
77
| ^^^^^^ assignment to borrowed `x` occurs here
88

99
error[E0506]: cannot assign to `x` because it is borrowed (Ast)
10-
--> /home/paulf/rust/src/test/ui/nll/maybe-initialized-drop.rs:31:5
10+
--> $DIR/maybe-initialized-drop.rs:31:5
1111
|
1212
29 | let wrap = Wrap { p: &mut x };
1313
| - borrow of `x` occurs here
1414
30 | std::mem::drop(wrap);
1515
31 | x += 1; // OK, drop is inert
1616
| ^^^^^^ assignment to borrowed `x` occurs here
1717

18-
error[E0506]: cannot assign to `x` because it is borrowed (Mir)
19-
--> /home/paulf/rust/src/test/ui/nll/maybe-initialized-drop.rs:24:5
20-
|
21-
23 | let wrap = Wrap { p: &mut x };
22-
| ------ borrow of `x` occurs here
23-
24 | x += 1; //~ ERROR because of dtor
24-
| ^^^^^^ assignment to borrowed `x` occurs here
25-
26-
error[E0503]: cannot use `x` because it was mutably borrowed (Mir)
27-
--> /home/paulf/rust/src/test/ui/nll/maybe-initialized-drop.rs:24:5
28-
|
29-
23 | let wrap = Wrap { p: &mut x };
30-
| ------ borrow of `x` occurs here
31-
24 | x += 1; //~ ERROR because of dtor
32-
| ^^^^^^ use of borrowed `x`
33-
34-
error[E0506]: cannot assign to `x` because it is borrowed (Mir)
35-
--> /home/paulf/rust/src/test/ui/nll/maybe-initialized-drop.rs:25:2
36-
|
37-
23 | let wrap = Wrap { p: &mut x };
38-
| ------ borrow of `x` occurs here
39-
24 | x += 1; //~ ERROR because of dtor
40-
25 | }
41-
| ^ assignment to borrowed `x` occurs here
42-
43-
error[E0506]: cannot assign to `x` because it is borrowed (Mir)
44-
--> /home/paulf/rust/src/test/ui/nll/maybe-initialized-drop.rs:31:5
45-
|
46-
29 | let wrap = Wrap { p: &mut x };
47-
| ------ borrow of `x` occurs here
48-
30 | std::mem::drop(wrap);
49-
31 | x += 1; // OK, drop is inert
50-
| ^^^^^^ assignment to borrowed `x` occurs here
51-
52-
error[E0503]: cannot use `x` because it was mutably borrowed (Mir)
53-
--> /home/paulf/rust/src/test/ui/nll/maybe-initialized-drop.rs:31:5
54-
|
55-
29 | let wrap = Wrap { p: &mut x };
56-
| ------ borrow of `x` occurs here
57-
30 | std::mem::drop(wrap);
58-
31 | x += 1; // OK, drop is inert
59-
| ^^^^^^ use of borrowed `x`
60-
61-
error[E0506]: cannot assign to `x` because it is borrowed (Mir)
62-
--> /home/paulf/rust/src/test/ui/nll/maybe-initialized-drop.rs:32:2
63-
|
64-
29 | let wrap = Wrap { p: &mut x };
65-
| ------ borrow of `x` occurs here
66-
...
67-
32 | }
68-
| ^ assignment to borrowed `x` occurs here
69-
70-
error[E0506]: cannot assign to `x` because it is borrowed (Mir)
71-
--> /home/paulf/rust/src/test/ui/nll/maybe-initialized-drop.rs:46:2
18+
error[E0506]: cannot assign to `x` because it is borrowed (Ast)
19+
--> $DIR/maybe-initialized-drop.rs:46:5
7220
|
7321
42 | let wrap = Wrap { p: &mut x };
74-
| ------ borrow of `x` occurs here
22+
| - borrow of `x` occurs here
7523
...
76-
46 | }
77-
| ^ assignment to borrowed `x` occurs here
24+
46 | x += 1; //~ ERROR because of Foo.b's Wrap dtor
25+
| ^^^^^^ assignment to borrowed `x` occurs here
7826

79-
error[E0506]: cannot assign to `x` because it is borrowed (Mir)
80-
--> /home/paulf/rust/src/test/ui/nll/maybe-initialized-drop.rs:55:2
27+
error[E0506]: cannot assign to `x` because it is borrowed (Ast)
28+
--> $DIR/maybe-initialized-drop.rs:56:5
8129
|
82-
50 | let wrap = Wrap { p: &mut x };
83-
| ------ borrow of `x` occurs here
30+
51 | let wrap = Wrap { p: &mut x };
31+
| - borrow of `x` occurs here
8432
...
85-
55 | }
86-
| ^ assignment to borrowed `x` occurs here
33+
56 | x += 1; // OK, drops are inert
34+
| ^^^^^^ assignment to borrowed `x` occurs here
8735

88-
error[E0506]: cannot assign to `x` because it is borrowed (Mir)
89-
--> /home/paulf/rust/src/test/ui/nll/maybe-initialized-drop.rs:63:2
36+
error[E0506]: cannot assign to `x` because it is borrowed (Ast)
37+
--> $DIR/maybe-initialized-drop.rs:65:5
9038
|
91-
59 | let wrap = Wrap { p: &mut x };
92-
| ------ borrow of `x` occurs here
39+
61 | let wrap = Wrap { p: &mut x };
40+
| - borrow of `x` occurs here
9341
...
94-
63 | }
95-
| ^ assignment to borrowed `x` occurs here
42+
65 | x += 1; //~ ERROR because of Foo.a's implicit dtor
43+
| ^^^^^^ assignment to borrowed `x` occurs here
44+
45+
error: aborting due to 5 previous errors
9646

97-
error: aborting due to 11 previous errors

0 commit comments

Comments
 (0)