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