Skip to content

Commit 93c4ffe

Browse files
committed
Revised graphviz rendering API to avoid requiring borrowed state.
Made `do_dataflow` and related API `pub(crate)`.
1 parent 691f022 commit 93c4ffe

File tree

6 files changed

+60
-41
lines changed

6 files changed

+60
-41
lines changed

src/librustc_mir/borrow_check/mod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use rustc_data_structures::indexed_vec::Idx;
2828
use syntax::ast;
2929
use syntax_pos::Span;
3030

31-
use dataflow::do_dataflow;
31+
use dataflow::{do_dataflow, DebugFormatted};
3232
use dataflow::MoveDataParamEnv;
3333
use dataflow::DataflowResultsConsumer;
3434
use dataflow::{FlowAtLocation, FlowsAtLocation};
@@ -157,7 +157,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
157157
&attributes,
158158
&dead_unwinds,
159159
MaybeInitializedLvals::new(tcx, mir, &mdpe),
160-
|bd, i| &bd.move_data().move_paths[i],
160+
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
161161
));
162162
let flow_uninits = FlowAtLocation::new(do_dataflow(
163163
tcx,
@@ -166,7 +166,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
166166
&attributes,
167167
&dead_unwinds,
168168
MaybeUninitializedLvals::new(tcx, mir, &mdpe),
169-
|bd, i| &bd.move_data().move_paths[i],
169+
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
170170
));
171171
let flow_move_outs = FlowAtLocation::new(do_dataflow(
172172
tcx,
@@ -175,7 +175,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
175175
&attributes,
176176
&dead_unwinds,
177177
MovingOutStatements::new(tcx, mir, &mdpe),
178-
|bd, i| &bd.move_data().moves[i],
178+
|bd, i| DebugFormatted::new(&bd.move_data().moves[i]),
179179
));
180180
let flow_ever_inits = FlowAtLocation::new(do_dataflow(
181181
tcx,
@@ -184,7 +184,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
184184
&attributes,
185185
&dead_unwinds,
186186
EverInitializedLvals::new(tcx, mir, &mdpe),
187-
|bd, i| &bd.move_data().inits[i],
187+
|bd, i| DebugFormatted::new(&bd.move_data().inits[i]),
188188
));
189189

190190
// If we are in non-lexical mode, compute the non-lexical lifetimes.
@@ -212,7 +212,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
212212
&attributes,
213213
&dead_unwinds,
214214
Borrows::new(tcx, mir, opt_regioncx, def_id, body_id),
215-
|bd, i| bd.location(i),
215+
|bd, i| DebugFormatted::new(bd.location(i)),
216216
));
217217

