Skip to content

Commit a4c68c6

Browse files
committed
Auto merge of #42924 - pnkfelix:mir-dataflow, r=arielb1
Shift mir-dataflow from `rustc_borrowck` to `rustc_mir` crate. Shift mir-dataflow from `rustc_borrowck` to `rustc_mir` crate. Turn `elaborate_drops` and `rustc_peek` implementations into MIR passes that also live in `rustc_mir` crate. Rewire things so `rustc_driver` uses the `ElaborateDrops` from `rustc_mir` crate. (This PR is another baby step for mir-borrowck; it is a piece of work that other people want to rebase their stuff on top of, namely developers who are doing other dataflow analyses on top of MIR.) I have deliberately architected this PR in an attempt to minimize the number of actual code changes. The majority of the diff should be little more than changes to mod and use declarations, as well as a few visibility promotions to pub(crate) when a declaration was moved downward in the module hierarchy. (I have no problem with other PR's that move declarations around to try to clean this up; my goal was to ensure that the diff here was as small as possible, to make the review nearly trivial.)
2 parents 5eef7c7 + 13cd022 commit a4c68c6

File tree

13 files changed

+178
-206
lines changed

13 files changed

+178
-206
lines changed

src/librustc_borrowck/borrowck/mod.rs

+9-18
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ pub use self::bckerr_code::*;
1818
pub use self::AliasableViolationKind::*;
1919
pub use self::MovedValueUseKind::*;
2020

21-
pub use self::mir::elaborate_drops::ElaborateDrops;
22-
2321
use self::InteriorKind::*;
2422

2523
use rustc::hir::map as hir_map;
@@ -55,8 +53,6 @@ pub mod gather_loans;
5553

5654
pub mod move_data;
5755

58-
mod mir;
59-
6056
#[derive(Clone, Copy)]
6157
pub struct LoanDataFlowOperator;
6258

@@ -100,26 +96,21 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) {
10096
}
10197

10298
let body_id = tcx.hir.body_owned_by(owner_id);
103-
let attributes = tcx.get_attrs(owner_def_id);
10499
let tables = tcx.typeck_tables_of(owner_def_id);
105100
let region_maps = tcx.region_maps(owner_def_id);
106101
let mut bccx = &mut BorrowckCtxt { tcx, tables, region_maps, owner_def_id };
107102

108103
let body = bccx.tcx.hir.body(body_id);
109104

110-
if bccx.tcx.has_attr(owner_def_id, "rustc_mir_borrowck") {
111-
mir::borrowck_mir(bccx, owner_id, &attributes);
112-
} else {
113-
// Eventually, borrowck will always read the MIR, but at the
114-
// moment we do not. So, for now, we always force MIR to be
115-
// constructed for a given fn, since this may result in errors
116-
// being reported and we want that to happen.
117-
//
118-
// Note that `mir_validated` is a "stealable" result; the
119-
// thief, `optimized_mir()`, forces borrowck, so we know that
120-
// is not yet stolen.
121-
tcx.mir_validated(owner_def_id).borrow();
122-
}
105+
// Eventually, borrowck will always read the MIR, but at the
106+
// moment we do not. So, for now, we always force MIR to be
107+
// constructed for a given fn, since this may result in errors
108+
// being reported and we want that to happen.
109+
//
110+
// Note that `mir_validated` is a "stealable" result; the
111+
// thief, `optimized_mir()`, forces borrowck, so we know that
112+
// is not yet stolen.
113+
tcx.mir_validated(owner_def_id).borrow();
123114

