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.
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.
12 pub use self::MethodProvenance::*;
14 use middle::privacy::LastPrivate;
15 use middle::subst::ParamSpace;
16 use util::nodemap::NodeMap;
18 use syntax::ast_util::local_def;
20 use std::cell::RefCell;
22 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
24 DefFn(ast::DefId, bool /* is_ctor */),
25 DefSelfTy(/* trait id */ ast::NodeId),
27 DefForeignMod(ast::DefId),
28 DefStatic(ast::DefId, bool /* is_mutbl */),
30 DefLocal(ast::NodeId),
31 DefVariant(ast::DefId /* enum */, ast::DefId /* variant */, bool /* is_structure */),
32 DefTy(ast::DefId, bool /* is_enum */),
33 DefAssociatedTy(ast::DefId /* trait */, ast::DefId),
35 DefPrimTy(ast::PrimTy),
36 DefTyParam(ParamSpace, u32, ast::DefId, ast::Name),
38 DefUpvar(ast::NodeId, // id of closed over local
39 ast::NodeId), // expr node that creates the closure
41 /// Note that if it's a tuple struct's definition, the node id of the ast::DefId
42 /// may either refer to the item definition's id or the StructDef.ctor_id.
44 /// The cases that I have encountered so far are (this is not exhaustive):
45 /// - If it's a ty_path referring to some tuple struct, then DefMap maps
46 /// it to a def whose id is the item definition's id.
47 /// - If it's an ExprPath referring to some tuple struct, then DefMap maps
48 /// it to a def whose id is the StructDef.ctor_id.
49 DefStruct(ast::DefId),
50 DefRegion(ast::NodeId),
51 DefLabel(ast::NodeId),
52 DefMethod(ast::DefId /* method */, MethodProvenance),
55 /// The result of resolving a path.
56 /// Before type checking completes, `depth` represents the number of
57 /// trailing segments which are yet unresolved. Afterwards, if there
58 /// were no errors, all paths should be fully resolved, with `depth`
59 /// set to `0` and `base_def` representing the final resolution.
61 /// module::Type::AssocX::AssocY::MethodOrAssocType
62 /// ^~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
63 /// base_def depth = 3
65 /// <T as Trait>::AssocX::AssocY::MethodOrAssocType
66 /// ^~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~
67 /// base_def depth = 2
68 #[derive(Copy, Clone, Debug)]
69 pub struct PathResolution {
71 pub last_private: LastPrivate,
76 /// Get the definition, if fully resolved, otherwise panic.
77 pub fn full_def(&self) -> Def {
79 panic!("path not fully resolved: {:?}", self);
84 /// Get the DefId, if fully resolved, otherwise panic.
85 pub fn def_id(&self) -> ast::DefId {
86 self.full_def().def_id()
89 pub fn new(base_def: Def,
90 last_private: LastPrivate,
95 last_private: last_private,
101 // Definition mapping
102 pub type DefMap = RefCell<NodeMap<PathResolution>>;
103 // This is the replacement export map. It maps a module to all of the exports
105 pub type ExportMap = NodeMap<Vec<Export>>;
109 pub name: ast::Name, // The name of the target.
110 pub def_id: ast::DefId, // The definition of the target.
113 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
114 pub enum MethodProvenance {
115 FromTrait(ast::DefId),
116 FromImpl(ast::DefId),
119 impl MethodProvenance {
120 pub fn map<F>(self, f: F) -> MethodProvenance where
121 F: FnOnce(ast::DefId) -> ast::DefId,
124 FromTrait(did) => FromTrait(f(did)),
125 FromImpl(did) => FromImpl(f(did))
131 pub fn local_node_id(&self) -> ast::NodeId {
132 let def_id = self.def_id();
133 assert_eq!(def_id.krate, ast::LOCAL_CRATE);
137 pub fn def_id(&self) -> ast::DefId {
139 DefFn(id, _) | DefMod(id) | DefForeignMod(id) | DefStatic(id, _) |
140 DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(_, id) |
141 DefTyParam(_, _, id, _) | DefUse(id) | DefStruct(id) | DefTrait(id) |
142 DefMethod(id, _) | DefConst(id) => {
153 DefPrimTy(_) => panic!("attempted .def_id() on DefPrimTy")
157 pub fn variant_def_ids(&self) -> Option<(ast::DefId, ast::DefId)> {
159 DefVariant(enum_id, var_id, _) => {
160 Some((enum_id, var_id))