Skip to content

Commit 04b9ee5

Browse files
committed
Revise dataflow to do a cfg-driven walk.
Fix rust-lang#6298. This is instead of the prior approach of emulating cfg traversal privately by traversing AST in same way). Of special note, this removes a special case handling of `ExprParen` that was actually injecting a bug (since it was acting like an expression like `(*func)()` was consuming `*func` *twice*: once from `(*func)` and again from `*func`). nikomatsakis was the first one to point out that it might suffice to simply have the outer `ExprParen` do the consumption of the contents (alone).
1 parent cf1b5bf commit 04b9ee5

File tree

5 files changed

+295
-579
lines changed

5 files changed

+295
-579
lines changed

src/librustc/middle/borrowck/mod.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#![allow(non_camel_case_types)]
1414

15+
use middle::cfg;
1516
use middle::dataflow::DataFlowContext;
1617
use middle::dataflow::DataFlowOperator;
1718
use middle::def;
@@ -127,20 +128,28 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
127128
let id_range = ast_util::compute_id_range_for_fn_body(fk, decl, body, sp, id);
128129
let (all_loans, move_data) =
129130
gather_loans::gather_loans_in_fn(this, decl, body);
131+
let cfg = cfg::CFG::new(this.tcx, body);
132+
130133
let mut loan_dfcx =
131134
DataFlowContext::new(this.tcx,
135+
"borrowck",
136+
Some(decl),
137+
&cfg,
132138
LoanDataFlowOperator,
133139
id_range,
134140
all_loans.len());
135141
for (loan_idx, loan) in all_loans.iter().enumerate() {
136142
loan_dfcx.add_gen(loan.gen_scope, loan_idx);
137143
loan_dfcx.add_kill(loan.kill_scope, loan_idx);
138144
}
139-
loan_dfcx.propagate(body);
145+
loan_dfcx.add_kills_from_flow_exits(&cfg);
146+
loan_dfcx.propagate(&cfg, body);
140147

141148
let flowed_moves = move_data::FlowedMoveData::new(move_data,
142149
this.tcx,
150+
&cfg,
143151
id_range,
152+
decl,
144153
body);
145154

146155
check_loans::check_loans(this, &loan_dfcx, flowed_moves,

src/librustc/middle/borrowck/move_data.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use std::rc::Rc;
2020
use std::uint;
2121
use std::collections::{HashMap, HashSet};
2222
use middle::borrowck::*;
23+
use middle::cfg;
2324
use middle::dataflow::DataFlowContext;
2425
use middle::dataflow::DataFlowOperator;
2526
use euv = middle::expr_use_visitor;
@@ -499,22 +500,33 @@ impl MoveData {
499500
impl<'a> FlowedMoveData<'a> {
500501
pub fn new(move_data: MoveData,
501502
tcx: &'a ty::ctxt,
503+
cfg: &'a cfg::CFG,
502504
id_range: ast_util::IdRange,
505+
decl: &ast::FnDecl,
503506
body: &ast::Block)
504507
-> FlowedMoveData<'a> {
505508
let mut dfcx_moves =
506509
DataFlowContext::new(tcx,
510+
"flowed_move_data_moves",
511+
Some(decl),
512+
cfg,
507513
MoveDataFlowOperator,
508514
id_range,
509515
move_data.moves.borrow().len());
510516
let mut dfcx_assign =
511517
DataFlowContext::new(tcx,
518+
"flowed_move_data_assigns",
519+
Some(decl),
520+
cfg,
512521
AssignDataFlowOperator,
513522
id_range,
514523
move_data.var_assignments.borrow().len());
515524
move_data.add_gen_kills(tcx, &mut dfcx_moves, &mut dfcx_assign);
516-
dfcx_moves.propagate(body);
517-
dfcx_assign.propagate(body);
525+
dfcx_moves.add_kills_from_flow_exits(cfg);
526+
dfcx_assign.add_kills_from_flow_exits(cfg);
527+
dfcx_moves.propagate(cfg, body);
528+
dfcx_assign.propagate(cfg, body);
529+
518530
FlowedMoveData {
519531
move_data: move_data,
520532
dfcx_moves: dfcx_moves,

0 commit comments

Comments
 (0)