Treat @T like ~T in borrowck
`@` pointers used to have special rooting and regions management. With `@` moving to standalone library, we don't need to keep that special treatment around. This patch modifies the way `@` pointers are treated by treating them as if they were `~` pointers Region checker and borrow checker were modified in this patch. Closes #11586 [breaking-change]
This commit is contained in:
parent
e80089576e
commit
d10735e384
3 changed files with 10 additions and 70 deletions
|
@ -65,9 +65,6 @@ struct GuaranteeLifetimeContext<'a> {
|
|||
}
|
||||
|
||||
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".
|
||||
|
@ -90,29 +87,10 @@ impl<'a> GuaranteeLifetimeContext<'a> {
|
|||
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)
|
||||
}
|
||||
|
||||
|
@ -174,19 +152,6 @@ impl<'a> GuaranteeLifetimeContext<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
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`
|
||||
|
||||
|
@ -197,32 +162,6 @@ impl<'a> GuaranteeLifetimeContext<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -101,12 +101,18 @@ impl<'a> RestrictionsContext<'a> {
|
|||
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);
|
||||
|
@ -134,11 +140,6 @@ impl<'a> RestrictionsContext<'a> {
|
|||
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) {
|
||||
|
|
|
@ -1263,12 +1263,12 @@ fn link_region(rcx: &Rcx,
|
|||
}
|
||||
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(..) |
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue