]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/def.rs
Refactor definitions of ADTs in rustc::middle::def
[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
13 use middle::def_id::DefId;
14 use middle::privacy::LastPrivate;
15 use middle::subst::ParamSpace;
16 use util::nodemap::NodeMap;
17 use syntax::ast;
18 use rustc_front::hir;
19
20 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
21 pub enum Def {
22     DefFn(DefId),
23     DefSelfTy(Option<DefId>,                    // trait id
24               Option<(ast::NodeId, ast::NodeId)>),   // (impl id, self type id)
25     DefMod(DefId),
26     DefForeignMod(DefId),
27     DefStatic(DefId, bool /* is_mutbl */),
28     DefConst(DefId),
29     DefAssociatedConst(DefId),
30     DefLocal(DefId, // def id of variable
31              ast::NodeId), // node id of variable
32     DefVariant(DefId /* enum */, DefId /* variant */),
33     DefEnum(DefId),
34     DefTyAlias(DefId),
35     DefAssociatedTy(DefId /* trait */, DefId),
36     DefTrait(DefId),
37     DefPrimTy(hir::PrimTy),
38     DefTyParam(ParamSpace, u32, DefId, ast::Name),
39     DefUpvar(DefId,        // def id of closed over local
40              ast::NodeId,  // node id of closed over local
41              usize,        // index in the freevars list of the closure
42              ast::NodeId), // expr node that creates the closure
43
44     // If DefStruct lives in type namespace it denotes a struct item and its DefId refers
45     // to NodeId of the struct itself.
46     // If DefStruct lives in value namespace (e.g. tuple struct, unit struct expressions)
47     // it denotes a constructor and its DefId refers to NodeId of the struct's constructor.
48     DefStruct(DefId),
49     DefLabel(ast::NodeId),
50     DefMethod(DefId),
51     DefErr,
52 }
53
54 /// The result of resolving a path.
55 /// Before type checking completes, `depth` represents the number of
56 /// trailing segments which are yet unresolved. Afterwards, if there
57 /// were no errors, all paths should be fully resolved, with `depth`
58 /// set to `0` and `base_def` representing the final resolution.
59 ///
60 ///     module::Type::AssocX::AssocY::MethodOrAssocType
61 ///     ^~~~~~~~~~~~  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
62 ///     base_def      depth = 3
63 ///
64 ///     <T as Trait>::AssocX::AssocY::MethodOrAssocType
65 ///           ^~~~~~~~~~~~~~  ^~~~~~~~~~~~~~~~~~~~~~~~~
66 ///           base_def        depth = 2
67 #[derive(Copy, Clone, Debug)]
68 pub struct PathResolution {
69     pub base_def: Def,
70     pub last_private: LastPrivate,
71     pub depth: usize
72 }
73
74 impl PathResolution {
75     /// Get the definition, if fully resolved, otherwise panic.
76     pub fn full_def(&self) -> Def {
77         if self.depth != 0 {
78             panic!("path not fully resolved: {:?}", self);
79         }
80         self.base_def
81     }
82
83     /// Get the DefId, if fully resolved, otherwise panic.
84     pub fn def_id(&self) -> DefId {
85         self.full_def().def_id()
86     }
87
88     pub fn new(base_def: Def,
89                last_private: LastPrivate,
90                depth: usize)
91                -> PathResolution {
92         PathResolution {
93             base_def: base_def,
94             last_private: last_private,
95             depth: depth,
96         }
97     }
98 }
99
100 // Definition mapping
101 pub type DefMap = NodeMap<PathResolution>;
102 // This is the replacement export map. It maps a module to all of the exports
103 // within.
104 pub type ExportMap = NodeMap<Vec<Export>>;
105
106 #[derive(Copy, Clone)]
107 pub struct Export {
108     pub name: ast::Name,    // The name of the target.
109     pub def_id: DefId, // The definition of the target.
110 }
111
112 impl Def {
113     pub fn var_id(&self) -> ast::NodeId {
114         match *self {
115             DefLocal(_, id) |
116             DefUpvar(_, id, _, _) => {
117                 id
118             }
119
120             DefFn(..) | DefMod(..) | DefForeignMod(..) | DefStatic(..) |
121             DefVariant(..) | DefEnum(..) | DefTyAlias(..) | DefAssociatedTy(..) |
122             DefTyParam(..) | DefStruct(..) | DefTrait(..) |
123             DefMethod(..) | DefConst(..) | DefAssociatedConst(..) |
124             DefPrimTy(..) | DefLabel(..) | DefSelfTy(..) | DefErr => {
125                 panic!("attempted .def_id() on invalid {:?}", self)
126             }
127         }
128     }
129
130     pub fn def_id(&self) -> DefId {
131         match *self {
132             DefFn(id) | DefMod(id) | DefForeignMod(id) | DefStatic(id, _) |
133             DefVariant(_, id) | DefEnum(id) | DefTyAlias(id) | DefAssociatedTy(_, id) |
134             DefTyParam(_, _, id, _) | DefStruct(id) | DefTrait(id) |
135             DefMethod(id) | DefConst(id) | DefAssociatedConst(id) |
136             DefLocal(id, _) | DefUpvar(id, _, _, _) => {
137                 id
138             }
139
140             DefLabel(..)  |
141             DefPrimTy(..) |
142             DefSelfTy(..) |
143             DefErr => {
144                 panic!("attempted .def_id() on invalid def: {:?}", self)
145             }
146         }
147     }
148
149     pub fn variant_def_ids(&self) -> Option<(DefId, DefId)> {
150         match *self {
151             DefVariant(enum_id, var_id) => {
152                 Some((enum_id, var_id))
153             }
154             _ => None
155         }
156     }
157 }