]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/def.rs
Auto merge of #30696 - steveklabnik:gh30655, r=brson
[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, bool /* is_ctor */),
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 */, bool /* is_structure */),
33     DefTy(DefId, bool /* is_enum */),
34     DefAssociatedTy(DefId /* trait */, DefId),
35     DefTrait(DefId),
36     DefPrimTy(hir::PrimTy),
37     DefTyParam(ParamSpace, u32, DefId, ast::Name),
38     DefUpvar(DefId,        // def id of closed over local
39              ast::NodeId,  // node id of closed over local
40              usize,        // index in the freevars list of the closure
41              ast::NodeId), // expr node that creates the closure
42
43     /// Note that if it's a tuple struct's definition, the node id of the DefId
44     /// may either refer to the item definition's id or the VariantData.ctor_id.
45     ///
46     /// The cases that I have encountered so far are (this is not exhaustive):
47     /// - If it's a ty_path referring to some tuple struct, then DefMap maps
48     ///   it to a def whose id is the item definition's id.
49     /// - If it's an ExprPath referring to some tuple struct, then DefMap maps
50     ///   it to a def whose id is the VariantData.ctor_id.
51     DefStruct(DefId),
52     DefLabel(ast::NodeId),
53     DefMethod(DefId),
54     DefErr,
55 }
56
57 /// The result of resolving a path.
58 /// Before type checking completes, `depth` represents the number of
59 /// trailing segments which are yet unresolved. Afterwards, if there
60 /// were no errors, all paths should be fully resolved, with `depth`
61 /// set to `0` and `base_def` representing the final resolution.
62 ///
63 ///     module::Type::AssocX::AssocY::MethodOrAssocType
64 ///     ^~~~~~~~~~~~  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
65 ///     base_def      depth = 3
66 ///
67 ///     <T as Trait>::AssocX::AssocY::MethodOrAssocType
68 ///           ^~~~~~~~~~~~~~  ^~~~~~~~~~~~~~~~~~~~~~~~~
69 ///           base_def        depth = 2
70 #[derive(Copy, Clone, Debug)]
71 pub struct PathResolution {
72     pub base_def: Def,
73     pub last_private: LastPrivate,
74     pub depth: usize
75 }
76
77 impl PathResolution {
78     /// Get the definition, if fully resolved, otherwise panic.
79     pub fn full_def(&self) -> Def {
80         if self.depth != 0 {
81             panic!("path not fully resolved: {:?}", self);
82         }
83         self.base_def
84     }
85
86     /// Get the DefId, if fully resolved, otherwise panic.
87     pub fn def_id(&self) -> DefId {
88         self.full_def().def_id()
89     }
90
91     pub fn new(base_def: Def,
92                last_private: LastPrivate,
93                depth: usize)
94                -> PathResolution {
95         PathResolution {
96             base_def: base_def,
97             last_private: last_private,
98             depth: depth,
99         }
100     }
101 }
102
103 // Definition mapping
104 pub type DefMap = NodeMap<PathResolution>;
105 // This is the replacement export map. It maps a module to all of the exports
106 // within.
107 pub type ExportMap = NodeMap<Vec<Export>>;
108
109 #[derive(Copy, Clone)]
110 pub struct Export {
111     pub name: ast::Name,    // The name of the target.
112     pub def_id: DefId, // The definition of the target.
113 }
114
115 impl Def {
116     pub fn var_id(&self) -> ast::NodeId {
117         match *self {
118             DefLocal(_, id) |
119             DefUpvar(_, id, _, _) => {
120                 id
121             }
122
123             DefFn(..) | DefMod(..) | DefForeignMod(..) | DefStatic(..) |
124             DefVariant(..) | DefTy(..) | DefAssociatedTy(..) |
125             DefTyParam(..) | DefStruct(..) | DefTrait(..) |
126             DefMethod(..) | DefConst(..) | DefAssociatedConst(..) |
127             DefPrimTy(..) | DefLabel(..) | DefSelfTy(..) | DefErr => {
128                 panic!("attempted .def_id() on invalid {:?}", self)
129             }
130         }
131     }
132
133     pub fn def_id(&self) -> DefId {
134         match *self {
135             DefFn(id, _) | DefMod(id) | DefForeignMod(id) | DefStatic(id, _) |
136             DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(_, id) |
137             DefTyParam(_, _, id, _) | DefStruct(id) | DefTrait(id) |
138             DefMethod(id) | DefConst(id) | DefAssociatedConst(id) |
139             DefLocal(id, _) | DefUpvar(id, _, _, _) => {
140                 id
141             }
142
143             DefLabel(..)  |
144             DefPrimTy(..) |
145             DefSelfTy(..) |
146             DefErr => {
147                 panic!("attempted .def_id() on invalid def: {:?}", self)
148             }
149         }
150     }
151
152     pub fn variant_def_ids(&self) -> Option<(DefId, DefId)> {
153         match *self {
154             DefVariant(enum_id, var_id, _) => {
155                 Some((enum_id, var_id))
156             }
157             _ => None
158         }
159     }
160 }