124115
let cfg = cfg::CFG::new(bccx.tcx, &body);
125116
let AnalysisData { all_loans,

src/librustc_borrowck/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#![feature(quote)]
2222
#![feature(rustc_diagnostic_macros)]
2323
#![feature(associated_consts)]
24-
#![feature(nonzero)]
2524

2625
#[macro_use] extern crate log;
2726
#[macro_use] extern crate syntax;
@@ -39,7 +38,7 @@ extern crate core; // for NonZero
3938

4039
pub use borrowck::check_crate;
4140
pub use borrowck::build_borrowck_dataflow_data_for_fn;
42-
pub use borrowck::{AnalysisData, BorrowckCtxt, ElaborateDrops};
41+
pub use borrowck::{AnalysisData, BorrowckCtxt};
4342

4443
// NB: This module needs to be declared first so diagnostics are
4544
// registered before they are used.

src/librustc_driver/driver.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
920920
// What we need to do constant evaluation.
921921
passes.push_pass(MIR_CONST, mir::transform::simplify::SimplifyCfg::new("initial"));
922922
passes.push_pass(MIR_CONST, mir::transform::type_check::TypeckMir);
923+
passes.push_pass(MIR_CONST, mir::transform::rustc_peek::SanityCheck);
923924

924925
// What we need to run borrowck etc.
925926
passes.push_pass(MIR_VALIDATED, mir::transform::qualify_consts::QualifyAndPromoteConstants);
@@ -934,7 +935,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
934935
// From here on out, regions are gone.
935936
passes.push_pass(MIR_OPTIMIZED, mir::transform::erase_regions::EraseRegions);
936937
passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::AddCallGuards);
937-
passes.push_pass(MIR_OPTIMIZED, borrowck::ElaborateDrops);
938+
passes.push_pass(MIR_OPTIMIZED, mir::transform::elaborate_drops::ElaborateDrops);
938939
passes.push_pass(MIR_OPTIMIZED, mir::transform::no_landing_pads::NoLandingPads);
939940
passes.push_pass(MIR_OPTIMIZED, mir::transform::simplify::SimplifyCfg::new("elaborate-drops"));
940941

src/librustc_borrowck/borrowck/mir/mod.rs src/librustc_mir/dataflow/drop_flag_effects.rs

+21-127
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2012-2017 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -8,33 +8,24 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use borrowck::BorrowckCtxt;
12-
1311
use syntax::ast::{self, MetaItem};
1412
use syntax_pos::DUMMY_SP;
1513

16-
use rustc::mir::{self, BasicBlock, BasicBlockData, Mir, Statement, Terminator, Location};
14+
15+
use rustc::mir::{self, Mir, BasicBlock, Location};
1716
use rustc::session::Session;
1817
use rustc::ty::{self, TyCtxt};
19-
use rustc_mir::util::elaborate_drops::DropFlagState;
20-
use rustc_data_structures::indexed_set::{IdxSet, IdxSetBuf};
21-
22-
mod abs_domain;
23-
pub mod elaborate_drops;
24-
mod dataflow;
25-
mod gather_moves;
26-
// mod graphviz;
27-
28-
use self::dataflow::{BitDenotation};
29-
use self::dataflow::{DataflowOperator};
30-
use self::dataflow::{Dataflow, DataflowAnalysis, DataflowResults};
31-
use self::dataflow::{MaybeInitializedLvals, MaybeUninitializedLvals};
32-
use self::dataflow::{DefinitelyInitializedLvals};
33-
use self::gather_moves::{HasMoveData, MoveData, MovePathIndex, LookupResult};
18+
use util::elaborate_drops::DropFlagState;
19+
use rustc_data_structures::indexed_set::{IdxSet};
3420

3521
use std::fmt;
3622

