}
impl<'a> GuaranteeLifetimeContext<'a> {
- fn tcx(&self) -> &'a ty::ctxt {
- self.bccx.tcx
- }
fn check(&self, cmt: &mc::cmt, discr_scope: Option<ast::NodeId>) -> R {
//! Main routine. Walks down `cmt` until we find the "guarantor".
Ok(())
}
- mc::cat_deref(ref base, _, mc::GcPtr) => {
- let base_scope = self.scope(base);
-
- // L-Deref-Managed-Imm-User-Root
- let omit_root =
- self.bccx.is_subregion_of(self.loan_region, base_scope) &&
- self.is_rvalue_or_immutable(base) &&
- !self.is_moved(base);
-
- if !omit_root {
- // L-Deref-Managed-Imm-Compiler-Root
- // L-Deref-Managed-Mut-Compiler-Root
- Err(())
- } else {
- debug!("omitting root, base={}, base_scope={:?}",
- base.repr(self.tcx()), base_scope);
- Ok(())
- }
- }
-
mc::cat_downcast(ref base) |
mc::cat_deref(ref base, _, mc::OwnedPtr) | // L-Deref-Send
- mc::cat_interior(ref base, _) => { // L-Field
+ mc::cat_interior(ref base, _) | // L-Field
+ mc::cat_deref(ref base, _, mc::GcPtr) => {
self.check(base, discr_scope)
}
}
}
- fn is_rvalue_or_immutable(&self,
- 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
- //! lvalue.
-
- cmt.mutbl.is_immutable() || match cmt.guarantor().cat {
- mc::cat_rvalue(..) => true,
- _ => false
- }
- }
-
fn check_scope(&self, max_scope: ty::Region) -> R {
//! Reports an error if `loan_region` is larger than `valid_scope`
}
}
- fn is_moved(&self, cmt: &mc::cmt) -> bool {
- //! True if `cmt` is something that is potentially moved
- //! out of the current stack frame.
-
- match cmt.guarantor().cat {
- mc::cat_local(id) |
- mc::cat_arg(id) => {
- self.bccx.moved_variables_set.contains(&id)
- }
- mc::cat_rvalue(..) |
- mc::cat_static_item |
- mc::cat_copied_upvar(..) |
- mc::cat_deref(..) |
- mc::cat_upvar(..) => {
- false
- }
- 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));
- }
- }
- }
-
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
self.extend(result, cmt.mutbl, LpInterior(i), restrictions)
}
- mc::cat_deref(cmt_base, _, pk @ mc::OwnedPtr) => {
+ mc::cat_deref(cmt_base, _, pk @ mc::OwnedPtr) |
+ mc::cat_deref(cmt_base, _, pk @ mc::GcPtr) => {
// R-Deref-Send-Pointer
//
// When we borrow the interior of an owned pointer, we
// cannot permit the base to be mutated, because that
// would cause the unique pointer to be freed.
+ //
+ // For a managed pointer, the rules are basically the
+ // same, because this could be the last ref.
+ // Eventually we should make these non-special and
+ // just rely on Deref<T> implementation.
let result = self.restrict(
cmt_base,
restrictions | RESTR_MUTATE);
Safe
}
- mc::cat_deref(_, _, mc::GcPtr) => {
- // R-Deref-Imm-Managed
- Safe
- }
-
mc::cat_deref(cmt_base, _, pk @ mc::BorrowedPtr(ty::MutBorrow, lt)) => {
// R-Deref-Mut-Borrowed
if !self.bccx.is_subregion_of(self.loan_region, lt) {
}
mc::cat_discr(cmt_base, _) |
mc::cat_downcast(cmt_base) |
+ mc::cat_deref(cmt_base, _, mc::GcPtr(..)) |
mc::cat_deref(cmt_base, _, mc::OwnedPtr) |
mc::cat_interior(cmt_base, _) => {
// Interior or owned data requires its base to be valid
cmt_borrowed = cmt_base;
}
- mc::cat_deref(_, _, mc::GcPtr(..)) |
mc::cat_deref(_, _, mc::UnsafePtr(..)) |
mc::cat_static_item |
mc::cat_copied_upvar(..) |