Skip to content

Commit b39fb9b

Browse files
committed
Fix control flow handling in generator_interior
All tests pass now! The issue was that we weren't handling all edges correctly, but now they are handled consistently. This includes code to dump a graphviz file for the CFG we built for drop tracking. Also removes old DropRanges tests.
1 parent c7afaa1 commit b39fb9b

File tree

5 files changed

+78
-22
lines changed

5 files changed

+78
-22
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4388,6 +4388,7 @@ dependencies = [
43884388
"rustc_attr",
43894389
"rustc_data_structures",
43904390
"rustc_errors",
4391+
"rustc_graphviz",
43914392
"rustc_hir",
43924393
"rustc_hir_pretty",
43934394
"rustc_index",

compiler/rustc_typeck/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ rustc_middle = { path = "../rustc_middle" }
1515
rustc_attr = { path = "../rustc_attr" }
1616
rustc_data_structures = { path = "../rustc_data_structures" }
1717
rustc_errors = { path = "../rustc_errors" }
18+
rustc_graphviz = { path = "../rustc_graphviz" }
1819
rustc_hir = { path = "../rustc_hir" }
1920
rustc_hir_pretty = { path = "../rustc_hir_pretty" }
2021
rustc_target = { path = "../rustc_target" }

compiler/rustc_typeck/src/check/generator_interior.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@ use rustc_span::Span;
2626
use smallvec::SmallVec;
2727
use tracing::debug;
2828

29-
#[cfg(test)]
30-
mod tests;
31-
3229
mod drop_ranges;
3330

3431
struct InteriorVisitor<'a, 'tcx> {
@@ -255,6 +252,7 @@ pub fn resolve_interior<'a, 'tcx>(
255252
intravisit::walk_body(&mut drop_range_visitor, body);
256253

257254
drop_range_visitor.drop_ranges.propagate_to_fixpoint();
255+
// drop_range_visitor.drop_ranges.save_graph("drop_ranges.dot");
258256

259257
InteriorVisitor {
260258
fcx,
@@ -877,18 +875,18 @@ impl<'tcx> Visitor<'tcx> for DropRangeVisitor<'tcx> {
877875
reinit = Some(lhs);
878876
}
879877
ExprKind::Loop(body, ..) => {
880-
let loop_begin = self.expr_count;
878+
let loop_begin = self.expr_count + 1;
881879
self.visit_block(body);
882880
self.drop_ranges.add_control_edge(self.expr_count, loop_begin);
883881
}
884882
ExprKind::Match(scrutinee, arms, ..) => {
885883
self.visit_expr(scrutinee);
886884

887-
let fork = self.expr_count - 1;
885+
let fork = self.expr_count;
888886
let arm_end_ids = arms
889887
.iter()
890888
.map(|Arm { pat, body, guard, .. }| {
891-
self.drop_ranges.add_control_edge(fork, self.expr_count);
889+
self.drop_ranges.add_control_edge(fork, self.expr_count + 1);
892890
self.visit_pat(pat);
893891
match guard {
894892
Some(Guard::If(expr)) => self.visit_expr(expr),
@@ -914,8 +912,8 @@ impl<'tcx> Visitor<'tcx> for DropRangeVisitor<'tcx> {
914912
_ => intravisit::walk_expr(self, expr),
915913
}
916914

917-
self.drop_ranges.add_node_mapping(expr.hir_id, self.expr_count);
918915
self.expr_count += 1;
916+
self.drop_ranges.add_node_mapping(expr.hir_id, self.expr_count);
919917
self.consume_expr(expr);
920918
if let Some(expr) = reinit {
921919
self.reinit_expr(expr);

compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::collections::BTreeMap;
22
use std::fmt::Debug;
33
use std::mem::swap;
44

5+
use rustc_graphviz as dot;
56
use rustc_hir::{HirId, HirIdMap};
67
use rustc_index::bit_set::BitSet;
78
use rustc_index::vec::IndexVec;
@@ -182,7 +183,9 @@ impl DropRanges {
182183
changed
183184
};
184185

185-
while propagate() {}
186+
while propagate() {
187+
trace!("drop_state changed, re-running propagation");
188+
}
186189

187190
trace!("after fixpoint: {:#?}", self);
188191
}
@@ -200,6 +203,73 @@ impl DropRanges {
200203
}
201204
preds
202205
}
206+
207+
// pub fn save_graph(&self, filename: &str) {
208+
// use std::fs::File;
209+
// dot::render(self, &mut File::create(filename).unwrap()).unwrap();
210+
// }
211+
}
212+
213+
impl<'a> dot::GraphWalk<'a> for DropRanges {
214+
type Node = PostOrderId;
215+
216+
type Edge = (PostOrderId, PostOrderId);
217+
218+
fn nodes(&'a self) -> dot::Nodes<'a, Self::Node> {
219+
self.nodes.iter_enumerated().map(|(i, _)| i).collect()
220+
}
221+
222+
fn edges(&'a self) -> dot::Edges<'a, Self::Edge> {
223+
self.nodes
224+
.iter_enumerated()
225+
.flat_map(|(i, node)| {
226+
if node.successors.len() == 0 {
227+
vec![(i, PostOrderId::from_usize(i.index() + 1))]
228+
} else {
229+
node.successors.iter().map(move |&s| (i, s)).collect()
230+
}
231+
})
232+
.collect()
233+
}
234+
235+
fn source(&'a self, edge: &Self::Edge) -> Self::Node {
236+
edge.0
237+
}
238+
239+
fn target(&'a self, edge: &Self::Edge) -> Self::Node {
240+
edge.1
241+
}
242+
}
243+
244+
impl<'a> dot::Labeller<'a> for DropRanges {
245+
type Node = PostOrderId;
246+
247+
type Edge = (PostOrderId, PostOrderId);
248+
249+
fn graph_id(&'a self) -> dot::Id<'a> {
250+
dot::Id::new("drop_ranges").unwrap()
251+
}
252+
253+
fn node_id(&'a self, n: &Self::Node) -> dot::Id<'a> {
254+
dot::Id::new(format!("id{}", n.index())).unwrap()
255+
}
256+
257+
fn node_label(&'a self, n: &Self::Node) -> dot::LabelText<'a> {
258+
dot::LabelText::LabelStr(
259+
format!(
260+
"{:?}, local_id: {}",
261+
n,
262+
self.post_order_map
263+
.iter()
264+
.find(|(_hir_id, &post_order_id)| post_order_id == n.index())
265+
.map_or("<unknown>".into(), |(hir_id, _)| format!(
266+
"{}",
267+
hir_id.local_id.index()
268+
))
269+
)
270+
.into(),
271+
)
272+
}
203273
}
204274

205275
#[derive(Debug)]

compiler/rustc_typeck/src/check/generator_interior/tests.rs

Lines changed: 0 additions & 14 deletions
This file was deleted.

0 commit comments

Comments
 (0)