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.
16 use syntax::codemap::Span;
18 /// Defines strategies for handling regions that are omitted. For
19 /// example, if one writes the type `&Foo`, then the lifetime of
20 /// this reference has been omitted. When converting this
21 /// type, the generic functions in astconv will invoke `anon_regions`
22 /// on the provided region-scope to decide how to translate this
25 /// It is not always legal to omit regions, therefore `anon_regions`
26 /// can return `Err(())` to indicate that this is not a scope in which
27 /// regions can legally be omitted.
28 pub trait RegionScope {
29 fn anon_regions(&self,
32 -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>>;
34 fn default_region_bound(&self, span: Span) -> Option<ty::Region>;
37 // A scope in which all regions must be explicitly named. This is used
38 // for types that appear in structs and so on.
39 pub struct ExplicitRscope;
41 impl RegionScope for ExplicitRscope {
42 fn default_region_bound(&self, _span: Span) -> Option<ty::Region> {
46 fn anon_regions(&self,
49 -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>> {
54 // Same as `ExplicitRscope`, but provides some extra information for diagnostics
55 pub struct UnelidableRscope(Vec<(String, uint)>);
57 impl UnelidableRscope {
58 pub fn new(v: Vec<(String, uint)>) -> UnelidableRscope {
63 impl RegionScope for UnelidableRscope {
64 fn default_region_bound(&self, _span: Span) -> Option<ty::Region> {
68 fn anon_regions(&self,
71 -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>> {
72 let UnelidableRscope(ref v) = *self;
77 // A scope in which any omitted region defaults to `default`. This is
78 // used after the `->` in function signatures, but also for backwards
79 // compatibility with object types. The latter use may go away.
80 pub struct SpecificRscope {
85 pub fn new(r: ty::Region) -> SpecificRscope {
86 SpecificRscope { default: r }
90 impl RegionScope for SpecificRscope {
91 fn default_region_bound(&self, _span: Span) -> Option<ty::Region> {
95 fn anon_regions(&self,
98 -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>>
100 Ok(Vec::from_elem(count, self.default))
104 /// A scope in which we generate anonymous, late-bound regions for
105 /// omitted regions. This occurs in function signatures.
106 pub struct BindingRscope {
107 anon_bindings: Cell<uint>,
111 pub fn new() -> BindingRscope {
113 anon_bindings: Cell::new(0),
117 fn next_region(&self) -> ty::Region {
118 let idx = self.anon_bindings.get();
119 self.anon_bindings.set(idx + 1);
120 ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrAnon(idx))
124 impl RegionScope for BindingRscope {
125 fn default_region_bound(&self, _span: Span) -> Option<ty::Region>
127 Some(self.next_region())
130 fn anon_regions(&self,
133 -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>>
135 Ok(Vec::from_fn(count, |_| self.next_region()))
139 /// A scope which simply shifts the Debruijn index of other scopes
140 /// to account for binding levels.
141 pub struct ShiftedRscope<'r> {
142 base_scope: &'r (RegionScope+'r)
145 impl<'r> ShiftedRscope<'r> {
146 pub fn new(base_scope: &'r (RegionScope+'r)) -> ShiftedRscope<'r> {
147 ShiftedRscope { base_scope: base_scope }
151 impl<'r> RegionScope for ShiftedRscope<'r> {
152 fn default_region_bound(&self, span: Span) -> Option<ty::Region>
154 self.base_scope.default_region_bound(span)
155 .map(|r| ty_fold::shift_region(r, 1))
158 fn anon_regions(&self,
161 -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>>
163 match self.base_scope.anon_regions(span, count) {
165 for r in v.iter_mut() {
166 *r = ty_fold::shift_region(*r, 1);