]> git.lizzy.rs Git - rust.git/commitdiff
rustc: combine partial_def_map and last_private_map into def_map.
authorEduard Burtescu <edy.burt@gmail.com>
Tue, 17 Feb 2015 04:44:23 +0000 (06:44 +0200)
committerEduard Burtescu <edy.burt@gmail.com>
Tue, 24 Feb 2015 12:16:02 +0000 (14:16 +0200)
38 files changed:
src/librustc/lint/builtin.rs
src/librustc/metadata/encoder.rs
src/librustc/middle/astconv_util.rs
src/librustc/middle/astencode.rs
src/librustc/middle/cfg/construct.rs
src/librustc/middle/check_const.rs
src/librustc/middle/check_match.rs
src/librustc/middle/check_static_recursion.rs
src/librustc/middle/const_eval.rs
src/librustc/middle/dead.rs
src/librustc/middle/def.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/infer/error_reporting.rs
src/librustc/middle/liveness.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/pat_util.rs
src/librustc/middle/privacy.rs
src/librustc/middle/reachable.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/middle/stability.rs
src/librustc/middle/ty.rs
src/librustc_driver/driver.rs
src/librustc_privacy/lib.rs
src/librustc_resolve/check_unused.rs
src/librustc_resolve/lib.rs
src/librustc_trans/save/mod.rs
src/librustc_trans/trans/_match.rs
src/librustc_trans/trans/common.rs
src/librustc_trans/trans/consts.rs
src/librustc_trans/trans/controlflow.rs
src/librustc_trans/trans/expr.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/lib.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/visit_ast.rs

