]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/def.rs
Tidying up and reformatting
[rust.git] / src / librustc / middle / def.rs
1 // Copyright 2014 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 pub use self::Def::*;
12 pub use self::MethodProvenance::*;
13
14 use middle::privacy::LastPrivate;
15 use middle::subst::ParamSpace;
16 use util::nodemap::NodeMap;
17 use syntax::ast;
18 use syntax::ast_util::local_def;
19
20 use std::cell::RefCell;
21
22 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
23 pub enum Def {
24     DefFn(ast::DefId, bool /* is_ctor */),
25     DefSelfTy(/* trait id */ ast::NodeId),
26     DefMod(ast::DefId),
27     DefForeignMod(ast::DefId),
28     DefStatic(ast::DefId, bool /* is_mutbl */),
29     DefConst(ast::DefId),
30     DefLocal(ast::NodeId),
31     DefVariant(ast::DefId /* enum */, ast::DefId /* variant */, bool /* is_structure */),
32     DefTy(ast::DefId, bool /* is_enum */),
33     DefAssociatedTy(ast::DefId /* trait */, ast::DefId),
34     DefTrait(ast::DefId),
35     DefPrimTy(ast::PrimTy),
36     DefTyParam(ParamSpace, u32, ast::DefId, ast::Name),
37     DefUse(ast::DefId),
38     DefUpvar(ast::NodeId,  // id of closed over local
39              ast::NodeId), // expr node that creates the closure
40
41     /// Note that if it's a tuple struct's definition, the node id of the ast::DefId
42     /// may either refer to the item definition's id or the StructDef.ctor_id.
43     ///
44     /// The cases that I have encountered so far are (this is not exhaustive):
45     /// - If it's a ty_path referring to some tuple struct, then DefMap maps
46     ///   it to a def whose id is the item definition's id.
47     /// - If it's an ExprPath referring to some tuple struct, then DefMap maps
48     ///   it to a def whose id is the StructDef.ctor_id.
49     DefStruct(ast::DefId),
50     DefRegion(ast::NodeId),
51     DefLabel(ast::NodeId),
52     DefMethod(ast::DefId /* method */, MethodProvenance),
53 }
54
55 /// The result of resolving a path.
56 /// Before type checking completes, `depth` represents the number of
57 /// trailing segments which are yet unresolved. Afterwards, if there
58 /// were no errors, all paths should be fully resolved, with `depth`
59 /// set to `0` and `base_def` representing the final resolution.
60 ///
61 ///     module::Type::AssocX::AssocY::MethodOrAssocType
62 ///     ^~~~~~~~~~~~  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
63 ///     base_def      depth = 3
64 ///
65 ///     <T as Trait>::AssocX::AssocY::MethodOrAssocType
66 ///           ^~~~~~~~~~~~~~  ^~~~~~~~~~~~~~~~~~~~~~~~~
67 ///           base_def        depth = 2
68 #[derive(Copy, Clone, Debug)]
69 pub struct PathResolution {
70     pub base_def: Def,
71     pub last_private: LastPrivate,
72     pub depth: usize
73 }
74
75 impl PathResolution {
76     /// Get the definition, if fully resolved, otherwise panic.
77     pub fn full_def(&self) -> Def {
78         if self.depth != 0 {
79             panic!("path not fully resolved: {:?}", self);
80         }
81         self.base_def
82     }
83
84     /// Get the DefId, if fully resolved, otherwise panic.
85     pub fn def_id(&self) -> ast::DefId {
86         self.full_def().def_id()
87     }
88
89     pub fn new(base_def: Def,
90                last_private: LastPrivate,
91                depth: usize)
92                -> PathResolution {
93         PathResolution {
94             base_def: base_def,
95             last_private: last_private,
96             depth: depth,
97         }
98     }
99 }
100
101 // Definition mapping
102 pub type DefMap = RefCell<NodeMap<PathResolution>>;
103 // This is the replacement export map. It maps a module to all of the exports
104 // within.
105 pub type ExportMap = NodeMap<Vec<Export>>;
106
107 #[derive(Copy)]
108 pub struct Export {
109     pub name: ast::Name,    // The name of the target.
110     pub def_id: ast::DefId, // The definition of the target.
111 }
112
113 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
114 pub enum MethodProvenance {
115     FromTrait(ast::DefId),
116     FromImpl(ast::DefId),
117 }
118
119 impl MethodProvenance {
120     pub fn map<F>(self, f: F) -> MethodProvenance where
121         F: FnOnce(ast::DefId) -> ast::DefId,
122     {
123         match self {
124             FromTrait(did) => FromTrait(f(did)),
125             FromImpl(did) => FromImpl(f(did))
126         }
127     }
128 }
129
130 impl Def {
131     pub fn local_node_id(&self) -> ast::NodeId {
132         let def_id = self.def_id();
133         assert_eq!(def_id.krate, ast::LOCAL_CRATE);
134         def_id.node
135     }
136
137     pub fn def_id(&self) -> ast::DefId {
138         match *self {
139             DefFn(id, _) | DefMod(id) | DefForeignMod(id) | DefStatic(id, _) |
140             DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(_, id) |
141             DefTyParam(_, _, id, _) | DefUse(id) | DefStruct(id) | DefTrait(id) |
142             DefMethod(id, _) | DefConst(id) => {
143                 id
144             }
145             DefLocal(id) |
146             DefSelfTy(id) |
147             DefUpvar(id, _) |
148             DefRegion(id) |
149             DefLabel(id) => {
150                 local_def(id)
151             }
152
153             DefPrimTy(_) => panic!("attempted .def_id() on DefPrimTy")
154         }
155     }
156
157     pub fn variant_def_ids(&self) -> Option<(ast::DefId, ast::DefId)> {
158         match *self {
159             DefVariant(enum_id, var_id, _) => {
160                 Some((enum_id, var_id))
161             }
162             _ => None
163         }
164     }
165 }