]>
git.proxmox.com Git - rustc.git/blob - src/librustc_borrowck/borrowck/gather_loans/lifetime.rs
1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! This module implements the check that the lifetime of a borrow
12 //! does not exceed the lifetime of the value being borrowed.
15 use rustc
::middle
::expr_use_visitor
as euv
;
16 use rustc
::middle
::mem_categorization
as mc
;
17 use rustc
::middle
::mem_categorization
::Categorization
;
18 use rustc
::middle
::region
;
22 use syntax
::codemap
::Span
;
24 type R
= Result
<(),()>;
26 pub fn guarantee_lifetime
<'a
, 'tcx
>(bccx
: &BorrowckCtxt
<'a
, 'tcx
>,
27 item_scope
: region
::CodeExtent
,
29 cause
: euv
::LoanCause
,
31 loan_region
: ty
::Region
,
34 //! Reports error if `loan_region` is larger than S
35 //! where S is `item_scope` if `cmt` is an upvar,
36 //! and is scope of `cmt` otherwise.
37 debug
!("guarantee_lifetime(cmt={:?}, loan_region={:?})",
39 let ctxt
= GuaranteeLifetimeContext
{bccx
: bccx
,
40 item_scope
: item_scope
,
43 loan_region
: loan_region
,
44 cmt_original
: cmt
.clone()};
45 ctxt
.check(&cmt
, None
)
48 ///////////////////////////////////////////////////////////////////////////
51 struct GuaranteeLifetimeContext
<'a
, 'tcx
: 'a
> {
52 bccx
: &'a BorrowckCtxt
<'a
, 'tcx
>,
54 // the scope of the function body for the enclosing item
55 item_scope
: region
::CodeExtent
,
58 cause
: euv
::LoanCause
,
59 loan_region
: ty
::Region
,
60 cmt_original
: mc
::cmt
<'tcx
>
63 impl<'a
, 'tcx
> GuaranteeLifetimeContext
<'a
, 'tcx
> {
65 fn check(&self, cmt
: &mc
::cmt
<'tcx
>, discr_scope
: Option
<ast
::NodeId
>) -> R
{
66 //! Main routine. Walks down `cmt` until we find the
67 //! "guarantor". Reports an error if `self.loan_region` is
68 //! larger than scope of `cmt`.
69 debug
!("guarantee_lifetime.check(cmt={:?}, loan_region={:?})",
74 Categorization
::Rvalue(..) |
75 Categorization
::Local(..) | // L-Local
76 Categorization
::Upvar(..) |
77 Categorization
::Deref(_
, _
, mc
::BorrowedPtr(..)) | // L-Deref-Borrowed
78 Categorization
::Deref(_
, _
, mc
::Implicit(..)) |
79 Categorization
::Deref(_
, _
, mc
::UnsafePtr(..)) => {
80 self.check_scope(self.scope(cmt
))
83 Categorization
::StaticItem
=> {
87 Categorization
::Downcast(ref base
, _
) |
88 Categorization
::Deref(ref base
, _
, mc
::Unique
) | // L-Deref-Send
89 Categorization
::Interior(ref base
, _
) => { // L-Field
90 self.check(base
, discr_scope
)
95 fn check_scope(&self, max_scope
: ty
::Region
) -> R
{
96 //! Reports an error if `loan_region` is larger than `max_scope`
98 if !self.bccx
.is_subregion_of(self.loan_region
, max_scope
) {
99 Err(self.report_error(err_out_of_scope(max_scope
, self.loan_region
)))
105 fn scope(&self, cmt
: &mc
::cmt
) -> ty
::Region
{
106 //! Returns the maximal region scope for the which the
107 //! lvalue `cmt` is guaranteed to be valid without any
108 //! rooting etc, and presuming `cmt` is not mutated.
111 Categorization
::Rvalue(temp_scope
) => {
114 Categorization
::Upvar(..) => {
115 ty
::ReScope(self.item_scope
)
117 Categorization
::StaticItem
=> {
120 Categorization
::Local(local_id
) => {
121 ty
::ReScope(self.bccx
.tcx
.region_maps
.var_scope(local_id
))
123 Categorization
::Deref(_
, _
, mc
::UnsafePtr(..)) => {
126 Categorization
::Deref(_
, _
, mc
::BorrowedPtr(_
, r
)) |
127 Categorization
::Deref(_
, _
, mc
::Implicit(_
, r
)) => {
130 Categorization
::Downcast(ref cmt
, _
) |
131 Categorization
::Deref(ref cmt
, _
, mc
::Unique
) |
132 Categorization
::Interior(ref cmt
, _
) => {
138 fn report_error(&self, code
: bckerr_code
) {
139 self.bccx
.report(BckError
{ cmt
: self.cmt_original
.clone(),
141 cause
: BorrowViolation(self.cause
),