]>
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
::region
;
18 use rustc
::middle
::ty
;
21 use syntax
::codemap
::Span
;
23 type R
= Result
<(),()>;
25 pub fn guarantee_lifetime
<'a
, 'tcx
>(bccx
: &BorrowckCtxt
<'a
, 'tcx
>,
26 item_scope
: region
::CodeExtent
,
28 cause
: euv
::LoanCause
,
30 loan_region
: ty
::Region
,
33 //! Reports error if `loan_region` is larger than S
34 //! where S is `item_scope` if `cmt` is an upvar,
35 //! and is scope of `cmt` otherwise.
36 debug
!("guarantee_lifetime(cmt={:?}, loan_region={:?})",
38 let ctxt
= GuaranteeLifetimeContext
{bccx
: bccx
,
39 item_scope
: item_scope
,
42 loan_region
: loan_region
,
43 cmt_original
: cmt
.clone()};
44 ctxt
.check(&cmt
, None
)
47 ///////////////////////////////////////////////////////////////////////////
50 struct GuaranteeLifetimeContext
<'a
, 'tcx
: 'a
> {
51 bccx
: &'a BorrowckCtxt
<'a
, 'tcx
>,
53 // the scope of the function body for the enclosing item
54 item_scope
: region
::CodeExtent
,
57 cause
: euv
::LoanCause
,
58 loan_region
: ty
::Region
,
59 cmt_original
: mc
::cmt
<'tcx
>
62 impl<'a
, 'tcx
> GuaranteeLifetimeContext
<'a
, 'tcx
> {
64 fn check(&self, cmt
: &mc
::cmt
<'tcx
>, discr_scope
: Option
<ast
::NodeId
>) -> R
{
65 //! Main routine. Walks down `cmt` until we find the
66 //! "guarantor". Reports an error if `self.loan_region` is
67 //! larger than scope of `cmt`.
68 debug
!("guarantee_lifetime.check(cmt={:?}, loan_region={:?})",
74 mc
::cat_local(..) | // L-Local
76 mc
::cat_deref(_
, _
, mc
::BorrowedPtr(..)) | // L-Deref-Borrowed
77 mc
::cat_deref(_
, _
, mc
::Implicit(..)) |
78 mc
::cat_deref(_
, _
, mc
::UnsafePtr(..)) => {
79 self.check_scope(self.scope(cmt
))
82 mc
::cat_static_item
=> {
86 mc
::cat_downcast(ref base
, _
) |
87 mc
::cat_deref(ref base
, _
, mc
::Unique
) | // L-Deref-Send
88 mc
::cat_interior(ref base
, _
) => { // L-Field
89 self.check(base
, discr_scope
)
94 fn check_scope(&self, max_scope
: ty
::Region
) -> R
{
95 //! Reports an error if `loan_region` is larger than `max_scope`
97 if !self.bccx
.is_subregion_of(self.loan_region
, max_scope
) {
98 Err(self.report_error(err_out_of_scope(max_scope
, self.loan_region
)))
104 fn scope(&self, cmt
: &mc
::cmt
) -> ty
::Region
{
105 //! Returns the maximal region scope for the which the
106 //! lvalue `cmt` is guaranteed to be valid without any
107 //! rooting etc, and presuming `cmt` is not mutated.
110 mc
::cat_rvalue(temp_scope
) => {
113 mc
::cat_upvar(..) => {
114 ty
::ReScope(self.item_scope
)
116 mc
::cat_static_item
=> {
119 mc
::cat_local(local_id
) => {
120 ty
::ReScope(self.bccx
.tcx
.region_maps
.var_scope(local_id
))
122 mc
::cat_deref(_
, _
, mc
::UnsafePtr(..)) => {
125 mc
::cat_deref(_
, _
, mc
::BorrowedPtr(_
, r
)) |
126 mc
::cat_deref(_
, _
, mc
::Implicit(_
, r
)) => {
129 mc
::cat_downcast(ref cmt
, _
) |
130 mc
::cat_deref(ref cmt
, _
, mc
::Unique
) |
131 mc
::cat_interior(ref cmt
, _
) => {
137 fn report_error(&self, code
: bckerr_code
) {
138 self.bccx
.report(BckError
{ cmt
: self.cmt_original
.clone(),