Skip to content

Commit

Permalink
Revise dataflow to do a cfg-driven walk.
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
pnkfelix committed Jun 16, 2014
1 parent cf1b5bf commit 04b9ee5
Show file tree
Hide file tree
Showing 5 changed files with 295 additions and 579 deletions.
11 changes: 10 additions & 1 deletion src/librustc/middle/borrowck/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#![allow(non_camel_case_types)]

use middle::cfg;
use middle::dataflow::DataFlowContext;
use middle::dataflow::DataFlowOperator;
use middle::def;
Expand Down Expand Up @@ -127,20 +128,28 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
let id_range = ast_util::compute_id_range_for_fn_body(fk, decl, body, sp, id);
let (all_loans, move_data) =
gather_loans::gather_loans_in_fn(this, decl, body);
let cfg = cfg::CFG::new(this.tcx, body);

let mut loan_dfcx =
DataFlowContext::new(this.tcx,
"borrowck",
Some(decl),
&cfg,
LoanDataFlowOperator,
id_range,
all_loans.len());
for (loan_idx, loan) in all_loans.iter().enumerate() {
loan_dfcx.add_gen(loan.gen_scope, loan_idx);
loan_dfcx.add_kill(loan.kill_scope, loan_idx);
}
loan_dfcx.propagate(body);
loan_dfcx.add_kills_from_flow_exits(&cfg);
loan_dfcx.propagate(&cfg, body);

let flowed_moves = move_data::FlowedMoveData::new(move_data,
this.tcx,
&cfg,
id_range,
decl,
body);

check_loans::check_loans(this, &loan_dfcx, flowed_moves,
Expand Down
16 changes: 14 additions & 2 deletions src/librustc/middle/borrowck/move_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use std::rc::Rc;
use std::uint;
use std::collections::{HashMap, HashSet};
use middle::borrowck::*;
use middle::cfg;
use middle::dataflow::DataFlowContext;
use middle::dataflow::DataFlowOperator;
use euv = middle::expr_use_visitor;
Expand Down Expand Up @@ -499,22 +500,33 @@ impl MoveData {
impl<'a> FlowedMoveData<'a> {
pub fn new(move_data: MoveData,
tcx: &'a ty::ctxt,
cfg: &'a cfg::CFG,
id_range: ast_util::IdRange,

This comment has been minimized.

Copy link
@nikomatsakis

nikomatsakis Jun 16, 2014

As far as I can tell, id_range is unused here (as I would expect, since it's primary purpose was to create a mapping between ast node ids and "dataflow node ids" -- the latter is replaced by cfg indices)

decl: &ast::FnDecl,
body: &ast::Block)
-> FlowedMoveData<'a> {
let mut dfcx_moves =
DataFlowContext::new(tcx,
"flowed_move_data_moves",
Some(decl),
cfg,
MoveDataFlowOperator,
id_range,
move_data.moves.borrow().len());
let mut dfcx_assign =
DataFlowContext::new(tcx,
"flowed_move_data_assigns",
Some(decl),
cfg,
AssignDataFlowOperator,
id_range,
move_data.var_assignments.borrow().len());
move_data.add_gen_kills(tcx, &mut dfcx_moves, &mut dfcx_assign);
dfcx_moves.propagate(body);
dfcx_assign.propagate(body);
dfcx_moves.add_kills_from_flow_exits(cfg);
dfcx_assign.add_kills_from_flow_exits(cfg);
dfcx_moves.propagate(cfg, body);
dfcx_assign.propagate(cfg, body);

FlowedMoveData {
move_data: move_data,
dfcx_moves: dfcx_moves,
Expand Down
Loading

0 comments on commit 04b9ee5

Please sign in to comment.