37-
fn has_rustc_mir_with(attrs: &[ast::Attribute], name: &str) -> Option<MetaItem> {
23+
use super::{Dataflow, DataflowBuilder, DataflowAnalysis};
24+
use super::{BitDenotation, DataflowOperator, DataflowResults};
25+
use super::indexes::MovePathIndex;
26+
use super::move_paths::{MoveData, LookupResult};
27+
28+
pub(crate) fn has_rustc_mir_with(attrs: &[ast::Attribute], name: &str) -> Option<MetaItem> {
3829
for attr in attrs {
3930
if attr.check_name("rustc_mir") {
4031
let items = attr.meta_item_list();
@@ -50,69 +41,11 @@ fn has_rustc_mir_with(attrs: &[ast::Attribute], name: &str) -> Option<MetaItem>
5041
}
5142

5243
pub struct MoveDataParamEnv<'tcx> {
53-
move_data: MoveData<'tcx>,
54-
param_env: ty::ParamEnv<'tcx>,
44+
pub(crate) move_data: MoveData<'tcx>,
45+
pub(crate) param_env: ty::ParamEnv<'tcx>,
5546
}
5647

57-
pub fn borrowck_mir(bcx: &mut BorrowckCtxt,
58-
id: ast::NodeId,
59-
attributes: &[ast::Attribute]) {
60-
let tcx = bcx.tcx;
61-
let def_id = tcx.hir.local_def_id(id);
62-
debug!("borrowck_mir({:?}) UNIMPLEMENTED", def_id);
63-
64-
// It is safe for us to borrow `mir_validated()`: `optimized_mir`
65-
// steals it, but it forces the `borrowck` query.
66-
let mir = &tcx.mir_validated(def_id).borrow();
67-
68-
let param_env = tcx.param_env(def_id);
69-
let move_data = MoveData::gather_moves(mir, tcx, param_env);
70-
let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env };
71-
let dead_unwinds = IdxSetBuf::new_empty(mir.basic_blocks().len());
72-
let flow_inits =
73-
do_dataflow(tcx, mir, id, attributes, &dead_unwinds,
74-
MaybeInitializedLvals::new(tcx, mir, &mdpe),
75-
|bd, i| &bd.move_data().move_paths[i]);
76-
let flow_uninits =
77-
do_dataflow(tcx, mir, id, attributes, &dead_unwinds,
78-
MaybeUninitializedLvals::new(tcx, mir, &mdpe),
79-
|bd, i| &bd.move_data().move_paths[i]);
80-
let flow_def_inits =
81-
do_dataflow(tcx, mir, id, attributes, &dead_unwinds,
82-
DefinitelyInitializedLvals::new(tcx, mir, &mdpe),
83-
|bd, i| &bd.move_data().move_paths[i]);
84-
85-
if has_rustc_mir_with(attributes, "rustc_peek_maybe_init").is_some() {
86-
dataflow::sanity_check_via_rustc_peek(bcx.tcx, mir, id, attributes, &flow_inits);
87-
}
88-
if has_rustc_mir_with(attributes, "rustc_peek_maybe_uninit").is_some() {
89-
dataflow::sanity_check_via_rustc_peek(bcx.tcx, mir, id, attributes, &flow_uninits);
90-
}
91-
if has_rustc_mir_with(attributes, "rustc_peek_definite_init").is_some() {
92-
dataflow::sanity_check_via_rustc_peek(bcx.tcx, mir, id, attributes, &flow_def_inits);
93-
}
94-
95-
if has_rustc_mir_with(attributes, "stop_after_dataflow").is_some() {
96-
bcx.tcx.sess.fatal("stop_after_dataflow ended compilation");
97-
}
98-
99-
let mut mbcx = MirBorrowckCtxt {
100-
bcx: bcx,
101-
mir: mir,
102-
node_id: id,
103-
move_data: &mdpe.move_data,
104-
flow_inits: flow_inits,
105-
flow_uninits: flow_uninits,
106-
};
107-
108-
for bb in mir.basic_blocks().indices() {
109-
mbcx.process_basic_block(bb);
110-
}
111-
112-
debug!("borrowck_mir done");
113-
}
114-
115-
fn do_dataflow<'a, 'tcx, BD, P>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
48+
pub(crate) fn do_dataflow<'a, 'tcx, BD, P>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
11649
mir: &Mir<'tcx>,
11750
node_id: ast::NodeId,
11851
attributes: &[ast::Attribute],
@@ -142,7 +75,7 @@ fn do_dataflow<'a, 'tcx, BD, P>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
14275
let print_postflow_to =
14376
name_found(tcx.sess, attributes, "borrowck_graphviz_postflow");
14477

145-
let mut mbcx = MirBorrowckCtxtPreDataflow {
78+
let mut mbcx = DataflowBuilder {
14679
node_id: node_id,
14780
print_preflow_to: print_preflow_to,
14881
print_postflow_to: print_postflow_to,
@@ -153,46 +86,7 @@ fn do_dataflow<'a, 'tcx, BD, P>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
15386
mbcx.flow_state.results()
15487
}
15588

156-
157-
pub struct MirBorrowckCtxtPreDataflow<'a, 'tcx: 'a, BD> where BD: BitDenotation
158-
{
159-
node_id: ast::NodeId,
160-
flow_state: DataflowAnalysis<'a, 'tcx, BD>,
161-
print_preflow_to: Option<String>,
162-
print_postflow_to: Option<String>,
163-
}
164-
165-
#[allow(dead_code)]
166-
pub struct MirBorrowckCtxt<'b, 'a: 'b, 'tcx: 'a> {
167-
bcx: &'b mut BorrowckCtxt<'a, 'tcx>,
168-
mir: &'b Mir<'tcx>,
169-
node_id: ast::NodeId,
170-
move_data: &'b MoveData<'tcx>,
171-
flow_inits: DataflowResults<MaybeInitializedLvals<'b, 'tcx>>,
172-
flow_uninits: DataflowResults<MaybeUninitializedLvals<'b, 'tcx>>
173-
}
174-
175-
impl<'b, 'a: 'b, 'tcx: 'a> MirBorrowckCtxt<'b, 'a, 'tcx> {
176-
fn process_basic_block(&mut self, bb: BasicBlock) {
177-
let BasicBlockData { ref statements, ref terminator, is_cleanup: _ } =
178-
self.mir[bb];
179-
for stmt in statements {
180-
self.process_statement(bb, stmt);
181-
}
182-
183-
self.process_terminator(bb, terminator);
184-
}
185-
186-
fn process_statement(&mut self, bb: BasicBlock, stmt: &Statement<'tcx>) {
187-
debug!("MirBorrowckCtxt::process_statement({:?}, {:?}", bb, stmt);
188-
}
189-
190-
fn process_terminator(&mut self, bb: BasicBlock, term: &Option<Terminator<'tcx>>) {
191-
debug!("MirBorrowckCtxt::process_terminator({:?}, {:?})", bb, term);
192-
}
193-
}
194-
195-
fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
89+
pub fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
19690
path: MovePathIndex,
19791
mut cond: F)
19892
-> Option<MovePathIndex>
@@ -253,7 +147,7 @@ fn lvalue_contents_drop_state_cannot_differ<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx
253147
}
254148
}
255149