218218
let mut state = Flows::new(

src/librustc_mir/dataflow/graphviz.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use rustc_data_structures::indexed_vec::Idx;
1818
use dot;
1919
use dot::IntoCow;
2020

21-
use std::fmt::Debug;
2221
use std::fs::File;
2322
use std::io;
2423
use std::io::prelude::*;
@@ -29,6 +28,7 @@ use util;
2928

3029
use super::{BitDenotation, DataflowState};
3130
use super::DataflowBuilder;
31+
use super::DebugFormatted;
3232

3333
pub trait MirWithFlowState<'tcx> {
3434
type BD: BitDenotation;
@@ -60,9 +60,9 @@ pub(crate) fn print_borrowck_graph_to<'a, 'tcx, BD, P>(
6060
render_idx: P)
6161
-> io::Result<()>
6262
where BD: BitDenotation,
63-
P: Fn(&BD, BD::Idx) -> &Debug
63+
P: Fn(&BD, BD::Idx) -> DebugFormatted
6464
{
65-
let g = Graph { mbcx: mbcx, phantom: PhantomData, render_idx: render_idx };
65+
let g = Graph { mbcx, phantom: PhantomData, render_idx };
6666
let mut v = Vec::new();
6767
dot::render(&g, &mut v)?;
6868
debug!("print_borrowck_graph_to path: {} node_id: {}",
@@ -82,7 +82,7 @@ fn outgoing(mir: &Mir, bb: BasicBlock) -> Vec<Edge> {
8282

8383
impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P>
8484
where MWF: MirWithFlowState<'tcx>,
85-
P: for <'b> Fn(&'b MWF::BD, <MWF::BD as BitDenotation>::Idx) -> &'b Debug,
85+
P: Fn(&MWF::BD, <MWF::BD as BitDenotation>::Idx) -> DebugFormatted,
8686
{
8787
type Node = Node;
8888
type Edge = Edge;
@@ -142,7 +142,7 @@ impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P>
142142
const ALIGN_RIGHT: &'static str = r#"align="right""#;
143143
const FACE_MONOSPACE: &'static str = r#"FACE="Courier""#;
144144
fn chunked_present_left<W:io::Write>(w: &mut W,
145-
interpreted: &[&Debug],
145+
interpreted: &[DebugFormatted],
146146
chunk_size: usize)
147147
-> io::Result<()>
148148
{

src/librustc_mir/dataflow/mod.rs

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc::mir::{self, Mir, BasicBlock, BasicBlockData, Location, Statement, Ter
1919
use rustc::session::Session;
2020

2121
use std::borrow::Borrow;
22-
use std::fmt::{self, Debug};
22+
use std::fmt;
2323
use std::io;
2424
use std::mem;
2525
use std::path::PathBuf;
@@ -51,10 +51,29 @@ pub(crate) struct DataflowBuilder<'a, 'tcx: 'a, BD> where BD: BitDenotation
5151
print_postflow_to: Option<String>,
5252
}
5353

54-
pub trait Dataflow<BD: BitDenotation> {
54+
/// `DebugFormatted` encapsulates the "{:?}" rendering of some
55+
/// arbitrary value. This way: you pay cost of allocating an extra
56+
/// string (as well as that of rendering up-front); in exchange, you
57+
/// don't have to hand over ownership of your value or deal with
58+
/// borrowing it.
59+
pub(crate) struct DebugFormatted(String);
60+
61+
impl DebugFormatted {
62+
pub fn new(input: &fmt::Debug) -> DebugFormatted {
63+
DebugFormatted(format!("{:?}", input))
64+
}
65+
}
66+
67+
impl fmt::Debug for DebugFormatted {
68+
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
69+
write!(w, "{}", self.0)
70+
}
71+
}
72+
73+
pub(crate) trait Dataflow<BD: BitDenotation> {
5574
/// Sets up and runs the dataflow problem, using `p` to render results if
5675
/// implementation so chooses.
57-
fn dataflow<P>(&mut self, p: P) where P: Fn(&BD, BD::Idx) -> &Debug {
76+
fn dataflow<P>(&mut self, p: P) where P: Fn(&BD, BD::Idx) -> DebugFormatted {
5877
let _ = p; // default implementation does not instrument process.
5978
self.build_sets();
6079
self.propagate();
@@ -69,7 +88,7 @@ pub trait Dataflow<BD: BitDenotation> {
6988

7089
impl<'a, 'tcx: 'a, BD> Dataflow<BD> for DataflowBuilder<'a, 'tcx, BD> where BD: BitDenotation
7190
{
72-
fn dataflow<P>(&mut self, p: P) where P: Fn(&BD, BD::Idx) -> &Debug {
91+
fn dataflow<P>(&mut self, p: P) where P: Fn(&BD, BD::Idx) -> DebugFormatted {
7392
self.flow_state.build_sets();
7493
self.pre_dataflow_instrumentation(|c,i| p(c,i)).unwrap();
7594
self.flow_state.propagate();
@@ -109,7 +128,7 @@ pub(crate) fn do_dataflow<'a, 'gcx, 'tcx, BD, P>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
109128
p: P)
110129
-> DataflowResults<BD>
111130
where BD: BitDenotation,
112-
P: Fn(&BD, BD::Idx) -> &fmt::Debug
131+
P: Fn(&BD, BD::Idx) -> DebugFormatted
113132
{
114133
let name_found = |sess: &Session, attrs: &[ast::Attribute], name| -> Option<String> {
115134
if let Some(item) = has_rustc_mir_with(attrs, name) {
@@ -231,7 +250,7 @@ fn dataflow_path(context: &str, prepost: &str, path: &str) -> PathBuf {
231250
impl<'a, 'tcx: 'a, BD> DataflowBuilder<'a, 'tcx, BD> where BD: BitDenotation
232251
{
233252
fn pre_dataflow_instrumentation<P>(&self, p: P) -> io::Result<()>
234-
where P: Fn(&BD, BD::Idx) -> &Debug
253+
where P: Fn(&BD, BD::Idx) -> DebugFormatted
235254
{
236255
if let Some(ref path_str) = self.print_preflow_to {
237256
let path = dataflow_path(BD::name(), "preflow", path_str);
@@ -242,7 +261,7 @@ impl<'a, 'tcx: 'a, BD> DataflowBuilder<'a, 'tcx, BD> where BD: BitDenotation
242261
}
243262

244263
fn post_dataflow_instrumentation<P>(&self, p: P) -> io::Result<()>
245-
where P: Fn(&BD, BD::Idx) -> &Debug
264+
where P: Fn(&BD, BD::Idx) -> DebugFormatted
246265
{
247266
if let Some(ref path_str) = self.print_postflow_to {
248267
let path = dataflow_path(BD::name(), "postflow", path_str);
@@ -403,12 +422,12 @@ impl<O: BitDenotation> DataflowState<O> {
403422
words.each_bit(bits_per_block, f)
404423
}
405424

406-
pub fn interpret_set<'c, P>(&self,
407-
o: &'c O,
408-
words: &IdxSet<O::Idx>,
409-
render_idx: &P)
410-
-> Vec<&'c Debug>
411-
where P: Fn(&O, O::Idx) -> &Debug
425+
pub(crate) fn interpret_set<'c, P>(&self,
426+
o: &'c O,
427+
words: &IdxSet<O::Idx>,
428+
render_idx: &P)
429+
-> Vec<DebugFormatted>
430+
where P: Fn(&O, O::Idx) -> DebugFormatted
412431
{
413432
let mut v = Vec::new();
414433
self.each_bit(words, |i| {

src/librustc_mir/transform/elaborate_drops.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use dataflow::{DataflowResults};
1414
use dataflow::{on_all_children_bits, on_all_drop_children_bits};
1515
use dataflow::{drop_flag_effects_for_location, on_lookup_result_bits};
1616
use dataflow::MoveDataParamEnv;
17-
use dataflow;
17+
use dataflow::{self, do_dataflow, DebugFormatted};
1818
use rustc::hir;
1919
use rustc::ty::{self, TyCtxt};
2020
use rustc::mir::*;
@@ -59,13 +59,13 @@ impl MirPass for ElaborateDrops {
5959
};
6060
let dead_unwinds = find_dead_unwinds(tcx, mir, id, &env);
6161
let flow_inits =
62-
dataflow::do_dataflow(tcx, mir, id, &[], &dead_unwinds,
63-
MaybeInitializedLvals::new(tcx, mir, &env),
64-
|bd, p| &bd.move_data().move_paths[p]);
62+
do_dataflow(tcx, mir, id, &[], &dead_unwinds,
63+
MaybeInitializedLvals::new(tcx, mir, &env),
64+
|bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]));
6565
let flow_uninits =
66-
dataflow::do_dataflow(tcx, mir, id, &[], &dead_unwinds,
67-
MaybeUninitializedLvals::new(tcx, mir, &env),
68-
|bd, p| &bd.move_data().move_paths[p]);
66+
do_dataflow(tcx, mir, id, &[], &dead_unwinds,
67+
MaybeUninitializedLvals::new(tcx, mir, &env),
68+
|bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]));
6969

7070
ElaborateDropsCtxt {
7171
tcx,
@@ -96,9 +96,9 @@ fn find_dead_unwinds<'a, 'tcx>(
9696
// reach cleanup blocks, which can't have unwind edges themselves.
9797
let mut dead_unwinds = IdxSetBuf::new_empty(mir.basic_blocks().len());
9898
let flow_inits =
99-
dataflow::do_dataflow(tcx, mir, id, &[], &dead_unwinds,
100-
MaybeInitializedLvals::new(tcx, mir, &env),
101-
|bd, p| &bd.move_data().move_paths[p]);
99+
do_dataflow(tcx, mir, id, &[], &dead_unwinds,
100+
MaybeInitializedLvals::new(tcx, mir, &env),
101+
|bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]));
102102
for (bb, bb_data) in mir.basic_blocks().iter_enumerated() {
103103
let location = match bb_data.terminator().kind {
104104
TerminatorKind::Drop { ref location, unwind: Some(_), .. } |

src/librustc_mir/transform/generator.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ use std::mem;
7878
use transform::{MirPass, MirSource};
7979
use transform::simplify;
8080
use transform::no_landing_pads::no_landing_pads;
81-
use dataflow::{self, MaybeStorageLive, state_for_location};
81+
use dataflow::{do_dataflow, DebugFormatted, MaybeStorageLive, state_for_location};
8282

8383
pub struct StateTransform;
8484

@@ -341,8 +341,8 @@ fn locals_live_across_suspend_points<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
341341
let node_id = tcx.hir.as_local_node_id(source.def_id).unwrap();
342342
let analysis = MaybeStorageLive::new(mir);
343343
let storage_live =
344-
dataflow::do_dataflow(tcx, mir, node_id, &[], &dead_unwinds, analysis,
345-
|bd, p| &bd.mir().local_decls[p]);
344+
do_dataflow(tcx, mir, node_id, &[], &dead_unwinds, analysis,
345+
|bd, p| DebugFormatted::new(&bd.mir().local_decls[p]));
346346

347347
let mut ignored = StorageIgnored(IdxSetBuf::new_filled(mir.local_decls.len()));
348348
ignored.visit_mir(mir);

src/librustc_mir/transform/rustc_peek.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc_data_structures::indexed_set::IdxSetBuf;
1818
use rustc_data_structures::indexed_vec::Idx;
1919
use transform::{MirPass, MirSource};
2020

21-
use dataflow::do_dataflow;
21+
use dataflow::{do_dataflow, DebugFormatted};
2222
use dataflow::MoveDataParamEnv;
2323
use dataflow::BitDenotation;
2424
use dataflow::DataflowResults;
@@ -51,15 +51,15 @@ impl MirPass for SanityCheck {
5151
let flow_inits =
5252
do_dataflow(tcx, mir, id, &attributes, &dead_unwinds,
5353
MaybeInitializedLvals::new(tcx, mir, &mdpe),
54-
|bd, i| &bd.move_data().move_paths[i]);
54+
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]));
5555
let flow_uninits =
5656
do_dataflow(tcx, mir, id, &attributes, &dead_unwinds,
5757
MaybeUninitializedLvals::new(tcx, mir, &mdpe),
58-
|bd, i| &bd.move_data().move_paths[i]);
58+
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]));
5959
let flow_def_inits =
6060
do_dataflow(tcx, mir, id, &attributes, &dead_unwinds,
6161
DefinitelyInitializedLvals::new(tcx, mir, &mdpe),
62-
|bd, i| &bd.move_data().move_paths[i]);
62+
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]));
6363

6464
if has_rustc_mir_with(&attributes, "rustc_peek_maybe_init").is_some() {
6565
sanity_check_via_rustc_peek(tcx, mir, id, &attributes, &flow_inits);

0 commit comments

Comments
 (0)