From 5a6a9ed792dd2a716ef583a50051a52a17574efc Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Tue, 17 Feb 2015 06:44:23 +0200 Subject: [PATCH] rustc: combine partial_def_map and last_private_map into def_map. --- src/librustc/lint/builtin.rs | 25 +- src/librustc/metadata/encoder.rs | 4 +- src/librustc/middle/astconv_util.rs | 2 +- src/librustc/middle/astencode.rs | 12 +- src/librustc/middle/cfg/construct.rs | 38 +- src/librustc/middle/check_const.rs | 4 +- src/librustc/middle/check_match.rs | 30 +- src/librustc/middle/check_static_recursion.rs | 6 +- src/librustc/middle/const_eval.rs | 10 +- src/librustc/middle/dead.rs | 10 +- src/librustc/middle/def.rs | 48 +- src/librustc/middle/expr_use_visitor.rs | 14 +- src/librustc/middle/infer/error_reporting.rs | 2 +- src/librustc/middle/liveness.rs | 10 +- src/librustc/middle/mem_categorization.rs | 13 +- src/librustc/middle/pat_util.rs | 12 +- src/librustc/middle/privacy.rs | 5 +- src/librustc/middle/reachable.rs | 2 +- src/librustc/middle/resolve_lifetime.rs | 4 +- src/librustc/middle/stability.rs | 14 +- src/librustc/middle/ty.rs | 21 +- src/librustc_driver/driver.rs | 4 - src/librustc_privacy/lib.rs | 26 +- src/librustc_resolve/check_unused.rs | 28 +- src/librustc_resolve/lib.rs | 412 +++++++++--------- src/librustc_trans/save/mod.rs | 18 +- src/librustc_trans/trans/_match.rs | 20 +- src/librustc_trans/trans/common.rs | 2 +- src/librustc_trans/trans/consts.rs | 8 +- src/librustc_trans/trans/controlflow.rs | 9 +- src/librustc_trans/trans/expr.rs | 2 +- src/librustc_typeck/astconv.rs | 20 +- src/librustc_typeck/check/_match.rs | 6 +- src/librustc_typeck/check/mod.rs | 42 +- src/librustc_typeck/lib.rs | 2 +- src/librustdoc/clean/inline.rs | 2 +- src/librustdoc/clean/mod.rs | 4 +- src/librustdoc/visit_ast.rs | 2 +- 38 files changed, 444 insertions(+), 449 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 8c6984972718f..28baeb5dc9e62 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -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 @@ impl LintPass for NonSnakeCase { 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 @@ impl LintPass for NonUpperCaseGlobals { 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 @@ impl LintPass for NonShorthandFieldPatterns { 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 @@ impl LintPass for UnconditionalRecursion { _: 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` diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 1a695baf7216b..4aea73cfb0ec0 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -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. diff --git a/src/librustc/middle/astconv_util.rs b/src/librustc/middle/astconv_util.rs index 1cd5a19d6788a..c9196f0cb2a64 100644 --- a/src/librustc/middle/astconv_util.rs +++ b/src/librustc/middle/astconv_util.rs @@ -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)) diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 3de29a4ca538a..5983829ed8fbe 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -25,6 +25,7 @@ use metadata::tydecode::{RegionParameter, ClosureSource}; 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); diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index 52eedc460eb87..ca9455ac421f2 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -610,32 +610,24 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { fn find_scope(&self, expr: &ast::Expr, label: Option) -> 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)); } } } diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 0d7e730b5cdd8..57e4d3d2f0203 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -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(..)) => { diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 7bd64a4f487d6..c409c8fb13f14 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -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) -> P { 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 \ diff --git a/src/librustc/middle/check_static_recursion.rs b/src/librustc/middle/check_static_recursion.rs index 4280b7fe3f096..a4393f4648b1e 100644 --- a/src/librustc/middle/check_static_recursion.rs +++ b/src/librustc/middle/check_static_recursion.rs @@ -94,9 +94,9 @@ impl<'a, 'ast, 'v> Visitor<'v> for CheckItemRecursionVisitor<'a, 'ast> { 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) => diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 5bf7422dbc0d4..d3c6a585fa3fd 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -31,7 +31,7 @@ use std::{i8, i16, i32, i64}; 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::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::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 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>, 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) { diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index ff78deb8d12ea..2d837ce52b56a 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -71,13 +71,13 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { 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 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { fn handle_field_pattern_match(&mut self, lhs: &ast::Pat, pats: &[codemap::Spanned]) { - 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, diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs index 355c52b374e01..1a054c0f464aa 100644 --- a/src/librustc/middle/def.rs +++ b/src/librustc/middle/def.rs @@ -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 /// -/// ::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, +/// ::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>; -pub type PartialDefMap = RefCell>; +pub type DefMap = RefCell>; // This is the replacement export map. It maps a module to all of the exports // within. pub type ExportMap = NodeMap>; @@ -119,7 +139,7 @@ impl Def { local_def(id) } - DefPrimTy(_) => panic!() + DefPrimTy(_) => panic!("attempted .def_id() on DefPrimTy") } } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 625093e3c5dea..f7c723c68746f 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -1017,7 +1017,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { // 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 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { 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 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { 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 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { 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. diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index 4439472ab5671..60b7e1169b49b 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -1242,7 +1242,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { "unbound path {}", pprust::path_to_string(path))) } - Some(&d) => d + Some(d) => d.full_def() }; match a_def { def::DefTy(did, _) | def::DefStruct(did) => { diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 145fccd7972bb..4685a05f41604 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -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 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { 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 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { 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 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { 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 diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index f8065f81aa8d8..44ab3cf60aaa3 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -530,7 +530,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { } 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 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { (*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 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { } 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 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { 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 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { 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)); } diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs index a7df2f4a5dafb..c5abff3b96360 100644 --- a/src/librustc/middle/pat_util.rs +++ b/src/librustc/middle/pat_util.rs @@ -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 } } diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index dd1e32d13a2be..3a253735f925b 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -16,7 +16,7 @@ pub use self::PrivateDep::*; 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 @@ pub type ExternalExports = DefIdSet; /// reexporting a public struct doesn't inline the doc). pub type PublicItems = NodeSet; -// FIXME: dox -pub type LastPrivateMap = NodeMap; - #[derive(Copy, Debug)] pub enum LastPrivate { LastMod(PrivateDep), diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 550f4e39447f8..a140c766758e3 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -96,7 +96,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> { 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?!") diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 7b957d6ce8498..9bcda68eb3ad7 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -168,8 +168,8 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> { 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); }); diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index cfa5e5fce3879..f67e470ee5491 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -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)) { - 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, diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 7dcdeaf16d2e8..7cd047279028c 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -46,12 +46,11 @@ use metadata::csearch; 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, pub named_region_map: resolve_lifetime::NamedRegionMap, @@ -2427,8 +2424,6 @@ impl<'tcx> CommonTypes<'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, @@ -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` 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( diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index aafa4dec0de94..bd911c20afc47 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -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, diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 1452c44ca7144..f325a6abede51 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -259,7 +259,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> { 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 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> { 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 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { 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 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { // 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 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { // 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 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { } } 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 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { 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 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { } } 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() diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index a239c73c110db..aebbe14407380 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -68,17 +68,17 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> { "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 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> { _ => {}, } - 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 + }; } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 6b05a64874654..265f398d25ca5 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -934,13 +934,11 @@ struct Resolver<'a, 'tcx:'a> { primitive_type_table: PrimitiveTypeTable, def_map: DefMap, - partial_def_map: PartialDefMap, freevars: RefCell, freevars_seen: RefCell>, 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } // 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { 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 { + 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { &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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { /// 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 { 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { _ => () } - 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { &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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { 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 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { pub struct CrateMap { pub def_map: DefMap, - pub partial_def_map: PartialDefMap, pub freevars: RefCell, pub export_map: ExportMap, pub trait_map: TraitMap, pub external_exports: ExternalExports, - pub last_private_map: LastPrivateMap, pub glob_map: Option } @@ -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 { diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 5484e3c7c5fc2..ea346798679c0 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -218,7 +218,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { 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 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { 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 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { 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 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { &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 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { &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 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> { def::DefStatic(_, _) => {} def::DefConst(..) => {} _ => error!("unexpected definition kind when processing collected paths: {:?}", - *def) + def) } } for &(id, ref path, ref_kind) in &paths_to_process { diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index 26e1a981f1bae..3e741640117aa 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -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); diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index a3ba506fc46a2..d8fc6df2685dd 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -603,7 +603,7 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> { 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)); diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index e321c5f0a13d5..6e1d2da02c101 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -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(_)) => { diff --git a/src/librustc_trans/trans/controlflow.rs b/src/librustc_trans/trans/controlflow.rs index 5eebe6a4a05fb..ad96c506c9ddf 100644 --- a/src/librustc_trans/trans/controlflow.rs +++ b/src/librustc_trans/trans/controlflow.rs @@ -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)) } } } diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 95c5122deacb6..80fe2ed8f3af3 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -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( diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index adbc4d546f190..982cc1e3792e1 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -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 diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index edbda795bde3c..dd2ab6c6b13ca 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -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); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 068e03dab120b..f99e4e4b2ed8a 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -91,7 +91,6 @@ use middle::infer; 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_expr_with_unifier<'a, 'tcx, F>(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_expr_with_unifier<'a, 'tcx, F>(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_expr_with_unifier<'a, 'tcx, F>(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_expr_with_unifier<'a, 'tcx, F>(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, } } diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 78f13b37a8238..6b1d46aa04df8 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -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") } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index d1283d6f46bd8..24b9d03400cb3 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -46,7 +46,7 @@ pub fn try_inline(cx: &DocContext, id: ast::NodeId, into: Option) 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(); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 7a27159bc47a2..0aa1a23ad7e76 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -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 { 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())) }) } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 9f5e3be9e3229..3e998166397bc 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -196,7 +196,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { 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