256-
fn on_lookup_result_bits<'a, 'tcx, F>(
150+
pub(crate) fn on_lookup_result_bits<'a, 'tcx, F>(
257151
tcx: TyCtxt<'a, 'tcx, 'tcx>,
258152
mir: &Mir<'tcx>,
259153
move_data: &MoveData<'tcx>,
@@ -271,7 +165,7 @@ fn on_lookup_result_bits<'a, 'tcx, F>(
271165
}
272166
}
273167

274-
fn on_all_children_bits<'a, 'tcx, F>(
168+
pub(crate) fn on_all_children_bits<'a, 'tcx, F>(
275169
tcx: TyCtxt<'a, 'tcx, 'tcx>,
276170
mir: &Mir<'tcx>,
277171
move_data: &MoveData<'tcx>,
@@ -312,7 +206,7 @@ fn on_all_children_bits<'a, 'tcx, F>(
312206
on_all_children_bits(tcx, mir, move_data, move_path_index, &mut each_child);
313207
}
314208

315-
fn on_all_drop_children_bits<'a, 'tcx, F>(
209+
pub(crate) fn on_all_drop_children_bits<'a, 'tcx, F>(
316210
tcx: TyCtxt<'a, 'tcx, 'tcx>,
317211
mir: &Mir<'tcx>,
318212
ctxt: &MoveDataParamEnv<'tcx>,
@@ -333,7 +227,7 @@ fn on_all_drop_children_bits<'a, 'tcx, F>(
333227
})
334228
}
335229

336-
fn drop_flag_effects_for_function_entry<'a, 'tcx, F>(
230+
pub(crate) fn drop_flag_effects_for_function_entry<'a, 'tcx, F>(
337231
tcx: TyCtxt<'a, 'tcx, 'tcx>,
338232
mir: &Mir<'tcx>,
339233
ctxt: &MoveDataParamEnv<'tcx>,
@@ -350,7 +244,7 @@ fn drop_flag_effects_for_function_entry<'a, 'tcx, F>(
350244
}
351245
}
352246

353-
fn drop_flag_effects_for_location<'a, 'tcx, F>(
247+
pub(crate) fn drop_flag_effects_for_location<'a, 'tcx, F>(
354248
tcx: TyCtxt<'a, 'tcx, 'tcx>,
355249
mir: &Mir<'tcx>,
356250
ctxt: &MoveDataParamEnv<'tcx>,

src/librustc_borrowck/borrowck/mir/dataflow/graphviz.rs src/librustc_mir/dataflow/graphviz.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use rustc::mir::{BasicBlock, Mir};
1515
use rustc_data_structures::bitslice::bits_to_string;
1616
use rustc_data_structures::indexed_set::{IdxSet};
1717
use rustc_data_structures::indexed_vec::Idx;
18-
use rustc_mir::util as mir_util;
1918

2019
use dot;
2120
use dot::IntoCow;
@@ -28,8 +27,10 @@ use std::marker::PhantomData;
2827
use std::mem;
2928
use std::path::Path;
3029

31-
use super::super::MirBorrowckCtxtPreDataflow;
30+
use util;
31+
3232
use super::{BitDenotation, DataflowState};
33+
use super::DataflowBuilder;
3334

3435
impl<O: BitDenotation> DataflowState<O> {
3536
fn each_bit<F>(&self, words: &IdxSet<O::Idx>, mut f: F)
@@ -86,7 +87,7 @@ pub trait MirWithFlowState<'tcx> {
8687
fn flow_state(&self) -> &DataflowState<Self::BD>;
8788
}
8889

89-
impl<'a, 'tcx: 'a, BD> MirWithFlowState<'tcx> for MirBorrowckCtxtPreDataflow<'a, 'tcx, BD>
90+
impl<'a, 'tcx: 'a, BD> MirWithFlowState<'tcx> for DataflowBuilder<'a, 'tcx, BD>
9091
where 'tcx: 'a, BD: BitDenotation
9192
{
9293
type BD = BD;
@@ -103,8 +104,8 @@ struct Graph<'a, 'tcx, MWF:'a, P> where
103104
render_idx: P,
104105
}
105106

106-
pub fn print_borrowck_graph_to<'a, 'tcx, BD, P>(
107-
mbcx: &MirBorrowckCtxtPreDataflow<'a, 'tcx, BD>,
107+
pub(crate) fn print_borrowck_graph_to<'a, 'tcx, BD, P>(
108+
mbcx: &DataflowBuilder<'a, 'tcx, BD>,
108109
path: &Path,
109110
render_idx: P)
110111
-> io::Result<()>
@@ -220,7 +221,7 @@ impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P>
220221
}
221222
Ok(())
222223
}
223-
mir_util::write_graphviz_node_label(
224+
util::write_graphviz_node_label(
224225
*n, self.mbcx.mir(), &mut v, 4,
225226
|w| {
226227
let flow = self.mbcx.flow_state();

0 commit comments

Comments
 (0)