1 //! This module handles the relationships between "free regions", i.e., lifetime parameters.
2 //! Ordinarily, free regions are unrelated to one another, but they can be related via implied
3 //! or explicit bounds. In that case, we track the bounds using the `TransitiveRelation` type,
4 //! and use that to decide when one free region outlives another, and so forth.
6 use crate::infer
::outlives
::free_region_map
::{FreeRegionMap, FreeRegionRelations}
;
7 use crate::hir
::def_id
::DefId
;
8 use crate::middle
::region
;
9 use crate::ty
::{self, TyCtxt, Region}
;
11 /// Combines a `region::ScopeTree` (which governs relationships between
12 /// scopes) and a `FreeRegionMap` (which governs relationships between
13 /// free regions) to yield a complete relation between concrete
16 /// This stuff is a bit convoluted and should be refactored, but as we
17 /// transition to NLL, it'll all go away anyhow.
18 pub struct RegionRelations
<'a
, 'tcx
> {
19 pub tcx
: TyCtxt
<'tcx
>,
21 /// The context used to fetch the region maps.
24 /// The region maps for the given context.
25 pub region_scope_tree
: &'a region
::ScopeTree
,
27 /// Free-region relationships.
28 pub free_regions
: &'a FreeRegionMap
<'tcx
>,
31 impl<'a
, 'tcx
> RegionRelations
<'a
, 'tcx
> {
35 region_scope_tree
: &'a region
::ScopeTree
,
36 free_regions
: &'a FreeRegionMap
<'tcx
>,
46 /// Determines whether one region is a subregion of another. This is intended to run *after
47 /// inference* and sadly the logic is somewhat duplicated with the code in infer.rs.
48 pub fn is_subregion_of(&self,
49 sub_region
: ty
::Region
<'tcx
>,
50 super_region
: ty
::Region
<'tcx
>)
52 let result
= sub_region
== super_region
|| {
53 match (sub_region
, super_region
) {
58 (ty
::ReScope(sub_scope
), ty
::ReScope(super_scope
)) =>
59 self.region_scope_tree
.is_subscope_of(*sub_scope
, *super_scope
),
61 (ty
::ReScope(sub_scope
), ty
::ReEarlyBound(ref br
)) => {
62 let fr_scope
= self.region_scope_tree
.early_free_scope(self.tcx
, br
);
63 self.region_scope_tree
.is_subscope_of(*sub_scope
, fr_scope
)
66 (ty
::ReScope(sub_scope
), ty
::ReFree(fr
)) => {
67 let fr_scope
= self.region_scope_tree
.free_scope(self.tcx
, fr
);
68 self.region_scope_tree
.is_subscope_of(*sub_scope
, fr_scope
)
71 (ty
::ReEarlyBound(_
), ty
::ReEarlyBound(_
)) |
72 (ty
::ReFree(_
), ty
::ReEarlyBound(_
)) |
73 (ty
::ReEarlyBound(_
), ty
::ReFree(_
)) |
74 (ty
::ReFree(_
), ty
::ReFree(_
)) =>
75 self.free_regions
.sub_free_regions(sub_region
, super_region
),
81 let result
= result
|| self.is_static(super_region
);
82 debug
!("is_subregion_of(sub_region={:?}, super_region={:?}) = {:?}",
83 sub_region
, super_region
, result
);
87 /// Determines whether this free region is required to be `'static`.
88 fn is_static(&self, super_region
: ty
::Region
<'tcx
>) -> bool
{
89 debug
!("is_static(super_region={:?})", super_region
);
92 ty
::ReEarlyBound(_
) | ty
::ReFree(_
) => {
93 let re_static
= self.tcx
.mk_region(ty
::ReStatic
);
94 self.free_regions
.sub_free_regions(&re_static
, &super_region
)
100 pub fn lub_free_regions(&self,
104 self.free_regions
.lub_free_regions(self.tcx
, r_a
, r_b
)