Update docs on the formal basis of the borrow checker.

This commit is contained in:
Niko Matsakis 2013-05-26 05:11:35 -04:00
parent 5851d3242c
commit 329f7a17e2
4 changed files with 545 additions and 653 deletions

File diff suppressed because it is too large Load Diff

View File

@ -70,11 +70,11 @@ impl GuaranteeLifetimeContext {
match cmt.cat {
mc::cat_rvalue |
mc::cat_implicit_self |
mc::cat_copied_upvar(*) |
mc::cat_local(*) |
mc::cat_arg(*) |
mc::cat_self(*) |
mc::cat_deref(_, _, mc::region_ptr(*)) |
mc::cat_copied_upvar(*) | // L-Local
mc::cat_local(*) | // L-Local
mc::cat_arg(*) | // L-Local
mc::cat_self(*) | // L-Local
mc::cat_deref(_, _, mc::region_ptr(*)) | // L-Deref-Borrowed
mc::cat_deref(_, _, mc::unsafe_ptr) => {
let scope = self.scope(cmt);
self.check_scope(scope)
@ -90,7 +90,7 @@ impl GuaranteeLifetimeContext {
mc::cat_deref(base, derefs, mc::gc_ptr(ptr_mutbl)) => {
let base_scope = self.scope(base);
// See rule Freeze-Imm-Managed-Ptr-2 in doc.rs
// L-Deref-Managed-Imm-User-Root
let omit_root = (
ptr_mutbl == m_imm &&
self.bccx.is_subregion_of(self.loan_region, base_scope) &&
@ -99,6 +99,8 @@ impl GuaranteeLifetimeContext {
);
if !omit_root {
// L-Deref-Managed-Imm-Compiler-Root
// L-Deref-Managed-Mut-Compiler-Root
self.check_root(cmt, base, derefs, ptr_mutbl, discr_scope);
} else {
debug!("omitting root, base=%s, base_scope=%?",
@ -107,8 +109,8 @@ impl GuaranteeLifetimeContext {
}
mc::cat_downcast(base) |
mc::cat_deref(base, _, mc::uniq_ptr(*)) |
mc::cat_interior(base, _) => {
mc::cat_deref(base, _, mc::uniq_ptr(*)) | // L-Deref-Owned
mc::cat_interior(base, _) => { // L-Field
self.check(base, discr_scope)
}
@ -321,6 +323,8 @@ impl GuaranteeLifetimeContext {
//! lvalue `cmt` is guaranteed to be valid without any
//! rooting etc, and presuming `cmt` is not mutated.
// See the SCOPE(LV) function in doc.rs
match cmt.cat {
mc::cat_rvalue => {
ty::re_scope(self.bccx.tcx.region_maps.cleanup_scope(cmt.id))

View File

@ -481,6 +481,8 @@ pub impl GatherLoanCtxt {
borrow_span: span,
cmt: mc::cmt,
req_mutbl: ast::mutability) {
//! Implements the M-* rules in doc.rs.
match req_mutbl {
m_const => {
// Data of any mutability can be lent as const.

View File

@ -76,6 +76,7 @@ impl RestrictionsContext {
mc::cat_local(local_id) |
mc::cat_arg(local_id) |
mc::cat_self(local_id) => {
// R-Variable
let lp = @LpVar(local_id);
SafeIf(lp, ~[Restriction {loan_path: lp,
set: restrictions}])
@ -89,6 +90,8 @@ impl RestrictionsContext {
}
mc::cat_interior(cmt_base, i) => {
// R-Field
//
// Overwriting the base would not change the type of
// the memory, so no additional restrictions are
// needed.
@ -97,6 +100,8 @@ impl RestrictionsContext {
}
mc::cat_deref(cmt_base, _, mc::uniq_ptr(*)) => {
// R-Deref-Owned-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.
@ -109,16 +114,20 @@ impl RestrictionsContext {
mc::cat_implicit_self(*) |
mc::cat_deref(_, _, mc::region_ptr(m_imm, _)) |
mc::cat_deref(_, _, mc::gc_ptr(m_imm)) => {
// R-Deref-Imm-Borrowed
Safe
}
mc::cat_deref(_, _, mc::region_ptr(m_const, _)) |
mc::cat_deref(_, _, mc::gc_ptr(m_const)) => {
// R-Deref-Const-Borrowed
self.check_no_mutability_control(cmt, restrictions);
Safe
}
mc::cat_deref(cmt_base, _, mc::gc_ptr(m_mutbl)) => {
// R-Deref-Managed-Borrowed
//
// Technically, no restrictions are *necessary* here.
// The validity of the borrow is guaranteed
// dynamically. However, nonetheless we add a
@ -170,9 +179,11 @@ impl RestrictionsContext {
// freezing if it is not aliased. Therefore, in such
// cases we restrict aliasing on `cmt_base`.
if restrictions.intersects(RESTR_MUTATE | RESTR_FREEZE) {
// R-Deref-Mut-Borrowed-1
let result = self.compute(cmt_base, restrictions | RESTR_ALIAS);
self.extend(result, cmt.mutbl, LpDeref, restrictions)
} else {
// R-Deref-Mut-Borrowed-2
let result = self.compute(cmt_base, restrictions);
self.extend(result, cmt.mutbl, LpDeref, restrictions)
}