Skip to content

Commit ede2958

Browse files
committed
mir::dataflow::sanity_check: extract an fn each_block to simplify presentation.
As a drive-by: unified pair of match arms that flowed to `bug!`, and replaced `bug!` invocation with a diagnostic `span_err` invocation.
1 parent b8c6d1c commit ede2958

File tree

1 file changed

+86
-76
lines changed

1 file changed

+86
-76
lines changed

src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs

Lines changed: 86 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -51,92 +51,102 @@ pub fn sanity_check_via_rustc_peek<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
5151

5252
let blocks = mir.all_basic_blocks();
5353
'next_block: for bb in blocks {
54-
let bb_data = mir.basic_block_data(bb);
55-
let &repr::BasicBlockData { ref statements,
56-
ref terminator,
57-
is_cleanup: _ } = bb_data;
58-
59-
let (args, span) = match is_rustc_peek(tcx, terminator) {
60-
Some(args_and_span) => args_and_span,
61-
None => continue,
62-
};
63-
assert!(args.len() == 1);
64-
let peek_arg_lval = match args[0] {
65-
repr::Operand::Consume(ref lval @ repr::Lvalue::Temp(_)) => {
66-
lval
67-
}
68-
repr::Operand::Consume(_) => {
69-
bug!("dataflow::sanity_check cannot feed a non-temp to rustc_peek.");
70-
}
71-
repr::Operand::Constant(_) => {
72-
bug!("dataflow::sanity_check cannot feed a constant to rustc_peek.");
73-
}
74-
};
54+
each_block(tcx, mir, flow_ctxt, results, bb);
55+
}
56+
}
7557

76-
let mut entry = results.0.sets.on_entry_set_for(bb.index()).to_owned();
77-
let mut gen = results.0.sets.gen_set_for(bb.index()).to_owned();
78-
let mut kill = results.0.sets.kill_set_for(bb.index()).to_owned();
58+
fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
59+
mir: &Mir<'tcx>,
60+
flow_ctxt: &O::Ctxt,
61+
results: &DataflowResults<O>,
62+
bb: repr::BasicBlock) where
63+
O: BitDenotation<Bit=MovePath<'tcx>, Idx=MovePathIndex>, O::Ctxt: HasMoveData<'tcx>
64+
{
65+
let bb_data = mir.basic_block_data(bb);
66+
let &repr::BasicBlockData { ref statements,
67+
ref terminator,
68+
is_cleanup: _ } = bb_data;
69+
70+
let (args, span) = match is_rustc_peek(tcx, terminator) {
71+
Some(args_and_span) => args_and_span,
72+
None => return,
73+
};
74+
assert!(args.len() == 1);
75+
let peek_arg_lval = match args[0] {
76+
repr::Operand::Consume(ref lval @ repr::Lvalue::Temp(_)) => {
77+
lval
78+
}
79+
repr::Operand::Consume(_) |
80+
repr::Operand::Constant(_) => {
81+
tcx.sess.diagnostic().span_err(
82+
span, "dataflow::sanity_check cannot feed a non-temp to rustc_peek.");
83+
return;
84+
}
85+
};
7986

80-
let move_data = flow_ctxt.move_data();
87+
let mut entry = results.0.sets.on_entry_set_for(bb.index()).to_owned();
88+
let mut gen = results.0.sets.gen_set_for(bb.index()).to_owned();
89+
let mut kill = results.0.sets.kill_set_for(bb.index()).to_owned();
8190

82-
// Emulate effect of all statements in the block up to (but
83-
// not including) the borrow within `peek_arg_lval`. Do *not*
84-
// include call to `peek_arg_lval` itself (since we are
85-
// peeking the state of the argument at time immediate
86-
// preceding Call to `rustc_peek`).
91+
let move_data = flow_ctxt.move_data();
8792

88-
let mut sets = super::BlockSets { on_entry: &mut entry,
89-
gen_set: &mut gen,
90-
kill_set: &mut kill };
93+
// Emulate effect of all statements in the block up to (but not
94+
// including) the borrow within `peek_arg_lval`. Do *not* include
95+
// call to `peek_arg_lval` itself (since we are peeking the state
96+
// of the argument at time immediate preceding Call to
97+
// `rustc_peek`).
9198

92-
for (j, stmt) in statements.iter().enumerate() {
93-
debug!("rustc_peek: ({:?},{}) {:?}", bb, j, stmt);
94-
let (lvalue, rvalue) = match stmt.kind {
95-
repr::StatementKind::Assign(ref lvalue, ref rvalue) => {
96-
(lvalue, rvalue)
97-
}
98-
};
99-
100-
if lvalue == peek_arg_lval {
101-
if let repr::Rvalue::Ref(_,
102-
repr::BorrowKind::Shared,
103-
ref peeking_at_lval) = *rvalue {
104-
// Okay, our search is over.
105-
let peek_mpi = move_data.rev_lookup.find(peeking_at_lval);
106-
let bit_state = sets.on_entry.contains(&peek_mpi);
107-
debug!("rustc_peek({:?} = &{:?}) bit_state: {}",
108-
lvalue, peeking_at_lval, bit_state);
109-
if !bit_state {
110-
tcx.sess.span_err(span, &format!("rustc_peek: bit not set"));
111-
}
112-
continue 'next_block;
113-
} else {
114-
// Our search should have been over, but the input
115-
// does not match expectations of `rustc_peek` for
116-
// this sanity_check.
117-
tcx.sess.span_err(span, &format!("rustc_peek: argument expression \
118-
must be immediate borrow of form `&expr`"));
119-
}
120-
}
99+
let mut sets = super::BlockSets { on_entry: &mut entry,
100+
gen_set: &mut gen,
101+
kill_set: &mut kill };
121102

122-
let lhs_mpi = move_data.rev_lookup.find(lvalue);
103+
for (j, stmt) in statements.iter().enumerate() {
104+
debug!("rustc_peek: ({:?},{}) {:?}", bb, j, stmt);
105+
let (lvalue, rvalue) = match stmt.kind {
106+
repr::StatementKind::Assign(ref lvalue, ref rvalue) => {
107+
(lvalue, rvalue)
108+
}
109+
};
123110

124-
debug!("rustc_peek: computing effect on lvalue: {:?} ({:?}) in stmt: {:?}",
125-
lvalue, lhs_mpi, stmt);
126-
// reset GEN and KILL sets before emulating their effect.
127-
for e in sets.gen_set.words_mut() { *e = 0; }
128-
for e in sets.kill_set.words_mut() { *e = 0; }
129-
results.0.operator.statement_effect(flow_ctxt, &mut sets, bb, j);
130-
sets.on_entry.union(sets.gen_set);
131-
sets.on_entry.subtract(sets.kill_set);
111+
if lvalue == peek_arg_lval {
112+
if let repr::Rvalue::Ref(_,
113+
repr::BorrowKind::Shared,
114+
ref peeking_at_lval) = *rvalue {
115+
// Okay, our search is over.
116+
let peek_mpi = move_data.rev_lookup.find(peeking_at_lval);
117+
let bit_state = sets.on_entry.contains(&peek_mpi);
118+
debug!("rustc_peek({:?} = &{:?}) bit_state: {}",
119+
lvalue, peeking_at_lval, bit_state);
120+
if !bit_state {
121+
tcx.sess.span_err(span, &format!("rustc_peek: bit not set"));
122+
}
123+
return;
124+
} else {
125+
// Our search should have been over, but the input
126+
// does not match expectations of `rustc_peek` for
127+
// this sanity_check.
128+
let msg = &format!("rustc_peek: argument expression \
129+
must be immediate borrow of form `&expr`");
130+
tcx.sess.span_err(span, msg);
131+
}
132132
}
133-
134-
tcx.sess.span_err(span, &format!("rustc_peek: MIR did not match \
135-
anticipated pattern; note that \
136-
rustc_peek expects input of \
137-
form `&expr`"));
133+
134+
let lhs_mpi = move_data.rev_lookup.find(lvalue);
135+
136+
debug!("rustc_peek: computing effect on lvalue: {:?} ({:?}) in stmt: {:?}",
137+
lvalue, lhs_mpi, stmt);
138+
// reset GEN and KILL sets before emulating their effect.
139+
for e in sets.gen_set.words_mut() { *e = 0; }
140+
for e in sets.kill_set.words_mut() { *e = 0; }
141+
results.0.operator.statement_effect(flow_ctxt, &mut sets, bb, j);
142+
sets.on_entry.union(sets.gen_set);
143+
sets.on_entry.subtract(sets.kill_set);
138144
}
139145

146+
tcx.sess.span_err(span, &format!("rustc_peek: MIR did not match \
147+
anticipated pattern; note that \
148+
rustc_peek expects input of \
149+
form `&expr`"));
140150
}
141151

142152
fn is_rustc_peek<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

0 commit comments

Comments
 (0)