]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/def.rs
Merge pull request #20510 from tshepang/patch-6
[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 pub use self::TraitItemKind::*;
14
15 use middle::subst::ParamSpace;
16 use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory};
17 use util::nodemap::NodeMap;
18 use syntax::ast;
19 use syntax::ast_util::local_def;
20
21 use std::cell::RefCell;
22
23 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
24 pub enum Def {
25     DefFn(ast::DefId, bool /* is_ctor */),
26     DefStaticMethod(/* method */ ast::DefId, MethodProvenance),
27     DefSelfTy(/* trait id */ ast::NodeId),
28     DefMod(ast::DefId),
29     DefForeignMod(ast::DefId),
30     DefStatic(ast::DefId, bool /* is_mutbl */),
31     DefConst(ast::DefId),
32     DefLocal(ast::NodeId),
33     DefVariant(ast::DefId /* enum */, ast::DefId /* variant */, bool /* is_structure */),
34     DefTy(ast::DefId, bool /* is_enum */),
35     DefAssociatedTy(ast::DefId),
36     // A partially resolved path to an associated type `T::U` where `T` is a concrete
37     // type (indicated by the DefId) which implements a trait which has an associated
38     // type `U` (indicated by the Ident).
39     // FIXME(#20301) -- should use Name
40     DefAssociatedPath(TyParamProvenance, ast::Ident),
41     DefTrait(ast::DefId),
42     DefPrimTy(ast::PrimTy),
43     DefTyParam(ParamSpace, u32, ast::DefId, ast::Name),
44     DefUse(ast::DefId),
45     DefUpvar(ast::NodeId,  // id of closed over local
46              ast::NodeId,  // expr node that creates the closure
47              ast::NodeId), // block node for the closest enclosing proc
48                            // or unboxed closure, DUMMY_NODE_ID otherwise
49
50     /// Note that if it's a tuple struct's definition, the node id of the ast::DefId
51     /// may either refer to the item definition's id or the StructDef.ctor_id.
52     ///
53     /// The cases that I have encountered so far are (this is not exhaustive):
54     /// - If it's a ty_path referring to some tuple struct, then DefMap maps
55     ///   it to a def whose id is the item definition's id.
56     /// - If it's an ExprPath referring to some tuple struct, then DefMap maps
57     ///   it to a def whose id is the StructDef.ctor_id.
58     DefStruct(ast::DefId),
59     DefTyParamBinder(ast::NodeId), /* struct, impl or trait with ty params */
60     DefRegion(ast::NodeId),
61     DefLabel(ast::NodeId),
62     DefMethod(ast::DefId /* method */, Option<ast::DefId> /* trait */, MethodProvenance),
63 }
64
65 // Definition mapping
66 pub type DefMap = RefCell<NodeMap<Def>>;
67 // This is the replacement export map. It maps a module to all of the exports
68 // within.
69 pub type ExportMap = NodeMap<Vec<Export>>;
70
71 #[derive(Copy)]
72 pub struct Export {
73     pub name: ast::Name,    // The name of the target.
74     pub def_id: ast::DefId, // The definition of the target.
75 }
76
77 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
78 pub enum MethodProvenance {
79     FromTrait(ast::DefId),
80     FromImpl(ast::DefId),
81 }
82
83 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
84 pub enum TyParamProvenance {
85     FromSelf(ast::DefId),
86     FromParam(ast::DefId),
87 }
88
89 impl MethodProvenance {
90     pub fn map<F>(self, f: F) -> MethodProvenance where
91         F: FnOnce(ast::DefId) -> ast::DefId,
92     {
93         match self {
94             FromTrait(did) => FromTrait(f(did)),
95             FromImpl(did) => FromImpl(f(did))
96         }
97     }
98 }
99
100 impl TyParamProvenance {
101     pub fn def_id(&self) -> ast::DefId {
102         match *self {
103             TyParamProvenance::FromSelf(ref did) => did.clone(),
104             TyParamProvenance::FromParam(ref did) => did.clone(),
105         }
106     }
107 }
108
109 #[derive(Clone, Copy, Eq, PartialEq)]
110 pub enum TraitItemKind {
111     NonstaticMethodTraitItemKind,
112     StaticMethodTraitItemKind,
113     TypeTraitItemKind,
114 }
115
116 impl TraitItemKind {
117     pub fn from_explicit_self_category(explicit_self_category:
118                                        ExplicitSelfCategory)
119                                        -> TraitItemKind {
120         if explicit_self_category == StaticExplicitSelfCategory {
121             StaticMethodTraitItemKind
122         } else {
123             NonstaticMethodTraitItemKind
124         }
125     }
126 }
127
128 impl Def {
129     pub fn local_node_id(&self) -> ast::NodeId {
130         let def_id = self.def_id();
131         assert_eq!(def_id.krate, ast::LOCAL_CRATE);
132         def_id.node
133     }
134
135     pub fn def_id(&self) -> ast::DefId {
136         match *self {
137             DefFn(id, _) | DefStaticMethod(id, _) | DefMod(id) |
138             DefForeignMod(id) | DefStatic(id, _) |
139             DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(id) |
140             DefTyParam(_, _, id, _) | DefUse(id) | DefStruct(id) | DefTrait(id) |
141             DefMethod(id, _, _) | DefConst(id) |
142             DefAssociatedPath(TyParamProvenance::FromSelf(id), _) |
143             DefAssociatedPath(TyParamProvenance::FromParam(id), _) => {
144                 id
145             }
146             DefLocal(id) |
147             DefSelfTy(id) |
148             DefUpvar(id, _, _) |
149             DefRegion(id) |
150             DefTyParamBinder(id) |
151             DefLabel(id) => {
152                 local_def(id)
153             }
154
155             DefPrimTy(_) => panic!()
156         }
157     }
158
159     pub fn variant_def_ids(&self) -> Option<(ast::DefId, ast::DefId)> {
160         match *self {
161             DefVariant(enum_id, var_id, _) => {
162                 Some((enum_id, var_id))
163             }
164             _ => None
165         }
166     }
167 }