use middle::ty;
use util::ppaux::{note_and_explain_region, Repr, UserString};
-use std::cell::{Cell};
use std::rc::Rc;
-use std::gc::{Gc, GC};
use std::string::String;
use syntax::ast;
use syntax::ast_map;
#[deriving(Clone)]
pub struct LoanDataFlowOperator;
-pub type LoanDataFlow<'a> = DataFlowContext<'a, LoanDataFlowOperator>;
+pub type LoanDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, LoanDataFlowOperator>;
-impl<'a> Visitor<()> for BorrowckCtxt<'a> {
- fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl,
- b: &Block, s: Span, n: NodeId, _: ()) {
+impl<'a, 'tcx, 'v> Visitor<'v> for BorrowckCtxt<'a, 'tcx> {
+ fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl,
+ b: &'v Block, s: Span, n: NodeId) {
borrowck_fn(self, fk, fd, b, s, n);
}
- fn visit_item(&mut self, item: &ast::Item, _: ()) {
+ fn visit_item(&mut self, item: &ast::Item) {
borrowck_item(self, item);
}
}
-pub fn check_crate(tcx: &ty::ctxt,
- krate: &ast::Crate) {
+pub fn check_crate(tcx: &ty::ctxt) {
let mut bccx = BorrowckCtxt {
tcx: tcx,
- stats: box(GC) BorrowStats {
- loaned_paths_same: Cell::new(0),
- loaned_paths_imm: Cell::new(0),
- stable_paths: Cell::new(0),
- guaranteed_paths: Cell::new(0),
+ stats: BorrowStats {
+ loaned_paths_same: 0,
+ loaned_paths_imm: 0,
+ stable_paths: 0,
+ guaranteed_paths: 0
}
};
- visit::walk_crate(&mut bccx, krate, ());
+ visit::walk_crate(&mut bccx, tcx.map.krate());
if tcx.sess.borrowck_stats() {
println!("--- borrowck stats ---");
println!("paths requiring guarantees: {}",
- bccx.stats.guaranteed_paths.get());
+ bccx.stats.guaranteed_paths);
println!("paths requiring loans : {}",
- make_stat(&bccx, bccx.stats.loaned_paths_same.get()));
+ make_stat(&bccx, bccx.stats.loaned_paths_same));
println!("paths requiring imm loans : {}",
- make_stat(&bccx, bccx.stats.loaned_paths_imm.get()));
+ make_stat(&bccx, bccx.stats.loaned_paths_imm));
println!("stable paths : {}",
- make_stat(&bccx, bccx.stats.stable_paths.get()));
+ make_stat(&bccx, bccx.stats.stable_paths));
}
fn make_stat(bccx: &BorrowckCtxt, stat: uint) -> String {
- let total = bccx.stats.guaranteed_paths.get() as f64;
+ let total = bccx.stats.guaranteed_paths as f64;
let perc = if total == 0.0 { 0.0 } else { stat as f64 * 100.0 / total };
format!("{} ({:.0f}%)", stat, perc)
}
// loan step is intended for things that have a data
// flow dependent conditions.
match item.node {
- ast::ItemStatic(_, _, ex) => {
- gather_loans::gather_loans_in_static_initializer(this, &*ex);
+ ast::ItemStatic(_, _, ref ex) => {
+ gather_loans::gather_loans_in_static_initializer(this, &**ex);
}
_ => {
- visit::walk_item(this, item, ());
+ visit::walk_item(this, item);
}
}
}
/// Collection of conclusions determined via borrow checker analyses.
-pub struct AnalysisData<'a> {
+pub struct AnalysisData<'a, 'tcx: 'a> {
pub all_loans: Vec<Loan>,
- pub loans: DataFlowContext<'a, LoanDataFlowOperator>,
- pub move_data: move_data::FlowedMoveData<'a>,
+ pub loans: DataFlowContext<'a, 'tcx, LoanDataFlowOperator>,
+ pub move_data: move_data::FlowedMoveData<'a, 'tcx>,
}
fn borrowck_fn(this: &mut BorrowckCtxt,
- fk: &FnKind,
+ fk: FnKind,
decl: &ast::FnDecl,
body: &ast::Block,
sp: Span,
check_loans::check_loans(this, &loan_dfcx, flowed_moves,
all_loans.as_slice(), decl, body);
- visit::walk_fn(this, fk, decl, body, sp, ());
+ visit::walk_fn(this, fk, decl, body, sp);
}
-fn build_borrowck_dataflow_data<'a>(this: &mut BorrowckCtxt<'a>,
- fk: &FnKind,
- decl: &ast::FnDecl,
- cfg: &cfg::CFG,
- body: &ast::Block,
- sp: Span,
- id: ast::NodeId) -> AnalysisData<'a> {
+fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
+ fk: FnKind,
+ decl: &ast::FnDecl,
+ cfg: &cfg::CFG,
+ body: &ast::Block,
+ sp: Span,
+ id: ast::NodeId) -> AnalysisData<'a, 'tcx> {
// Check the body of fn items.
let id_range = ast_util::compute_id_range_for_fn_body(fk, decl, body, sp, id);
let (all_loans, move_data) =
/// Accessor for introspective clients inspecting `AnalysisData` and
/// the `BorrowckCtxt` itself , e.g. the flowgraph visualizer.
-pub fn build_borrowck_dataflow_data_for_fn<'a>(
- tcx: &'a ty::ctxt,
- input: FnPartsWithCFG<'a>) -> (BorrowckCtxt<'a>, AnalysisData<'a>) {
+pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
+ tcx: &'a ty::ctxt<'tcx>,
+ input: FnPartsWithCFG<'a>) -> (BorrowckCtxt<'a, 'tcx>, AnalysisData<'a, 'tcx>) {
let mut bccx = BorrowckCtxt {
tcx: tcx,
- stats: box(GC) BorrowStats {
- loaned_paths_same: Cell::new(0),
- loaned_paths_imm: Cell::new(0),
- stable_paths: Cell::new(0),
- guaranteed_paths: Cell::new(0),
+ stats: BorrowStats {
+ loaned_paths_same: 0,
+ loaned_paths_imm: 0,
+ stable_paths: 0,
+ guaranteed_paths: 0
}
};
let p = input.fn_parts;
let dataflow_data = build_borrowck_dataflow_data(&mut bccx,
- &p.kind,
+ p.kind,
&*p.decl,
input.cfg,
&*p.body,
// ----------------------------------------------------------------------
// Type definitions
-pub struct BorrowckCtxt<'a> {
- tcx: &'a ty::ctxt,
+pub struct BorrowckCtxt<'a, 'tcx: 'a> {
+ tcx: &'a ty::ctxt<'tcx>,
// Statistics:
- stats: Gc<BorrowStats>,
+ stats: BorrowStats
}
-pub struct BorrowStats {
- loaned_paths_same: Cell<uint>,
- loaned_paths_imm: Cell<uint>,
- stable_paths: Cell<uint>,
- guaranteed_paths: Cell<uint>,
+struct BorrowStats {
+ loaned_paths_same: uint,
+ loaned_paths_imm: uint,
+ stable_paths: uint,
+ guaranteed_paths: uint
}
pub type BckResult<T> = Result<T, BckError>;
tcx: &ty::ctxt) -> ast::NodeId {
match tcx.map.get(closure_id) {
ast_map::NodeExpr(expr) => match expr.node {
- ast::ExprProc(_, block) |
- ast::ExprFnBlock(_, _, block) |
- ast::ExprUnboxedFn(_, _, _, block) => { block.id }
+ ast::ExprProc(_, ref block) |
+ ast::ExprFnBlock(_, _, ref block) |
+ ast::ExprUnboxedFn(_, _, _, ref block) => { block.id }
_ => fail!("encountered non-closure id: {}", closure_id)
},
_ => fail!("encountered non-expr id: {}", closure_id)
None
}
- mc::cat_local(id) |
- mc::cat_arg(id) => {
+ mc::cat_local(id) => {
Some(Rc::new(LpVar(id)))
}
///////////////////////////////////////////////////////////////////////////
// Misc
-impl<'a> BorrowckCtxt<'a> {
+impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
pub fn is_subregion_of(&self, r_sub: ty::Region, r_sup: ty::Region)
-> bool {
self.tcx.region_maps.is_subregion_of(r_sub, r_sup)
self.tcx.region_maps.is_subscope_of(r_sub, r_sup)
}
- pub fn mc(&self) -> mc::MemCategorizationContext<'a,ty::ctxt> {
+ pub fn mc(&self) -> mc::MemCategorizationContext<'a, ty::ctxt<'tcx>> {
mc::MemCategorizationContext::new(self.tcx)
}
adj: &ty::AutoAdjustment)
-> mc::cmt {
let r = match *adj {
- ty::AutoDerefRef(
+ ty::AdjustDerefRef(
ty::AutoDerefRef {
autoderefs: autoderefs, ..}) => {
self.mc().cat_expr_autoderefd(expr, autoderefs)
}
- ty::AutoAddEnv(..) => {
+ ty::AdjustAddEnv(..) => {
// no autoderefs
self.mc().cat_expr_unadjusted(expr)
}
out.push_str(token::get_name(fname).get());
}
mc::PositionalField(idx) => {
- out.push_char('#'); // invent a notation here
+ out.push_char('.');
out.push_str(idx.to_string().as_slice());
}
}