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