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 std::iter::repeat;
17 use syntax::codemap::Span;
19 /// Defines strategies for handling regions that are omitted. For
20 /// example, if one writes the type `&Foo`, then the lifetime of
21 /// this reference has been omitted. When converting this
22 /// type, the generic functions in astconv will invoke `anon_regions`
23 /// on the provided region-scope to decide how to translate this
26 /// It is not always legal to omit regions, therefore `anon_regions`
27 /// can return `Err(())` to indicate that this is not a scope in which
28 /// regions can legally be omitted.
29 pub trait RegionScope {
30 fn anon_regions(&self,
33 -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>>;
35 /// If an object omits any explicit lifetime bound, and none can
36 /// be derived from the object traits, what should we use? If
37 /// `None` is returned, an explicit annotation is required.
38 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region>;
41 // A scope in which all regions must be explicitly named. This is used
42 // for types that appear in structs and so on.
44 pub struct ExplicitRscope;
46 impl RegionScope for ExplicitRscope {
47 fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region> {
51 fn anon_regions(&self,
54 -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>> {
59 // Same as `ExplicitRscope`, but provides some extra information for diagnostics
60 pub struct UnelidableRscope(Vec<(String, uint)>);
62 impl UnelidableRscope {
63 pub fn new(v: Vec<(String, uint)>) -> UnelidableRscope {
68 impl RegionScope for UnelidableRscope {
69 fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region> {
73 fn anon_regions(&self,
76 -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>> {
77 let UnelidableRscope(ref v) = *self;
82 // A scope in which omitted anonymous region defaults to
83 // `default`. This is used after the `->` in function signatures. The
84 // latter use may go away. Note that object-lifetime defaults work a
85 // bit differently, as specified in RFC #599.
86 pub struct ElidableRscope {
91 pub fn new(r: ty::Region) -> ElidableRscope {
92 ElidableRscope { default: r }
96 impl RegionScope for ElidableRscope {
97 fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region> {
98 // Per RFC #599, object-lifetimes default to 'static unless
99 // overridden by context, and this takes precedence over
104 fn anon_regions(&self,
107 -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>>
109 Ok(repeat(self.default).take(count).collect())
113 /// A scope in which we generate anonymous, late-bound regions for
114 /// omitted regions. This occurs in function signatures.
115 pub struct BindingRscope {
116 anon_bindings: Cell<u32>,
120 pub fn new() -> BindingRscope {
122 anon_bindings: Cell::new(0),
126 fn next_region(&self) -> ty::Region {
127 let idx = self.anon_bindings.get();
128 self.anon_bindings.set(idx + 1);
129 ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrAnon(idx))
133 impl RegionScope for BindingRscope {
134 fn object_lifetime_default(&self, _span: Span) -> Option<ty::Region> {
135 // Per RFC #599, object-lifetimes default to 'static unless
136 // overridden by context, and this takes precedence over the
141 fn anon_regions(&self,
144 -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>>
146 Ok((0..count).map(|_| self.next_region()).collect())
150 /// A scope which overrides the default object lifetime but has no other effect.
151 pub struct ObjectLifetimeDefaultRscope<'r> {
152 base_scope: &'r (RegionScope+'r),
153 default: Option<ty::ObjectLifetimeDefault>,
156 impl<'r> ObjectLifetimeDefaultRscope<'r> {
157 pub fn new(base_scope: &'r (RegionScope+'r),
158 default: Option<ty::ObjectLifetimeDefault>)
159 -> ObjectLifetimeDefaultRscope<'r>
161 ObjectLifetimeDefaultRscope {
162 base_scope: base_scope,
168 impl<'r> RegionScope for ObjectLifetimeDefaultRscope<'r> {
169 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
171 None => self.base_scope.object_lifetime_default(span),
172 Some(ty::ObjectLifetimeDefault::Ambiguous) => None,
173 Some(ty::ObjectLifetimeDefault::Specific(r)) => Some(r),
177 fn anon_regions(&self,
180 -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>>
182 self.base_scope.anon_regions(span, count)
186 /// A scope which simply shifts the Debruijn index of other scopes
187 /// to account for binding levels.
188 pub struct ShiftedRscope<'r> {
189 base_scope: &'r (RegionScope+'r)
192 impl<'r> ShiftedRscope<'r> {
193 pub fn new(base_scope: &'r (RegionScope+'r)) -> ShiftedRscope<'r> {
194 ShiftedRscope { base_scope: base_scope }
198 impl<'r> RegionScope for ShiftedRscope<'r> {
199 fn object_lifetime_default(&self, span: Span) -> Option<ty::Region> {
200 self.base_scope.object_lifetime_default(span)
201 .map(|r| ty_fold::shift_region(r, 1))
204 fn anon_regions(&self,
207 -> Result<Vec<ty::Region>, Option<Vec<(String, uint)>>>
209 match self.base_scope.anon_regions(span, count) {
212 *r = ty_fold::shift_region(*r, 1);