]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/typeck/rscope.rs
4fc027e6fee6901da8e9c9d4f7fdf241eb63637f
[rust.git] / src / librustc / middle / typeck / rscope.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.
4 //
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.
10
11
12 use middle::ty;
13
14 use std::cell::Cell;
15 use std::vec;
16 use syntax::ast;
17 use syntax::codemap::Span;
18 use syntax::opt_vec::OptVec;
19
20 /// Defines strategies for handling regions that are omitted.  For
21 /// example, if one writes the type `&Foo`, then the lifetime of
22 /// this reference has been omitted. When converting this
23 /// type, the generic functions in astconv will invoke `anon_regions`
24 /// on the provided region-scope to decide how to translate this
25 /// omitted region.
26 ///
27 /// It is not always legal to omit regions, therefore `anon_regions`
28 /// can return `Err(())` to indicate that this is not a scope in which
29 /// regions can legally be omitted.
30 pub trait RegionScope {
31     fn anon_regions(&self,
32                     span: Span,
33                     count: uint)
34                     -> Result<~[ty::Region], ()>;
35 }
36
37 // A scope in which all regions must be explicitly named
38 pub struct ExplicitRscope;
39
40 impl RegionScope for ExplicitRscope {
41     fn anon_regions(&self,
42                     _span: Span,
43                     _count: uint)
44                     -> Result<~[ty::Region], ()> {
45         Err(())
46     }
47 }
48
49 /// A scope in which we generate anonymous, late-bound regions for
50 /// omitted regions. This occurs in function signatures.
51 pub struct BindingRscope {
52     binder_id: ast::NodeId,
53     anon_bindings: Cell<uint>,
54 }
55
56 impl BindingRscope {
57     pub fn new(binder_id: ast::NodeId) -> BindingRscope {
58         BindingRscope {
59             binder_id: binder_id,
60             anon_bindings: Cell::new(0),
61         }
62     }
63 }
64
65 impl RegionScope for BindingRscope {
66     fn anon_regions(&self,
67                     _: Span,
68                     count: uint)
69                     -> Result<~[ty::Region], ()> {
70         let idx = self.anon_bindings.get();
71         self.anon_bindings.set(idx + count);
72         Ok(vec::from_fn(count, |i| ty::ReLateBound(self.binder_id,
73                                                    ty::BrAnon(idx + i))))
74     }
75 }
76
77 pub fn bound_type_regions(defs: &[ty::RegionParameterDef])
78                           -> OptVec<ty::Region> {
79     assert!(defs.iter().all(|def| def.def_id.krate == ast::LOCAL_CRATE));
80     defs.iter().enumerate().map(
81         |(i, def)| ty::ReEarlyBound(def.def_id.node, i, def.ident)).collect()
82 }