98 lines
3.4 KiB
Rust
98 lines
3.4 KiB
Rust
// ----------------------------------------------------------------------
|
|
// Loan(Ex, M, S) = Ls holds if ToAddr(Ex) will remain valid for the entirety
|
|
// of the scope S, presuming that the returned set of loans `Ls` are honored.
|
|
|
|
export public_methods;
|
|
|
|
impl public_methods for borrowck_ctxt {
|
|
fn loan(cmt: cmt, mutbl: ast::mutability) -> @dvec<loan> {
|
|
let lc = @{bccx: self, loans: @dvec()};
|
|
lc.loan(cmt, mutbl);
|
|
ret lc.loans;
|
|
}
|
|
}
|
|
|
|
type loan_ctxt = @{
|
|
bccx: borrowck_ctxt,
|
|
loans: @dvec<loan>
|
|
};
|
|
|
|
impl loan_methods for loan_ctxt {
|
|
fn ok_with_loan_of(cmt: cmt,
|
|
mutbl: ast::mutability) {
|
|
// Note: all cmt's that we deal with will have a non-none lp, because
|
|
// the entry point into this routine, `borrowck_ctxt::loan()`, rejects
|
|
// any cmt with a none-lp.
|
|
(*self.loans).push({lp:option::get(cmt.lp),
|
|
cmt:cmt,
|
|
mutbl:mutbl});
|
|
}
|
|
|
|
fn loan(cmt: cmt, req_mutbl: ast::mutability) {
|
|
|
|
#debug["loan(%s, %s)",
|
|
self.bccx.cmt_to_repr(cmt),
|
|
self.bccx.mut_to_str(req_mutbl)];
|
|
let _i = indenter();
|
|
|
|
// see stable() above; should only be called when `cmt` is lendable
|
|
if cmt.lp.is_none() {
|
|
self.bccx.tcx.sess.span_bug(
|
|
cmt.span,
|
|
"loan() called with non-lendable value");
|
|
}
|
|
|
|
alt cmt.cat {
|
|
cat_rvalue | cat_special(_) {
|
|
// should never be loanable
|
|
self.bccx.tcx.sess.span_bug(
|
|
cmt.span,
|
|
"rvalue with a non-none lp");
|
|
}
|
|
cat_local(_) | cat_arg(_) | cat_stack_upvar(_) {
|
|
self.ok_with_loan_of(cmt, req_mutbl)
|
|
}
|
|
cat_discr(base, _) {
|
|
self.loan(base, req_mutbl)
|
|
}
|
|
cat_comp(cmt_base, comp_field(*)) |
|
|
cat_comp(cmt_base, comp_index(*)) |
|
|
cat_comp(cmt_base, comp_tuple) |
|
|
cat_comp(cmt_base, comp_res) {
|
|
// For most components, the type of the embedded data is
|
|
// stable. Therefore, the base structure need only be
|
|
// const---unless the component must be immutable. In
|
|
// that case, it must also be embedded in an immutable
|
|
// location, or else the whole structure could be
|
|
// overwritten and the component along with it.
|
|
let base_mutbl = alt req_mutbl {
|
|
m_imm { m_imm }
|
|
m_const | m_mutbl { m_const }
|
|
};
|
|
|
|
self.loan(cmt_base, base_mutbl);
|
|
self.ok_with_loan_of(cmt, req_mutbl)
|
|
}
|
|
cat_comp(cmt1, comp_variant) |
|
|
cat_deref(cmt1, _, uniq_ptr) {
|
|
// Variant components: the base must be immutable, because
|
|
// if it is overwritten, the types of the embedded data
|
|
// could change.
|
|
//
|
|
// Unique pointers: the base must be immutable, because if
|
|
// it is overwritten, the unique content will be freed.
|
|
self.loan(cmt1, m_imm);
|
|
self.ok_with_loan_of(cmt, req_mutbl)
|
|
}
|
|
cat_deref(cmt1, _, unsafe_ptr) |
|
|
cat_deref(cmt1, _, gc_ptr) |
|
|
cat_deref(cmt1, _, region_ptr) {
|
|
// Aliased data is simply not lendable.
|
|
self.bccx.tcx.sess.span_bug(
|
|
cmt.span,
|
|
"aliased ptr with a non-none lp");
|
|
}
|
|
}
|
|
}
|
|
}
|