diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 13849512ba6e4..e09507f5d5f44 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -390,10 +390,9 @@ impl<'a> CheckLoanCtxt<'a> { // Mutable values can be assigned, as long as they obey loans // and aliasing restrictions: if cmt.mutbl.is_mutable() { - if check_for_aliasable_mutable_writes(self, expr, cmt) { + if check_for_aliasable_mutable_writes(self, expr, cmt.clone()) { if check_for_assignment_to_restricted_or_frozen_location( - self, expr, cmt) - { + self, expr, cmt.clone()) { // Safe, but record for lint pass later: mark_variable_as_used_mut(self, cmt); } @@ -403,9 +402,9 @@ impl<'a> CheckLoanCtxt<'a> { // For immutable local variables, assignments are legal // if they cannot already have been assigned - if self.is_local_variable(cmt) { + if self.is_local_variable(cmt.clone()) { assert!(cmt.mutbl.is_immutable()); // no "const" locals - let lp = opt_loan_path(cmt).unwrap(); + let lp = opt_loan_path(&cmt).unwrap(); self.move_data.each_assignment_of(expr.id, &lp, |assign| { self.bccx.report_reassigned_immutable_variable( expr.span, @@ -417,13 +416,13 @@ impl<'a> CheckLoanCtxt<'a> { } // Otherwise, just a plain error. - match opt_loan_path(cmt) { + match opt_loan_path(&cmt) { Some(lp) => { self.bccx.span_err( expr.span, format!("cannot assign to {} {} `{}`", cmt.mutbl.to_user_str(), - self.bccx.cmt_to_str(cmt), + self.bccx.cmt_to_str(&*cmt), self.bccx.loan_path_to_str(&*lp))); } None => { @@ -431,7 +430,7 @@ impl<'a> CheckLoanCtxt<'a> { expr.span, format!("cannot assign to {} {}", cmt.mutbl.to_user_str(), - self.bccx.cmt_to_str(cmt))); + self.bccx.cmt_to_str(&*cmt))); } } return; @@ -448,7 +447,7 @@ impl<'a> CheckLoanCtxt<'a> { loop { debug!("mark_writes_through_upvars_as_used_mut(cmt={})", cmt.repr(this.tcx())); - match cmt.cat { + match cmt.cat.clone() { mc::cat_local(id) | mc::cat_arg(id) => { this.tcx().used_mut_nodes.borrow_mut().insert(id); return; @@ -496,10 +495,10 @@ impl<'a> CheckLoanCtxt<'a> { debug!("check_for_aliasable_mutable_writes(cmt={}, guarantor={})", cmt.repr(this.tcx()), guarantor.repr(this.tcx())); match guarantor.cat { - mc::cat_deref(b, _, mc::BorrowedPtr(ty::MutBorrow, _)) => { + mc::cat_deref(ref b, _, mc::BorrowedPtr(ty::MutBorrow, _)) => { // Statically prohibit writes to `&mut` when aliasable - check_for_aliasability_violation(this, expr, b); + check_for_aliasability_violation(this, expr, b.clone()); } _ => {} @@ -537,7 +536,7 @@ impl<'a> CheckLoanCtxt<'a> { //! Check for assignments that violate the terms of an //! outstanding loan. - let loan_path = match opt_loan_path(cmt) { + let loan_path = match opt_loan_path(&cmt) { Some(lp) => lp, None => { return true; /* no loan path, can't be any loans */ } }; @@ -814,7 +813,7 @@ fn check_loans_in_expr<'a>(this: &mut CheckLoanCtxt<'a>, if !this.move_data.is_assignee(expr.id) { let cmt = this.bccx.cat_expr_unadjusted(expr); debug!("path cmt={}", cmt.repr(this.tcx())); - for lp in opt_loan_path(cmt).iter() { + for lp in opt_loan_path(&cmt).iter() { this.check_if_path_is_moved(expr.id, expr.span, MovedInUse, lp); } } diff --git a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs index b44db1f3fc9aa..f4eee0526dd93 100644 --- a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs @@ -23,6 +23,8 @@ use syntax::ast; use syntax::codemap::Span; use util::ppaux::Repr; +use std::rc::Rc; + struct GatherMoveInfo { id: ast::NodeId, kind: MoveKind, @@ -30,8 +32,6 @@ struct GatherMoveInfo { span_path_opt: Option } -use std::rc::Rc; - pub fn gather_decl(bccx: &BorrowckCtxt, move_data: &MoveData, decl_id: ast::NodeId, @@ -107,7 +107,7 @@ fn gather_move(bccx: &BorrowckCtxt, move_info.id, move_info.cmt.repr(bccx.tcx)); let potentially_illegal_move = - check_and_get_illegal_move_origin(bccx, move_info.cmt); + check_and_get_illegal_move_origin(bccx, &move_info.cmt); match potentially_illegal_move { Some(illegal_move_origin) => { let error = MoveError::with_move_info(illegal_move_origin, @@ -118,7 +118,7 @@ fn gather_move(bccx: &BorrowckCtxt, None => () } - match opt_loan_path(move_info.cmt) { + match opt_loan_path(&move_info.cmt) { Some(loan_path) => { move_data.add_move(bccx.tcx, loan_path, move_info.id, move_info.kind); @@ -158,14 +158,14 @@ pub fn gather_move_and_assignment(bccx: &BorrowckCtxt, } fn check_and_get_illegal_move_origin(bccx: &BorrowckCtxt, - cmt: mc::cmt) -> Option { + cmt: &mc::cmt) -> Option { match cmt.cat { mc::cat_deref(_, _, mc::BorrowedPtr(..)) | mc::cat_deref(_, _, mc::GcPtr) | mc::cat_deref(_, _, mc::UnsafePtr(..)) | mc::cat_upvar(..) | mc::cat_static_item | mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Many, .. }) => { - Some(cmt) + Some(cmt.clone()) } // Can move out of captured upvars only if the destination closure @@ -181,12 +181,12 @@ fn check_and_get_illegal_move_origin(bccx: &BorrowckCtxt, None } - mc::cat_downcast(b) | - mc::cat_interior(b, _) => { + mc::cat_downcast(ref b) | + mc::cat_interior(ref b, _) => { match ty::get(b.ty).sty { ty::ty_struct(did, _) | ty::ty_enum(did, _) => { if ty::has_dtor(bccx.tcx, did) { - Some(cmt) + Some(cmt.clone()) } else { check_and_get_illegal_move_origin(bccx, b) } @@ -197,8 +197,8 @@ fn check_and_get_illegal_move_origin(bccx: &BorrowckCtxt, } } - mc::cat_deref(b, _, mc::OwnedPtr) | - mc::cat_discr(b, _) => { + mc::cat_deref(ref b, _, mc::OwnedPtr) | + mc::cat_discr(ref b, _) => { check_and_get_illegal_move_origin(bccx, b) } } diff --git a/src/librustc/middle/borrowck/gather_loans/lifetime.rs b/src/librustc/middle/borrowck/gather_loans/lifetime.rs index a04afd6d5f386..a27fe5cec2252 100644 --- a/src/librustc/middle/borrowck/gather_loans/lifetime.rs +++ b/src/librustc/middle/borrowck/gather_loans/lifetime.rs @@ -39,9 +39,9 @@ pub fn guarantee_lifetime(bccx: &BorrowckCtxt, cause: cause, loan_region: loan_region, loan_kind: loan_kind, - cmt_original: cmt, + cmt_original: cmt.clone(), root_scope_id: root_scope_id}; - ctxt.check(cmt, None) + ctxt.check(&cmt, None) } /////////////////////////////////////////////////////////////////////////// @@ -69,7 +69,7 @@ impl<'a> GuaranteeLifetimeContext<'a> { self.bccx.tcx } - fn check(&self, cmt: mc::cmt, discr_scope: Option) -> R { + fn check(&self, cmt: &mc::cmt, discr_scope: Option) -> R { //! Main routine. Walks down `cmt` until we find the "guarantor". debug!("guarantee_lifetime.check(cmt={}, loan_region={})", cmt.repr(self.bccx.tcx), @@ -83,15 +83,14 @@ impl<'a> GuaranteeLifetimeContext<'a> { mc::cat_upvar(..) | mc::cat_deref(_, _, mc::BorrowedPtr(..)) | // L-Deref-Borrowed mc::cat_deref(_, _, mc::UnsafePtr(..)) => { - let scope = self.scope(cmt); - self.check_scope(scope) + self.check_scope(self.scope(cmt)) } mc::cat_static_item => { Ok(()) } - mc::cat_deref(base, derefs, mc::GcPtr) => { + mc::cat_deref(ref base, derefs, mc::GcPtr) => { let base_scope = self.scope(base); // L-Deref-Managed-Imm-User-Root @@ -111,13 +110,13 @@ impl<'a> GuaranteeLifetimeContext<'a> { } } - mc::cat_downcast(base) | - mc::cat_deref(base, _, mc::OwnedPtr) | // L-Deref-Send - mc::cat_interior(base, _) => { // L-Field + mc::cat_downcast(ref base) | + mc::cat_deref(ref base, _, mc::OwnedPtr) | // L-Deref-Send + mc::cat_interior(ref base, _) => { // L-Field self.check(base, discr_scope) } - mc::cat_discr(base, new_discr_scope) => { + mc::cat_discr(ref base, new_discr_scope) => { // Subtle: in a match, we must ensure that each binding // variable remains valid for the duration of the arm in // which it appears, presuming that this arm is taken. @@ -176,7 +175,7 @@ impl<'a> GuaranteeLifetimeContext<'a> { } fn is_rvalue_or_immutable(&self, - cmt: mc::cmt) -> bool { + cmt: &mc::cmt) -> bool { //! We can omit the root on an `@T` value if the location //! that holds the box is either (1) an rvalue, in which case //! it is in a non-user-accessible temporary, or (2) an immutable @@ -189,8 +188,8 @@ impl<'a> GuaranteeLifetimeContext<'a> { } fn check_root(&self, - cmt_deref: mc::cmt, - cmt_base: mc::cmt, + cmt_deref: &mc::cmt, + cmt_base: &mc::cmt, derefs: uint, discr_scope: Option) -> R { debug!("check_root(cmt_deref={}, cmt_base={}, derefs={:?}, \ @@ -253,7 +252,7 @@ impl<'a> GuaranteeLifetimeContext<'a> { } } - fn is_moved(&self, cmt: mc::cmt) -> bool { + fn is_moved(&self, cmt: &mc::cmt) -> bool { //! True if `cmt` is something that is potentially moved //! out of the current stack frame. @@ -269,9 +268,9 @@ impl<'a> GuaranteeLifetimeContext<'a> { mc::cat_upvar(..) => { false } - r @ mc::cat_downcast(..) | - r @ mc::cat_interior(..) | - r @ mc::cat_discr(..) => { + ref r @ mc::cat_downcast(..) | + ref r @ mc::cat_interior(..) | + ref r @ mc::cat_discr(..) => { self.tcx().sess.span_bug( cmt.span, format!("illegal guarantor category: {:?}", r)); @@ -279,7 +278,7 @@ impl<'a> GuaranteeLifetimeContext<'a> { } } - fn scope(&self, cmt: mc::cmt) -> ty::Region { + fn scope(&self, cmt: &mc::cmt) -> ty::Region { //! Returns the maximal region scope for the which the //! lvalue `cmt` is guaranteed to be valid without any //! rooting etc, and presuming `cmt` is not mutated. @@ -307,18 +306,18 @@ impl<'a> GuaranteeLifetimeContext<'a> { mc::cat_deref(_, _, mc::BorrowedPtr(_, r)) => { r } - mc::cat_downcast(cmt) | - mc::cat_deref(cmt, _, mc::OwnedPtr) | - mc::cat_deref(cmt, _, mc::GcPtr) | - mc::cat_interior(cmt, _) | - mc::cat_discr(cmt, _) => { + mc::cat_downcast(ref cmt) | + mc::cat_deref(ref cmt, _, mc::OwnedPtr) | + mc::cat_deref(ref cmt, _, mc::GcPtr) | + mc::cat_interior(ref cmt, _) | + mc::cat_discr(ref cmt, _) => { self.scope(cmt) } } } fn report_error(&self, code: bckerr_code) { - self.bccx.report(BckError { cmt: self.cmt_original, + self.bccx.report(BckError { cmt: self.cmt_original.clone(), span: self.span, cause: self.cause, code: code }); diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs index 106c2a5ee525a..7f748dffd702b 100644 --- a/src/librustc/middle/borrowck/gather_loans/mod.rs +++ b/src/librustc/middle/borrowck/gather_loans/mod.rs @@ -230,7 +230,7 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt, let cmt = this.bccx.cat_expr(ex_v); for arm in arms.iter() { for pat in arm.pats.iter() { - this.gather_pat(cmt, *pat, Some((arm.body.id, ex.id))); + this.gather_pat(cmt.clone(), *pat, Some((arm.body.id, ex.id))); } } visit::walk_expr(this, ex, ()); @@ -300,7 +300,7 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt, fn with_assignee_loan_path(bccx: &BorrowckCtxt, expr: &ast::Expr, op: |Rc|) { let cmt = bccx.cat_expr(expr); - match opt_loan_path(cmt) { + match opt_loan_path(&cmt) { Some(lp) => op(lp), None => { // This can occur with e.g. `*foo() = 5`. In such @@ -552,20 +552,20 @@ impl<'a> GatherLoanCtxt<'a> { // Check that the lifetime of the borrow does not exceed // the lifetime of the data being borrowed. if lifetime::guarantee_lifetime(self.bccx, self.item_ub, root_ub, - borrow_span, cause, cmt, loan_region, + borrow_span, cause, cmt.clone(), loan_region, req_kind).is_err() { return; // reported an error, no sense in reporting more. } // Check that we don't allow mutable borrows of non-mutable data. if check_mutability(self.bccx, borrow_span, cause, - cmt, req_kind).is_err() { + cmt.clone(), req_kind).is_err() { return; // reported an error, no sense in reporting more. } // Check that we don't allow mutable borrows of aliasable data. if check_aliasability(self.bccx, borrow_span, cause, - cmt, req_kind).is_err() { + cmt.clone(), req_kind).is_err() { return; // reported an error, no sense in reporting more. } @@ -573,7 +573,7 @@ impl<'a> GatherLoanCtxt<'a> { // loan is safe. let restr = restrictions::compute_restrictions( self.bccx, borrow_span, cause, - cmt, loan_region, self.restriction_set(req_kind)); + cmt.clone(), loan_region, self.restriction_set(req_kind)); // Create the loan record (if needed). let loan = match restr { diff --git a/src/librustc/middle/borrowck/gather_loans/move_error.rs b/src/librustc/middle/borrowck/gather_loans/move_error.rs index c9a8df0f53595..24d873e0ff76b 100644 --- a/src/librustc/middle/borrowck/gather_loans/move_error.rs +++ b/src/librustc/middle/borrowck/gather_loans/move_error.rs @@ -79,7 +79,7 @@ pub struct GroupedMoveErrors { fn report_move_errors(bccx: &BorrowckCtxt, errors: &Vec) { let grouped_errors = group_errors_with_same_origin(errors); for error in grouped_errors.iter() { - report_cannot_move_out_of(bccx, error.move_from); + report_cannot_move_out_of(bccx, error.move_from.clone()); let mut is_first_note = true; for move_to in error.move_to_places.iter() { note_move_destination(bccx, move_to.span, @@ -112,7 +112,7 @@ fn group_errors_with_same_origin(errors: &Vec) } } grouped_errors.push(GroupedMoveErrors { - move_from: error.move_from, + move_from: error.move_from.clone(), move_to_places: move_to }) } @@ -128,11 +128,11 @@ fn report_cannot_move_out_of(bccx: &BorrowckCtxt, move_from: mc::cmt) { bccx.span_err( move_from.span, format!("cannot move out of {}", - bccx.cmt_to_str(move_from))); + bccx.cmt_to_str(&*move_from))); } - mc::cat_downcast(b) | - mc::cat_interior(b, _) => { + mc::cat_downcast(ref b) | + mc::cat_interior(ref b, _) => { match ty::get(b.ty).sty { ty::ty_struct(did, _) | ty::ty_enum(did, _) if ty::has_dtor(bccx.tcx, did) => { diff --git a/src/librustc/middle/borrowck/gather_loans/restrictions.rs b/src/librustc/middle/borrowck/gather_loans/restrictions.rs index c4e1b0bf27f35..de4ce84fb0a59 100644 --- a/src/librustc/middle/borrowck/gather_loans/restrictions.rs +++ b/src/librustc/middle/borrowck/gather_loans/restrictions.rs @@ -35,7 +35,7 @@ pub fn compute_restrictions(bccx: &BorrowckCtxt, bccx: bccx, span: span, cause: cause, - cmt_original: cmt, + cmt_original: cmt.clone(), loan_region: loan_region, }; @@ -61,7 +61,7 @@ impl<'a> RestrictionsContext<'a> { cmt.repr(self.bccx.tcx), restrictions.repr(self.bccx.tcx)); - match cmt.cat { + match cmt.cat.clone() { mc::cat_rvalue(..) => { // Effectively, rvalues are stored into a // non-aliasable temporary on the stack. Since they diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index ba01e4aa4189c..06491d36b021b 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -225,7 +225,7 @@ impl LoanPath { } } -pub fn opt_loan_path(cmt: mc::cmt) -> Option> { +pub fn opt_loan_path(cmt: &mc::cmt) -> Option> { //! Computes the `LoanPath` (if any) for a `cmt`. //! Note that this logic is somewhat duplicated in //! the method `compute()` found in `gather_loans::restrictions`, @@ -246,20 +246,20 @@ pub fn opt_loan_path(cmt: mc::cmt) -> Option> { Some(Rc::new(LpVar(id))) } - mc::cat_deref(cmt_base, _, pk) => { + mc::cat_deref(ref cmt_base, _, pk) => { opt_loan_path(cmt_base).map(|lp| { Rc::new(LpExtend(lp, cmt.mutbl, LpDeref(pk))) }) } - mc::cat_interior(cmt_base, ik) => { + mc::cat_interior(ref cmt_base, ik) => { opt_loan_path(cmt_base).map(|lp| { Rc::new(LpExtend(lp, cmt.mutbl, LpInterior(ik))) }) } - mc::cat_downcast(cmt_base) | - mc::cat_discr(cmt_base, _) => { + mc::cat_downcast(ref cmt_base) | + mc::cat_discr(ref cmt_base, _) => { opt_loan_path(cmt_base) } } @@ -469,14 +469,16 @@ impl<'a> BorrowckCtxt<'a> { } pub fn cat_discr(&self, cmt: mc::cmt, match_id: ast::NodeId) -> mc::cmt { - @mc::cmt_ {cat:mc::cat_discr(cmt, match_id), - mutbl:cmt.mutbl.inherit(), - ..*cmt} + Rc::new(mc::cmt_ { + cat: mc::cat_discr(cmt.clone(), match_id), + mutbl: cmt.mutbl.inherit(), + ..*cmt + }) } pub fn cat_pattern(&self, cmt: mc::cmt, - pat: @ast::Pat, + pat: &ast::Pat, op: |mc::cmt, &ast::Pat|) { let r = self.mc().cat_pattern(cmt, pat, |_,x,y| op(x,y)); assert!(r.is_ok()); @@ -485,7 +487,7 @@ impl<'a> BorrowckCtxt<'a> { pub fn report(&self, err: BckError) { self.span_err( err.span, - self.bckerr_to_str(err)); + self.bckerr_to_str(&err)); self.note_and_explain_bckerr(err); } @@ -607,16 +609,16 @@ impl<'a> BorrowckCtxt<'a> { self.tcx.sess.span_end_note(s, m); } - pub fn bckerr_to_str(&self, err: BckError) -> ~str { + pub fn bckerr_to_str(&self, err: &BckError) -> ~str { match err.code { err_mutbl => { - let descr = match opt_loan_path(err.cmt) { + let descr = match opt_loan_path(&err.cmt) { None => format!("{} {}", err.cmt.mutbl.to_user_str(), - self.cmt_to_str(err.cmt)), + self.cmt_to_str(&*err.cmt)), Some(lp) => format!("{} {} `{}`", err.cmt.mutbl.to_user_str(), - self.cmt_to_str(err.cmt), + self.cmt_to_str(&*err.cmt), self.loan_path_to_str(&*lp)), }; @@ -633,16 +635,16 @@ impl<'a> BorrowckCtxt<'a> { format!("cannot root managed value long enough") } err_out_of_scope(..) => { - let msg = match opt_loan_path(err.cmt) { + let msg = match opt_loan_path(&err.cmt) { None => format!("borrowed value"), Some(lp) => format!("`{}`", self.loan_path_to_str(&*lp)), }; format!("{} does not live long enough", msg) } err_borrowed_pointer_too_short(..) => { - let descr = match opt_loan_path(err.cmt) { + let descr = match opt_loan_path(&err.cmt) { Some(lp) => format!("`{}`", self.loan_path_to_str(&*lp)), - None => self.cmt_to_str(err.cmt), + None => self.cmt_to_str(&*err.cmt), }; format!("lifetime of {} is too short to guarantee \ @@ -734,9 +736,9 @@ impl<'a> BorrowckCtxt<'a> { } err_borrowed_pointer_too_short(loan_scope, ptr_scope, _) => { - let descr = match opt_loan_path(err.cmt) { + let descr = match opt_loan_path(&err.cmt) { Some(lp) => format!("`{}`", self.loan_path_to_str(&*lp)), - None => self.cmt_to_str(err.cmt), + None => self.cmt_to_str(&*err.cmt), }; note_and_explain_region( self.tcx, @@ -809,7 +811,7 @@ impl<'a> BorrowckCtxt<'a> { result.into_owned() } - pub fn cmt_to_str(&self, cmt: mc::cmt) -> ~str { + pub fn cmt_to_str(&self, cmt: &mc::cmt_) -> ~str { self.mc().cmt_to_str(cmt) } } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 1a54d7d937f55..35124aa991699 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -74,8 +74,9 @@ use syntax::print::pprust; use syntax::parse::token; use std::cell::RefCell; +use std::rc::Rc; -#[deriving(Eq)] +#[deriving(Clone, Eq)] pub enum categorization { cat_rvalue(ty::Region), // temporary val, argument is its scope cat_static_item, @@ -91,14 +92,14 @@ pub enum categorization { // (*1) downcast is only required if the enum has more than one variant } -#[deriving(Eq)] +#[deriving(Clone, Eq)] pub struct CopiedUpvar { pub upvar_id: ast::NodeId, pub onceness: ast::Onceness, } // different kinds of pointers: -#[deriving(Eq, TotalEq, Hash)] +#[deriving(Clone, Eq, TotalEq, Hash)] pub enum PointerKind { OwnedPtr, GcPtr, @@ -108,26 +109,26 @@ pub enum PointerKind { // We use the term "interior" to mean "something reachable from the // base without a pointer dereference", e.g. a field -#[deriving(Eq, TotalEq, Hash)] +#[deriving(Clone, Eq, TotalEq, Hash)] pub enum InteriorKind { InteriorField(FieldName), InteriorElement(ElementKind), } -#[deriving(Eq, TotalEq, Hash)] +#[deriving(Clone, Eq, TotalEq, Hash)] pub enum FieldName { NamedField(ast::Name), PositionalField(uint) } -#[deriving(Eq, TotalEq, Hash)] +#[deriving(Clone, Eq, TotalEq, Hash)] pub enum ElementKind { VecElement, StrElement, OtherElement, } -#[deriving(Eq, TotalEq, Hash, Show)] +#[deriving(Clone, Eq, TotalEq, Hash, Show)] pub enum MutabilityCategory { McImmutable, // Immutable. McDeclared, // Directly declared as mutable. @@ -148,7 +149,7 @@ pub enum MutabilityCategory { // dereference, but its type is the type *before* the dereference // (`@T`). So use `cmt.type` to find the type of the value in a consistent // fashion. For more details, see the method `cat_pattern` -#[deriving(Eq)] +#[deriving(Clone, Eq)] pub struct cmt_ { pub id: ast::NodeId, // id of expr/pat producing this value pub span: Span, // span of same expr/pat @@ -157,7 +158,7 @@ pub struct cmt_ { pub ty: ty::t // type of the expr (*see WARNING above*) } -pub type cmt = @cmt_; +pub type cmt = Rc; // We pun on *T to mean both actual deref of a ptr as well // as accessing of components: @@ -368,7 +369,7 @@ impl MemCategorizationContext { self.typer.node_ty(id) } - fn pat_ty(&self, pat: @ast::Pat) -> McResult { + fn pat_ty(&self, pat: &ast::Pat) -> McResult { self.typer.node_ty(pat.id) } @@ -385,8 +386,9 @@ impl MemCategorizationContext { // Implicity casts a concrete object to trait object // so just patch up the type let expr_ty = if_ok!(self.expr_ty_adjusted(expr)); - let expr_cmt = if_ok!(self.cat_expr_unadjusted(expr)); - Ok(@cmt_ {ty: expr_ty, ..*expr_cmt}) + let mut expr_cmt = (*if_ok!(self.cat_expr_unadjusted(expr))).clone(); + expr_cmt.ty = expr_ty; + Ok(Rc::new(expr_cmt)) } ty::AutoAddEnv(..) => { @@ -492,23 +494,23 @@ impl MemCategorizationContext { ast::DefUse(_) | ast::DefTrait(_) | ast::DefTy(_) | ast::DefPrimTy(_) | ast::DefTyParam(..) | ast::DefTyParamBinder(..) | ast::DefRegion(_) | ast::DefLabel(_) | ast::DefSelfTy(..) | ast::DefMethod(..) => { - Ok(@cmt_ { + Ok(Rc::new(cmt_ { id:id, span:span, cat:cat_static_item, mutbl: McImmutable, ty:expr_ty - }) + })) } ast::DefStatic(_, true) => { - Ok(@cmt_ { + Ok(Rc::new(cmt_ { id:id, span:span, cat:cat_static_item, mutbl: McDeclared, ty:expr_ty - }) + })) } ast::DefArg(vid, binding_mode) => { @@ -520,13 +522,13 @@ impl MemCategorizationContext { ast::BindByValue(ast::MutMutable) => McDeclared, _ => McImmutable }; - Ok(@cmt_ { + Ok(Rc::new(cmt_ { id: id, span: span, cat: cat_arg(vid), mutbl: m, ty:expr_ty - }) + })) } ast::DefUpvar(var_id, _, fn_node_id, _) => { @@ -550,7 +552,7 @@ impl MemCategorizationContext { self.cat_upvar(id, span, var_id, fn_node_id) } else { // FIXME #2152 allow mutation of moved upvars - Ok(@cmt_ { + Ok(Rc::new(cmt_ { id:id, span:span, cat:cat_copied_upvar(CopiedUpvar { @@ -558,7 +560,7 @@ impl MemCategorizationContext { onceness: closure_ty.onceness}), mutbl:McImmutable, ty:expr_ty - }) + })) } } _ => { @@ -578,13 +580,13 @@ impl MemCategorizationContext { _ => McImmutable }; - Ok(@cmt_ { + Ok(Rc::new(cmt_ { id: id, span: span, cat: cat_local(vid), mutbl: m, ty: expr_ty - }) + })) } } } @@ -618,23 +620,23 @@ impl MemCategorizationContext { // give err type. Nobody should be inspecting this type anyhow. let upvar_ty = ty::mk_err(); - let base_cmt = @cmt_ { + let base_cmt = Rc::new(cmt_ { id:id, span:span, cat:cat_upvar(upvar_id, upvar_borrow), mutbl:McImmutable, ty:upvar_ty, - }; + }); let ptr = BorrowedPtr(upvar_borrow.kind, upvar_borrow.region); - let deref_cmt = @cmt_ { + let deref_cmt = Rc::new(cmt_ { id:id, span:span, cat:cat_deref(base_cmt, 0, ptr), mutbl:MutabilityCategory::from_borrow_kind(upvar_borrow.kind), ty:var_ty, - }; + }); Ok(deref_cmt) } @@ -659,13 +661,13 @@ impl MemCategorizationContext { span: Span, temp_scope: ty::Region, expr_ty: ty::t) -> cmt { - @cmt_ { + Rc::new(cmt_ { id:cmt_id, span:span, cat:cat_rvalue(temp_scope), mutbl:McDeclared, ty:expr_ty - } + }) } pub fn cat_field(&self, @@ -674,13 +676,13 @@ impl MemCategorizationContext { f_name: ast::Ident, f_ty: ty::t) -> cmt { - @cmt_ { + Rc::new(cmt_ { id: node.id(), span: node.span(), - cat: cat_interior(base_cmt, InteriorField(NamedField(f_name.name))), mutbl: base_cmt.mutbl.inherit(), + cat: cat_interior(base_cmt, InteriorField(NamedField(f_name.name))), ty: f_ty - } + }) } pub fn cat_deref_obj(&self, node: &N, base_cmt: cmt) -> cmt { @@ -736,13 +738,13 @@ impl MemCategorizationContext { (base_cmt.mutbl.inherit(), cat_interior(base_cmt, interior)) } }; - @cmt_ { + Rc::new(cmt_ { id: node.id(), span: node.span(), cat: cat, mutbl: m, ty: deref_ty - } + }) } pub fn cat_index(&self, @@ -798,13 +800,13 @@ impl MemCategorizationContext { let m = MutabilityCategory::from_pointer_kind(base_cmt.mutbl, ptr); // the deref is explicit in the resulting cmt - let deref_cmt = @cmt_ { + let deref_cmt = Rc::new(cmt_ { id:elt.id(), span:elt.span(), - cat:cat_deref(base_cmt, derefs, ptr), + cat:cat_deref(base_cmt.clone(), derefs, ptr), mutbl:m, ty:element_ty - }; + }); interior(elt, deref_cmt, base_cmt.ty, m.inherit(), element_ty) } @@ -812,7 +814,7 @@ impl MemCategorizationContext { deref_interior(_) => { // fixed-length vectors have no deref let m = base_cmt.mutbl.inherit(); - interior(elt, base_cmt, base_cmt.ty, m, element_ty) + interior(elt, base_cmt.clone(), base_cmt.ty, m, element_ty) } }; @@ -822,19 +824,19 @@ impl MemCategorizationContext { mutbl: MutabilityCategory, element_ty: ty::t) -> cmt { - @cmt_ { + Rc::new(cmt_ { id:elt.id(), span:elt.span(), cat:cat_interior(of_cmt, InteriorElement(element_kind(vec_ty))), mutbl:mutbl, ty:element_ty - } + }) } } pub fn cat_slice_pattern(&self, vec_cmt: cmt, - slice_pat: @ast::Pat) + slice_pat: &ast::Pat) -> McResult<(cmt, ast::Mutability, ty::Region)> { /*! * Given a pattern P like: `[_, ..Q, _]`, where `vec_cmt` is @@ -854,7 +856,7 @@ impl MemCategorizationContext { return Ok((cmt_slice, slice_mutbl, slice_r)); fn vec_slice_info(tcx: &ty::ctxt, - pat: @ast::Pat, + pat: &ast::Pat, slice_ty: ty::t) -> (ast::Mutability, ty::Region) { /*! @@ -885,13 +887,13 @@ impl MemCategorizationContext { interior_ty: ty::t, interior: InteriorKind) -> cmt { - @cmt_ { + Rc::new(cmt_ { id: node.id(), span: node.span(), - cat: cat_interior(base_cmt, interior), mutbl: base_cmt.mutbl.inherit(), + cat: cat_interior(base_cmt, interior), ty: interior_ty - } + }) } pub fn cat_downcast(&self, @@ -899,13 +901,13 @@ impl MemCategorizationContext { base_cmt: cmt, downcast_ty: ty::t) -> cmt { - @cmt_ { + Rc::new(cmt_ { id: node.id(), span: node.span(), - cat: cat_downcast(base_cmt), mutbl: base_cmt.mutbl.inherit(), + cat: cat_downcast(base_cmt), ty: downcast_ty - } + }) } pub fn cat_pattern(&self, @@ -964,7 +966,7 @@ impl MemCategorizationContext { pat.id, pprust::pat_to_str(pat), cmt.repr(self.tcx())); - op(self, cmt, pat); + op(self, cmt.clone(), pat); match pat.node { ast::PatWild | ast::PatWildMulti => { @@ -983,7 +985,7 @@ impl MemCategorizationContext { if ty::enum_is_univariant(self.tcx(), enum_did) { cmt // univariant, no downcast needed } else { - self.cat_downcast(pat, cmt, cmt.ty) + self.cat_downcast(pat, cmt.clone(), cmt.ty) } }; @@ -992,7 +994,7 @@ impl MemCategorizationContext { let subcmt = self.cat_imm_interior( - pat, downcast_cmt, subpat_ty, + pat, downcast_cmt.clone(), subpat_ty, InteriorField(PositionalField(i))); if_ok!(self.cat_pattern(subcmt, subpat, |x,y,z| op(x,y,z))); @@ -1004,14 +1006,14 @@ impl MemCategorizationContext { let subpat_ty = if_ok!(self.pat_ty(subpat)); // see (*2) let cmt_field = self.cat_imm_interior( - pat, cmt, subpat_ty, + pat, cmt.clone(), subpat_ty, InteriorField(PositionalField(i))); if_ok!(self.cat_pattern(cmt_field, subpat, |x,y,z| op(x,y,z))); } } Some(&ast::DefStatic(..)) => { for &subpat in subpats.iter() { - if_ok!(self.cat_pattern(cmt, subpat, |x,y,z| op(x,y,z))); + if_ok!(self.cat_pattern(cmt.clone(), subpat, |x,y,z| op(x,y,z))); } } _ => { @@ -1034,7 +1036,7 @@ impl MemCategorizationContext { // {f1: p1, ..., fN: pN} for fp in field_pats.iter() { let field_ty = if_ok!(self.pat_ty(fp.pat)); // see (*2) - let cmt_field = self.cat_field(pat, cmt, fp.ident, field_ty); + let cmt_field = self.cat_field(pat, cmt.clone(), fp.ident, field_ty); if_ok!(self.cat_pattern(cmt_field, fp.pat, |x,y,z| op(x,y,z))); } } @@ -1045,7 +1047,7 @@ impl MemCategorizationContext { let subpat_ty = if_ok!(self.pat_ty(subpat)); // see (*2) let subcmt = self.cat_imm_interior( - pat, cmt, subpat_ty, + pat, cmt.clone(), subpat_ty, InteriorField(PositionalField(i))); if_ok!(self.cat_pattern(subcmt, subpat, |x,y,z| op(x,y,z))); } @@ -1060,7 +1062,7 @@ impl MemCategorizationContext { ast::PatVec(ref before, slice, ref after) => { let elt_cmt = self.cat_index(pat, cmt, 0); for &before_pat in before.iter() { - if_ok!(self.cat_pattern(elt_cmt, before_pat, |x,y,z| op(x,y,z))); + if_ok!(self.cat_pattern(elt_cmt.clone(), before_pat, |x,y,z| op(x,y,z))); } for &slice_pat in slice.iter() { let slice_ty = if_ok!(self.pat_ty(slice_pat)); @@ -1068,7 +1070,7 @@ impl MemCategorizationContext { if_ok!(self.cat_pattern(slice_cmt, slice_pat, |x,y,z| op(x,y,z))); } for &after_pat in after.iter() { - if_ok!(self.cat_pattern(elt_cmt, after_pat, |x,y,z| op(x,y,z))); + if_ok!(self.cat_pattern(elt_cmt.clone(), after_pat, |x,y,z| op(x,y,z))); } } @@ -1080,7 +1082,7 @@ impl MemCategorizationContext { Ok(()) } - pub fn cmt_to_str(&self, cmt: cmt) -> ~str { + pub fn cmt_to_str(&self, cmt: &cmt_) -> ~str { match cmt.cat { cat_static_item => { "static item".to_owned() @@ -1097,7 +1099,7 @@ impl MemCategorizationContext { cat_arg(..) => { "argument".to_owned() } - cat_deref(base, _, pk) => { + cat_deref(ref base, _, pk) => { match base.cat { cat_upvar(..) => { format!("captured outer variable") @@ -1125,11 +1127,11 @@ impl MemCategorizationContext { cat_upvar(..) => { "captured outer variable".to_owned() } - cat_discr(cmt, _) => { - self.cmt_to_str(cmt) + cat_discr(ref cmt, _) => { + self.cmt_to_str(&**cmt) } - cat_downcast(cmt) => { - self.cmt_to_str(cmt) + cat_downcast(ref cmt) => { + self.cmt_to_str(&**cmt) } } } @@ -1149,7 +1151,7 @@ pub enum AliasableReason { } impl cmt_ { - pub fn guarantor(self) -> cmt { + pub fn guarantor(&self) -> cmt { //! Returns `self` after stripping away any owned pointer derefs or //! interior content. The return value is basically the `cmt` which //! determines how long the value in `self` remains live. @@ -1164,12 +1166,12 @@ impl cmt_ { cat_deref(_, _, GcPtr(..)) | cat_deref(_, _, BorrowedPtr(..)) | cat_upvar(..) => { - @self + Rc::new((*self).clone()) } - cat_downcast(b) | - cat_discr(b, _) | - cat_interior(b, _) | - cat_deref(b, _, OwnedPtr) => { + cat_downcast(ref b) | + cat_discr(ref b, _) | + cat_interior(ref b, _) | + cat_deref(ref b, _, OwnedPtr) => { b.guarantor() } } @@ -1186,12 +1188,12 @@ impl cmt_ { // aliased and eventually recused. match self.cat { - cat_deref(b, _, BorrowedPtr(ty::MutBorrow, _)) | - cat_deref(b, _, BorrowedPtr(ty::UniqueImmBorrow, _)) | - cat_downcast(b) | - cat_deref(b, _, OwnedPtr) | - cat_interior(b, _) | - cat_discr(b, _) => { + cat_deref(ref b, _, BorrowedPtr(ty::MutBorrow, _)) | + cat_deref(ref b, _, BorrowedPtr(ty::UniqueImmBorrow, _)) | + cat_downcast(ref b) | + cat_deref(ref b, _, OwnedPtr) | + cat_interior(ref b, _) | + cat_discr(ref b, _) => { // Aliasability depends on base cmt b.freely_aliasable(ctxt) } @@ -1255,21 +1257,21 @@ impl Repr for categorization { cat_arg(..) => { format!("{:?}", *self) } - cat_deref(cmt, derefs, ptr) => { + cat_deref(ref cmt, derefs, ptr) => { format!("{}-{}{}->", cmt.cat.repr(tcx), ptr_sigil(ptr), derefs) } - cat_interior(cmt, interior) => { + cat_interior(ref cmt, interior) => { format!("{}.{}", cmt.cat.repr(tcx), interior.repr(tcx)) } - cat_downcast(cmt) => { + cat_downcast(ref cmt) => { format!("{}->(enum)", cmt.cat.repr(tcx)) } - cat_discr(cmt, _) => { + cat_discr(ref cmt, _) => { cmt.cat.repr(tcx) } } diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index c8c878d6c2a2e..7273023e1bfeb 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -1065,7 +1065,7 @@ fn link_match(rcx: &Rcx, discr: &ast::Expr, arms: &[ast::Arm]) { debug!("discr_cmt={}", discr_cmt.repr(mc.typer.tcx())); for arm in arms.iter() { for &root_pat in arm.pats.iter() { - link_pattern(mc, discr_cmt, root_pat); + link_pattern(mc, discr_cmt.clone(), root_pat); } } } @@ -1194,7 +1194,7 @@ fn link_region(rcx: &Rcx, region_min.repr(rcx.tcx()), mutbl.repr(rcx.tcx()), cmt_borrowed.repr(rcx.tcx())); - match cmt_borrowed.cat { + match cmt_borrowed.cat.clone() { mc::cat_deref(base, _, mc::BorrowedPtr(_, r_borrowed)) => { // References to an upvar `x` are translated to // `*x`, since that is what happens in the @@ -1304,7 +1304,7 @@ fn adjust_upvar_borrow_kind_for_mut(rcx: &Rcx, debug!("adjust_upvar_borrow_kind_for_mut(cmt={})", cmt.repr(rcx.tcx())); - match cmt.cat { + match cmt.cat.clone() { mc::cat_deref(base, _, mc::OwnedPtr) | mc::cat_interior(base, _) | mc::cat_downcast(base) | @@ -1328,14 +1328,14 @@ fn adjust_upvar_borrow_kind_for_mut(rcx: &Rcx, return adjust_upvar_borrow_kind(*upvar_id, ub, ty::MutBorrow); } - _ => { - // assignment to deref of an `&mut` - // borrowed pointer implies that the - // pointer itself must be unique, but not - // necessarily *mutable* - return adjust_upvar_borrow_kind_for_unique(rcx, base); - } + _ => {} } + + // assignment to deref of an `&mut` + // borrowed pointer implies that the + // pointer itself must be unique, but not + // necessarily *mutable* + return adjust_upvar_borrow_kind_for_unique(rcx, base); } mc::cat_deref(_, _, mc::UnsafePtr(..)) | @@ -1358,7 +1358,7 @@ fn adjust_upvar_borrow_kind_for_unique(rcx: &Rcx, cmt: mc::cmt) { debug!("adjust_upvar_borrow_kind_for_unique(cmt={})", cmt.repr(rcx.tcx())); - match cmt.cat { + match cmt.cat.clone() { mc::cat_deref(base, _, mc::OwnedPtr) | mc::cat_interior(base, _) | mc::cat_downcast(base) | @@ -1381,12 +1381,12 @@ fn adjust_upvar_borrow_kind_for_unique(rcx: &Rcx, cmt: mc::cmt) { return adjust_upvar_borrow_kind(*upvar_id, ub, ty::UniqueImmBorrow); } - _ => { - // for a borrowed pointer to be unique, its - // base must be unique - return adjust_upvar_borrow_kind_for_unique(rcx, base); - } + _ => {} } + + // for a borrowed pointer to be unique, its + // base must be unique + return adjust_upvar_borrow_kind_for_unique(rcx, base); } mc::cat_deref(_, _, mc::UnsafePtr(..)) |