index 8c6984972718fa092ef36d00e487080967bec672..28baeb5dc9e62c2c455465f67206987a588a3651 100644 (file)
@@ -406,7 +406,7 @@ struct ImproperCTypesVisitor<'a, 'tcx: 'a> {
 
 impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
     fn check_def(&mut self, sp: Span, id: ast::NodeId) {
-        match self.cx.tcx.def_map.borrow()[id].clone() {
+        match self.cx.tcx.def_map.borrow()[id].full_def() {
             def::DefPrimTy(ast::TyInt(ast::TyIs(_))) => {
                 self.cx.span_lint(IMPROPER_CTYPES, sp,
                                   "found rust type `isize` in foreign module, while \
@@ -1000,7 +1000,8 @@ fn check_lifetime_def(&mut self, cx: &Context, t: &ast::LifetimeDef) {
 
     fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
         if let &ast::PatIdent(_, ref path1, _) = &p.node {
-            if let Some(&def::DefLocal(_)) = cx.tcx.def_map.borrow().get(&p.id) {
+            let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
+            if let Some(def::DefLocal(_)) = def {
                 self.check_snake_case(cx, "variable", path1.node, p.span);
             }
         }
@@ -1065,8 +1066,8 @@ fn check_item(&mut self, cx: &Context, it: &ast::Item) {
 
     fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
         // Lint for constants that look like binding identifiers (#7526)
-        match (&p.node, cx.tcx.def_map.borrow().get(&p.id)) {
-            (&ast::PatIdent(_, ref path1, _), Some(&def::DefConst(..))) => {
+        match (&p.node, cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def())) {
+            (&ast::PatIdent(_, ref path1, _), Some(def::DefConst(..))) => {
                 NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern",
                                                       path1.node, p.span);
             }
@@ -1226,10 +1227,13 @@ fn get_lints(&self) -> LintArray {
     fn check_pat(&mut self, cx: &Context, pat: &ast::Pat) {
         let def_map = cx.tcx.def_map.borrow();
         if let ast::PatStruct(_, ref v, _) = pat.node {
-            for fieldpat in v.iter()
-                             .filter(|fieldpat| !fieldpat.node.is_shorthand)
-                             .filter(|fieldpat| def_map.get(&fieldpat.node.pat.id)
-                                                == Some(&def::DefLocal(fieldpat.node.pat.id))) {
+            let field_pats = v.iter()
+                              .filter(|fieldpat| !fieldpat.node.is_shorthand)
+                              .filter(|fieldpat| {
+                let def = def_map.get(&fieldpat.node.pat.id).map(|d| d.full_def());
+                def == Some(def::DefLocal(fieldpat.node.pat.id))
+            });
+            for fieldpat in field_pats {
                 if let ast::PatIdent(_, ident, None) = fieldpat.node.pat.node {
                     if ident.node.as_str() == fieldpat.node.ident.as_str() {
                         cx.span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span,
@@ -1908,10 +1912,7 @@ fn id_refers_to_this_fn<'tcx>(tcx: &ty::ctxt<'tcx>,
                                       _: ast::Ident,
                                       id: ast::NodeId) -> bool {
             tcx.def_map.borrow().get(&id)
-                .map_or(false, |def| {
-                    let did = def.def_id();
-                    ast_util::is_local(did) && did.node == fn_id
-                })
+                .map_or(false, |def| def.def_id() == ast_util::local_def(fn_id))
         }
 
         // check if the method call `id` refers to method `method_id`
index 1a695baf7216bf69791a62625fb39d924ffda8d2..4aea73cfb0ec0a18b7ff8f7566e986de65722ee9 100644 (file)
@@ -1870,9 +1870,7 @@ struct ImplVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> {
 impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'b, 'c, 'tcx> {
     fn visit_item(&mut self, item: &ast::Item) {
         if let ast::ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node {
-            let def_map = &self.ecx.tcx.def_map;
-            let trait_def = def_map.borrow()[trait_ref.ref_id].clone();
-            let def_id = trait_def.def_id();
+            let def_id = self.ecx.tcx.def_map.borrow()[trait_ref.ref_id].def_id();
 
             // Load eagerly if this is an implementation of the Drop trait
             // or if the trait is not defined in this crate.
index 1cd5a19d6788a2435558b918d17f2de5e44d26d0..c9196f0cb2a64fd860bcc9ed89b943e6210f12e7 100644 (file)
@@ -65,7 +65,7 @@ pub fn ast_ty_to_prim_ty<'tcx>(tcx: &ty::ctxt<'tcx>, ast_ty: &ast::Ty)
                 tcx.sess.span_bug(ast_ty.span,
                                   &format!("unbound path {}", path.repr(tcx)))
             }
-            Some(&d) => d
+            Some(d) => d.full_def()
         };
         if let def::DefPrimTy(nty) = def {
             Some(prim_ty_to_ty(tcx, &path.segments[], nty))
index 3de29a4ca538adf3f022361eddbef1a4a237271c..5983829ed8fbef20e56b6124b2a1e868201aaf0d 100644 (file)
@@ -25,6 +25,7 @@
 use metadata::tyencode;
 use middle::check_const::ConstQualif;
 use middle::mem_categorization::Typer;
+use middle::privacy::{AllPublic, LastMod};
 use middle::subst;
 use middle::subst::VecPerParamSpace;
 use middle::ty::{self, Ty, MethodCall, MethodCallee, MethodOrigin};
@@ -1148,10 +1149,10 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
 
     debug!("Encoding side tables for id {}", id);
 
-    if let Some(def) = tcx.def_map.borrow().get(&id) {
+    if let Some(def) = tcx.def_map.borrow().get(&id).map(|d| d.full_def()) {
         rbml_w.tag(c::tag_table_def, |rbml_w| {
             rbml_w.id(id);
-            rbml_w.tag(c::tag_table_val, |rbml_w| (*def).encode(rbml_w).unwrap());
+            rbml_w.tag(c::tag_table_val, |rbml_w| def.encode(rbml_w).unwrap());
         })
     }
 
@@ -1851,7 +1852,12 @@ fn decode_side_tables(dcx: &DecodeContext,
                 match value {
                     c::tag_table_def => {
                         let def = decode_def(dcx, val_doc);
-                        dcx.tcx.def_map.borrow_mut().insert(id, def);
+                        dcx.tcx.def_map.borrow_mut().insert(id, def::PathResolution {
+                            base_def: def,
+                            // This doesn't matter cross-crate.
+                            last_private: LastMod(AllPublic),
+                            depth: 0
+                        });
                     }
                     c::tag_table_node_type => {
                         let ty = val_dsr.read_ty(dcx);
index 52eedc460eb8749695fcb74cca6efab951c950cd..ca9455ac421f2e1c5d1327b3b4b22a7b931c726e 100644 (file)
@@ -610,32 +610,24 @@ fn add_returning_edge(&mut self,
     fn find_scope(&self,
                   expr: &ast::Expr,
                   label: Option<ast::Ident>) -> LoopScope {
-        match label {
-            None => {
-                return *self.loop_scopes.last().unwrap();
-            }
-
-            Some(_) => {
-                match self.tcx.def_map.borrow().get(&expr.id) {
-                    Some(&def::DefLabel(loop_id)) => {
-                        for l in &self.loop_scopes {
-                            if l.loop_id == loop_id {
-                                return *l;
-                            }
-                        }
-                        self.tcx.sess.span_bug(
-                            expr.span,
-                            &format!("no loop scope for id {}",
-                                    loop_id));
-                    }
+        if label.is_none() {
+            return *self.loop_scopes.last().unwrap();
+        }
 
-                    r => {
-                        self.tcx.sess.span_bug(
-                            expr.span,
-                            &format!("bad entry `{:?}` in def_map for label",
-                                    r));
+        match self.tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def()) {
+            Some(def::DefLabel(loop_id)) => {
+                for l in &self.loop_scopes {
+                    if l.loop_id == loop_id {
+                        return *l;
                     }
                 }
+                self.tcx.sess.span_bug(expr.span,
+                    &format!("no loop scope for id {}", loop_id));
+            }
+
+            r => {
+                self.tcx.sess.span_bug(expr.span,
+                    &format!("bad entry `{:?}` in def_map for label", r));
             }
         }
     }
index 0d7e730b5cdd80c9f415891066eb2850449ae0a4..57e4d3d2f02030353c7d0be8a18773edcc94d219 100644 (file)
@@ -440,7 +440,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
             }
         }
         ast::ExprPath(_) | ast::ExprQPath(_) => {
-            let def = v.tcx.def_map.borrow().get(&e.id).cloned();
+            let def = v.tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
             match def {
                 Some(def::DefVariant(_, _, _)) => {
                     // Count the discriminator or function pointer.
@@ -499,7 +499,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                     _ => break
                 };
             }
-            let def = v.tcx.def_map.borrow().get(&callee.id).cloned();
+            let def = v.tcx.def_map.borrow().get(&callee.id).map(|d| d.full_def());
             match def {
                 Some(def::DefStruct(..)) => {}
                 Some(def::DefVariant(..)) => {
index 7bd64a4f487d60414863d6456ad65cd330d6f676..c409c8fb13f14502437aa2d1c9813b1365624f9d 100644 (file)
@@ -242,7 +242,7 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat)
             ast::PatIdent(ast::BindByValue(ast::MutImmutable), ident, None) => {
                 let pat_ty = ty::pat_ty(cx.tcx, p);
                 if let ty::ty_enum(def_id, _) = pat_ty.sty {
-                    let def = cx.tcx.def_map.borrow().get(&p.id).cloned();
+                    let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
                     if let Some(DefLocal(_)) = def {
                         if ty::enum_variants(cx.tcx, def_id).iter().any(|variant|
                             token::get_name(variant.name) == token::get_name(ident.node.name)
@@ -434,7 +434,7 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
     fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> {
         return match pat.node {
             ast::PatIdent(..) | ast::PatEnum(..) => {
-                let def = self.tcx.def_map.borrow().get(&pat.id).cloned();
+                let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def());
                 match def {
                     Some(DefConst(did)) => match lookup_const_by_id(self.tcx, did) {
                         Some(const_expr) => {
@@ -733,28 +733,28 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
     let pat = raw_pat(p);
     match pat.node {
         ast::PatIdent(..) =>
-            match cx.tcx.def_map.borrow().get(&pat.id) {
-                Some(&DefConst(..)) =>
+            match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
+                Some(DefConst(..)) =>
                     cx.tcx.sess.span_bug(pat.span, "const pattern should've \
                                                     been rewritten"),
-                Some(&DefStruct(_)) => vec!(Single),
-                Some(&DefVariant(_, id, _)) => vec!(Variant(id)),
+                Some(DefStruct(_)) => vec!(Single),
+                Some(DefVariant(_, id, _)) => vec!(Variant(id)),
                 _ => vec!()
             },
         ast::PatEnum(..) =>
-            match cx.tcx.def_map.borrow().get(&pat.id) {
-                Some(&DefConst(..)) =>
+            match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
+                Some(DefConst(..)) =>
                     cx.tcx.sess.span_bug(pat.span, "const pattern should've \
                                                     been rewritten"),
-                Some(&DefVariant(_, id, _)) => vec!(Variant(id)),
+                Some(DefVariant(_, id, _)) => vec!(Variant(id)),
                 _ => vec!(Single)
             },
         ast::PatStruct(..) =>
-            match cx.tcx.def_map.borrow().get(&pat.id) {
-                Some(&DefConst(..)) =>
+            match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
+                Some(DefConst(..)) =>
                     cx.tcx.sess.span_bug(pat.span, "const pattern should've \
                                                     been rewritten"),
-                Some(&DefVariant(_, id, _)) => vec!(Variant(id)),
+                Some(DefVariant(_, id, _)) => vec!(Variant(id)),
                 _ => vec!(Single)
             },
         ast::PatLit(ref expr) =>
@@ -847,7 +847,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
             Some(repeat(DUMMY_WILD_PAT).take(arity).collect()),
 
         ast::PatIdent(_, _, _) => {
-            let opt_def = cx.tcx.def_map.borrow().get(&pat_id).cloned();
+            let opt_def = cx.tcx.def_map.borrow().get(&pat_id).map(|d| d.full_def());
             match opt_def {
                 Some(DefConst(..)) =>
                     cx.tcx.sess.span_bug(pat_span, "const pattern should've \
@@ -862,7 +862,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
         }
 
         ast::PatEnum(_, ref args) => {
-            let def = cx.tcx.def_map.borrow()[pat_id].clone();
+            let def = cx.tcx.def_map.borrow()[pat_id].full_def();
             match def {
                 DefConst(..) =>
                     cx.tcx.sess.span_bug(pat_span, "const pattern should've \
@@ -880,7 +880,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
 
         ast::PatStruct(_, ref pattern_fields, _) => {
             // Is this a struct or an enum variant?
-            let def = cx.tcx.def_map.borrow()[pat_id].clone();
+            let def = cx.tcx.def_map.borrow()[pat_id].full_def();
             let class_id = match def {
                 DefConst(..) =>
                     cx.tcx.sess.span_bug(pat_span, "const pattern should've \
index 4280b7fe3f09649170a73dc7e37f90873a22fa9f..a4393f4648b1eec0c6899444d3f6a13f63032ca3 100644 (file)
@@ -94,9 +94,9 @@ fn visit_item(&mut self, it: &ast::Item) {
     fn visit_expr(&mut self, e: &ast::Expr) {
         match e.node {
             ast::ExprPath(_) | ast::ExprQPath(_) => {
-                match self.def_map.borrow().get(&e.id) {
-                    Some(&DefStatic(def_id, _)) |
-                    Some(&DefConst(def_id)) if
+                match self.def_map.borrow().get(&e.id).map(|d| d.full_def()) {
+                    Some(DefStatic(def_id, _)) |
+                    Some(DefConst(def_id)) if
                             ast_util::is_local(def_id) => {
                         match self.ast_map.get(def_id.node) {
                           ast_map::NodeItem(item) =>
index 5bf7422dbc0d41ce7051d5a801238c4d4a28b12f..d3c6a585fa3fd0b82ad8b3a1f32e8553dc2c845c 100644 (file)
@@ -31,7 +31,7 @@
 use std::rc::Rc;
 
 fn lookup_const<'a>(tcx: &'a ty::ctxt, e: &Expr) -> Option<&'a Expr> {
-    let opt_def = tcx.def_map.borrow().get(&e.id).cloned();
+    let opt_def = tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
     match opt_def {
         Some(def::DefConst(def_id)) => {
             lookup_const_by_id(tcx, def_id)
@@ -148,11 +148,11 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<ast::Pat>
             ast::PatTup(exprs.iter().map(|expr| const_expr_to_pat(tcx, &**expr, span)).collect()),
 
         ast::ExprCall(ref callee, ref args) => {
-            let def = tcx.def_map.borrow()[callee.id].clone();
+            let def = tcx.def_map.borrow()[callee.id];
             if let Vacant(entry) = tcx.def_map.borrow_mut().entry(expr.id) {
                entry.insert(def);
             }
-            let path = match def {
+            let path = match def.full_def() {
                 def::DefStruct(def_id) => def_to_path(tcx, def_id),
                 def::DefVariant(_, variant_did, _) => def_to_path(tcx, variant_did),
                 _ => unreachable!()
@@ -179,7 +179,7 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<ast::Pat>
         }
 
         ast::ExprPath(ref path) => {
-            let opt_def = tcx.def_map.borrow().get(&expr.id).cloned();
+            let opt_def = tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def());
             match opt_def {
                 Some(def::DefStruct(..)) =>
                     ast::PatStruct(path.clone(), vec![], false),
@@ -389,7 +389,7 @@ fn fromb(b: bool) -> Result<const_val, String> { Ok(const_int(b as i64)) }
         cast_const(val, ety)
       }
       ast::ExprPath(_) | ast::ExprQPath(_) => {
-          let opt_def = tcx.def_map.borrow().get(&e.id).cloned();
+          let opt_def = tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
           let (const_expr, const_ty) = match opt_def {
               Some(def::DefConst(def_id)) => {
                   if ast_util::is_local(def_id) {
index ff78deb8d12ea6ba945531b6c34f0762b38a2ee6..2d837ce52b56a4f9abcee7e973d8dc95d7a55d3f 100644 (file)
@@ -71,13 +71,13 @@ fn check_def_id(&mut self, def_id: ast::DefId) {
 
     fn lookup_and_handle_definition(&mut self, id: &ast::NodeId) {
         self.tcx.def_map.borrow().get(id).map(|def| {
-            match def {
-                &def::DefConst(_) => {
+            match def.full_def() {
+                def::DefConst(_) => {
                     self.check_def_id(def.def_id())
                 }
                 _ if self.ignore_non_const_paths => (),
-                &def::DefPrimTy(_) => (),
-                &def::DefVariant(enum_id, variant_id, _) => {
+                def::DefPrimTy(_) => (),
+                def::DefVariant(enum_id, variant_id, _) => {
                     self.check_def_id(enum_id);
                     self.check_def_id(variant_id);
                 }
@@ -158,7 +158,7 @@ fn handle_tup_field_access(&mut self, lhs: &ast::Expr, idx: uint) {
 
     fn handle_field_pattern_match(&mut self, lhs: &ast::Pat,
                                   pats: &[codemap::Spanned<ast::FieldPat>]) {
-        let id = match (*self.tcx.def_map.borrow())[lhs.id] {
+        let id = match self.tcx.def_map.borrow()[lhs.id].full_def() {
             def::DefVariant(_, id, _) => id,
             _ => {
                 match ty::ty_to_def_id(ty::node_id_to_type(self.tcx,
index 355c52b374e0174ad23ab25ea0c16a096d8263e6..1a054c0f464aac9afb5a91adb6f007490a8969da 100644 (file)
@@ -11,6 +11,7 @@
 pub use self::Def::*;
 pub use self::MethodProvenance::*;
 
+use middle::privacy::LastPrivate;
 use middle::subst::ParamSpace;
 use util::nodemap::NodeMap;
 use syntax::ast;
@@ -51,24 +52,43 @@ pub enum Def {
     DefMethod(ast::DefId /* method */, MethodProvenance),
 }
 
-/// The result of resolving the prefix of a path to a type:
+/// The result of resolving a path.
+/// Before type checking completes, `depth` represents the number of
+/// trailing segments which are yet unresolved. Afterwards, if there
+/// were no errors, all paths should be fully resolved, with `depth`
+/// set to `0` and `base_def` representing the final resolution.
 ///
-///     module::Type::AssocA::AssocB::AssocC::MethodOrAssocType
-///     ^~~~~~~~~~~~  ^~~~~~~~~~~~~~~~~~~~~~
-///     base_type     extra_associated_types
+///     module::Type::AssocX::AssocY::MethodOrAssocType
+///     ^~~~~~~~~~~~  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+///     base_def      depth = 3
 ///
-///     <T as Trait>::AssocA::AssocB::AssocC::MethodOrAssocType
-///           ^~~~~~~~~~~~~~  ^~~~~~~~~~~~~~
-///           base_type       extra_associated_types
-#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct PartialDef {
-    pub base_type: Def,
-    pub extra_associated_types: u32,
+///     <T as Trait>::AssocX::AssocY::MethodOrAssocType
+///           ^~~~~~~~~~~~~~  ^~~~~~~~~~~~~~~~~~~~~~~~~
+///           base_def        depth = 2
+#[derive(Copy, Debug)]
+pub struct PathResolution {
+    pub base_def: Def,
+    pub last_private: LastPrivate,
+    pub depth: usize
+}
+
+impl PathResolution {
+    /// Get the definition, if fully resolved, otherwise panic.
+    pub fn full_def(&self) -> Def {
+        if self.depth != 0 {
+            panic!("path not fully resolved: {:?}", self);
+        }
+        self.base_def
+    }
+
+    /// Get the DefId, if fully resolved, otherwise panic.
+    pub fn def_id(&self) -> ast::DefId {
+        self.full_def().def_id()
+    }
 }
 
 // Definition mapping
-pub type DefMap = RefCell<NodeMap<Def>>;
-pub type PartialDefMap = RefCell<NodeMap<PartialDef>>;
+pub type DefMap = RefCell<NodeMap<PathResolution>>;
 // This is the replacement export map. It maps a module to all of the exports
 // within.
 pub type ExportMap = NodeMap<Vec<Export>>;
@@ -119,7 +139,7 @@ pub fn def_id(&self) -> ast::DefId {
                 local_def(id)
             }
 
-            DefPrimTy(_) => panic!()
+            DefPrimTy(_) => panic!("attempted .def_id() on DefPrimTy")
         }
     }
 
index 625093e3c5dea50bb8c976a39cbbbec3fa5962db..f7c723c68746fef3d49ef8a45a2e74033c5c56a1 100644 (file)
@@ -1017,7 +1017,7 @@ fn walk_pat(&mut self,
 
                 // Each match binding is effectively an assignment to the
                 // binding being produced.
-                let def = def_map.borrow()[pat.id].clone();
+                let def = def_map.borrow()[pat.id].full_def();
                 match mc.cat_def(pat.id, pat.span, pat_ty, def) {
                     Ok(binding_cmt) => {
                         delegate.mutate(pat.id, pat.span, binding_cmt, Init);
@@ -1097,13 +1097,13 @@ fn walk_pat(&mut self,
 
             match pat.node {
                 ast::PatEnum(_, _) | ast::PatIdent(_, _, None) | ast::PatStruct(..) => {
-                    match def_map.get(&pat.id) {
+                    match def_map.get(&pat.id).map(|d| d.full_def()) {
                         None => {
                             // no definition found: pat is not a
                             // struct or enum pattern.
                         }
 
-                        Some(&def::DefVariant(enum_did, variant_did, _is_struct)) => {
+                        Some(def::DefVariant(enum_did, variant_did, _is_struct)) => {
                             let downcast_cmt =
                                 if ty::enum_is_univariant(tcx, enum_did) {
                                     cmt_pat
@@ -1119,7 +1119,7 @@ fn walk_pat(&mut self,
                             delegate.matched_pat(pat, downcast_cmt, match_mode);
                         }
 
-                        Some(&def::DefStruct(..)) | Some(&def::DefTy(_, false)) => {
+                        Some(def::DefStruct(..)) | Some(def::DefTy(_, false)) => {
                             // A struct (in either the value or type
                             // namespace; we encounter the former on
                             // e.g. patterns for unit structs).
@@ -1131,14 +1131,14 @@ fn walk_pat(&mut self,
                             delegate.matched_pat(pat, cmt_pat, match_mode);
                         }
 
-                        Some(&def::DefConst(..)) |
-                        Some(&def::DefLocal(..)) => {
+                        Some(def::DefConst(..)) |
+                        Some(def::DefLocal(..)) => {
                             // This is a leaf (i.e. identifier binding
                             // or constant value to match); thus no
                             // `matched_pat` call.
                         }
 
-                        Some(def @ &def::DefTy(_, true)) => {
+                        Some(def @ def::DefTy(_, true)) => {
                             // An enum's type -- should never be in a
                             // pattern.
 
index 4439472ab5671bb0f4d2bf43a42cc29254cd30b9..60b7e1169b49bcb923534fd909569c66e8704e80 100644 (file)
@@ -1242,7 +1242,7 @@ fn rebuild_arg_ty_or_output(&self,
                                         "unbound path {}",
                                         pprust::path_to_string(path)))
                         }
-                        Some(&d) => d
+                        Some(d) => d.full_def()
                     };
                     match a_def {
                         def::DefTy(did, _) | def::DefStruct(did) => {
index 145fccd7972bb5bcbf927d27d391abc5f4d41c97..4685a05f41604d31887f98b8db6574a4e8fb3367 100644 (file)
@@ -446,7 +446,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
     match expr.node {
       // live nodes required for uses or definitions of variables:
       ast::ExprPath(_) | ast::ExprQPath(_) => {
-        let def = ir.tcx.def_map.borrow()[expr.id].clone();
+        let def = ir.tcx.def_map.borrow()[expr.id].full_def();
         debug!("expr {}: path that leads to {:?}", expr.id, def);
         if let DefLocal(..) = def {
             ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
@@ -705,8 +705,8 @@ fn find_loop_scope(&self,
             Some(_) => {
                 // Refers to a labeled loop. Use the results of resolve
                 // to find with one
-                match self.ir.tcx.def_map.borrow().get(&id) {
-                    Some(&DefLabel(loop_id)) => loop_id,
+                match self.ir.tcx.def_map.borrow().get(&id).map(|d| d.full_def()) {
+                    Some(DefLabel(loop_id)) => loop_id,
                     _ => self.ir.tcx.sess.span_bug(sp, "label on break/loop \
                                                         doesn't refer to a loop")
                 }
@@ -1300,7 +1300,7 @@ fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: uint)
 
     fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: uint)
                    -> LiveNode {
-        match self.ir.tcx.def_map.borrow()[expr.id].clone() {
+        match self.ir.tcx.def_map.borrow()[expr.id].full_def() {
           DefLocal(nid) => {
             let ln = self.live_node(expr.id, expr.span);
             if acc != 0 {
@@ -1562,7 +1562,7 @@ fn check_ret(&self,
     fn check_lvalue(&mut self, expr: &Expr) {
         match expr.node {
             ast::ExprPath(_) | ast::ExprQPath(_) => {
-                if let DefLocal(nid) = self.ir.tcx.def_map.borrow()[expr.id].clone() {
+                if let DefLocal(nid) = self.ir.tcx.def_map.borrow()[expr.id].full_def() {
                     // Assignment to an immutable variable or argument: only legal
                     // if there is no later assignment. If this local is actually
                     // mutable, then check for a reassignment to flag the mutability
index f8065f81aa8d8b56a264fa5e87af913545f08fbc..44ab3cf60aaa3dbe6f0ff19df2db8b41747f0eb8 100644 (file)
@@ -530,7 +530,7 @@ pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> McResult<cmt<'tcx>> {
           }
 
           ast::ExprPath(_) | ast::ExprQPath(_) => {
-            let def = (*self.tcx().def_map.borrow())[expr.id];
+            let def = self.tcx().def_map.borrow()[expr.id].full_def();
             self.cat_def(expr.id, expr.span, expr_ty, def)
           }
 
@@ -1199,14 +1199,13 @@ fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat, op: &mut F)
 
         (*op)(self, cmt.clone(), pat);
 
-        let def_map = self.tcx().def_map.borrow();
-        let opt_def = def_map.get(&pat.id);
+        let opt_def = self.tcx().def_map.borrow().get(&pat.id).map(|d| d.full_def());
 
         // Note: This goes up here (rather than within the PatEnum arm
         // alone) because struct patterns can refer to struct types or
         // to struct variants within enums.
         let cmt = match opt_def {
-            Some(&def::DefVariant(enum_did, variant_did, _))
+            Some(def::DefVariant(enum_did, variant_did, _))
                 // univariant enums do not need downcasts
                 if !ty::enum_is_univariant(self.tcx(), enum_did) => {
                     self.cat_downcast(pat, cmt.clone(), cmt.ty, variant_did)
@@ -1224,7 +1223,7 @@ fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat, op: &mut F)
           }
           ast::PatEnum(_, Some(ref subpats)) => {
             match opt_def {
-                Some(&def::DefVariant(..)) => {
+                Some(def::DefVariant(..)) => {
                     // variant(x, y, z)
                     for (i, subpat) in subpats.iter().enumerate() {
                         let subpat_ty = try!(self.pat_ty(&**subpat)); // see (*2)
@@ -1237,7 +1236,7 @@ fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat, op: &mut F)
                         try!(self.cat_pattern_(subcmt, &**subpat, op));
                     }
                 }
-                Some(&def::DefStruct(..)) => {
+                Some(def::DefStruct(..)) => {
                     for (i, subpat) in subpats.iter().enumerate() {
                         let subpat_ty = try!(self.pat_ty(&**subpat)); // see (*2)
                         let cmt_field =
@@ -1247,7 +1246,7 @@ fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat, op: &mut F)
                         try!(self.cat_pattern_(cmt_field, &**subpat, op));
                     }
                 }
-                Some(&def::DefConst(..)) => {
+                Some(def::DefConst(..)) => {
                     for subpat in subpats {
                         try!(self.cat_pattern_(cmt.clone(), &**subpat, op));
                     }
index a7df2f4a5dafb4dfe3e4b90e6a2a0b748ca05f2f..c5abff3b96360bceaa9ca8b8d8124e02ad4fb08e 100644 (file)
@@ -34,8 +34,8 @@ pub fn pat_is_refutable(dm: &DefMap, pat: &ast::Pat) -> bool {
         ast::PatEnum(_, _) |
         ast::PatIdent(_, _, None) |
         ast::PatStruct(..) => {
-            match dm.borrow().get(&pat.id) {
-                Some(&DefVariant(..)) => true,
+            match dm.borrow().get(&pat.id).map(|d| d.full_def()) {
+                Some(DefVariant(..)) => true,
                 _ => false
             }
         }
@@ -49,8 +49,8 @@ pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &ast::Pat) -> bool {
         ast::PatEnum(_, _) |
         ast::PatIdent(_, _, None) |
         ast::PatStruct(..) => {
-            match dm.borrow().get(&pat.id) {
-                Some(&DefVariant(..)) | Some(&DefStruct(..)) => true,
+            match dm.borrow().get(&pat.id).map(|d| d.full_def()) {
+                Some(DefVariant(..)) | Some(DefStruct(..)) => true,
                 _ => false
             }
         }
@@ -61,8 +61,8 @@ pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &ast::Pat) -> bool {
 pub fn pat_is_const(dm: &DefMap, pat: &ast::Pat) -> bool {
     match pat.node {
         ast::PatIdent(_, _, None) | ast::PatEnum(..) => {
-            match dm.borrow().get(&pat.id) {
-                Some(&DefConst(..)) => true,
+            match dm.borrow().get(&pat.id).map(|d| d.full_def()) {
+                Some(DefConst(..)) => true,
                 _ => false
             }
         }
index dd1e32d13a2be07d512d3d506f159b8387d13f51..3a253735f925b032e93390ce3618f6c4aa4aec87 100644 (file)
@@ -16,7 +16,7 @@
 pub use self::ImportUse::*;
 pub use self::LastPrivate::*;
 
-use util::nodemap::{DefIdSet, NodeMap, NodeSet};
+use util::nodemap::{DefIdSet, NodeSet};
 
 use syntax::ast;
 
@@ -32,9 +32,6 @@
 /// reexporting a public struct doesn't inline the doc).
 pub type PublicItems = NodeSet;
 
-// FIXME: dox
-pub type LastPrivateMap = NodeMap<LastPrivate>;
-
 #[derive(Copy, Debug)]
 pub enum LastPrivate {
     LastMod(PrivateDep),
index 550f4e39447f8252298a6a33fa41c7c9d6207adb..a140c766758e38a6f4a1790fe1d30744c88ed145 100644 (file)
@@ -96,7 +96,7 @@ fn visit_expr(&mut self, expr: &ast::Expr) {
         match expr.node {
             ast::ExprPath(_) | ast::ExprQPath(_) => {
                 let def = match self.tcx.def_map.borrow().get(&expr.id) {
-                    Some(&def) => def,
+                    Some(d) => d.full_def(),
                     None => {
                         self.tcx.sess.span_bug(expr.span,
                                                "def ID not in def map?!")
index 7b957d6ce84986368123b4988aa3255ffcb25947..9bcda68eb3ad797503fd5767515d93b6324b0395 100644 (file)
@@ -168,8 +168,8 @@ fn visit_ty(&mut self, ty: &ast::Ty) {
             ast::TyPath(ref path) => {
                 // if this path references a trait, then this will resolve to
                 // a trait ref, which introduces a binding scope.
-                match self.def_map.borrow().get(&ty.id) {
-                    Some(&def::DefTrait(..)) => {
+                match self.def_map.borrow().get(&ty.id).map(|d| (d.base_def, d.depth)) {
+                    Some((def::DefTrait(..), 0)) => {
                         self.with(LateScope(&Vec::new(), self.scope), |_, this| {
                             this.visit_path(path, ty.id);
                         });
index cfa5e5fce387930a2a71a6ef89c2dc3b3fdd1824..f67e470ee54917a1a2f9105fca63a5c50c5a877a 100644 (file)
@@ -393,12 +393,14 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
 
 pub fn check_path(tcx: &ty::ctxt, path: &ast::Path, id: ast::NodeId,
                   cb: &mut FnMut(ast::DefId, Span, &Option<Stability>)) {
-    let did = match tcx.def_map.borrow().get(&id) {
-        Some(&def::DefPrimTy(..)) => return,
-        Some(def) => def.def_id(),
-        None => return
-    };
-    maybe_do_stability_check(tcx, did, path.span, cb)
+    match tcx.def_map.borrow().get(&id).map(|d| d.full_def()) {
+        Some(def::DefPrimTy(..)) => {}
+        Some(def) => {
+            maybe_do_stability_check(tcx, def.def_id(), path.span, cb);
+        }
+        None => {}
+    }
+
 }
 
 fn maybe_do_stability_check(tcx: &ty::ctxt, id: ast::DefId, span: Span,
index 7dcdeaf16d2e80614414596f41b22ae292fe6263..7cd047279028cc90c667575d744af14d1fe725b2 100644 (file)
 use middle;
 use middle::check_const;
 use middle::const_eval;
-use middle::def::{self, DefMap, ExportMap, PartialDefMap};
+use middle::def::{self, DefMap, ExportMap};
 use middle::dependency_format;
 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem};
 use middle::lang_items::{FnOnceTraitLangItem, TyDescStructLangItem};
 use middle::mem_categorization as mc;
-use middle::privacy::LastPrivateMap;
 use middle::region;
 use middle::resolve_lifetime;
 use middle::infer;
@@ -683,8 +682,6 @@ pub struct ctxt<'tcx> {
 
     pub sess: Session,
     pub def_map: DefMap,
-    pub partial_def_map: PartialDefMap,
-    pub last_private_map: RefCell<LastPrivateMap>,
 
     pub named_region_map: resolve_lifetime::NamedRegionMap,
 
@@ -2427,8 +2424,6 @@ fn new(arena: &'tcx TypedArena<TyS<'tcx>>,
 pub fn mk_ctxt<'tcx>(s: Session,
                      arenas: &'tcx CtxtArenas<'tcx>,
                      def_map: DefMap,
-                     partial_def_map: PartialDefMap,
-                     last_private_map: LastPrivateMap,
                      named_region_map: resolve_lifetime::NamedRegionMap,
                      map: ast_map::Map<'tcx>,
                      freevars: RefCell<FreevarMap>,
@@ -2451,8 +2446,6 @@ pub fn mk_ctxt<'tcx>(s: Session,
         variance_computed: Cell::new(false),
         sess: s,
         def_map: def_map,
-        partial_def_map: partial_def_map,
-        last_private_map: RefCell::new(last_private_map),
         region_maps: region_maps,
         node_types: RefCell::new(FnvHashMap()),
         item_substs: RefCell::new(NodeMap()),
@@ -4509,7 +4502,7 @@ pub fn unsize_ty<'tcx>(cx: &ctxt<'tcx>,
 
 pub fn resolve_expr(tcx: &ctxt, expr: &ast::Expr) -> def::Def {
     match tcx.def_map.borrow().get(&expr.id) {
-        Some(&def) => def,
+        Some(def) => def.full_def(),
         None => {
             tcx.sess.span_bug(expr.span, &format!(
                 "no def-map entry for expr {}", expr.id));
@@ -4692,11 +4685,10 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
 
         ast::ExprBox(Some(ref place), _) => {
             // Special case `Box<T>` for now:
-            let definition = match tcx.def_map.borrow().get(&place.id) {
-                Some(&def) => def,
+            let def_id = match tcx.def_map.borrow().get(&place.id) {
+                Some(def) => def.def_id(),
                 None => panic!("no def for place"),
             };
-            let def_id = definition.def_id();
             if tcx.lang_items.exchange_heap() == Some(def_id) {
                 RvalueDatumExpr
             } else {
@@ -5144,10 +5136,7 @@ pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
 }
 
 pub fn trait_ref_to_def_id(tcx: &ctxt, tr: &ast::TraitRef) -> ast::DefId {
-    let def = *tcx.def_map.borrow()
-                     .get(&tr.ref_id)
-                     .expect("no def-map entry for trait");
-    def.def_id()
+    tcx.def_map.borrow().get(&tr.ref_id).expect("no def-map entry for trait").def_id()
 }
 
 pub fn try_add_builtin_trait(
index aafa4dec0de94efee7ec788bfbfdd1e091e6001d..bd911c20afc47e0aeb178cd30485ec1470ef926f 100644 (file)
@@ -567,12 +567,10 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
 
     let resolve::CrateMap {
         def_map,
-        partial_def_map,
         freevars,
         export_map,
         trait_map,
         external_exports,
-        last_private_map,
         glob_map,
     } =
         time(time_passes, "resolution", (),
@@ -608,8 +606,6 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
     let ty_cx = ty::mk_ctxt(sess,
                             arenas,
                             def_map,
-                            partial_def_map,
-                            last_private_map,
                             named_region_map,
                             ast_map,
                             freevars,
index 1452c44ca71441db61cf72f9b610b3b4683b6e08..f325a6abede51a7518935cd5b146a12519263efd 100644 (file)
@@ -259,7 +259,7 @@ fn visit_item(&mut self, item: &ast::Item) {
             ast::ItemImpl(_, _, _, _, ref ty, ref impl_items) => {
                 let public_ty = match ty.node {
                     ast::TyPath(_) => {
-                        match self.tcx.def_map.borrow()[ty.id].clone() {
+                        match self.tcx.def_map.borrow()[ty.id].full_def() {
                             def::DefPrimTy(..) => true,
                             def => {
                                 let did = def.def_id();
@@ -326,7 +326,7 @@ fn visit_item(&mut self, item: &ast::Item) {
 
             ast::ItemTy(ref ty, _) if public_first => {
                 if let ast::TyPath(_) = ty.node {
-                    match self.tcx.def_map.borrow()[ty.id].clone() {
+                    match self.tcx.def_map.borrow()[ty.id].full_def() {
                         def::DefPrimTy(..) | def::DefTyParam(..) => {},
                         def => {
                             let did = def.def_id();
@@ -630,7 +630,7 @@ fn ensure_public(&self, span: Span, to_check: ast::DefId,
                             ast::TyPath(_) => {}
                             _ => return Some((err_span, err_msg, None)),
                         };
-                        let def = self.tcx.def_map.borrow()[ty.id].clone();
+                        let def = self.tcx.def_map.borrow()[ty.id].full_def();
                         let did = def.def_id();
                         assert!(is_local(did));
                         match self.tcx.map.get(did.node) {
@@ -716,19 +716,19 @@ fn check_static_method(&mut self,
     // Checks that a path is in scope.
     fn check_path(&mut self, span: Span, path_id: ast::NodeId, last: ast::Ident) {
         debug!("privacy - path {}", self.nodestr(path_id));
-        let orig_def = self.tcx.def_map.borrow()[path_id].clone();
+        let path_res = self.tcx.def_map.borrow()[path_id];
         let ck = |tyname: &str| {
             let ck_public = |def: ast::DefId| {
                 debug!("privacy - ck_public {:?}", def);
                 let name = token::get_ident(last);
-                let origdid = orig_def.def_id();
+                let origdid = path_res.def_id();
                 self.ensure_public(span,
                                    def,
                                    Some(origdid),
                                    &format!("{} `{}`", tyname, name))
             };
 
-            match self.tcx.last_private_map.borrow()[path_id] {
+            match path_res.last_private {
                 LastMod(AllPublic) => {},
                 LastMod(DependsOn(def)) => {
                     self.report_error(ck_public(def));
@@ -792,7 +792,7 @@ fn check_path(&mut self, span: Span, path_id: ast::NodeId, last: ast::Ident) {
         // def map is not. Therefore the names we work out below will not always
         // be accurate and we can get slightly wonky error messages (but type
         // checking is always correct).
-        match self.tcx.def_map.borrow()[path_id].clone() {
+        match path_res.full_def() {
             def::DefFn(..) => ck("function"),
             def::DefStatic(..) => ck("static"),
             def::DefConst(..) => ck("const"),
@@ -889,7 +889,7 @@ fn visit_expr(&mut self, expr: &ast::Expr) {
                         }
                     }
                     ty::ty_enum(_, _) => {
-                        match self.tcx.def_map.borrow()[expr.id].clone() {
+                        match self.tcx.def_map.borrow()[expr.id].full_def() {
                             def::DefVariant(_, variant_id, _) => {
                                 for field in fields {
                                     self.check_field(expr.span, variant_id,
@@ -922,8 +922,8 @@ struct type?!"),
                              with private fields");
                     }
                 };
-                match self.tcx.def_map.borrow().get(&expr.id) {
-                    Some(&def::DefStruct(did)) => {
+                match self.tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def()) {
+                    Some(def::DefStruct(did)) => {
                         guard(if is_local(did) {
                             local_def(self.tcx.map.get_parent(did.node))
                         } else {
@@ -962,8 +962,8 @@ fn visit_pat(&mut self, pattern: &ast::Pat) {
                         }
                     }
                     ty::ty_enum(_, _) => {
-                        match self.tcx.def_map.borrow().get(&pattern.id) {
-                            Some(&def::DefVariant(_, variant_id, _)) => {
+                        match self.tcx.def_map.borrow().get(&pattern.id).map(|d| d.full_def()) {
+                            Some(def::DefVariant(_, variant_id, _)) => {
                                 for field in fields {
                                     self.check_field(pattern.span, variant_id,
                                                      NamedField(field.node.ident.name));
@@ -1214,7 +1214,7 @@ struct CheckTypeForPrivatenessVisitor<'a, 'b: 'a, 'tcx: 'b> {
 
 impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
     fn path_is_private_type(&self, path_id: ast::NodeId) -> bool {
-        let did = match self.tcx.def_map.borrow().get(&path_id).cloned() {
+        let did = match self.tcx.def_map.borrow().get(&path_id).map(|d| d.full_def()) {
             // `int` etc. (None doesn't seem to occur.)
             None | Some(def::DefPrimTy(..)) => return false,
             Some(def) => def.def_id()
index a239c73c110dbd67e96353ad8efca3f20b6b82b5..aebbe14407380336174b9c85f82bd693b5084dbd 100644 (file)
@@ -68,17 +68,17 @@ fn finalize_import(&mut self, id: ast::NodeId, span: Span) {
                                   "unused import".to_string());
         }
 
-        let (v_priv, t_priv) = match self.last_private.get(&id) {
-            Some(&LastImport {
-                value_priv: v,
-                value_used: _,
-                type_priv: t,
-                type_used: _
-            }) => (v, t),
-            Some(_) => {
+        let mut def_map = self.def_map.borrow_mut();
+        let path_res = if let Some(r) = def_map.get_mut(&id) {
+            r
+        } else {
+            return;
+        };
+        let (v_priv, t_priv) = match path_res.last_private {
+            LastImport { value_priv, type_priv, .. } => (value_priv, type_priv),
+            _ => {
                 panic!("we should only have LastImport for `use` directives")
             }
-            _ => return,
         };
 
         let mut v_used = if self.used_imports.contains(&(id, ValueNS)) {
@@ -100,10 +100,12 @@ fn finalize_import(&mut self, id: ast::NodeId, span: Span) {
             _ => {},
         }
 
-        self.last_private.insert(id, LastImport{value_priv: v_priv,
-                                                value_used: v_used,
-                                                type_priv: t_priv,
-                                                type_used: t_used});
+        path_res.last_private = LastImport {
+            value_priv: v_priv,
+            value_used: v_used,
+            type_priv: t_priv,
+            type_used: t_used
+        };
     }
 }
 
index 6b05a648746546fdf16af5d5eab44dab7e51756b..265f398d25ca5d881986839828324d87de6a73fc 100644 (file)
@@ -934,13 +934,11 @@ struct Resolver<'a, 'tcx:'a> {
     primitive_type_table: PrimitiveTypeTable,
 
     def_map: DefMap,
-    partial_def_map: PartialDefMap,
     freevars: RefCell<FreevarMap>,
     freevars_seen: RefCell<NodeMap<NodeSet>>,
     export_map: ExportMap,
     trait_map: TraitMap,
     external_exports: ExternalExports,
-    last_private: LastPrivateMap,
 
     // Whether or not to print error messages. Can be set to true
     // when getting additional info for error message suggestions,
@@ -1008,7 +1006,6 @@ fn new(session: &'a Session,
             primitive_type_table: PrimitiveTypeTable::new(),
 
             def_map: RefCell::new(NodeMap()),
-            partial_def_map: RefCell::new(NodeMap()),
             freevars: RefCell::new(NodeMap()),
             freevars_seen: RefCell::new(NodeMap()),
             export_map: NodeMap(),
@@ -1016,7 +1013,6 @@ fn new(session: &'a Session,
             used_imports: HashSet::new(),
             used_crates: HashSet::new(),
             external_exports: DefIdSet(),
-            last_private: NodeMap(),
 
             emit_errors: true,
             make_glob_map: make_glob_map == MakeGlobMap::Yes,
@@ -1574,31 +1570,36 @@ fn get_binding(this: &mut Resolver,
         // record what this import resolves to for later uses in documentation,
         // this may resolve to either a value or a type, but for documentation
         // purposes it's good enough to just favor one over the other.
-        let value_private = match import_resolution.value_target {
-            Some(ref target) => {
-                let def = target.bindings.def_for_namespace(ValueNS).unwrap();
-                self.def_map.borrow_mut().insert(directive.id, def);
-                let did = def.def_id();
-                if value_used_public {Some(lp)} else {Some(DependsOn(did))}
-            },
-            // AllPublic here and below is a dummy value, it should never be used because
-            // _exists is false.
-            None => None,
-        };
-        let type_private = match import_resolution.type_target {
-            Some(ref target) => {
-                let def = target.bindings.def_for_namespace(TypeNS).unwrap();
-                self.def_map.borrow_mut().insert(directive.id, def);
-                let did = def.def_id();
-                if type_used_public {Some(lp)} else {Some(DependsOn(did))}
-            },
-            None => None,
+        let value_def_and_priv = import_resolution.value_target.as_ref().map(|target| {
+            let def = target.bindings.def_for_namespace(ValueNS).unwrap();
+            (def, if value_used_public { lp } else { DependsOn(def.def_id()) })
+        });
+        let type_def_and_priv = import_resolution.type_target.as_ref().map(|target| {
+            let def = target.bindings.def_for_namespace(TypeNS).unwrap();
+            (def, if type_used_public { lp } else { DependsOn(def.def_id()) })
+        });
+
+        let import_lp = LastImport {
+            value_priv: value_def_and_priv.map(|(_, p)| p),
+            value_used: Used,
+            type_priv: type_def_and_priv.map(|(_, p)| p),
+            type_used: Used
         };
 
-        self.last_private.insert(directive.id, LastImport{value_priv: value_private,
-                                                          value_used: Used,
-                                                          type_priv: type_private,
-                                                          type_used: Used});
+        if let Some((def, _)) = value_def_and_priv {
+            self.def_map.borrow_mut().insert(directive.id, PathResolution {
+                base_def: def,
+                last_private: import_lp,
+                depth: 0
+            });
+        }
+        if let Some((def, _)) = type_def_and_priv {
+            self.def_map.borrow_mut().insert(directive.id, PathResolution {
+                base_def: def,
+                last_private: import_lp,
+                depth: 0
+            });
+        }
 
         debug!("(resolving single import) successfully resolved import");
         return Success(());
@@ -1716,12 +1717,12 @@ fn resolve_glob_import(&mut self,
         }
 
         // Record the destination of this import
-        match containing_module.def_id.get() {
-            Some(did) => {
-                self.def_map.borrow_mut().insert(id, DefMod(did));
-                self.last_private.insert(id, lp);
-            }
-            None => {}
+        if let Some(did) = containing_module.def_id.get() {
+            self.def_map.borrow_mut().insert(id, PathResolution {
+                base_def: DefMod(did),
+                last_private: lp,
+                depth: 0
+            });
         }
 
         debug!("(resolving glob import) successfully resolved import");
@@ -2846,8 +2847,8 @@ fn resolve_item(&mut self, item: &Item) {
             ItemUse(ref view_path) => {
                 // check for imports shadowing primitive types
                 if let ast::ViewPathSimple(ident, _) = view_path.node {
-                    match self.def_map.borrow().get(&item.id) {
-                        Some(&DefTy(..)) | Some(&DefStruct(..)) | Some(&DefTrait(..)) | None => {
+                    match self.def_map.borrow().get(&item.id).map(|d| d.full_def()) {
+                        Some(DefTy(..)) | Some(DefStruct(..)) | Some(DefTrait(..)) | None => {
                             self.check_if_primitive_type_name(ident.name, item.span);
                         }
                         _ => {}
@@ -2959,30 +2960,28 @@ fn resolve_trait_reference(&mut self,
                                id: NodeId,
                                trait_path: &Path,
                                path_depth: usize)
-                               -> Result<(Def, LastPrivate, usize), ()> {
-        match self.resolve_path(id, trait_path, path_depth, TypeNS, true) {
-            Some(def @ (DefTrait(_), _, _)) => {
-                debug!("(resolving trait) found trait def: {:?}", def);
-                Ok(def)
-            }
-            Some((def, _, _)) => {
+                               -> Result<PathResolution, ()> {
+        if let Some(path_res) = self.resolve_path(id, trait_path, path_depth, TypeNS, true) {
+            if let DefTrait(_) = path_res.base_def {
+                debug!("(resolving trait) found trait def: {:?}", path_res);
+                Ok(path_res)
+            } else {
                 self.resolve_error(trait_path.span,
                     &format!("`{}` is not a trait",
                              self.path_names_to_string(trait_path, path_depth)));
 
                 // If it's a typedef, give a note
-                if let DefTy(..) = def {
+                if let DefTy(..) = path_res.base_def {
                     self.session.span_note(trait_path.span,
                                            "`type` aliases cannot be used for traits");
                 }
                 Err(())
             }
-            None => {
-                let msg = format!("use of undeclared trait name `{}`",
-                                  self.path_names_to_string(trait_path, path_depth));
-                self.resolve_error(trait_path.span, &msg[]);
-                Err(())
-            }
+        } else {
+            let msg = format!("use of undeclared trait name `{}`",
+                              self.path_names_to_string(trait_path, path_depth));
+            self.resolve_error(trait_path.span, &msg[]);
+            Err(())
         }
     }
 
@@ -2995,14 +2994,11 @@ fn resolve_generics(&mut self, generics: &Generics) {
                 &ast::WherePredicate::BoundPredicate(_) |
                 &ast::WherePredicate::RegionPredicate(_) => {}
                 &ast::WherePredicate::EqPredicate(ref eq_pred) => {
-                    match self.resolve_path(eq_pred.id, &eq_pred.path, 0, TypeNS, true) {
-                        Some(def @ (DefTyParam(..), _, _)) => {
-                            self.record_def(eq_pred.id, def);
-                        }
-                        _ => {
-                            self.resolve_error(eq_pred.path.span,
-                                               "undeclared associated type");
-                        }
+                    let path_res = self.resolve_path(eq_pred.id, &eq_pred.path, 0, TypeNS, true);
+                    if let Some(PathResolution { base_def: DefTyParam(..), .. }) = path_res {
+                        self.record_def(eq_pred.id, path_res.unwrap());
+                    } else {
+                        self.resolve_error(eq_pred.path.span, "undeclared associated type");
                     }
                 }
             }
@@ -3028,9 +3024,9 @@ fn with_optional_trait_ref<T, F>(&mut self,
         let mut new_val = None;
         if let Some(ref trait_ref) = *opt_trait_ref {
             match self.resolve_trait_reference(trait_ref.ref_id, &trait_ref.path, 0) {
-                Ok(def) => {
-                    self.record_def(trait_ref.ref_id, def);
-                    new_val = Some((def.0.def_id(), trait_ref.clone()));
+                Ok(path_res) => {
+                    self.record_def(trait_ref.ref_id, path_res);
+                    new_val = Some((path_res.base_def.def_id(), trait_ref.clone()));
                 }
                 Err(_) => { /* error was already reported */ }
             }
@@ -3259,23 +3255,23 @@ fn resolve_type(&mut self, ty: &Ty) {
                     path.segments.len()
                 };
 
-                let mut result = None;
+                let mut resolution = None;
                 for depth in 0..max_assoc_types {
                     self.with_no_errors(|this| {
-                        result = this.resolve_path(ty.id, path, depth, TypeNS, true);
+                        resolution = this.resolve_path(ty.id, path, depth, TypeNS, true);
                     });
-                    if result.is_some() {
+                    if resolution.is_some() {
                         break;
                     }
                 }
-                if let Some((DefMod(_), _, _)) = result {
+                if let Some(DefMod(_)) = resolution.map(|r| r.base_def) {
                     // A module is not a valid type.
-                    result = None;
+                    resolution = None;
                 }
 
                 // This is a path in the type namespace. Walk through scopes
                 // looking for it.
-                match result {
+                match resolution {
                     Some(def) => {
                         // Write the result into the def map.
                         debug!("(resolving type) writing resolution for `{}` \
@@ -3338,7 +3334,11 @@ struct or enum variant",
                                 pattern,
                                 binding_mode,
                                 "an enum variant");
-                            self.record_def(pattern.id, (def, lp, 0));
+                            self.record_def(pattern.id, PathResolution {
+                                base_def: def,
+                                last_private: lp,
+                                depth: 0
+                            });
                         }
                         FoundStructOrEnumVariant(..) => {
                             self.resolve_error(
@@ -3357,7 +3357,11 @@ struct or enum variant",
                                 pattern,
                                 binding_mode,
                                 "a constant");
-                            self.record_def(pattern.id, (def, lp, 0));
+                            self.record_def(pattern.id, PathResolution {
+                                base_def: def,
+                                last_private: lp,
+                                depth: 0
+                            });
                         }
                         FoundConst(..) => {
                             self.resolve_error(pattern.span,
@@ -3374,7 +3378,11 @@ struct or enum variant",
                             // will be able to distinguish variants from
                             // locals in patterns.
 
-                            self.record_def(pattern.id, (def, LastMod(AllPublic), 0));
+                            self.record_def(pattern.id, PathResolution {
+                                base_def: def,
+                                last_private: LastMod(AllPublic),
+                                depth: 0
+                            });
 
                             // Add the binding to the local ribs, if it
                             // doesn't already exist in the bindings list. (We
@@ -3417,29 +3425,28 @@ struct or enum variant",
 
                 PatEnum(ref path, _) => {
                     // This must be an enum variant, struct or const.
-                    match self.resolve_path(pat_id, path, 0, ValueNS, false) {
-                        Some(def @ (DefVariant(..), _, _)) |
-                        Some(def @ (DefStruct(..), _, _))  |
-                        Some(def @ (DefConst(..), _, _)) => {
-                            self.record_def(pattern.id, def);
-                        }
-                        Some((DefStatic(..), _, _)) => {
-                            self.resolve_error(path.span,
-                                               "static variables cannot be \
-                                                referenced in a pattern, \
-                                                use a `const` instead");
-                        }
-                        Some(_) => {
-                            self.resolve_error(path.span,
-                                &format!("`{}` is not an enum variant, struct or const",
-                                    token::get_ident(
-                                        path.segments.last().unwrap().identifier)));
-                        }
-                        None => {
-                            self.resolve_error(path.span,
-                                &format!("unresolved enum variant, struct or const `{}`",
-                                    token::get_ident(path.segments.last().unwrap().identifier)));
+                    if let Some(path_res) = self.resolve_path(pat_id, path, 0, ValueNS, false) {
+                        match path_res.base_def {
+                            DefVariant(..) | DefStruct(..) | DefConst(..) => {
+                                self.record_def(pattern.id, path_res);
+                            }
+                            DefStatic(..) => {
+                                self.resolve_error(path.span,
+                                                   "static variables cannot be \
+                                                    referenced in a pattern, \
+                                                    use a `const` instead");
+                            }
+                            _ => {
+                                self.resolve_error(path.span,
+                                    &format!("`{}` is not an enum variant, struct or const",
+                                        token::get_ident(
+                                            path.segments.last().unwrap().identifier)));
+                            }
                         }
+                    } else {
+                        self.resolve_error(path.span,
+                            &format!("unresolved enum variant, struct or const `{}`",
+                                token::get_ident(path.segments.last().unwrap().identifier)));
                     }
                     visit::walk_path(self, path);
                 }
@@ -3535,18 +3542,26 @@ fn resolve_bare_identifier_pattern(&mut self, name: Name, span: Span)
 
     /// If `check_ribs` is true, checks the local definitions first; i.e.
     /// doesn't skip straight to the containing module.
+    /// Skips `path_depth` trailing segments, which is also reflected in the
+    /// returned value. See `middle::def::PathResolution` for more info.
     fn resolve_path(&mut self,
                     id: NodeId,
                     path: &Path,
                     path_depth: usize,
                     namespace: Namespace,
-                    check_ribs: bool) -> Option<(Def, LastPrivate, usize)> {
+                    check_ribs: bool) -> Option<PathResolution> {
         let span = path.span;
         let segments = &path.segments[..path.segments.len()-path_depth];
 
+        let mk_res = |(def, lp)| PathResolution {
+            base_def: def,
+            last_private: lp,
+            depth: path_depth
+        };
+
         if path.global {
             let def = self.resolve_crate_relative_path(span, segments, namespace);
-            return def.map(|(def, lp)| (def, lp, path_depth));
+            return def.map(mk_res);
         }
 
         // Try to find a path to an item in a module.
@@ -3568,9 +3583,9 @@ fn resolve_path(&mut self,
                 _ => ()
             }
 
-            def.map(|(def, lp)| (def, lp, path_depth))
+            def.map(mk_res)
         } else {
-            unqualified_def.map(|(def, lp)| (def, lp, path_depth))
+            unqualified_def.map(mk_res)
         }
     }
 
@@ -3957,10 +3972,10 @@ fn is_static_method(this: &Resolver, did: DefId) -> bool {
 
         if allowed == Everything {
             // Look for a field with the same name in the current self_type.
-            match self.def_map.borrow().get(&node_id) {
-                 Some(&DefTy(did, _))
-                | Some(&DefStruct(did))
-                | Some(&DefVariant(_, did, _)) => match self.structs.get(&did) {
+            match self.def_map.borrow().get(&node_id).map(|d| d.full_def()) {
+                Some(DefTy(did, _)) |
+                Some(DefStruct(did)) |
+                Some(DefVariant(_, did, _)) => match self.structs.get(&did) {
                     None => {}
                     Some(fields) => {
                         if fields.iter().any(|&field_name| name == field_name) {
@@ -4060,27 +4075,27 @@ fn resolve_expr(&mut self, expr: &Expr) {
                     path.segments.len()
                 };
 
-                let mut result = self.with_no_errors(|this| {
+                let mut resolution = self.with_no_errors(|this| {
                     this.resolve_path(expr.id, path, 0, ValueNS, true)
                 });
                 for depth in 1..max_assoc_types {
-                    if result.is_some() {
+                    if resolution.is_some() {
                         break;
                     }
                     self.with_no_errors(|this| {
-                        result = this.resolve_path(expr.id, path, depth, TypeNS, true);
+                        resolution = this.resolve_path(expr.id, path, depth, TypeNS, true);
                     });
                 }
-                if let Some((DefMod(_), _, _)) = result {
+                if let Some(DefMod(_)) = resolution.map(|r| r.base_def) {
                     // A module is not a valid type or value.
-                    result = None;
+                    resolution = None;
                 }
 
                 // This is a local path in the value namespace. Walk through
                 // scopes looking for it.
-                match result {
+                if let Some(path_res) = resolution {
                     // Check if struct variant
-                    Some((DefVariant(_, _, true), _, 0)) => {
+                    if let DefVariant(_, _, true) = path_res.base_def {
                         let path_name = self.path_names_to_string(path, 0);
                         self.resolve_error(expr.span,
                                 &format!("`{}` is a struct variant name, but \
@@ -4092,95 +4107,93 @@ fn resolve_expr(&mut self, expr: &Expr) {
                             &format!("Did you mean to write: \
                                      `{} {{ /* fields */ }}`?",
                                      path_name));
-                    }
-                    Some(def) => {
+                    } else {
                         // Write the result into the def map.
                         debug!("(resolving expr) resolved `{}`",
                                self.path_names_to_string(path, 0));
 
                         // Partial resolutions will need the set of traits in scope,
                         // so they can be completed during typeck.
-                        if def.2 != 0 {
+                        if path_res.depth != 0 {
                             let method_name = path.segments.last().unwrap().identifier.name;
                             let traits = self.search_for_traits_containing_method(method_name);
                             self.trait_map.insert(expr.id, traits);
                         }
 
-                        self.record_def(expr.id, def);
+                        self.record_def(expr.id, path_res);
                     }
-                    None => {
-                        // Be helpful if the name refers to a struct
-                        // (The pattern matching def_tys where the id is in self.structs
-                        // matches on regular structs while excluding tuple- and enum-like
-                        // structs, which wouldn't result in this error.)
-                        let path_name = self.path_names_to_string(path, 0);
-                        match self.with_no_errors(|this|
-                            this.resolve_path(expr.id, path, 0, TypeNS, false)) {
-                            Some((DefTy(struct_id, _), _, 0))
-                              if self.structs.contains_key(&struct_id) => {
-                                self.resolve_error(expr.span,
-                                        &format!("`{}` is a structure name, but \
-                                                  this expression \
-                                                  uses it like a function name",
-                                                 path_name));
-
-                                self.session.span_help(expr.span,
-                                    &format!("Did you mean to write: \
-                                             `{} {{ /* fields */ }}`?",
-                                             path_name));
-
-                            }
-                            _ => {
-                                // Keep reporting some errors even if they're ignored above.
-                                self.resolve_path(expr.id, path, 0, ValueNS, true);
-
-                                let mut method_scope = false;
-                                self.value_ribs.iter().rev().all(|rib| {
-                                    method_scope = match rib.kind {
-                                        MethodRibKind => true,
-                                        ItemRibKind | ConstantItemRibKind => false,
-                                        _ => return true, // Keep advancing
-                                    };
-                                    false // Stop advancing
-                                });
+                } else {
+                    // Be helpful if the name refers to a struct
+                    // (The pattern matching def_tys where the id is in self.structs
+                    // matches on regular structs while excluding tuple- and enum-like
+                    // structs, which wouldn't result in this error.)
+                    let path_name = self.path_names_to_string(path, 0);
+                    let type_res = self.with_no_errors(|this| {
+                        this.resolve_path(expr.id, path, 0, TypeNS, false)
+                    });
+                    match type_res.map(|r| r.base_def) {
+                        Some(DefTy(struct_id, _))
+                            if self.structs.contains_key(&struct_id) => {
+                            self.resolve_error(expr.span,
+                                    &format!("`{}` is a structure name, but \
+                                                this expression \
+                                                uses it like a function name",
+                                                path_name));
+
+                            self.session.span_help(expr.span,
+                                &format!("Did you mean to write: \
+                                            `{} {{ /* fields */ }}`?",
+                                            path_name));
 
-                                if method_scope && &token::get_name(self.self_name)[..]
-                                                                   == path_name {
-                                        self.resolve_error(
-                                            expr.span,
-                                            "`self` is not available \
-                                             in a static method. Maybe a \
-                                             `self` argument is missing?");
-                                } else {
-                                    let last_name = path.segments.last().unwrap().identifier.name;
-                                    let mut msg = match self.find_fallback_in_self_type(last_name) {
-                                        NoSuggestion => {
-                                            // limit search to 5 to reduce the number
-                                            // of stupid suggestions
-                                            self.find_best_match_for_name(&path_name, 5)
-                                                                .map_or("".to_string(),
-                                                                        |x| format!("`{}`", x))
-                                        }
-                                        Field =>
-                                            format!("`self.{}`", path_name),
-                                        Method
-                                        | TraitItem =>
-                                            format!("to call `self.{}`", path_name),
-                                        TraitMethod(path_str)
-                                        | StaticMethod(path_str) =>
-                                            format!("to call `{}::{}`", path_str, path_name)
-                                    };
-
-                                    if msg.len() > 0 {
-                                        msg = format!(". Did you mean {}?", msg)
-                                    }
+                        }
+                        _ => {
+                            // Keep reporting some errors even if they're ignored above.
+                            self.resolve_path(expr.id, path, 0, ValueNS, true);
+
+                            let mut method_scope = false;
+                            self.value_ribs.iter().rev().all(|rib| {
+                                method_scope = match rib.kind {
+                                    MethodRibKind => true,
+                                    ItemRibKind | ConstantItemRibKind => false,
+                                    _ => return true, // Keep advancing
+                                };
+                                false // Stop advancing
+                            });
 
+                            if method_scope && &token::get_name(self.self_name)[..]
+                                                                == path_name {
                                     self.resolve_error(
                                         expr.span,
-                                        &format!("unresolved name `{}`{}",
-                                                 path_name,
-                                                 msg));
+                                        "`self` is not available \
+                                         in a static method. Maybe a \
+                                         `self` argument is missing?");
+                            } else {
+                                let last_name = path.segments.last().unwrap().identifier.name;
+                                let mut msg = match self.find_fallback_in_self_type(last_name) {
+                                    NoSuggestion => {
+                                        // limit search to 5 to reduce the number
+                                        // of stupid suggestions
+                                        self.find_best_match_for_name(&path_name, 5)
+                                                            .map_or("".to_string(),
+                                                                    |x| format!("`{}`", x))
+                                    }
+                                    Field => format!("`self.{}`", path_name),
+                                    Method |
+                                    TraitItem =>
+                                        format!("to call `self.{}`", path_name),
+                                    TraitMethod(path_str) |
+                                    StaticMethod(path_str) =>
+                                        format!("to call `{}::{}`", path_str, path_name)
+                                };
+
+                                if msg.len() > 0 {
+                                    msg = format!(". Did you mean {}?", msg)
                                 }
+
+                                self.resolve_error(
+                                    expr.span,
+                                    &format!("unresolved name `{}`{}",
+                                             path_name, msg));
                             }
                         }
                     }
@@ -4231,7 +4244,11 @@ fn resolve_expr(&mut self, expr: &Expr) {
                     }
                     Some(DlDef(def @ DefLabel(_))) => {
                         // Since this def is a label, it is never read.
-                        self.record_def(expr.id, (def, LastMod(AllPublic), 0))
+                        self.record_def(expr.id, PathResolution {
+                            base_def: def,
+                            last_private: LastMod(AllPublic),
+                            depth: 0
+                        })
                     }
                     Some(_) => {
                         self.session.span_bug(expr.span,
@@ -4349,33 +4366,16 @@ fn add_trait_info(found_traits: &mut Vec<DefId>,
         found_traits
     }
 
-    fn record_def(&mut self,
-                  node_id: NodeId,
-                  (def, lp, depth): (Def, LastPrivate, usize)) {
-        debug!("(recording def) recording {:?} for {}, last private {:?}",
-                def, node_id, lp);
-        assert!(match lp {LastImport{..} => false, _ => true},
+    fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) {
+        debug!("(recording def) recording {:?} for {}", resolution, node_id);
+        assert!(match resolution.last_private {LastImport{..} => false, _ => true},
                 "Import should only be used for `use` directives");
-        self.last_private.insert(node_id, lp);
 
-        if depth == 0 {
-            if let Some(prev_def) = self.def_map.borrow_mut().insert(node_id, def) {
-                let span = self.ast_map.opt_span(node_id).unwrap_or(codemap::DUMMY_SP);
-                self.session.span_bug(span, &format!("path resolved multiple times \
-                                                      ({:?} before, {:?} now)",
-                                                     prev_def, def));
-            }
-        } else {
-            let def = PartialDef {
-                base_type: def,
-                extra_associated_types: (depth - 1) as u32
-            };
-            if let Some(prev_def) = self.partial_def_map.borrow_mut().insert(node_id, def) {
-                let span = self.ast_map.opt_span(node_id).unwrap_or(codemap::DUMMY_SP);
-                self.session.span_bug(span, &format!("path resolved multiple times \
-                                                      ({:?} before, {:?} now)",
-                                                     prev_def, def));
-            }
+        if let Some(prev_res) = self.def_map.borrow_mut().insert(node_id, resolution) {
+            let span = self.ast_map.opt_span(node_id).unwrap_or(codemap::DUMMY_SP);
+            self.session.span_bug(span, &format!("path resolved multiple times \
+                                                  ({:?} before, {:?} now)",
+                                                 prev_res, resolution));
         }
     }
 
@@ -4466,12 +4466,10 @@ fn dump_module(&mut self, module_: Rc<Module>) {
 
 pub struct CrateMap {
     pub def_map: DefMap,
-    pub partial_def_map: PartialDefMap,
     pub freevars: RefCell<FreevarMap>,
     pub export_map: ExportMap,
     pub trait_map: TraitMap,
     pub external_exports: ExternalExports,
-    pub last_private_map: LastPrivateMap,
     pub glob_map: Option<GlobMap>
 }
 
@@ -4506,12 +4504,10 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
 
     CrateMap {
         def_map: resolver.def_map,
-        partial_def_map: resolver.partial_def_map,
         freevars: resolver.freevars,
         export_map: resolver.export_map,
         trait_map: resolver.trait_map,
         external_exports: resolver.external_exports,
-        last_private_map: resolver.last_private,
         glob_map: if resolver.make_glob_map {
                         Some(resolver.glob_map)
                     } else {
index 5484e3c7c5fc2813b64d4e539886048cf1c02746..ea346798679c0fdcdcdbd4788ec437729f1229c8 100644 (file)
@@ -218,7 +218,7 @@ fn lookup_type_ref(&self, ref_id: NodeId) -> Option<DefId> {
             self.sess.bug(&format!("def_map has no key for {} in lookup_type_ref",
                                   ref_id));
         }
-        let def = (*self.analysis.ty_cx.def_map.borrow())[ref_id];
+        let def = self.analysis.ty_cx.def_map.borrow()[ref_id].full_def();
         match def {
             def::DefPrimTy(_) => None,
             _ => Some(def.def_id()),
@@ -231,7 +231,7 @@ fn lookup_def_kind(&self, ref_id: NodeId, span: Span) -> Option<recorder::Row> {
             self.sess.span_bug(span, &format!("def_map has no key for {} in lookup_def_kind",
                                              ref_id));
         }
-        let def = (*def_map)[ref_id];
+        let def = def_map[ref_id].full_def();
         match def {
             def::DefMod(_) |
             def::DefForeignMod(_) => Some(recorder::ModRef),
@@ -792,9 +792,9 @@ fn process_path(&mut self,
             self.sess.span_bug(span,
                                &format!("def_map has no key for {} in visit_expr", id));
         }
-        let def = &(*def_map)[id];
+        let def = def_map[id].full_def();
         let sub_span = self.span.span_for_last_ident(span);
-        match *def {
+        match def {
             def::DefUpvar(..) |
             def::DefLocal(..) |
             def::DefStatic(..) |
@@ -866,10 +866,10 @@ fn process_path(&mut self,
                                     &format!("Unexpected def kind while looking \
                                               up path in `{}`: `{:?}`",
                                              self.span.snippet(span),
-                                             *def)),
+                                             def)),
         }
         // modules or types in the path prefix
-        match *def {
+        match def {
             def::DefMethod(did, _) => {
                 let ti = ty::impl_or_trait_item(&self.analysis.ty_cx, did);
                 if let ty::MethodTraitItem(m) = ti {
@@ -1456,8 +1456,8 @@ fn visit_arm(&mut self, arm: &ast::Arm) {
                                    &format!("def_map has no key for {} in visit_arm",
                                            id));
             }
-            let def = &(*def_map)[id];
-            match *def {
+            let def = def_map[id].full_def();
+            match def {
                 def::DefLocal(id)  => {
                     let value = if *immut {
                         self.span.snippet(p.span).to_string()
@@ -1480,7 +1480,7 @@ fn visit_arm(&mut self, arm: &ast::Arm) {
                 def::DefStatic(_, _) => {}
                 def::DefConst(..) => {}
                 _ => error!("unexpected definition kind when processing collected paths: {:?}",
-                            *def)
+                            def)
             }
         }
         for &(id, ref path, ref_kind) in &paths_to_process {
index 26e1a981f1bae25de1e722c0783e17af900126a9..3e741640117aa14c779d23cdec6a7ece0a269ed0 100644 (file)
@@ -598,7 +598,7 @@ fn get_branches<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             }
             ast::PatIdent(..) | ast::PatEnum(..) | ast::PatStruct(..) => {
                 // This is either an enum variant or a variable binding.
-                let opt_def = tcx.def_map.borrow().get(&cur.id).cloned();
+                let opt_def = tcx.def_map.borrow().get(&cur.id).map(|d| d.full_def());
                 match opt_def {
                     Some(def::DefVariant(enum_id, var_id, _)) => {
                         let variant = ty::enum_variant_with_id(tcx, enum_id, var_id);
@@ -725,14 +725,14 @@ fn any_irrefutable_adt_pat(tcx: &ty::ctxt, m: &[Match], col: uint) -> bool {
         match pat.node {
             ast::PatTup(_) => true,
             ast::PatStruct(..) => {
-                match tcx.def_map.borrow().get(&pat.id) {
-                    Some(&def::DefVariant(..)) => false,
+                match tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
+                    Some(def::DefVariant(..)) => false,
                     _ => true,
                 }
             }
             ast::PatEnum(..) | ast::PatIdent(_, _, None) => {
-                match tcx.def_map.borrow().get(&pat.id) {
-                    Some(&def::DefStruct(..)) => true,
+                match tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
+                    Some(def::DefStruct(..)) => true,
                     _ => false
                 }
             }
@@ -1282,15 +1282,15 @@ fn is_discr_reassigned(bcx: Block, discr: &ast::Expr, body: &ast::Expr) -> bool
             _ => return false
         },
         ast::ExprField(ref base, field) => {
-            let vid = match bcx.tcx().def_map.borrow().get(&base.id) {
-                Some(&def::DefLocal(vid)) | Some(&def::DefUpvar(vid, _)) => vid,
+            let vid = match bcx.tcx().def_map.borrow().get(&base.id).map(|d| d.full_def()) {
+                Some(def::DefLocal(vid)) | Some(def::DefUpvar(vid, _)) => vid,
                 _ => return false
             };
             (vid, Some(mc::NamedField(field.node.name)))
         },
         ast::ExprTupField(ref base, field) => {
-            let vid = match bcx.tcx().def_map.borrow().get(&base.id) {
-                Some(&def::DefLocal(vid)) | Some(&def::DefUpvar(vid, _)) => vid,
+            let vid = match bcx.tcx().def_map.borrow().get(&base.id).map(|d| d.full_def()) {
+                Some(def::DefLocal(vid)) | Some(def::DefUpvar(vid, _)) => vid,
                 _ => return false
             };
             (vid, Some(mc::PositionalField(field.node)))
@@ -1689,7 +1689,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             }
         }
         ast::PatEnum(_, ref sub_pats) => {
-            let opt_def = bcx.tcx().def_map.borrow().get(&pat.id).cloned();
+            let opt_def = bcx.tcx().def_map.borrow().get(&pat.id).map(|d| d.full_def());
             match opt_def {
                 Some(def::DefVariant(enum_id, var_id, _)) => {
                     let repr = adt::represent_node(bcx, pat.id);
index a3ba506fc46a2034b977589d18f3300cb6c89d56..d8fc6df2685dd5d9656ee561e0dd9a5565b90371 100644 (file)
@@ -603,7 +603,7 @@ pub fn expr_to_string(&self, e: &ast::Expr) -> String {
 
     pub fn def(&self, nid: ast::NodeId) -> def::Def {
         match self.tcx().def_map.borrow().get(&nid) {
-            Some(v) => v.clone(),
+            Some(v) => v.full_def(),
             None => {
                 self.tcx().sess.bug(&format!(
                     "no def associated with node id {}", nid));
index e321c5f0a13d5bd9ca2a1c1f733142da525ce129..6e1d2da02c10185f675faf8c14e58d4ead4eedb7 100644 (file)
@@ -194,7 +194,7 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     // Special-case constants to cache a common global for all uses.
     match expr.node {
         ast::ExprPath(_) => {
-            let def = ccx.tcx().def_map.borrow()[expr.id];
+            let def = ccx.tcx().def_map.borrow()[expr.id].full_def();
             match def {
                 def::DefConst(def_id) => {
                     if !ccx.tcx().adjustments.borrow().contains_key(&expr.id) {
@@ -582,7 +582,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                       _ => break,
                   }
               }
-              let opt_def = cx.tcx().def_map.borrow().get(&cur.id).cloned();
+              let opt_def = cx.tcx().def_map.borrow().get(&cur.id).map(|d| d.full_def());
               if let Some(def::DefStatic(def_id, _)) = opt_def {
                   return get_static_val(cx, def_id, ety);
               }
@@ -664,7 +664,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             }
           }
           ast::ExprPath(_) | ast::ExprQPath(_) => {
-            let def = cx.tcx().def_map.borrow()[e.id];
+            let def = cx.tcx().def_map.borrow()[e.id].full_def();
             match def {
                 def::DefFn(..) | def::DefMethod(..) => {
                     expr::trans_def_fn_unadjusted(cx, e, def, param_substs).val
@@ -701,7 +701,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             }
           }
           ast::ExprCall(ref callee, ref args) => {
-              let opt_def = cx.tcx().def_map.borrow().get(&callee.id).cloned();
+              let opt_def = cx.tcx().def_map.borrow().get(&callee.id).map(|d| d.full_def());
               let arg_vals = map_list(&args[..]);
               match opt_def {
                   Some(def::DefStruct(_)) => {
index 5eebe6a4a05fb5e98ca06b3b15793b5692923924..ad96c506c9ddf14333af894780629a2dc254f47b 100644 (file)
@@ -306,11 +306,10 @@ pub fn trans_break_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let loop_id = match opt_label {
         None => fcx.top_loop_scope(),
         Some(_) => {
-            match bcx.tcx().def_map.borrow().get(&expr.id) {
-                Some(&def::DefLabel(loop_id)) => loop_id,
-                ref r => {
-                    bcx.tcx().sess.bug(&format!("{:?} in def-map for label",
-                                               r))
+            match bcx.tcx().def_map.borrow().get(&expr.id).map(|d| d.full_def())  {
+                Some(def::DefLabel(loop_id)) => loop_id,
+                r => {
+                    bcx.tcx().sess.bug(&format!("{:?} in def-map for label", r))
                 }
             }
         }
index 95c5122deacb677e0f4fd7192dbf198ea61df102..80fe2ed8f3af31da7940cea19d60051562cde690 100644 (file)
@@ -1363,7 +1363,7 @@ pub fn with_field_tys<'tcx, R, F>(tcx: &ty::ctxt<'tcx>,
                         ty.repr(tcx)));
                 }
                 Some(node_id) => {
-                    let def = tcx.def_map.borrow()[node_id].clone();
+                    let def = tcx.def_map.borrow()[node_id].full_def();
                     match def {
                         def::DefVariant(enum_id, variant_id, _) => {
                             let variant_info = ty::enum_variant_with_id(
index adbc4d546f1903ba30ee201462f6ecf866de6b06..982cc1e3792e1a6d4c77578d2d13cfe9b16be9c6 100644 (file)
@@ -898,7 +898,7 @@ fn ast_ty_to_trait_ref<'tcx>(this: &AstConv<'tcx>,
 
     match ty.node {
         ast::TyPath(ref path) => {
-            let def = this.tcx().def_map.borrow().get(&ty.id).cloned();
+            let def = this.tcx().def_map.borrow().get(&ty.id).map(|d| d.full_def());
             match def {
                 Some(def::DefTrait(trait_def_id)) => {
                     let mut projection_bounds = Vec::new();
@@ -1303,16 +1303,14 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
             conv_ty_poly_trait_ref(this, rscope, ast_ty.span, bounds)
         }
         ast::TyPath(ref path) | ast::TyQPath(ast::QPath { ref path, .. }) => {
-            let result = if let Some(&d) = tcx.def_map.borrow().get(&ast_ty.id) {
-                (d, 0)
-            } else if let Some(d) = tcx.partial_def_map.borrow().get(&ast_ty.id) {
-                (d.base_type, (d.extra_associated_types + 1) as usize)
+            let path_res = if let Some(&d) = tcx.def_map.borrow().get(&ast_ty.id) {
+                d
             } else {
                 tcx.sess.span_bug(ast_ty.span,
                                   &format!("unbound path {}", ast_ty.repr(tcx)))
             };
-            let (mut def, max_depth) = result;
-            let base_ty_end = path.segments.len() - max_depth;
+            let mut def = path_res.base_def;
+            let base_ty_end = path.segments.len() - path_res.depth;
             let opt_self_ty = if let ast::TyQPath(ref qpath) = ast_ty.node {
                 Some(ast_ty_to_ty(this, rscope, &*qpath.self_type))
             } else {
@@ -1324,9 +1322,13 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
                                                 &path.segments[..base_ty_end],
                                                 &path.segments[base_ty_end..]);
 
-            if max_depth != 0 && ty.sty != ty::ty_err {
+            if path_res.depth != 0 && ty.sty != ty::ty_err {
                 // Write back the new resolution.
-                tcx.def_map.borrow_mut().insert(ast_ty.id, def);
+                tcx.def_map.borrow_mut().insert(ast_ty.id, def::PathResolution {
+                    base_def: def,
+                    last_private: path_res.last_private,
+                    depth: 0
+                });
             }
 
             ty
index edbda795bde3c075e131b22ce282d56f4af1d201..dd2ab6c6b13ca5d5ee273eb59080b04edc962333 100644 (file)
@@ -103,7 +103,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
             demand::eqtype(fcx, pat.span, expected, lhs_ty);
         }
         ast::PatEnum(..) | ast::PatIdent(..) if pat_is_const(&tcx.def_map, pat) => {
-            let const_did = tcx.def_map.borrow()[pat.id].clone().def_id();
+            let const_did = tcx.def_map.borrow()[pat.id].def_id();
             let const_scheme = ty::lookup_item_type(tcx, const_did);
             assert!(const_scheme.generics.is_empty());
             let const_ty = pcx.fcx.instantiate_type_scheme(pat.span,
@@ -433,7 +433,7 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx ast::Pat,
     let fcx = pcx.fcx;
     let tcx = pcx.fcx.ccx.tcx;
 
-    let def = tcx.def_map.borrow()[pat.id].clone();
+    let def = tcx.def_map.borrow()[pat.id].full_def();
     let (enum_def_id, variant_def_id) = match def {
         def::DefTrait(_) => {
             let name = pprust::path_to_string(path);
@@ -502,7 +502,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
     let fcx = pcx.fcx;
     let tcx = pcx.fcx.ccx.tcx;
 
-    let def = tcx.def_map.borrow()[pat.id].clone();
+    let def = tcx.def_map.borrow()[pat.id].full_def();
     let enum_def = def.variant_def_ids()
         .map_or_else(|| def.def_id(), |(enum_def, _)| enum_def);
 
index 068e03dab120bf6142ea153e30ed79794fc8a616..f99e4e4b2ed8a984f8482532353f1d8cde240bbd 100644 (file)
@@ -91,7 +91,6 @@
 use middle::mem_categorization as mc;
 use middle::mem_categorization::McResult;
 use middle::pat_util::{self, pat_id_map};
-use middle::privacy::{AllPublic, LastMod};
 use middle::region::{self, CodeExtent};
 use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace};
 use middle::traits;
@@ -3598,21 +3597,23 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
               None
           };
 
-          // Helpers to avoid keeping the RefCell borrow for too long.
-          let get_def = || tcx.def_map.borrow().get(&id).cloned();
-          let get_partial_def = || tcx.partial_def_map.borrow().get(&id).cloned();
+          let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) {
+              d
+          } else {
+              tcx.sess.span_bug(expr.span,
+                                &format!("unbound path {}", expr.repr(tcx))[])
+          };
 
-          if let Some(def) = get_def() {
+          let mut def = path_res.base_def;
+          if path_res.depth == 0 {
               let (scheme, predicates) =
                   type_scheme_and_predicates_for_def(fcx, expr.span, def);
               instantiate_path(fcx, &path.segments,
                                scheme, &predicates,
-                               None, def, expr.span, id);
-          } else if let Some(partial) = get_partial_def() {
-              let mut def = partial.base_type;
+                               opt_self_ty, def, expr.span, id);
+          } else {
               let ty_segments = path.segments.init();
-              let ty_assoc_num = partial.extra_associated_types as usize;
-              let base_ty_end = ty_segments.len() - ty_assoc_num;
+              let base_ty_end = path.segments.len() - path_res.depth;
               let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, expr.span,
                                                            PathParamMode::Optional,
                                                            &mut def,
@@ -3624,13 +3625,11 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
               match method::resolve_ufcs(fcx, expr.span, method_name, ty, id) {
                   Ok((def, lp)) => {
                       // Write back the new resolution.
-                      tcx.def_map.borrow_mut().insert(id, def);
-
-                      if let LastMod(AllPublic) = lp {
-                          // Public method, don't change the last private entry.
-                      } else {
-                          tcx.last_private_map.borrow_mut().insert(id, lp);
-                      }
+                      tcx.def_map.borrow_mut().insert(id, def::PathResolution {
+                          base_def: def,
+                          last_private: path_res.last_private.or(lp),
+                          depth: 0
+                      });
 
                       let (scheme, predicates) =
                           type_scheme_and_predicates_for_def(fcx, expr.span, def);
@@ -3644,9 +3643,6 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
                       fcx.write_error(id);
                   }
               }
-          } else {
-              tcx.sess.span_bug(expr.span,
-                                &format!("unbound path {}", expr.repr(tcx))[])
           }
 
           // We always require that the type provided as the value for
@@ -3882,7 +3878,7 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
       }
       ast::ExprStruct(ref path, ref fields, ref base_expr) => {
         // Resolve the path.
-        let def = tcx.def_map.borrow().get(&id).cloned();
+        let def = tcx.def_map.borrow().get(&id).map(|d| d.full_def());
         let struct_id = match def {
             Some(def::DefVariant(enum_id, variant_id, true)) => {
                 check_struct_enum_variant(fcx, id, expr.span, enum_id,
@@ -5174,8 +5170,8 @@ pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &ast::Block) -> bool {
     (block_query(b, |e| {
         match e.node {
             ast::ExprBreak(Some(_)) => {
-                match cx.def_map.borrow().get(&e.id) {
-                    Some(&def::DefLabel(loop_id)) if id == loop_id => true,
+                match cx.def_map.borrow().get(&e.id).map(|d| d.full_def()) {
+                    Some(def::DefLabel(loop_id)) if id == loop_id => true,
                     _ => false,
                 }
             }
index 78f13b37a8238012127ec66826562a994b3d0d42..6b1d46aa04df85cc2cf340f8bfde4839df67d673 100644 (file)
@@ -165,7 +165,7 @@ fn write_substs_to_tcx<'tcx>(tcx: &ty::ctxt<'tcx>,
 }
 fn lookup_def_tcx(tcx:&ty::ctxt, sp: Span, id: ast::NodeId) -> def::Def {
     match tcx.def_map.borrow().get(&id) {
-        Some(x) => x.clone(),
+        Some(x) => x.full_def(),
         _ => {
             span_fatal!(tcx.sess, sp, E0242, "internal error looking up a definition")
         }
index d1283d6f46bd842ed3a945f5ef3668df9af1e2d8..24b9d03400cb32275d92e2ae02683c49e55e0e3c 100644 (file)
@@ -46,7 +46,7 @@ pub fn try_inline(cx: &DocContext, id: ast::NodeId, into: Option<ast::Ident>)
         None => return None,
     };
     let def = match tcx.def_map.borrow().get(&id) {
-        Some(def) => *def,
+        Some(d) => d.full_def(),
         None => return None,
     };
     let did = def.def_id();
index 7a27159bc47a25c294a8f5ddef35be454ea2f67f..0aa1a23ad7e763052bf9bc5da18e8ca5fcee99e3 100644 (file)
@@ -2388,7 +2388,7 @@ fn resolve_type(cx: &DocContext,
     };
     debug!("searching for {} in defmap", id);
     let def = match tcx.def_map.borrow().get(&id) {
-        Some(&k) => k,
+        Some(k) => k.full_def(),
         None => panic!("unresolved id not in defmap")
     };
 
@@ -2454,7 +2454,7 @@ fn resolve_use_source(cx: &DocContext, path: Path, id: ast::NodeId) -> ImportSou
 
 fn resolve_def(cx: &DocContext, id: ast::NodeId) -> Option<ast::DefId> {
     cx.tcx_opt().and_then(|tcx| {
-        tcx.def_map.borrow().get(&id).map(|&def| register_def(cx, def))
+        tcx.def_map.borrow().get(&id).map(|d| register_def(cx, d.full_def()))
     })
 }
 
index 9f5e3be9e3229a71711e60e1dcdcf1d0dcc1215c..3e998166397bc5deb38e2a30bb6497c0da82e63c 100644 (file)
@@ -196,7 +196,7 @@ fn resolve_id(&mut self, id: ast::NodeId, renamed: Option<ast::Ident>,
             Some(tcx) => tcx,
             None => return false
         };
-        let def = (*tcx.def_map.borrow())[id].def_id();
+        let def = tcx.def_map.borrow()[id].def_id();
         if !ast_util::is_local(def) { return false }
         let analysis = match self.analysis {
             Some(analysis) => analysis, None => return false