mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 00:34:06 +00:00
Add ty
to LoanPath
.
To make this clean, refactored old `LoanPath` enum into a `LoanPath` struct with a `ty::t` and a newly-added `LoanPathVariant` enum. This enabled me to get rid of the ugly and fragile `LoanPath::to_type` method, and I can probably also get rid of other stuff that was supporting it, maybe.
This commit is contained in:
parent
d6c8f3b726
commit
91b88c54c2
@ -19,6 +19,8 @@
|
||||
use self::UseError::*;
|
||||
|
||||
use middle::borrowck::*;
|
||||
use middle::borrowck::LoanPathElem::*;
|
||||
use middle::borrowck::LoanPathKind::*;
|
||||
use middle::expr_use_visitor as euv;
|
||||
use middle::mem_categorization as mc;
|
||||
use middle::region;
|
||||
@ -33,51 +35,51 @@ use std::rc::Rc;
|
||||
// be less precise in its handling of Box while still allowing moves out of a
|
||||
// Box. They should be removed when OwnedPtr is removed from LoanPath.
|
||||
|
||||
fn owned_ptr_base_path<'a>(loan_path: &'a LoanPath) -> &'a LoanPath {
|
||||
fn owned_ptr_base_path<'a, 'tcx>(loan_path: &'a LoanPath<'tcx>) -> &'a LoanPath<'tcx> {
|
||||
//! Returns the base of the leftmost dereference of an OwnedPtr in
|
||||
//! `loan_path`. If there is no dereference of an OwnedPtr in `loan_path`,
|
||||
//! then it just returns `loan_path` itself.
|
||||
|
||||
return match owned_ptr_base_path_helper(loan_path) {
|
||||
return match helper(loan_path) {
|
||||
Some(new_loan_path) => new_loan_path,
|
||||
None => loan_path.clone()
|
||||
};
|
||||
|
||||
fn owned_ptr_base_path_helper<'a>(loan_path: &'a LoanPath) -> Option<&'a LoanPath> {
|
||||
match *loan_path {
|
||||
fn helper<'a, 'tcx>(loan_path: &'a LoanPath<'tcx>) -> Option<&'a LoanPath<'tcx>> {
|
||||
match loan_path.kind {
|
||||
LpVar(_) | LpUpvar(_) => None,
|
||||
LpExtend(ref lp_base, _, LpDeref(mc::OwnedPtr)) => {
|
||||
match owned_ptr_base_path_helper(&**lp_base) {
|
||||
match helper(&**lp_base) {
|
||||
v @ Some(_) => v,
|
||||
None => Some(&**lp_base)
|
||||
}
|
||||
}
|
||||
LpDowncast(ref lp_base, _) |
|
||||
LpExtend(ref lp_base, _, _) => owned_ptr_base_path_helper(&**lp_base)
|
||||
LpExtend(ref lp_base, _, _) => helper(&**lp_base)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn owned_ptr_base_path_rc(loan_path: &Rc<LoanPath>) -> Rc<LoanPath> {
|
||||
fn owned_ptr_base_path_rc<'tcx>(loan_path: &Rc<LoanPath<'tcx>>) -> Rc<LoanPath<'tcx>> {
|
||||
//! The equivalent of `owned_ptr_base_path` for an &Rc<LoanPath> rather than
|
||||
//! a &LoanPath.
|
||||
|
||||
return match owned_ptr_base_path_helper(loan_path) {
|
||||
return match helper(loan_path) {
|
||||
Some(new_loan_path) => new_loan_path,
|
||||
None => loan_path.clone()
|
||||
};
|
||||
|
||||
fn owned_ptr_base_path_helper(loan_path: &Rc<LoanPath>) -> Option<Rc<LoanPath>> {
|
||||
match **loan_path {
|
||||
fn helper<'tcx>(loan_path: &Rc<LoanPath<'tcx>>) -> Option<Rc<LoanPath<'tcx>>> {
|
||||
match loan_path.kind {
|
||||
LpVar(_) | LpUpvar(_) => None,
|
||||
LpExtend(ref lp_base, _, LpDeref(mc::OwnedPtr)) => {
|
||||
match owned_ptr_base_path_helper(lp_base) {
|
||||
match helper(lp_base) {
|
||||
v @ Some(_) => v,
|
||||
None => Some(lp_base.clone())
|
||||
}
|
||||
}
|
||||
LpDowncast(ref lp_base, _) |
|
||||
LpExtend(ref lp_base, _, _) => owned_ptr_base_path_helper(lp_base)
|
||||
LpExtend(ref lp_base, _, _) => helper(lp_base)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -86,7 +88,7 @@ struct CheckLoanCtxt<'a, 'tcx: 'a> {
|
||||
bccx: &'a BorrowckCtxt<'a, 'tcx>,
|
||||
dfcx_loans: &'a LoanDataFlow<'a, 'tcx>,
|
||||
move_data: move_data::FlowedMoveData<'a, 'tcx>,
|
||||
all_loans: &'a [Loan],
|
||||
all_loans: &'a [Loan<'tcx>],
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> {
|
||||
@ -185,7 +187,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> {
|
||||
pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||
dfcx_loans: &LoanDataFlow<'b, 'tcx>,
|
||||
move_data: move_data::FlowedMoveData<'c, 'tcx>,
|
||||
all_loans: &[Loan],
|
||||
all_loans: &[Loan<'tcx>],
|
||||
decl: &ast::FnDecl,
|
||||
body: &ast::Block) {
|
||||
debug!("check_loans(body id={})", body.id);
|
||||
@ -204,9 +206,9 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
enum UseError {
|
||||
enum UseError<'tcx> {
|
||||
UseOk,
|
||||
UseWhileBorrowed(/*loan*/Rc<LoanPath>, /*loan*/Span)
|
||||
UseWhileBorrowed(/*loan*/Rc<LoanPath<'tcx>>, /*loan*/Span)
|
||||
}
|
||||
|
||||
fn compatible_borrow_kinds(borrow_kind1: ty::BorrowKind,
|
||||
@ -218,7 +220,7 @@ fn compatible_borrow_kinds(borrow_kind1: ty::BorrowKind,
|
||||
impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
pub fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.bccx.tcx }
|
||||
|
||||
pub fn each_issued_loan(&self, scope: region::CodeExtent, op: |&Loan| -> bool)
|
||||
pub fn each_issued_loan(&self, scope: region::CodeExtent, op: |&Loan<'tcx>| -> bool)
|
||||
-> bool {
|
||||
//! Iterates over each loan that has been issued
|
||||
//! on entrance to `scope`, regardless of whether it is
|
||||
@ -234,7 +236,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
|
||||
pub fn each_in_scope_loan(&self,
|
||||
scope: region::CodeExtent,
|
||||
op: |&Loan| -> bool)
|
||||
op: |&Loan<'tcx>| -> bool)
|
||||
-> bool {
|
||||
//! Like `each_issued_loan()`, but only considers loans that are
|
||||
//! currently in scope.
|
||||
@ -251,8 +253,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
|
||||
fn each_in_scope_loan_affecting_path(&self,
|
||||
scope: region::CodeExtent,
|
||||
loan_path: &LoanPath,
|
||||
op: |&Loan| -> bool)
|
||||
loan_path: &LoanPath<'tcx>,
|
||||
op: |&Loan<'tcx>| -> bool)
|
||||
-> bool {
|
||||
//! Iterates through all of the in-scope loans affecting `loan_path`,
|
||||
//! calling `op`, and ceasing iteration if `false` is returned.
|
||||
@ -296,7 +298,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
|
||||
let mut loan_path = loan_path;
|
||||
loop {
|
||||
match *loan_path {
|
||||
match loan_path.kind {
|
||||
LpVar(_) | LpUpvar(_) => {
|
||||
break;
|
||||
}
|
||||
@ -366,8 +368,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn report_error_if_loans_conflict(&self,
|
||||
old_loan: &Loan,
|
||||
new_loan: &Loan) {
|
||||
old_loan: &Loan<'tcx>,
|
||||
new_loan: &Loan<'tcx>) {
|
||||
//! Checks whether `old_loan` and `new_loan` can safely be issued
|
||||
//! simultaneously.
|
||||
|
||||
@ -386,10 +388,10 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn report_error_if_loan_conflicts_with_restriction(&self,
|
||||
loan1: &Loan,
|
||||
loan2: &Loan,
|
||||
old_loan: &Loan,
|
||||
new_loan: &Loan)
|
||||
loan1: &Loan<'tcx>,
|
||||
loan2: &Loan<'tcx>,
|
||||
old_loan: &Loan<'tcx>,
|
||||
new_loan: &Loan<'tcx>)
|
||||
-> bool {
|
||||
//! Checks whether the restrictions introduced by `loan1` would
|
||||
//! prohibit `loan2`. Returns false if an error is reported.
|
||||
@ -552,7 +554,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
true
|
||||
}
|
||||
|
||||
fn is_local_variable_or_arg(&self, cmt: mc::cmt) -> bool {
|
||||
fn is_local_variable_or_arg(&self, cmt: mc::cmt<'tcx>) -> bool {
|
||||
match cmt.cat {
|
||||
mc::cat_local(_) => true,
|
||||
_ => false
|
||||
@ -562,7 +564,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
fn consume_common(&self,
|
||||
id: ast::NodeId,
|
||||
span: Span,
|
||||
cmt: mc::cmt,
|
||||
cmt: mc::cmt<'tcx>,
|
||||
mode: euv::ConsumeMode) {
|
||||
match opt_loan_path(&cmt) {
|
||||
Some(lp) => {
|
||||
@ -603,7 +605,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
fn check_for_copy_of_frozen_path(&self,
|
||||
id: ast::NodeId,
|
||||
span: Span,
|
||||
copy_path: &LoanPath) {
|
||||
copy_path: &LoanPath<'tcx>) {
|
||||
match self.analyze_restrictions_on_use(id, copy_path, ty::ImmBorrow) {
|
||||
UseOk => { }
|
||||
UseWhileBorrowed(loan_path, loan_span) => {
|
||||
@ -624,7 +626,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
fn check_for_move_of_borrowed_path(&self,
|
||||
id: ast::NodeId,
|
||||
span: Span,
|
||||
move_path: &LoanPath,
|
||||
move_path: &LoanPath<'tcx>,
|
||||
move_kind: move_data::MoveKind) {
|
||||
// We want to detect if there are any loans at all, so we search for
|
||||
// any loans incompatible with MutBorrrow, since all other kinds of
|
||||
@ -655,9 +657,9 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
|
||||
pub fn analyze_restrictions_on_use(&self,
|
||||
expr_id: ast::NodeId,
|
||||
use_path: &LoanPath,
|
||||
use_path: &LoanPath<'tcx>,
|
||||
borrow_kind: ty::BorrowKind)
|
||||
-> UseError {
|
||||
-> UseError<'tcx> {
|
||||
debug!("analyze_restrictions_on_use(expr_id={}, use_path={})",
|
||||
self.tcx().map.node_to_string(expr_id),
|
||||
use_path.repr(self.tcx()));
|
||||
@ -681,7 +683,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
id: ast::NodeId,
|
||||
span: Span,
|
||||
use_kind: MovedValueUseKind,
|
||||
lp: &Rc<LoanPath>) {
|
||||
lp: &Rc<LoanPath<'tcx>>) {
|
||||
/*!
|
||||
* Reports an error if `expr` (which should be a path)
|
||||
* is using a moved/uninitialized value
|
||||
@ -705,7 +707,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
id: ast::NodeId,
|
||||
span: Span,
|
||||
use_kind: MovedValueUseKind,
|
||||
lp: &Rc<LoanPath>)
|
||||
lp: &Rc<LoanPath<'tcx>>)
|
||||
{
|
||||
/*!
|
||||
* Reports an error if assigning to `lp` will use a
|
||||
@ -725,7 +727,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
* (*p).x = 22; // not ok, p is uninitialized, can't deref
|
||||
*/
|
||||
|
||||
match **lp {
|
||||
match lp.kind {
|
||||
LpVar(_) | LpUpvar(_) => {
|
||||
// assigning to `x` does not require that `x` is initialized
|
||||
}
|
||||
@ -923,11 +925,11 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_for_assignment_to_borrowed_path(
|
||||
this: &CheckLoanCtxt,
|
||||
fn check_for_assignment_to_borrowed_path<'a, 'tcx>(
|
||||
this: &CheckLoanCtxt<'a, 'tcx>,
|
||||
assignment_id: ast::NodeId,
|
||||
assignment_span: Span,
|
||||
assignee_cmt: mc::cmt)
|
||||
assignee_cmt: mc::cmt<'tcx>)
|
||||
{
|
||||
//! Check for assignments that violate the terms of an
|
||||
//! outstanding loan.
|
||||
@ -947,7 +949,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||
|
||||
pub fn report_illegal_mutation(&self,
|
||||
span: Span,
|
||||
loan_path: &LoanPath,
|
||||
loan_path: &LoanPath<'tcx>,
|
||||
loan: &Loan) {
|
||||
self.bccx.span_err(
|
||||
span,
|
||||
|
@ -13,6 +13,7 @@
|
||||
*/
|
||||
|
||||
use middle::borrowck::*;
|
||||
use middle::borrowck::LoanPathKind::*;
|
||||
use middle::borrowck::gather_loans::move_error::MoveSpanAndPath;
|
||||
use middle::borrowck::gather_loans::move_error::{MoveError, MoveErrorCollector};
|
||||
use middle::borrowck::move_data::*;
|
||||
@ -32,17 +33,18 @@ struct GatherMoveInfo<'tcx> {
|
||||
span_path_opt: Option<MoveSpanAndPath>
|
||||
}
|
||||
|
||||
pub fn gather_decl(bccx: &BorrowckCtxt,
|
||||
move_data: &MoveData,
|
||||
decl_id: ast::NodeId,
|
||||
_decl_span: Span,
|
||||
var_id: ast::NodeId) {
|
||||
let loan_path = Rc::new(LpVar(var_id));
|
||||
pub fn gather_decl<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
decl_id: ast::NodeId,
|
||||
_decl_span: Span,
|
||||
var_id: ast::NodeId) {
|
||||
let ty = ty::node_id_to_type(bccx.tcx, var_id);
|
||||
let loan_path = Rc::new(LoanPath::new(LpVar(var_id), ty));
|
||||
move_data.add_move(bccx.tcx, loan_path, decl_id, Declared);
|
||||
}
|
||||
|
||||
pub fn gather_move_from_expr<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||
move_data: &MoveData,
|
||||
move_data: &MoveData<'tcx>,
|
||||
move_error_collector: &MoveErrorCollector<'tcx>,
|
||||
move_expr_id: ast::NodeId,
|
||||
cmt: mc::cmt<'tcx>,
|
||||
@ -61,7 +63,7 @@ pub fn gather_move_from_expr<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||
}
|
||||
|
||||
pub fn gather_move_from_pat<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||
move_data: &MoveData,
|
||||
move_data: &MoveData<'tcx>,
|
||||
move_error_collector: &MoveErrorCollector<'tcx>,
|
||||
move_pat: &ast::Pat,
|
||||
cmt: mc::cmt<'tcx>) {
|
||||
@ -82,7 +84,7 @@ pub fn gather_move_from_pat<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||
}
|
||||
|
||||
fn gather_move<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||
move_data: &MoveData,
|
||||
move_data: &MoveData<'tcx>,
|
||||
move_error_collector: &MoveErrorCollector<'tcx>,
|
||||
move_info: GatherMoveInfo<'tcx>) {
|
||||
debug!("gather_move(move_id={}, cmt={})",
|
||||
@ -112,13 +114,13 @@ fn gather_move<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn gather_assignment(bccx: &BorrowckCtxt,
|
||||
move_data: &MoveData,
|
||||
assignment_id: ast::NodeId,
|
||||
assignment_span: Span,
|
||||
assignee_loan_path: Rc<LoanPath>,
|
||||
assignee_id: ast::NodeId,
|
||||
mode: euv::MutateMode) {
|
||||
pub fn gather_assignment<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
assignment_id: ast::NodeId,
|
||||
assignment_span: Span,
|
||||
assignee_loan_path: Rc<LoanPath<'tcx>>,
|
||||
assignee_id: ast::NodeId,
|
||||
mode: euv::MutateMode) {
|
||||
move_data.add_assignment(bccx.tcx,
|
||||
assignee_loan_path,
|
||||
assignment_id,
|
||||
|
@ -17,6 +17,7 @@
|
||||
// sure that all of these loans are honored.
|
||||
|
||||
use middle::borrowck::*;
|
||||
use middle::borrowck::LoanPathKind::*;
|
||||
use middle::borrowck::move_data::MoveData;
|
||||
use middle::expr_use_visitor as euv;
|
||||
use middle::mem_categorization as mc;
|
||||
@ -35,10 +36,10 @@ mod restrictions;
|
||||
mod gather_moves;
|
||||
mod move_error;
|
||||
|
||||
pub fn gather_loans_in_fn(bccx: &BorrowckCtxt,
|
||||
decl: &ast::FnDecl,
|
||||
body: &ast::Block)
|
||||
-> (Vec<Loan>, move_data::MoveData)
|
||||
pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||
decl: &ast::FnDecl,
|
||||
body: &ast::Block)
|
||||
-> (Vec<Loan<'tcx>>, move_data::MoveData<'tcx>)
|
||||
{
|
||||
let mut glcx = GatherLoanCtxt {
|
||||
bccx: bccx,
|
||||
@ -60,9 +61,9 @@ pub fn gather_loans_in_fn(bccx: &BorrowckCtxt,
|
||||
|
||||
struct GatherLoanCtxt<'a, 'tcx: 'a> {
|
||||
bccx: &'a BorrowckCtxt<'a, 'tcx>,
|
||||
move_data: move_data::MoveData,
|
||||
move_data: move_data::MoveData<'tcx>,
|
||||
move_error_collector: move_error::MoveErrorCollector<'tcx>,
|
||||
all_loans: Vec<Loan>,
|
||||
all_loans: Vec<Loan<'tcx>>,
|
||||
/// `item_ub` is used as an upper-bound on the lifetime whenever we
|
||||
/// ask for the scope of an expression categorized as an upvar.
|
||||
item_ub: region::CodeExtent,
|
||||
@ -395,7 +396,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
|
||||
//! For mutable loans of content whose mutability derives
|
||||
//! from a local variable, mark the mutability decl as necessary.
|
||||
|
||||
match *loan_path {
|
||||
match loan_path.kind {
|
||||
LpVar(local_id) |
|
||||
LpUpvar(ty::UpvarId{ var_id: local_id, closure_expr_id: _ }) => {
|
||||
self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
|
||||
@ -427,7 +428,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compute_kill_scope(&self, loan_scope: region::CodeExtent, lp: &LoanPath)
|
||||
pub fn compute_kill_scope(&self, loan_scope: region::CodeExtent, lp: &LoanPath<'tcx>)
|
||||
-> region::CodeExtent {
|
||||
//! Determine when the loan restrictions go out of scope.
|
||||
//! This is either when the lifetime expires or when the
|
||||
|
@ -15,6 +15,8 @@
|
||||
pub use self::RestrictionResult::*;
|
||||
|
||||
use middle::borrowck::*;
|
||||
use middle::borrowck::LoanPathElem::*;
|
||||
use middle::borrowck::LoanPathKind::*;
|
||||
use middle::expr_use_visitor as euv;
|
||||
use middle::mem_categorization as mc;
|
||||
use middle::ty;
|
||||
@ -24,9 +26,9 @@ use util::ppaux::Repr;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[deriving(Show)]
|
||||
pub enum RestrictionResult {
|
||||
pub enum RestrictionResult<'tcx> {
|
||||
Safe,
|
||||
SafeIf(Rc<LoanPath>, Vec<Rc<LoanPath>>)
|
||||
SafeIf(Rc<LoanPath<'tcx>>, Vec<Rc<LoanPath<'tcx>>>)
|
||||
}
|
||||
|
||||
pub fn compute_restrictions<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||
@ -34,7 +36,7 @@ pub fn compute_restrictions<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
|
||||
cause: euv::LoanCause,
|
||||
cmt: mc::cmt<'tcx>,
|
||||
loan_region: ty::Region)
|
||||
-> RestrictionResult {
|
||||
-> RestrictionResult<'tcx> {
|
||||
let ctxt = RestrictionsContext {
|
||||
bccx: bccx,
|
||||
span: span,
|
||||
@ -57,9 +59,11 @@ struct RestrictionsContext<'a, 'tcx: 'a> {
|
||||
|
||||
impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
|
||||
fn restrict(&self,
|
||||
cmt: mc::cmt<'tcx>) -> RestrictionResult {
|
||||
cmt: mc::cmt<'tcx>) -> RestrictionResult<'tcx> {
|
||||
debug!("restrict(cmt={})", cmt.repr(self.bccx.tcx));
|
||||
|
||||
let new_lp = |v: LoanPathKind<'tcx>| Rc::new(LoanPath::new(v, cmt.ty));
|
||||
|
||||
match cmt.cat.clone() {
|
||||
mc::cat_rvalue(..) => {
|
||||
// Effectively, rvalues are stored into a
|
||||
@ -72,13 +76,13 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
|
||||
|
||||
mc::cat_local(local_id) => {
|
||||
// R-Variable, locally declared
|
||||
let lp = Rc::new(LpVar(local_id));
|
||||
let lp = new_lp(LpVar(local_id));
|
||||
SafeIf(lp.clone(), vec![lp])
|
||||
}
|
||||
|
||||
mc::cat_upvar(mc::Upvar { id, .. }) => {
|
||||
// R-Variable, captured into closure
|
||||
let lp = Rc::new(LpUpvar(id));
|
||||
let lp = new_lp(LpUpvar(id));
|
||||
SafeIf(lp.clone(), vec![lp])
|
||||
}
|
||||
|
||||
@ -96,10 +100,9 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
|
||||
// the memory, so no additional restrictions are
|
||||
// needed.
|
||||
let result = self.restrict(cmt_base);
|
||||
self.extend(result, cmt.mutbl, LpInterior(i))
|
||||
self.extend(result, &cmt, LpInterior(i))
|
||||
}
|
||||
|
||||
|
||||
mc::cat_static_item(..) => {
|
||||
Safe
|
||||
}
|
||||
@ -116,7 +119,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
|
||||
// Eventually we should make these non-special and
|
||||
// just rely on Deref<T> implementation.
|
||||
let result = self.restrict(cmt_base);
|
||||
self.extend(result, cmt.mutbl, LpDeref(pk))
|
||||
self.extend(result, &cmt, LpDeref(pk))
|
||||
}
|
||||
mc::Implicit(bk, lt) | mc::BorrowedPtr(bk, lt) => {
|
||||
// R-Deref-[Mut-]Borrowed
|
||||
@ -140,7 +143,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
|
||||
// references lifetime ends (by a newly-unfrozen
|
||||
// borrow).
|
||||
let result = self.restrict(cmt_base);
|
||||
self.extend(result, cmt.mutbl, LpDeref(pk))
|
||||
self.extend(result, &cmt, LpDeref(pk))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -152,13 +155,14 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn extend(&self,
|
||||
result: RestrictionResult,
|
||||
mc: mc::MutabilityCategory,
|
||||
elem: LoanPathElem) -> RestrictionResult {
|
||||
result: RestrictionResult<'tcx>,
|
||||
cmt: &mc::cmt<'tcx>,
|
||||
elem: LoanPathElem) -> RestrictionResult<'tcx> {
|
||||
match result {
|
||||
Safe => Safe,
|
||||
SafeIf(base_lp, mut base_vec) => {
|
||||
let lp = Rc::new(LpExtend(base_lp, mc, elem));
|
||||
let v = LpExtend(base_lp, cmt.mutbl, elem);
|
||||
let lp = Rc::new(LoanPath::new(v, cmt.ty));
|
||||
base_vec.push(lp.clone());
|
||||
SafeIf(lp, base_vec)
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
|
||||
e: EntryOrExit,
|
||||
cfgidx: CFGIndex,
|
||||
dfcx: &DataFlowContext<'a, 'tcx, O>,
|
||||
to_lp: |uint| -> Rc<LoanPath>) -> String {
|
||||
to_lp: |uint| -> Rc<LoanPath<'tcx>>) -> String {
|
||||
let mut saw_some = false;
|
||||
let mut set = "{".to_string();
|
||||
dfcx.each_bit_for_node(e, cfgidx, |index| {
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
pub use self::LoanPath::*;
|
||||
pub use self::LoanPathKind::*;
|
||||
pub use self::LoanPathElem::*;
|
||||
pub use self::bckerr_code::*;
|
||||
pub use self::AliasableViolationKind::*;
|
||||
@ -125,7 +125,7 @@ fn borrowck_item(this: &mut BorrowckCtxt, item: &ast::Item) {
|
||||
|
||||
/// Collection of conclusions determined via borrow checker analyses.
|
||||
pub struct AnalysisData<'a, 'tcx: 'a> {
|
||||
pub all_loans: Vec<Loan>,
|
||||
pub all_loans: Vec<Loan<'tcx>>,
|
||||
pub loans: DataFlowContext<'a, 'tcx, LoanDataFlowOperator>,
|
||||
pub move_data: move_data::FlowedMoveData<'a, 'tcx>,
|
||||
}
|
||||
@ -254,11 +254,11 @@ pub type BckResult<'tcx, T> = Result<T, BckError<'tcx>>;
|
||||
// Loans and loan paths
|
||||
|
||||
/// Record of a loan that was issued.
|
||||
pub struct Loan {
|
||||
pub struct Loan<'tcx> {
|
||||
index: uint,
|
||||
loan_path: Rc<LoanPath>,
|
||||
loan_path: Rc<LoanPath<'tcx>>,
|
||||
kind: ty::BorrowKind,
|
||||
restricted_paths: Vec<Rc<LoanPath>>,
|
||||
restricted_paths: Vec<Rc<LoanPath<'tcx>>>,
|
||||
|
||||
/// gen_scope indicates where loan is introduced. Typically the
|
||||
/// loan is introduced at the point of the borrow, but in some
|
||||
@ -276,33 +276,31 @@ pub struct Loan {
|
||||
cause: euv::LoanCause,
|
||||
}
|
||||
|
||||
impl Loan {
|
||||
pub fn loan_path(&self) -> Rc<LoanPath> {
|
||||
impl<'tcx> Loan<'tcx> {
|
||||
pub fn loan_path(&self) -> Rc<LoanPath<'tcx>> {
|
||||
self.loan_path.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(PartialEq, Eq, Hash, Show)]
|
||||
pub enum LoanPath {
|
||||
LpVar(ast::NodeId), // `x` in doc.rs
|
||||
LpUpvar(ty::UpvarId), // `x` captured by-value into closure
|
||||
LpDowncast(Rc<LoanPath>, ast::DefId), // `x` downcast to particular enum variant
|
||||
LpExtend(Rc<LoanPath>, mc::MutabilityCategory, LoanPathElem)
|
||||
pub struct LoanPath<'tcx> {
|
||||
kind: LoanPathKind<'tcx>,
|
||||
ty: ty::Ty<'tcx>,
|
||||
}
|
||||
|
||||
impl LoanPath {
|
||||
fn kill_id(&self, tcx: &ty::ctxt) -> ast::NodeId {
|
||||
//! Returns the lifetime of the local variable that forms the
|
||||
//! base of this path. (See move_data::add_gen_kills.)
|
||||
match *self {
|
||||
LpVar(id) =>
|
||||
tcx.region_maps.var_scope(id),
|
||||
LpUpvar(ty::UpvarId { var_id: _, closure_expr_id }) =>
|
||||
closure_to_block(closure_expr_id, tcx),
|
||||
LpDowncast(ref base_lp, _) | LpExtend(ref base_lp, _, _) =>
|
||||
base_lp.kill_id(tcx),
|
||||
}
|
||||
#[deriving(PartialEq, Eq, Hash, Show)]
|
||||
pub enum LoanPathKind<'tcx> {
|
||||
LpVar(ast::NodeId), // `x` in doc.rs
|
||||
LpUpvar(ty::UpvarId), // `x` captured by-value into closure
|
||||
LpDowncast(Rc<LoanPath<'tcx>>, ast::DefId), // `x` downcast to particular enum variant
|
||||
LpExtend(Rc<LoanPath<'tcx>>, mc::MutabilityCategory, LoanPathElem)
|
||||
}
|
||||
|
||||
impl<'tcx> LoanPath<'tcx> {
|
||||
fn new(kind: LoanPathKind<'tcx>, ty: ty::Ty<'tcx>) -> LoanPath<'tcx> {
|
||||
LoanPath { kind: kind, ty: ty }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[deriving(PartialEq, Eq, Hash, Show)]
|
||||
@ -312,7 +310,7 @@ pub enum LoanPathElem {
|
||||
}
|
||||
|
||||
pub fn closure_to_block(closure_id: ast::NodeId,
|
||||
tcx: &ty::ctxt) -> ast::NodeId {
|
||||
tcx: &ty::ctxt) -> ast::NodeId {
|
||||
match tcx.map.get(closure_id) {
|
||||
ast_map::NodeExpr(expr) => match expr.node {
|
||||
ast::ExprProc(_, ref block) |
|
||||
@ -327,9 +325,9 @@ pub fn closure_to_block(closure_id: ast::NodeId,
|
||||
}
|
||||
}
|
||||
|
||||
impl LoanPath {
|
||||
pub fn kill_scope(&self, tcx: &ty::ctxt) -> region::CodeExtent {
|
||||
match *self {
|
||||
impl<'tcx> LoanPath<'tcx> {
|
||||
pub fn kill_scope(&self, tcx: &ty::ctxt<'tcx>) -> region::CodeExtent {
|
||||
match self.kind {
|
||||
LpVar(local_id) => tcx.region_maps.var_scope(local_id),
|
||||
LpUpvar(upvar_id) => {
|
||||
let block_id = closure_to_block(upvar_id.closure_expr_id, tcx);
|
||||
@ -340,8 +338,8 @@ impl LoanPath {
|
||||
}
|
||||
}
|
||||
|
||||
fn has_fork(&self, other: &LoanPath) -> bool {
|
||||
match (self, other) {
|
||||
fn has_fork(&self, other: &LoanPath<'tcx>) -> bool {
|
||||
match (&self.kind, &other.kind) {
|
||||
(&LpExtend(ref base, _, LpInterior(id)), &LpExtend(ref base2, _, LpInterior(id2))) =>
|
||||
if id == id2 {
|
||||
base.has_fork(&**base2)
|
||||
@ -355,44 +353,66 @@ impl LoanPath {
|
||||
}
|
||||
|
||||
fn depth(&self) -> uint {
|
||||
match *self {
|
||||
match self.kind {
|
||||
LpExtend(ref base, _, LpDeref(_)) => base.depth(),
|
||||
LpExtend(ref base, _, LpInterior(_)) => base.depth() + 1,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn common(&self, other: &LoanPath) -> Option<LoanPath> {
|
||||
match (self, other) {
|
||||
(&LpExtend(ref base, a, LpInterior(id)), &LpExtend(ref base2, _, LpInterior(id2))) =>
|
||||
fn common(&self, other: &LoanPath<'tcx>) -> Option<LoanPath<'tcx>> {
|
||||
match (&self.kind, &other.kind) {
|
||||
(&LpExtend(ref base, a, LpInterior(id)),
|
||||
&LpExtend(ref base2, _, LpInterior(id2))) => {
|
||||
if id == id2 {
|
||||
assert!(self.ty == other.ty);
|
||||
base.common(&**base2).map(|x| {
|
||||
let xd = x.depth();
|
||||
if base.depth() == xd && base2.depth() == xd {
|
||||
LpExtend(Rc::new(x), a, LpInterior(id))
|
||||
LoanPath {
|
||||
kind: LpExtend(Rc::new(x), a, LpInterior(id)),
|
||||
ty: self.ty,
|
||||
}
|
||||
} else {
|
||||
x
|
||||
}
|
||||
})
|
||||
} else {
|
||||
base.common(&**base2)
|
||||
},
|
||||
}
|
||||
}
|
||||
(&LpExtend(ref base, _, LpDeref(_)), _) => base.common(other),
|
||||
(_, &LpExtend(ref other, _, LpDeref(_))) => self.common(&**other),
|
||||
(&LpVar(id), &LpVar(id2)) => if id == id2 { Some(LpVar(id)) } else { None },
|
||||
(&LpUpvar(id), &LpUpvar(id2)) => if id == id2 { Some(LpUpvar(id)) } else { None },
|
||||
(&LpVar(id), &LpVar(id2)) => {
|
||||
if id == id2 {
|
||||
assert!(self.ty == other.ty);
|
||||
Some(LoanPath { kind: LpVar(id), ty: self.ty })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
(&LpUpvar(id), &LpUpvar(id2)) => {
|
||||
if id == id2 {
|
||||
assert!(self.ty == other.ty);
|
||||
Some(LoanPath { kind: LpUpvar(id), ty: self.ty })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn opt_loan_path(cmt: &mc::cmt) -> Option<Rc<LoanPath>> {
|
||||
pub fn opt_loan_path<'tcx>(cmt: &mc::cmt<'tcx>) -> Option<Rc<LoanPath<'tcx>>> {
|
||||
//! Computes the `LoanPath` (if any) for a `cmt`.
|
||||
//! Note that this logic is somewhat duplicated in
|
||||
//! the method `compute()` found in `gather_loans::restrictions`,
|
||||
//! which allows it to share common loan path pieces as it
|
||||
//! traverses the CMT.
|
||||
|
||||
let new_lp = |v: LoanPathKind<'tcx>| Rc::new(LoanPath::new(v, cmt.ty));
|
||||
|
||||
match cmt.cat {
|
||||
mc::cat_rvalue(..) |
|
||||
mc::cat_static_item => {
|
||||
@ -400,29 +420,29 @@ pub fn opt_loan_path(cmt: &mc::cmt) -> Option<Rc<LoanPath>> {
|
||||
}
|
||||
|
||||
mc::cat_local(id) => {
|
||||
Some(Rc::new(LpVar(id)))
|
||||
Some(new_lp(LpVar(id)))
|
||||
}
|
||||
|
||||
mc::cat_upvar(mc::Upvar { id, .. }) => {
|
||||
Some(Rc::new(LpUpvar(id)))
|
||||
Some(new_lp(LpUpvar(id)))
|
||||
}
|
||||
|
||||
mc::cat_deref(ref cmt_base, _, pk) => {
|
||||
opt_loan_path(cmt_base).map(|lp| {
|
||||
Rc::new(LpExtend(lp, cmt.mutbl, LpDeref(pk)))
|
||||
new_lp(LpExtend(lp, cmt.mutbl, LpDeref(pk)))
|
||||
})
|
||||
}
|
||||
|
||||
mc::cat_interior(ref cmt_base, ik) => {
|
||||
opt_loan_path(cmt_base).map(|lp| {
|
||||
Rc::new(LpExtend(lp, cmt.mutbl, LpInterior(ik)))
|
||||
new_lp(LpExtend(lp, cmt.mutbl, LpInterior(ik)))
|
||||
})
|
||||
}
|
||||
|
||||
mc::cat_downcast(ref cmt_base, variant_def_id) =>
|
||||
opt_loan_path(cmt_base)
|
||||
.map(|lp| {
|
||||
Rc::new(LpDowncast(lp, variant_def_id))
|
||||
new_lp(LpDowncast(lp, variant_def_id))
|
||||
}),
|
||||
|
||||
}
|
||||
@ -492,9 +512,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
pub fn report_use_of_moved_value(&self,
|
||||
use_span: Span,
|
||||
use_kind: MovedValueUseKind,
|
||||
lp: &LoanPath,
|
||||
lp: &LoanPath<'tcx>,
|
||||
the_move: &move_data::Move,
|
||||
moved_lp: &LoanPath) {
|
||||
moved_lp: &LoanPath<'tcx>) {
|
||||
let verb = match use_kind {
|
||||
MovedInUse => "use",
|
||||
MovedInCapture => "capture",
|
||||
@ -643,7 +663,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
|
||||
pub fn report_reassigned_immutable_variable(&self,
|
||||
span: Span,
|
||||
lp: &LoanPath,
|
||||
lp: &LoanPath<'tcx>,
|
||||
assign:
|
||||
&move_data::Assignment) {
|
||||
self.tcx.sess.span_err(
|
||||
@ -874,9 +894,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn append_loan_path_to_string(&self,
|
||||
loan_path: &LoanPath,
|
||||
out: &mut String) {
|
||||
match *loan_path {
|
||||
loan_path: &LoanPath<'tcx>,
|
||||
out: &mut String) {
|
||||
match loan_path.kind {
|
||||
LpUpvar(ty::UpvarId{ var_id: id, closure_expr_id: _ }) |
|
||||
LpVar(id) => {
|
||||
out.push_str(ty::local_var_name_str(self.tcx, id).get());
|
||||
@ -918,9 +938,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn append_autoderefd_loan_path_to_string(&self,
|
||||
loan_path: &LoanPath,
|
||||
out: &mut String) {
|
||||
match *loan_path {
|
||||
loan_path: &LoanPath<'tcx>,
|
||||
out: &mut String) {
|
||||
match loan_path.kind {
|
||||
LpExtend(ref lp_base, _, LpDeref(_)) => {
|
||||
// For a path like `(*x).f` or `(*x)[3]`, autoderef
|
||||
// rules would normally allow users to omit the `*x`.
|
||||
@ -942,7 +962,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn loan_path_to_string(&self, loan_path: &LoanPath) -> String {
|
||||
pub fn loan_path_to_string(&self, loan_path: &LoanPath<'tcx>) -> String {
|
||||
let mut result = String::new();
|
||||
self.append_loan_path_to_string(loan_path, &mut result);
|
||||
result
|
||||
@ -979,8 +999,8 @@ impl DataFlowOperator for LoanDataFlowOperator {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Repr<'tcx> for Loan {
|
||||
fn repr(&self, tcx: &ty::ctxt) -> String {
|
||||
impl<'tcx> Repr<'tcx> for Loan<'tcx> {
|
||||
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
|
||||
format!("Loan_{}({}, {}, {}-{}, {})",
|
||||
self.index,
|
||||
self.loan_path.repr(tcx),
|
||||
@ -991,19 +1011,19 @@ impl<'tcx> Repr<'tcx> for Loan {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Repr<'tcx> for LoanPath {
|
||||
fn repr(&self, tcx: &ty::ctxt) -> String {
|
||||
match self {
|
||||
&LpVar(id) => {
|
||||
impl<'tcx> Repr<'tcx> for LoanPath<'tcx> {
|
||||
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
|
||||
match self.kind {
|
||||
LpVar(id) => {
|
||||
format!("$({})", tcx.map.node_to_string(id))
|
||||
}
|
||||
|
||||
&LpUpvar(ty::UpvarId{ var_id, closure_expr_id }) => {
|
||||
LpUpvar(ty::UpvarId{ var_id, closure_expr_id }) => {
|
||||
let s = tcx.map.node_to_string(var_id);
|
||||
format!("$({} captured by id={})", s, closure_expr_id)
|
||||
}
|
||||
|
||||
&LpDowncast(ref lp, variant_def_id) => {
|
||||
LpDowncast(ref lp, variant_def_id) => {
|
||||
let variant_str = if variant_def_id.krate == ast::LOCAL_CRATE {
|
||||
ty::item_path_str(tcx, variant_def_id)
|
||||
} else {
|
||||
@ -1012,11 +1032,11 @@ impl<'tcx> Repr<'tcx> for LoanPath {
|
||||
format!("({}->{})", lp.repr(tcx), variant_str)
|
||||
}
|
||||
|
||||
&LpExtend(ref lp, _, LpDeref(_)) => {
|
||||
LpExtend(ref lp, _, LpDeref(_)) => {
|
||||
format!("{}.*", lp.repr(tcx))
|
||||
}
|
||||
|
||||
&LpExtend(ref lp, _, LpInterior(ref interior)) => {
|
||||
LpExtend(ref lp, _, LpInterior(ref interior)) => {
|
||||
format!("{}.{}", lp.repr(tcx), interior.repr(tcx))
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::uint;
|
||||
use middle::borrowck::*;
|
||||
use middle::borrowck::LoanPathKind::{LpVar, LpUpvar, LpDowncast, LpExtend};
|
||||
use middle::borrowck::LoanPathElem::{LpInterior};
|
||||
use middle::cfg;
|
||||
use middle::dataflow::DataFlowContext;
|
||||
use middle::dataflow::BitwiseOperator;
|
||||
@ -34,12 +36,12 @@ use syntax::codemap::Span;
|
||||
use util::nodemap::{FnvHashMap, NodeSet};
|
||||
use util::ppaux::Repr;
|
||||
|
||||
pub struct MoveData {
|
||||
pub struct MoveData<'tcx> {
|
||||
/// Move paths. See section "Move paths" in `doc.rs`.
|
||||
pub paths: RefCell<Vec<MovePath>>,
|
||||
pub paths: RefCell<Vec<MovePath<'tcx>>>,
|
||||
|
||||
/// Cache of loan path to move path index, for easy lookup.
|
||||
pub path_map: RefCell<FnvHashMap<Rc<LoanPath>, MovePathIndex>>,
|
||||
pub path_map: RefCell<FnvHashMap<Rc<LoanPath<'tcx>>, MovePathIndex>>,
|
||||
|
||||
/// Each move or uninitialized variable gets an entry here.
|
||||
pub moves: RefCell<Vec<Move>>,
|
||||
@ -59,7 +61,7 @@ pub struct MoveData {
|
||||
}
|
||||
|
||||
pub struct FlowedMoveData<'a, 'tcx: 'a> {
|
||||
pub move_data: MoveData,
|
||||
pub move_data: MoveData<'tcx>,
|
||||
|
||||
pub dfcx_moves: MoveDataFlow<'a, 'tcx>,
|
||||
|
||||
@ -103,9 +105,9 @@ impl MoveIndex {
|
||||
static InvalidMoveIndex: MoveIndex =
|
||||
MoveIndex(uint::MAX);
|
||||
|
||||
pub struct MovePath {
|
||||
pub struct MovePath<'tcx> {
|
||||
/// Loan path corresponding to this move path
|
||||
pub loan_path: Rc<LoanPath>,
|
||||
pub loan_path: Rc<LoanPath<'tcx>>,
|
||||
|
||||
/// Parent pointer, `InvalidMovePathIndex` if root
|
||||
pub parent: MovePathIndex,
|
||||
@ -166,7 +168,7 @@ pub struct AssignDataFlowOperator;
|
||||
pub type AssignDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, AssignDataFlowOperator>;
|
||||
|
||||
fn loan_path_is_precise(loan_path: &LoanPath) -> bool {
|
||||
match *loan_path {
|
||||
match loan_path.kind {
|
||||
LpVar(_) | LpUpvar(_) => {
|
||||
true
|
||||
}
|
||||
@ -182,8 +184,8 @@ fn loan_path_is_precise(loan_path: &LoanPath) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
impl MoveData {
|
||||
pub fn new() -> MoveData {
|
||||
impl<'tcx> MoveData<'tcx> {
|
||||
pub fn new() -> MoveData<'tcx> {
|
||||
MoveData {
|
||||
paths: RefCell::new(Vec::new()),
|
||||
path_map: RefCell::new(FnvHashMap::new()),
|
||||
@ -194,7 +196,7 @@ impl MoveData {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn path_loan_path(&self, index: MovePathIndex) -> Rc<LoanPath> {
|
||||
pub fn path_loan_path(&self, index: MovePathIndex) -> Rc<LoanPath<'tcx>> {
|
||||
(*self.paths.borrow())[index.get()].loan_path.clone()
|
||||
}
|
||||
|
||||
@ -237,8 +239,8 @@ impl MoveData {
|
||||
}
|
||||
|
||||
pub fn move_path(&self,
|
||||
tcx: &ty::ctxt,
|
||||
lp: Rc<LoanPath>) -> MovePathIndex {
|
||||
tcx: &ty::ctxt<'tcx>,
|
||||
lp: Rc<LoanPath<'tcx>>) -> MovePathIndex {
|
||||
/*!
|
||||
* Returns the existing move path index for `lp`, if any,
|
||||
* and otherwise adds a new index for `lp` and any of its
|
||||
@ -252,7 +254,7 @@ impl MoveData {
|
||||
None => {}
|
||||
}
|
||||
|
||||
let index = match *lp {
|
||||
let index = match lp.kind {
|
||||
LpVar(..) | LpUpvar(..) => {
|
||||
let index = MovePathIndex(self.paths.borrow().len());
|
||||
|
||||
@ -297,19 +299,19 @@ impl MoveData {
|
||||
return index;
|
||||
}
|
||||
|
||||
fn existing_move_path(&self, lp: &Rc<LoanPath>)
|
||||
fn existing_move_path(&self, lp: &Rc<LoanPath<'tcx>>)
|
||||
-> Option<MovePathIndex> {
|
||||
self.path_map.borrow().get(lp).cloned()
|
||||
}
|
||||
|
||||
fn existing_base_paths(&self, lp: &Rc<LoanPath>)
|
||||
fn existing_base_paths(&self, lp: &Rc<LoanPath<'tcx>>)
|
||||
-> Vec<MovePathIndex> {
|
||||
let mut result = vec!();
|
||||
self.add_existing_base_paths(lp, &mut result);
|
||||
result
|
||||
}
|
||||
|
||||
fn add_existing_base_paths(&self, lp: &Rc<LoanPath>,
|
||||
fn add_existing_base_paths(&self, lp: &Rc<LoanPath<'tcx>>,
|
||||
result: &mut Vec<MovePathIndex>) {
|
||||
/*!
|
||||
* Adds any existing move path indices for `lp` and any base
|
||||
@ -324,7 +326,7 @@ impl MoveData {
|
||||
});
|
||||
}
|
||||
None => {
|
||||
match **lp {
|
||||
match lp.kind {
|
||||
LpVar(..) | LpUpvar(..) => { }
|
||||
LpDowncast(ref b, _) |
|
||||
LpExtend(ref b, _, _) => {
|
||||
@ -337,8 +339,8 @@ impl MoveData {
|
||||
}
|
||||
|
||||
pub fn add_move(&self,
|
||||
tcx: &ty::ctxt,
|
||||
lp: Rc<LoanPath>,
|
||||
tcx: &ty::ctxt<'tcx>,
|
||||
lp: Rc<LoanPath<'tcx>>,
|
||||
id: ast::NodeId,
|
||||
kind: MoveKind) {
|
||||
/*!
|
||||
@ -366,8 +368,8 @@ impl MoveData {
|
||||
}
|
||||
|
||||
pub fn add_assignment(&self,
|
||||
tcx: &ty::ctxt,
|
||||
lp: Rc<LoanPath>,
|
||||
tcx: &ty::ctxt<'tcx>,
|
||||
lp: Rc<LoanPath<'tcx>>,
|
||||
assign_id: ast::NodeId,
|
||||
span: Span,
|
||||
assignee_id: ast::NodeId,
|
||||
@ -409,7 +411,7 @@ impl MoveData {
|
||||
}
|
||||
|
||||
fn add_gen_kills(&self,
|
||||
tcx: &ty::ctxt,
|
||||
tcx: &ty::ctxt<'tcx>,
|
||||
dfcx_moves: &mut MoveDataFlow,
|
||||
dfcx_assign: &mut AssignDataFlow) {
|
||||
/*!
|
||||
@ -436,10 +438,10 @@ impl MoveData {
|
||||
// Kill all moves related to a variable `x` when it goes out
|
||||
// of scope:
|
||||
for path in self.paths.borrow().iter() {
|
||||
match *path.loan_path {
|
||||
match path.loan_path.kind {
|
||||
LpVar(..) | LpUpvar(..) | LpDowncast(..) => {
|
||||
let kill_scope = path.loan_path.kill_scope(tcx);
|
||||
let path = *self.path_map.borrow().get(&path.loan_path);
|
||||
let path = self.path_map.borrow()[path.loan_path];
|
||||
self.kill_moves(path, kill_scope.node_id(), dfcx_moves);
|
||||
}
|
||||
LpExtend(..) => {}
|
||||
@ -450,7 +452,7 @@ impl MoveData {
|
||||
for (assignment_index, assignment) in
|
||||
self.var_assignments.borrow().iter().enumerate() {
|
||||
let lp = self.path_loan_path(assignment.path);
|
||||
match *lp {
|
||||
match lp.kind {
|
||||
LpVar(..) | LpUpvar(..) | LpDowncast(..) => {
|
||||
let kill_scope = lp.kill_scope(tcx);
|
||||
dfcx_assign.add_kill(kill_scope.node_id(), assignment_index);
|
||||
@ -531,7 +533,7 @@ impl MoveData {
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
|
||||
pub fn new(move_data: MoveData,
|
||||
pub fn new(move_data: MoveData<'tcx>,
|
||||
tcx: &'a ty::ctxt<'tcx>,
|
||||
cfg: &cfg::CFG,
|
||||
id_range: ast_util::IdRange,
|
||||
@ -569,7 +571,7 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
|
||||
|
||||
pub fn kind_of_move_of_path(&self,
|
||||
id: ast::NodeId,
|
||||
loan_path: &Rc<LoanPath>)
|
||||
loan_path: &Rc<LoanPath<'tcx>>)
|
||||
-> Option<MoveKind> {
|
||||
//! Returns the kind of a move of `loan_path` by `id`, if one exists.
|
||||
|
||||
@ -591,8 +593,8 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
|
||||
|
||||
pub fn each_move_of(&self,
|
||||
id: ast::NodeId,
|
||||
loan_path: &Rc<LoanPath>,
|
||||
f: |&Move, &LoanPath| -> bool)
|
||||
loan_path: &Rc<LoanPath<'tcx>>,
|
||||
f: |&Move, &LoanPath<'tcx>| -> bool)
|
||||
-> bool {
|
||||
/*!
|
||||
* Iterates through each move of `loan_path` (or some base path
|
||||
@ -651,7 +653,7 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
|
||||
|
||||
pub fn each_assignment_of(&self,
|
||||
id: ast::NodeId,
|
||||
loan_path: &Rc<LoanPath>,
|
||||
loan_path: &Rc<LoanPath<'tcx>>,
|
||||
f: |&Assignment| -> bool)
|
||||
-> bool {
|
||||
/*!
|
||||
|
@ -98,7 +98,7 @@ pub enum categorization<'tcx> {
|
||||
cat_local(ast::NodeId), // local variable
|
||||
cat_deref(cmt<'tcx>, uint, PointerKind), // deref of a ptr
|
||||
cat_interior(cmt<'tcx>, InteriorKind), // something interior: field, tuple, etc
|
||||
cat_downcast(cmt, ast::DefId), // selects a particular enum variant (*1)
|
||||
cat_downcast(cmt<'tcx>, ast::DefId), // selects a particular enum variant (*1)
|
||||
|
||||
// (*1) downcast is only required if the enum has more than one variant
|
||||
}
|
||||
@ -1118,7 +1118,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
||||
pub fn cat_pattern(&self,
|
||||
cmt: cmt<'tcx>,
|
||||
pat: &ast::Pat,
|
||||
op: |&MemCategorizationContext<TYPER>,
|
||||
op: |&MemCategorizationContext<'t,TYPER>,
|
||||
cmt<'tcx>,
|
||||
&ast::Pat|)
|
||||
-> McResult<()> {
|
||||
|
Loading…
Reference in New Issue
Block a user