From ee4e55398b39509bde4cc4983d615dbde406355c Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 3 Jun 2016 23:15:00 +0300 Subject: [PATCH] Introduce TyCtxt::expect_def/expect_resolution helpers and use them where possible --- src/librustc/cfg/construct.rs | 4 +- src/librustc/hir/def.rs | 18 ++----- src/librustc/hir/lowering.rs | 14 ++--- src/librustc/infer/error_reporting.rs | 12 +---- src/librustc/middle/astconv_util.rs | 8 +-- src/librustc/middle/dead.rs | 51 +++++++++--------- src/librustc/middle/effect.rs | 2 +- src/librustc/middle/expr_use_visitor.rs | 18 +++---- src/librustc/middle/intrinsicck.rs | 2 +- src/librustc/middle/liveness.rs | 12 ++--- src/librustc/middle/mem_categorization.rs | 10 ++-- src/librustc/middle/reachable.rs | 8 +-- src/librustc/middle/stability.rs | 12 ++--- src/librustc/ty/mod.rs | 57 +++++++++----------- src/librustc_const_eval/check_match.rs | 21 +++----- src/librustc_const_eval/eval.rs | 39 +++++--------- src/librustc_lint/bad_style.rs | 5 +- src/librustc_lint/builtin.rs | 33 +++++------- src/librustc_metadata/astencode.rs | 7 +-- src/librustc_mir/hair/cx/expr.rs | 23 +++----- src/librustc_mir/hair/cx/pattern.rs | 17 +++--- src/librustc_passes/consts.rs | 23 ++++---- src/librustc_privacy/lib.rs | 29 +++++----- src/librustc_resolve/lib.rs | 63 ++++++++++------------ src/librustc_resolve/resolve_imports.rs | 4 +- src/librustc_save_analysis/dump_visitor.rs | 36 ++++--------- src/librustc_save_analysis/lib.rs | 14 ++--- src/librustc_trans/_match.rs | 20 ++++--- src/librustc_trans/common.rs | 12 +---- src/librustc_trans/consts.rs | 12 ++--- src/librustc_trans/controlflow.rs | 4 +- src/librustc_trans/expr.rs | 10 ++-- src/librustc_typeck/astconv.rs | 24 +++------ src/librustc_typeck/check/_match.rs | 62 +++++++++------------ src/librustc_typeck/check/callee.rs | 2 +- src/librustc_typeck/check/mod.rs | 18 ++----- src/librustc_typeck/collect.rs | 16 +++--- src/librustc_typeck/diagnostics.rs | 2 +- src/librustc_typeck/lib.rs | 10 ---- src/librustdoc/clean/inline.rs | 4 +- src/librustdoc/clean/mod.rs | 4 +- src/librustdoc/visit_ast.rs | 6 +-- 42 files changed, 276 insertions(+), 472 deletions(-) diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index 76b53094a72..18ea17f4816 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -574,8 +574,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { return *self.loop_scopes.last().unwrap(); } - match self.tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def()) { - Some(Def::Label(loop_id)) => { + match self.tcx.expect_def(expr.id) { + Def::Label(loop_id) => { for l in &self.loop_scopes { if l.loop_id == loop_id { return *l; diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index 3b2d5ba4493..72261c473e5 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -67,6 +67,10 @@ pub struct PathResolution { } impl PathResolution { + pub fn new(def: Def) -> PathResolution { + PathResolution { base_def: def, depth: 0 } + } + /// Get the definition, if fully resolved, otherwise panic. pub fn full_def(&self) -> Def { if self.depth != 0 { @@ -75,20 +79,6 @@ impl PathResolution { self.base_def } - /// Get the DefId, if fully resolved, otherwise panic. - pub fn def_id(&self) -> DefId { - self.full_def().def_id() - } - - pub fn new(base_def: Def, - depth: usize) - -> PathResolution { - PathResolution { - base_def: base_def, - depth: depth, - } - } - pub fn kind_name(&self) -> &'static str { if self.depth != 0 { "associated item" diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 7d98aab8d27..69cf5baa26f 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -866,7 +866,7 @@ impl<'a> LoweringContext<'a> { PatKind::Wild => hir::PatKind::Wild, PatKind::Ident(ref binding_mode, pth1, ref sub) => { self.with_parent_def(p.id, |this| { - match this.resolver.get_resolution(p.id).map(|d| d.full_def()) { + match this.resolver.get_resolution(p.id).map(|d| d.base_def) { // `None` can occur in body-less function signatures None | Some(Def::Local(..)) => { hir::PatKind::Binding(this.lower_binding_mode(binding_mode), @@ -1238,14 +1238,10 @@ impl<'a> LoweringContext<'a> { position: position, } }); - let rename = if qself.is_none() && path.segments.len() == 1 { - // Only local variables are renamed - match self.resolver.get_resolution(e.id).map(|d| d.full_def()) { - Some(Def::Local(..)) | Some(Def::Upvar(..)) => true, - _ => false, - } - } else { - false + // Only local variables are renamed + let rename = match self.resolver.get_resolution(e.id).map(|d| d.base_def) { + Some(Def::Local(..)) | Some(Def::Upvar(..)) => true, + _ => false, }; hir::ExprPath(hir_qself, self.lower_path_full(path, rename)) } diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index 041abf9b7de..27896b09981 100644 --- a/src/librustc/infer/error_reporting.rs +++ b/src/librustc/infer/error_reporting.rs @@ -1357,17 +1357,7 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> { ty_queue.push(&mut_ty.ty); } hir::TyPath(ref maybe_qself, ref path) => { - let a_def = match self.tcx.def_map.borrow().get(&cur_ty.id) { - None => { - self.tcx - .sess - .fatal(&format!( - "unbound path {}", - pprust::path_to_string(path))) - } - Some(d) => d.full_def() - }; - match a_def { + match self.tcx.expect_def(cur_ty.id) { Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) => { let generics = self.tcx.lookup_item_type(did).generics; diff --git a/src/librustc/middle/astconv_util.rs b/src/librustc/middle/astconv_util.rs index 8f97a89e654..f132212415f 100644 --- a/src/librustc/middle/astconv_util.rs +++ b/src/librustc/middle/astconv_util.rs @@ -65,13 +65,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// to it. pub fn ast_ty_to_prim_ty(self, ast_ty: &ast::Ty) -> Option> { if let ast::TyPath(None, ref path) = ast_ty.node { - let def = match self.def_map.borrow().get(&ast_ty.id) { - None => { - span_bug!(ast_ty.span, "unbound path {:?}", path) - } - Some(d) => d.full_def() - }; - if let Def::PrimTy(nty) = def { + if let Def::PrimTy(nty) = self.expect_def(ast_ty.id) { Some(self.prim_ty_to_ty(&path.segments, nty)) } else { None diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index cc6b83fccf9..e65074a4f07 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -84,36 +84,35 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } } - fn lookup_and_handle_definition(&mut self, id: &ast::NodeId) { + fn lookup_and_handle_definition(&mut self, id: ast::NodeId) { use ty::TypeVariants::{TyEnum, TyStruct}; // If `bar` is a trait item, make sure to mark Foo as alive in `Foo::bar` - self.tcx.tables.borrow().item_substs.get(id) + self.tcx.tables.borrow().item_substs.get(&id) .and_then(|substs| substs.substs.self_ty()) .map(|ty| match ty.sty { TyEnum(tyid, _) | TyStruct(tyid, _) => self.check_def_id(tyid.did), _ => (), }); - self.tcx.def_map.borrow().get(id).map(|def| { - match def.full_def() { - Def::Const(_) | Def::AssociatedConst(..) => { - self.check_def_id(def.def_id()); - } - _ if self.ignore_non_const_paths => (), - Def::PrimTy(_) => (), - Def::SelfTy(..) => (), - Def::Variant(enum_id, variant_id) => { - self.check_def_id(enum_id); - if !self.ignore_variant_stack.contains(&variant_id) { - self.check_def_id(variant_id); - } - } - _ => { - self.check_def_id(def.def_id()); + let def = self.tcx.expect_def(id); + match def { + Def::Const(_) | Def::AssociatedConst(..) => { + self.check_def_id(def.def_id()); + } + _ if self.ignore_non_const_paths => (), + Def::PrimTy(_) => (), + Def::SelfTy(..) => (), + Def::Variant(enum_id, variant_id) => { + self.check_def_id(enum_id); + if !self.ignore_variant_stack.contains(&variant_id) { + self.check_def_id(variant_id); } } - }); + _ => { + self.check_def_id(def.def_id()); + } + } } fn lookup_and_handle_method(&mut self, id: ast::NodeId) { @@ -138,10 +137,10 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { fn handle_field_pattern_match(&mut self, lhs: &hir::Pat, pats: &[codemap::Spanned]) { - let def = self.tcx.def_map.borrow().get(&lhs.id).unwrap().full_def(); - let pat_ty = self.tcx.node_id_to_type(lhs.id); - let variant = match pat_ty.sty { - ty::TyStruct(adt, _) | ty::TyEnum(adt, _) => adt.variant_of_def(def), + let variant = match self.tcx.node_id_to_type(lhs.id).sty { + ty::TyStruct(adt, _) | ty::TyEnum(adt, _) => { + adt.variant_of_def(self.tcx.expect_def(lhs.id)) + } _ => span_bug!(lhs.span, "non-ADT in struct pattern") }; for pat in pats { @@ -272,7 +271,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> { } _ if pat_util::pat_is_const(&def_map.borrow(), pat) => { // it might be the only use of a const - self.lookup_and_handle_definition(&pat.id) + self.lookup_and_handle_definition(pat.id) } _ => () } @@ -283,12 +282,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> { } fn visit_path(&mut self, path: &hir::Path, id: ast::NodeId) { - self.lookup_and_handle_definition(&id); + self.lookup_and_handle_definition(id); intravisit::walk_path(self, path); } fn visit_path_list_item(&mut self, path: &hir::Path, item: &hir::PathListItem) { - self.lookup_and_handle_definition(&item.node.id()); + self.lookup_and_handle_definition(item.node.id()); intravisit::walk_path_list_item(self, path, item); } } diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index b62368c2a98..24816d2b497 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -172,7 +172,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { self.require_unsafe(expr.span, "use of inline assembly"); } hir::ExprPath(..) => { - if let Def::Static(_, true) = self.tcx.resolve_expr(expr) { + if let Def::Static(_, true) = self.tcx.expect_def(expr.id) { self.require_unsafe(expr.span, "use of mutable static"); } } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index ba93e897677..3b571ed0576 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -955,9 +955,9 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { debug!("walk_pat cmt_discr={:?} pat={:?}", cmt_discr, pat); + let tcx = &self.tcx(); let mc = &self.mc; let infcx = self.mc.infcx; - let def_map = &self.tcx().def_map; let delegate = &mut self.delegate; return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |mc, cmt_pat, pat| { match pat.node { @@ -972,8 +972,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { // Each match binding is effectively an assignment to the // binding being produced. - let def = def_map.borrow().get(&pat.id).unwrap().full_def(); - if let Ok(binding_cmt) = mc.cat_def(pat.id, pat.span, pat_ty, def) { + if let Ok(binding_cmt) = mc.cat_def(pat.id, pat.span, pat_ty, + tcx.expect_def(pat.id)) { delegate.mutate(pat.id, pat.span, binding_cmt, MutateMode::Init); } @@ -1002,14 +1002,11 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { // to the above loop's visit of than the bindings that form // the leaves of the pattern tree structure. return_if_err!(mc.cat_pattern(cmt_discr, pat, |mc, cmt_pat, pat| { - let def_map = def_map.borrow(); - let tcx = infcx.tcx; - match pat.node { PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) | PatKind::QPath(..) => { - match def_map.get(&pat.id).map(|d| d.full_def()) { - Some(Def::Variant(enum_did, variant_did)) => { + match tcx.expect_def(pat.id) { + Def::Variant(enum_did, variant_did) => { let downcast_cmt = if tcx.lookup_adt_def(enum_did).is_univariant() { cmt_pat @@ -1025,7 +1022,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { delegate.matched_pat(pat, downcast_cmt, match_mode); } - Some(Def::Struct(..)) | Some(Def::TyAlias(..)) => { + Def::Struct(..) | Def::TyAlias(..) => { // A struct (in either the value or type // namespace; we encounter the former on // e.g. patterns for unit structs). @@ -1037,8 +1034,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { delegate.matched_pat(pat, cmt_pat, match_mode); } - Some(Def::Const(..)) | - Some(Def::AssociatedConst(..)) => { + Def::Const(..) | Def::AssociatedConst(..) => { // This is a leaf (i.e. identifier binding // or constant value to match); thus no // `matched_pat` call. diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index 07e69d85ff4..70158e9b9df 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -156,7 +156,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ItemVisitor<'a, 'tcx> { impl<'a, 'gcx, 'tcx, 'v> Visitor<'v> for ExprVisitor<'a, 'gcx, 'tcx> { fn visit_expr(&mut self, expr: &hir::Expr) { if let hir::ExprPath(..) = expr.node { - match self.infcx.tcx.resolve_expr(expr) { + match self.infcx.tcx.expect_def(expr.id) { Def::Fn(did) if self.def_id_is_transmute(did) => { let typ = self.infcx.tcx.node_id_to_type(expr.id); match typ.sty { diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index f6ea10a70eb..ceffa366413 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -445,7 +445,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) { match expr.node { // live nodes required for uses or definitions of variables: hir::ExprPath(..) => { - let def = ir.tcx.def_map.borrow().get(&expr.id).unwrap().full_def(); + let def = ir.tcx.expect_def(expr.id); debug!("expr {}: path that leads to {:?}", expr.id, def); if let Def::Local(..) = def { ir.add_live_node_for_node(expr.id, ExprNode(expr.span)); @@ -695,8 +695,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).map(|d| d.full_def()) { - Some(Def::Label(loop_id)) => loop_id, + match self.ir.tcx.expect_def(id) { + Def::Label(loop_id) => loop_id, _ => span_bug!(sp, "label on break/loop \ doesn't refer to a loop") } @@ -1269,7 +1269,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: u32) -> LiveNode { - match self.ir.tcx.def_map.borrow().get(&expr.id).unwrap().full_def() { + match self.ir.tcx.expect_def(expr.id) { Def::Local(_, nid) => { let ln = self.live_node(expr.id, expr.span); if acc != 0 { @@ -1534,9 +1534,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn check_lvalue(&mut self, expr: &Expr) { match expr.node { hir::ExprPath(..) => { - if let Def::Local(_, nid) = self.ir.tcx.def_map.borrow().get(&expr.id) - .unwrap() - .full_def() { + if let Def::Local(_, nid) = self.ir.tcx.expect_def(expr.id) { // 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 1ea3a469d9c..d2a5cd73503 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -517,8 +517,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { } hir::ExprPath(..) => { - let def = self.tcx().def_map.borrow().get(&expr.id).unwrap().full_def(); - self.cat_def(expr.id, expr.span, expr_ty, def) + self.cat_def(expr.id, expr.span, expr_ty, self.tcx().expect_def(expr.id)) } hir::ExprType(ref e, _) => { @@ -1106,12 +1105,11 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { (*op)(self, cmt.clone(), pat); + // This function can be used during region checking when not all paths are fully + // resolved. Partially resolved paths in patterns can only legally refer to + // associated constants which don't require categorization. let opt_def = if let Some(path_res) = self.tcx().def_map.borrow().get(&pat.id) { if path_res.depth != 0 || path_res.base_def == Def::Err { - // Since patterns can be associated constants - // which are resolved during typeck, we might have - // some unresolved patterns reaching this stage - // without aborting return Err(()); } Some(path_res.full_def()) diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 55d75ace081..6ea0fa20c57 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -92,13 +92,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> { fn visit_expr(&mut self, expr: &hir::Expr) { match expr.node { hir::ExprPath(..) => { - let def = match self.tcx.def_map.borrow().get(&expr.id) { - Some(d) => d.full_def(), - None => { - span_bug!(expr.span, "def ID not in def map?!") - } - }; - + let def = self.tcx.expect_def(expr.id); let def_id = def.def_id(); if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) { if self.def_id_represents_local_inlined_item(def_id) { diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index eb1fb43789f..3744f564fa2 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -494,7 +494,7 @@ pub fn check_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // individually as it's possible to have a stable trait with unstable // items. hir::ItemImpl(_, _, _, Some(ref t), _, ref impl_items) => { - let trait_did = tcx.def_map.borrow().get(&t.ref_id).unwrap().def_id(); + let trait_did = tcx.expect_def(t.ref_id).def_id(); let trait_items = tcx.trait_items(trait_did); for impl_item in impl_items { @@ -580,7 +580,8 @@ pub fn check_path<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cb: &mut FnMut(DefId, Span, &Option<&Stability>, &Option)) { - match tcx.def_map.borrow().get(&id).map(|d| d.full_def()) { + // Paths in import prefixes may have no resolution. + match tcx.expect_def_or_none(id) { Some(Def::PrimTy(..)) => {} Some(Def::SelfTy(..)) => {} Some(def) => { @@ -595,12 +596,11 @@ pub fn check_path_list_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cb: &mut FnMut(DefId, Span, &Option<&Stability>, &Option)) { - match tcx.def_map.borrow().get(&item.node.id()).map(|d| d.full_def()) { - Some(Def::PrimTy(..)) => {} - Some(def) => { + match tcx.expect_def(item.node.id()) { + Def::PrimTy(..) => {} + def => { maybe_do_stability_check(tcx, def.def_id(), item.span, cb); } - None => {} } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 3ab7d90bf8c..28266809266 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -22,7 +22,7 @@ use dep_graph::{self, DepNode}; use hir::map as ast_map; use middle; use middle::cstore::{self, LOCAL_CRATE}; -use hir::def::{self, Def, ExportMap}; +use hir::def::{Def, PathResolution, ExportMap}; use hir::def_id::DefId; use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; use middle::region::{CodeExtent, ROOT_CODE_EXTENT}; @@ -308,13 +308,11 @@ impl Visibility { match *visibility { hir::Public => Visibility::Public, hir::Visibility::Crate => Visibility::Restricted(ast::CRATE_NODE_ID), - hir::Visibility::Restricted { id, .. } => match tcx.def_map.borrow().get(&id) { - Some(resolution) => Visibility::Restricted({ - tcx.map.as_local_node_id(resolution.base_def.def_id()).unwrap() - }), + hir::Visibility::Restricted { id, .. } => match tcx.expect_def(id) { // If there is no resolution, `resolve` will have already reported an error, so // assume that the visibility is public to avoid reporting more privacy errors. - None => Visibility::Public, + Def::Err => Visibility::Public, + def => Visibility::Restricted(tcx.map.as_local_node_id(def.def_id()).unwrap()), }, hir::Inherited => Visibility::Restricted(tcx.map.get_module_parent(id)), } @@ -2249,34 +2247,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } - pub fn resolve_expr(self, expr: &hir::Expr) -> Def { - match self.def_map.borrow().get(&expr.id) { - Some(def) => def.full_def(), - None => { - span_bug!(expr.span, "no def-map entry for expr {}", expr.id); - } - } - } - pub fn expr_is_lval(self, expr: &hir::Expr) -> bool { match expr.node { hir::ExprPath(..) => { - // We can't use resolve_expr here, as this needs to run on broken - // programs. We don't need to through - associated items are all - // rvalues. - match self.def_map.borrow().get(&expr.id) { - Some(&def::PathResolution { - base_def: Def::Static(..), .. - }) | Some(&def::PathResolution { - base_def: Def::Upvar(..), .. - }) | Some(&def::PathResolution { - base_def: Def::Local(..), .. - }) => { - true - } - Some(&def::PathResolution { base_def: Def::Err, .. })=> true, - Some(..) => false, - None => span_bug!(expr.span, "no def for path {}", expr.id) + // This function can be used during type checking when not all paths are + // fully resolved. Partially resolved paths in expressions can only legally + // refer to associated items which are always rvalues. + match self.expect_resolution(expr.id).base_def { + Def::Local(..) | Def::Upvar(..) | Def::Static(..) | Def::Err => true, + _ => false, } } @@ -2459,8 +2438,20 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } - pub fn trait_ref_to_def_id(self, tr: &hir::TraitRef) -> DefId { - self.def_map.borrow().get(&tr.ref_id).expect("no def-map entry for trait").def_id() + /// Returns a path resolution for node id if it exists, panics otherwise. + pub fn expect_resolution(self, id: NodeId) -> PathResolution { + *self.def_map.borrow().get(&id).expect("no def-map entry for node id") + } + + /// Returns a fully resolved definition for node id if it exists, panics otherwise. + pub fn expect_def(self, id: NodeId) -> Def { + self.expect_resolution(id).full_def() + } + + /// Returns a fully resolved definition for node id if it exists, or none if no + /// definition exists, panics on partial resolutions to catch errors. + pub fn expect_def_or_none(self, id: NodeId) -> Option { + self.def_map.borrow().get(&id).map(|resolution| resolution.full_def()) } pub fn def_key(self, id: DefId) -> ast_map::DefKey { diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 1380e0b45f2..f183736b9ed 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -245,8 +245,7 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat) if let PatKind::Binding(hir::BindByValue(hir::MutImmutable), name, None) = p.node { let pat_ty = cx.tcx.pat_ty(p); if let ty::TyEnum(edef, _) = pat_ty.sty { - let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def()); - if let Some(Def::Local(..)) = def { + if let Def::Local(..) = cx.tcx.expect_def(p.id) { if edef.variants.iter().any(|variant| variant.name == name.node.unhygienize() && variant.kind() == VariantKind::Unit @@ -492,9 +491,8 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> { fn fold_pat(&mut self, pat: P) -> P { return match pat.node { PatKind::Path(..) | PatKind::QPath(..) => { - let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()); - match def { - Some(Def::AssociatedConst(did)) | Some(Def::Const(did)) => { + match self.tcx.expect_def(pat.id) { + Def::AssociatedConst(did) | Def::Const(did) => { let substs = Some(self.tcx.node_id_item_substs(pat.id).substs); if let Some((const_expr, _)) = lookup_const_by_id(self.tcx, did, substs) { match const_expr_to_pat(self.tcx, const_expr, pat.id, pat.span) { @@ -788,7 +786,7 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat, let pat = raw_pat(p); match pat.node { PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) => - match cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def() { + match cx.tcx.expect_def(pat.id) { Def::Const(..) | Def::AssociatedConst(..) => span_bug!(pat.span, "const pattern should've \ been rewritten"), @@ -903,21 +901,19 @@ pub fn specialize<'a, 'b, 'tcx>( Some(vec![dummy_pat; arity]), PatKind::Path(..) => { - let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def(); - match def { + match cx.tcx.expect_def(pat_id) { Def::Const(..) | Def::AssociatedConst(..) => span_bug!(pat_span, "const pattern should've \ been rewritten"), Def::Variant(_, id) if *constructor != Variant(id) => None, Def::Variant(..) | Def::Struct(..) => Some(Vec::new()), - _ => span_bug!(pat_span, "specialize: unexpected \ + def => span_bug!(pat_span, "specialize: unexpected \ definition {:?}", def), } } PatKind::TupleStruct(_, ref args, ddpos) => { - let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def(); - match def { + match cx.tcx.expect_def(pat_id) { Def::Const(..) | Def::AssociatedConst(..) => span_bug!(pat_span, "const pattern should've \ been rewritten"), @@ -944,10 +940,9 @@ pub fn specialize<'a, 'b, 'tcx>( } PatKind::Struct(_, ref pattern_fields, _) => { - let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def(); let adt = cx.tcx.node_id_to_type(pat_id).ty_adt_def().unwrap(); let variant = constructor.variant_for_adt(adt); - let def_variant = adt.variant_of_def(def); + let def_variant = adt.variant_of_def(cx.tcx.expect_def(pat_id)); if variant.did == def_variant.did { Some(variant.fields.iter().map(|sf| { match pattern_fields.iter().find(|f| f.node.name == sf.name) { diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index 5637b44335e..c3db252584c 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -19,7 +19,7 @@ use rustc::hir::map as ast_map; use rustc::hir::map::blocks::FnLikeNode; use rustc::middle::cstore::{self, InlinedItem}; use rustc::traits; -use rustc::hir::def::Def; +use rustc::hir::def::{Def, PathResolution}; use rustc::hir::def_id::DefId; use rustc::hir::pat_util::def_to_path; use rustc::ty::{self, Ty, TyCtxt, subst}; @@ -276,11 +276,11 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, .collect()), None), hir::ExprCall(ref callee, ref args) => { - let def = *tcx.def_map.borrow().get(&callee.id).unwrap(); + let def = tcx.expect_def(callee.id); if let Vacant(entry) = tcx.def_map.borrow_mut().entry(expr.id) { - entry.insert(def); + entry.insert(PathResolution::new(def)); } - let path = match def.full_def() { + let path = match def { Def::Struct(def_id) => def_to_path(tcx, def_id), Def::Variant(_, variant_did) => def_to_path(tcx, variant_did), Def::Fn(..) | Def::Method(..) => return Ok(P(hir::Pat { @@ -322,12 +322,9 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } hir::ExprPath(_, ref path) => { - let opt_def = tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def()); - match opt_def { - Some(Def::Struct(..)) | Some(Def::Variant(..)) => - PatKind::Path(path.clone()), - Some(Def::Const(def_id)) | - Some(Def::AssociatedConst(def_id)) => { + match tcx.expect_def(expr.id) { + Def::Struct(..) | Def::Variant(..) => PatKind::Path(path.clone()), + Def::Const(def_id) | Def::AssociatedConst(def_id) => { let substs = Some(tcx.node_id_item_substs(expr.id).substs); let (expr, _ty) = lookup_const_by_id(tcx, def_id, substs).unwrap(); return const_expr_to_pat(tcx, expr, pat_id, span); @@ -714,21 +711,13 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } hir::ExprPath(..) => { - let opt_def = if let Some(def) = tcx.def_map.borrow().get(&e.id) { - // After type-checking, def_map contains definition of the - // item referred to by the path. During type-checking, it - // can contain the raw output of path resolution, which - // might be a partially resolved path. - // FIXME: There's probably a better way to make sure we don't - // panic here. - if def.depth != 0 { - signal!(e, UnresolvedPath); - } - def.full_def() - } else { - signal!(e, NonConstPath); - }; - match opt_def { + // This function can be used before type checking when not all paths are fully resolved. + // FIXME: There's probably a better way to make sure we don't panic here. + let resolution = tcx.expect_resolution(e.id); + if resolution.depth != 0 { + signal!(e, UnresolvedPath); + } + match resolution.base_def { Def::Const(def_id) | Def::AssociatedConst(def_id) => { let substs = if let ExprTypeChecked = ty_hint { diff --git a/src/librustc_lint/bad_style.rs b/src/librustc_lint/bad_style.rs index 4c4dea406ba..54e5824cbc7 100644 --- a/src/librustc_lint/bad_style.rs +++ b/src/librustc_lint/bad_style.rs @@ -276,7 +276,7 @@ impl LateLintPass for NonSnakeCase { fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) { if let &PatKind::Binding(_, ref path1, _) = &p.node { // Exclude parameter names from foreign functions (they have no `Def`) - if cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def()).is_some() { + if cx.tcx.expect_def_or_none(p.id).is_some() { self.check_snake_case(cx, "variable", &path1.node.as_str(), Some(p.span)); } } @@ -362,8 +362,7 @@ impl LateLintPass for NonUpperCaseGlobals { // Lint for constants that look like binding identifiers (#7526) if let PatKind::Path(ref path) = p.node { if !path.global && path.segments.len() == 1 && path.segments[0].parameters.is_empty() { - if let Some(Def::Const(..)) = cx.tcx.def_map.borrow().get(&p.id) - .map(|d| d.full_def()) { + if let Def::Const(..) = cx.tcx.expect_def(p.id) { NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern", path.segments[0].name, path.span); } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 3005f564ff4..2bd2997566e 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -157,20 +157,11 @@ impl LintPass for NonShorthandFieldPatterns { impl LateLintPass for NonShorthandFieldPatterns { fn check_pat(&mut self, cx: &LateContext, pat: &hir::Pat) { - let def_map = cx.tcx.def_map.borrow(); - if let PatKind::Struct(_, ref v, _) = pat.node { - let field_pats = v.iter().filter(|fieldpat| { - if fieldpat.node.is_shorthand { - return false; - } - let def = def_map.get(&fieldpat.node.pat.id).map(|d| d.full_def()); - if let Some(def_id) = cx.tcx.map.opt_local_def_id(fieldpat.node.pat.id) { - def == Some(Def::Local(def_id, fieldpat.node.pat.id)) - } else { - false - } - }); + if let PatKind::Struct(_, ref field_pats, _) = pat.node { for fieldpat in field_pats { + if fieldpat.node.is_shorthand { + continue; + } if let PatKind::Binding(_, ident, None) = fieldpat.node.pat.node { if ident.node.unhygienize() == fieldpat.node.name { cx.span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span, @@ -377,7 +368,7 @@ impl LateLintPass for MissingDoc { hir::ItemImpl(_, _, _, Some(ref trait_ref), _, ref impl_items) => { // If the trait is private, add the impl items to private_traits so they don't get // reported for missing docs. - let real_trait = cx.tcx.trait_ref_to_def_id(trait_ref); + let real_trait = cx.tcx.expect_def(trait_ref.ref_id).def_id(); if let Some(node_id) = cx.tcx.map.as_local_node_id(real_trait) { match cx.tcx.map.find(node_id) { Some(hir_map::NodeItem(item)) => if item.vis == hir::Visibility::Inherited { @@ -780,11 +771,9 @@ impl LateLintPass for UnconditionalRecursion { id: ast::NodeId) -> bool { match tcx.map.get(id) { hir_map::NodeExpr(&hir::Expr { node: hir::ExprCall(ref callee, _), .. }) => { - tcx.def_map - .borrow() - .get(&callee.id) - .map_or(false, - |def| def.def_id() == tcx.map.local_def_id(fn_id)) + tcx.expect_def_or_none(callee.id).map_or(false, |def| { + def.def_id() == tcx.map.local_def_id(fn_id) + }) } _ => false } @@ -820,7 +809,9 @@ impl LateLintPass for UnconditionalRecursion { // Check for calls to methods via explicit paths (e.g. `T::method()`). match tcx.map.get(id) { hir_map::NodeExpr(&hir::Expr { node: hir::ExprCall(ref callee, _), .. }) => { - match tcx.def_map.borrow().get(&callee.id).map(|d| d.full_def()) { + // The callee is an arbitrary expression, + // it doesn't necessarily have a definition. + match tcx.expect_def_or_none(callee.id) { Some(Def::Method(def_id)) => { let item_substs = tcx.node_id_item_substs(callee.id); method_call_refers_to_method( @@ -1057,7 +1048,7 @@ impl LateLintPass for MutableTransmutes { hir::ExprPath(..) => (), _ => return None } - if let Def::Fn(did) = cx.tcx.resolve_expr(expr) { + if let Def::Fn(did) = cx.tcx.expect_def(expr.id) { if !def_id_is_transmute(cx, did) { return None; } diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index ad0e8e1c376..78825aca418 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -719,7 +719,7 @@ 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).map(|d| d.full_def()) { + if let Some(def) = tcx.expect_def_or_none(id) { rbml_w.tag(c::tag_table_def, |rbml_w| { rbml_w.id(id); def.encode(rbml_w).unwrap(); @@ -1133,10 +1133,7 @@ fn decode_side_tables(dcx: &DecodeContext, match value { c::tag_table_def => { let def = decode_def(dcx, val_dsr); - dcx.tcx.def_map.borrow_mut().insert(id, def::PathResolution { - base_def: def, - depth: 0 - }); + dcx.tcx.def_map.borrow_mut().insert(id, def::PathResolution::new(def)); } c::tag_table_node_type => { let ty = val_dsr.read_ty(dcx); diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index cebdaad13db..47f94e5b315 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -264,7 +264,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, let adt_data = if let hir::ExprPath(..) = fun.node { // Tuple-like ADTs are represented as ExprCall. We convert them here. expr_ty.ty_adt_def().and_then(|adt_def|{ - match cx.tcx.def_map.borrow()[&fun.id].full_def() { + match cx.tcx.expect_def(fun.id) { Def::Variant(_, variant_id) => { Some((adt_def, adt_def.variant_index_with_id(variant_id))) }, @@ -472,7 +472,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } } ty::TyEnum(adt, substs) => { - match cx.tcx.def_map.borrow()[&expr.id].full_def() { + match cx.tcx.expect_def(expr.id) { Def::Variant(enum_id, variant_id) => { debug_assert!(adt.did == enum_id); assert!(base.is_none()); @@ -675,7 +675,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, -> ExprKind<'tcx> { let substs = cx.tcx.node_id_item_substs(expr.id).substs; // Otherwise there may be def_map borrow conflicts - let def = cx.tcx.def_map.borrow()[&expr.id].full_def(); + let def = cx.tcx.expect_def(expr.id); let def_id = match def { // A regular function. Def::Fn(def_id) | Def::Method(def_id) => def_id, @@ -731,14 +731,9 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, id: node_id, }, - def @ Def::Local(..) | - def @ Def::Upvar(..) => return convert_var(cx, expr, def), + Def::Local(..) | Def::Upvar(..) => return convert_var(cx, expr, def), - def => - span_bug!( - expr.span, - "def `{:?}` not yet implemented", - def), + _ => span_bug!(expr.span, "def `{:?}` not yet implemented", def), }; ExprKind::Literal { literal: Literal::Item { def_id: def_id, substs: substs } @@ -1039,11 +1034,9 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, fn loop_label<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, expr: &'tcx hir::Expr) -> CodeExtent { - match cx.tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def()) { - Some(Def::Label(loop_id)) => cx.tcx.region_maps.node_extent(loop_id), - d => { - span_bug!(expr.span, "loop scope resolved to {:?}", d); - } + match cx.tcx.expect_def(expr.id) { + Def::Label(loop_id) => cx.tcx.region_maps.node_extent(loop_id), + d => span_bug!(expr.span, "loop scope resolved to {:?}", d), } } diff --git a/src/librustc_mir/hair/cx/pattern.rs b/src/librustc_mir/hair/cx/pattern.rs index d527936c899..c1f3dc15623 100644 --- a/src/librustc_mir/hair/cx/pattern.rs +++ b/src/librustc_mir/hair/cx/pattern.rs @@ -85,8 +85,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> { PatKind::Path(..) | PatKind::QPath(..) if pat_is_resolved_const(&self.cx.tcx.def_map.borrow(), pat) => { - let def = self.cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def(); - match def { + match self.cx.tcx.expect_def(pat.id) { Def::Const(def_id) | Def::AssociatedConst(def_id) => { let tcx = self.cx.tcx.global_tcx(); let substs = Some(self.cx.tcx.node_id_item_substs(pat.id).substs); @@ -111,7 +110,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> { } } } - _ => + def => span_bug!( pat.span, "def not a constant: {:?}", @@ -219,8 +218,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> { ty::TyStruct(adt_def, _) | ty::TyEnum(adt_def, _) => adt_def, _ => span_bug!(pat.span, "tuple struct pattern not applied to struct or enum"), }; - let def = self.cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def(); - let variant_def = adt_def.variant_of_def(def); + let variant_def = adt_def.variant_of_def(self.cx.tcx.expect_def(pat.id)); let subpatterns = subpatterns.iter() @@ -243,9 +241,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> { "struct pattern not applied to struct or enum"); } }; - - let def = self.cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def(); - let variant_def = adt_def.variant_of_def(def); + let variant_def = adt_def.variant_of_def(self.cx.tcx.expect_def(pat.id)); let subpatterns = fields.iter() @@ -324,8 +320,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> { pat: &hir::Pat, subpatterns: Vec>) -> PatternKind<'tcx> { - let def = self.cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def(); - match def { + match self.cx.tcx.expect_def(pat.id) { Def::Variant(enum_id, variant_id) => { let adt_def = self.cx.tcx.lookup_adt_def(enum_id); if adt_def.variants.len() > 1 { @@ -343,7 +338,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> { PatternKind::Leaf { subpatterns: subpatterns } } - _ => { + def => { span_bug!(pat.span, "inappropriate def for pattern: {:?}", def); } } diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index b1bb48aacee..774d19a0655 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -499,38 +499,36 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, } } hir::ExprPath(..) => { - let def = v.tcx.def_map.borrow().get(&e.id).map(|d| d.full_def()); - match def { - Some(Def::Variant(..)) => { + match v.tcx.expect_def(e.id) { + Def::Variant(..) => { // Count the discriminator or function pointer. v.add_qualif(ConstQualif::NON_ZERO_SIZED); } - Some(Def::Struct(..)) => { + Def::Struct(..) => { if let ty::TyFnDef(..) = node_ty.sty { // Count the function pointer. v.add_qualif(ConstQualif::NON_ZERO_SIZED); } } - Some(Def::Fn(..)) | Some(Def::Method(..)) => { + Def::Fn(..) | Def::Method(..) => { // Count the function pointer. v.add_qualif(ConstQualif::NON_ZERO_SIZED); } - Some(Def::Static(..)) => { + Def::Static(..) => { match v.mode { Mode::Static | Mode::StaticMut => {} Mode::Const | Mode::ConstFn => {} Mode::Var => v.add_qualif(ConstQualif::NOT_CONST) } } - Some(Def::Const(did)) | - Some(Def::AssociatedConst(did)) => { + Def::Const(did) | Def::AssociatedConst(did) => { let substs = Some(v.tcx.node_id_item_substs(e.id).substs); if let Some((expr, _)) = lookup_const_by_id(v.tcx, did, substs) { let inner = v.global_expr(Mode::Const, expr); v.add_qualif(inner); } } - Some(Def::Local(..)) if v.mode == Mode::ConstFn => { + Def::Local(..) if v.mode == Mode::ConstFn => { // Sadly, we can't determine whether the types are zero-sized. v.add_qualif(ConstQualif::NOT_CONST | ConstQualif::NON_ZERO_SIZED); } @@ -550,8 +548,8 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, _ => break }; } - let def = v.tcx.def_map.borrow().get(&callee.id).map(|d| d.full_def()); - let is_const = match def { + // The callee is an arbitrary expression, it doesn't necessarily have a definition. + let is_const = match v.tcx.expect_def_or_none(callee.id) { Some(Def::Struct(..)) => true, Some(Def::Variant(..)) => { // Count the discriminator. @@ -586,8 +584,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, } } hir::ExprStruct(..) => { - let did = v.tcx.def_map.borrow().get(&e.id).map(|def| def.def_id()); - if did == v.tcx.lang_items.unsafe_cell_type() { + if v.tcx.expect_def(e.id).def_id() == v.tcx.lang_items.unsafe_cell_type().unwrap() { v.add_qualif(ConstQualif::MUTABLE_MEM); } } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 7e76842a9f4..918c149ef85 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -65,7 +65,7 @@ struct ReachEverythingInTheInterfaceVisitor<'b, 'a: 'b, 'tcx: 'a> { impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> { fn ty_level(&self, ty: &hir::Ty) -> Option { if let hir::TyPath(..) = ty.node { - match self.tcx.def_map.borrow().get(&ty.id).unwrap().full_def() { + match self.tcx.expect_def(ty.id) { Def::PrimTy(..) | Def::SelfTy(..) | Def::TyParam(..) => { Some(AccessLevel::Public) } @@ -83,7 +83,7 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> { } fn trait_level(&self, trait_ref: &hir::TraitRef) -> Option { - let did = self.tcx.trait_ref_to_def_id(trait_ref); + let did = self.tcx.expect_def(trait_ref.ref_id).def_id(); if let Some(node_id) = self.tcx.map.as_local_node_id(did) { self.get(node_id) } else { @@ -317,7 +317,7 @@ impl<'b, 'a, 'tcx: 'a> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> { impl<'b, 'a, 'tcx: 'a, 'v> Visitor<'v> for ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> { fn visit_ty(&mut self, ty: &hir::Ty) { if let hir::TyPath(_, ref path) = ty.node { - let def = self.ev.tcx.def_map.borrow().get(&ty.id).unwrap().full_def(); + let def = self.ev.tcx.expect_def(ty.id); match def { Def::Struct(def_id) | Def::Enum(def_id) | Def::TyAlias(def_id) | Def::Trait(def_id) | Def::AssociatedTy(def_id, _) => { @@ -343,7 +343,7 @@ impl<'b, 'a, 'tcx: 'a, 'v> Visitor<'v> for ReachEverythingInTheInterfaceVisitor< } fn visit_trait_ref(&mut self, trait_ref: &hir::TraitRef) { - let def_id = self.ev.tcx.trait_ref_to_def_id(trait_ref); + let def_id = self.ev.tcx.expect_def(trait_ref.ref_id).def_id(); if let Some(node_id) = self.ev.tcx.map.as_local_node_id(def_id) { let item = self.ev.tcx.map.expect_item(node_id); self.ev.update(item.id, Some(AccessLevel::Reachable)); @@ -426,7 +426,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { } hir::ExprStruct(..) => { let adt = self.tcx.expr_ty(expr).ty_adt_def().unwrap(); - let variant = adt.variant_of_def(self.tcx.resolve_expr(expr)); + let variant = adt.variant_of_def(self.tcx.expect_def(expr.id)); // RFC 736: ensure all unmentioned fields are visible. // Rather than computing the set of unmentioned fields // (i.e. `all_fields - fields`), just check them all. @@ -436,7 +436,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { } hir::ExprPath(..) => { - if let Def::Struct(..) = self.tcx.resolve_expr(expr) { + if let Def::Struct(..) = self.tcx.expect_def(expr.id) { let expr_ty = self.tcx.expr_ty(expr); let def = match expr_ty.sty { ty::TyFnDef(_, _, &ty::BareFnTy { sig: ty::Binder(ty::FnSig { @@ -470,8 +470,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { match pattern.node { PatKind::Struct(_, ref fields, _) => { let adt = self.tcx.pat_ty(pattern).ty_adt_def().unwrap(); - let def = self.tcx.def_map.borrow().get(&pattern.id).unwrap().full_def(); - let variant = adt.variant_of_def(def); + let variant = adt.variant_of_def(self.tcx.expect_def(pattern.id)); for field in fields { self.check_field(pattern.span, adt, variant.field_named(field.node.name)); } @@ -534,10 +533,9 @@ struct ObsoleteCheckTypeForPrivatenessVisitor<'a, 'b: 'a, 'tcx: 'b> { impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { fn path_is_private_type(&self, path_id: ast::NodeId) -> bool { - 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::PrimTy(..)) | Some(Def::SelfTy(..)) => return false, - Some(def) => def.def_id(), + let did = match self.tcx.expect_def(path_id) { + Def::PrimTy(..) | Def::SelfTy(..) => return false, + def => def.def_id(), }; // A path can only be private if: @@ -653,7 +651,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> let not_private_trait = trait_ref.as_ref().map_or(true, // no trait counts as public trait |tr| { - let did = self.tcx.trait_ref_to_def_id(tr); + let did = self.tcx.expect_def(tr.ref_id).def_id(); if let Some(node_id) = self.tcx.map.as_local_node_id(did) { self.trait_is_public(node_id) @@ -911,8 +909,7 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { fn visit_ty(&mut self, ty: &hir::Ty) { if let hir::TyPath(_, ref path) = ty.node { - let def = self.tcx.def_map.borrow().get(&ty.id).unwrap().full_def(); - match def { + match self.tcx.expect_def(ty.id) { Def::PrimTy(..) | Def::SelfTy(..) | Def::TyParam(..) => { // Public } @@ -962,7 +959,7 @@ impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a, fn visit_trait_ref(&mut self, trait_ref: &hir::TraitRef) { // Non-local means public (private items can't leave their crate, modulo bugs) - let def_id = self.tcx.trait_ref_to_def_id(trait_ref); + let def_id = self.tcx.expect_def(trait_ref.ref_id).def_id(); if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) { let item = self.tcx.map.expect_item(node_id); let vis = ty::Visibility::from_hir(&item.vis, node_id, self.tcx); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 921a6683069..13a3d53d497 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1081,7 +1081,7 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> { } fn record_resolution(&mut self, id: NodeId, def: Def) { - self.def_map.insert(id, PathResolution { base_def: def, depth: 0 }); + self.def_map.insert(id, PathResolution::new(def)); } fn definitions(&mut self) -> Option<&mut Definitions> { @@ -1674,7 +1674,7 @@ impl<'a> Resolver<'a> { TypeNS) { Ok(binding) => { let def = binding.def().unwrap(); - self.record_def(item.id, PathResolution::new(def, 0)); + self.record_def(item.id, PathResolution::new(def)); } Err(true) => self.record_def(item.id, err_path_resolution()), Err(false) => { @@ -2239,15 +2239,19 @@ impl<'a> Resolver<'a> { unexpected pattern source {:?}", pat_src); } None => { - // A completely fresh binding, add to the lists - bindings_list.insert(renamed, outer_pat_id); + // A completely fresh binding, add to the lists. + // FIXME: Later stages are not ready to deal with `Def::Err` here yet, so + // define `Invalid` bindings as `Def::Local`, just don't add them to the lists. let def = Def::Local(self.definitions.local_def_id(pat_id), pat_id); - self.value_ribs.last_mut().unwrap().bindings.insert(renamed, def); + if ident.node.name != keywords::Invalid.name() { + bindings_list.insert(renamed, outer_pat_id); + self.value_ribs.last_mut().unwrap().bindings.insert(renamed, def); + } def } }; - PathResolution { base_def: def, depth: 0 } + PathResolution::new(def) } fn resolve_pattern_path(&mut self, @@ -2316,11 +2320,6 @@ impl<'a> Resolver<'a> { let always_binding = !pat_src.is_refutable() || opt_pat.is_some() || bmode != BindingMode::ByValue(Mutability::Immutable); match resolution.base_def { - // Def::Err => { - // // Just pass it through, the error is already - // // reported if it was necessary. - // resolution - // } Def::Struct(..) | Def::Variant(..) | Def::Const(..) | Def::AssociatedConst(..) if !always_binding => { // A constant, unit variant, etc pattern. @@ -2417,7 +2416,7 @@ impl<'a> Resolver<'a> { // FIXME: Create some fake resolution that can't possibly be a type. return Some(PathResolution { base_def: Def::Mod(self.definitions.local_def_id(ast::CRATE_NODE_ID)), - depth: path.segments.len() + depth: path.segments.len(), }); } max_assoc_types = path.segments.len() - qself.position; @@ -2457,7 +2456,7 @@ impl<'a> Resolver<'a> { let span = path.span; let segments = &path.segments[..path.segments.len() - path_depth]; - let mk_res = |def| PathResolution::new(def, path_depth); + let mk_res = |def| PathResolution { base_def: def, depth: path_depth }; if path.global { let binding = self.resolve_crate_relative_path(span, segments, namespace); @@ -2725,19 +2724,18 @@ impl<'a> Resolver<'a> { if let Some(node_id) = self.current_self_type.as_ref().and_then(extract_node_id) { // Look for a field with the same name in the current self_type. - match self.def_map.get(&node_id).map(|d| d.full_def()) { - Some(Def::Enum(did)) | - Some(Def::TyAlias(did)) | - Some(Def::Struct(did)) | - Some(Def::Variant(_, did)) => match self.structs.get(&did) { - None => {} - Some(fields) => { - if fields.iter().any(|&field_name| name == field_name) { - return Field; + if let Some(resolution) = self.def_map.get(&node_id) { + match resolution.base_def { + Def::Enum(did) | Def::TyAlias(did) | + Def::Struct(did) | Def::Variant(_, did) if resolution.depth == 0 => { + if let Some(fields) = self.structs.get(&did) { + if fields.iter().any(|&field_name| name == field_name) { + return Field; + } } } - }, - _ => {} // Self type didn't resolve properly + _ => {} + } } } @@ -3000,11 +2998,7 @@ impl<'a> Resolver<'a> { } Some(def @ Def::Label(_)) => { // Since this def is a label, it is never read. - self.record_def(expr.id, - PathResolution { - base_def: def, - depth: 0, - }) + self.record_def(expr.id, PathResolution::new(def)) } Some(_) => { span_bug!(expr.span, "label wasn't mapped to a label def!") @@ -3271,11 +3265,11 @@ impl<'a> Resolver<'a> { }; let segments: Vec<_> = path.segments.iter().map(|seg| seg.identifier.name).collect(); + let mut path_resolution = err_path_resolution(); let vis = match self.resolve_module_path(&segments, DontUseLexicalScope, path.span) { Success(module) => { let def = module.def.unwrap(); - let path_resolution = PathResolution { base_def: def, depth: 0 }; - self.def_map.insert(id, path_resolution); + path_resolution = PathResolution::new(def); ty::Visibility::Restricted(self.definitions.as_local_node_id(def.def_id()).unwrap()) } Failed(Some((span, msg))) => { @@ -3287,6 +3281,7 @@ impl<'a> Resolver<'a> { ty::Visibility::Public } }; + self.def_map.insert(id, path_resolution); if !self.is_accessible(vis) { let msg = format!("visibilities can only be restricted to ancestor modules"); self.session.span_err(path.span, &msg); @@ -3487,13 +3482,9 @@ fn module_to_string(module: Module) -> String { } fn err_path_resolution() -> PathResolution { - PathResolution { - base_def: Def::Err, - depth: 0, - } + PathResolution::new(Def::Err) } - #[derive(PartialEq,Copy, Clone)] pub enum MakeGlobMap { Yes, diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 629b687d8f7..3082a8b4307 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -598,7 +598,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { Some(def) => def, None => value_result.success().and_then(NameBinding::def).unwrap(), }; - let path_resolution = PathResolution { base_def: def, depth: 0 }; + let path_resolution = PathResolution::new(def); self.resolver.def_map.insert(directive.id, path_resolution); debug!("(resolving single import) successfully resolved import"); @@ -644,7 +644,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { // Record the destination of this import if let Some(did) = target_module.def_id() { - let resolution = PathResolution { base_def: Def::Mod(did), depth: 0 }; + let resolution = PathResolution::new(Def::Mod(did)); self.resolver.def_map.insert(directive.id, resolution); } diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 4d79ddfe8cb..216d188a503 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -269,14 +269,10 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { // looks up anything, not just a type fn lookup_type_ref(&self, ref_id: NodeId) -> Option { - if !self.tcx.def_map.borrow().contains_key(&ref_id) { - bug!("def_map has no key for {} in lookup_type_ref", ref_id); - } - let def = self.tcx.def_map.borrow().get(&ref_id).unwrap().full_def(); - match def { + match self.tcx.expect_def(ref_id) { Def::PrimTy(..) => None, Def::SelfTy(..) => None, - _ => Some(def.def_id()), + def => Some(def.def_id()), } } @@ -290,13 +286,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { return; } - let def_map = self.tcx.def_map.borrow(); - if !def_map.contains_key(&ref_id) { - span_bug!(span, - "def_map has no key for {} in lookup_def_kind", - ref_id); - } - let def = def_map.get(&ref_id).unwrap().full_def(); + let def = self.tcx.expect_def(ref_id); match def { Def::Mod(_) | Def::ForeignMod(_) => { @@ -853,9 +843,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { } // Modules or types in the path prefix. - let def_map = self.tcx.def_map.borrow(); - let def = def_map.get(&id).unwrap().full_def(); - match def { + match self.tcx.expect_def(id) { Def::Method(did) => { let ti = self.tcx.impl_or_trait_item(did); if let ty::MethodTraitItem(m) = ti { @@ -924,8 +912,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { PatKind::Struct(ref path, ref fields, _) => { visit::walk_path(self, path); let adt = self.tcx.node_id_to_type(p.id).ty_adt_def().unwrap(); - let def = self.tcx.def_map.borrow()[&p.id].full_def(); - let variant = adt.variant_of_def(def); + let variant = adt.variant_of_def(self.tcx.expect_def(p.id)); for &Spanned { node: ref field, span } in fields { let sub_span = self.span.span_for_first_ident(span); @@ -1269,7 +1256,7 @@ impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx, ast::ExprKind::Struct(ref path, ref fields, ref base) => { let hir_expr = self.save_ctxt.tcx.map.expect_expr(ex.id); let adt = self.tcx.expr_ty(&hir_expr).ty_adt_def().unwrap(); - let def = self.tcx.resolve_expr(&hir_expr); + let def = self.tcx.expect_def(hir_expr.id); self.process_struct_lit(ex, path, fields, adt.variant_of_def(def), base) } ast::ExprKind::MethodCall(_, _, ref args) => self.process_method_call(ex, args), @@ -1366,12 +1353,7 @@ impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx, // process collected paths for &(id, ref p, immut, ref_kind) in &collector.collected_paths { - let def_map = self.tcx.def_map.borrow(); - if !def_map.contains_key(&id) { - span_bug!(p.span, "def_map has no key for {} in visit_arm", id); - } - let def = def_map.get(&id).unwrap().full_def(); - match def { + match self.tcx.expect_def(id) { Def::Local(_, id) => { let value = if immut == ast::Mutability::Immutable { self.span.snippet(p.span).to_string() @@ -1401,8 +1383,8 @@ impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx, Def::Static(_, _) | Def::Const(..) | Def::AssociatedConst(..) => {} - _ => error!("unexpected definition kind when processing collected paths: {:?}", - def), + def => error!("unexpected definition kind when processing collected paths: {:?}", + def), } } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 23c03670c1e..27f15756a91 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -465,11 +465,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } pub fn get_path_data(&self, id: NodeId, path: &ast::Path) -> Option { - let def_map = self.tcx.def_map.borrow(); - if !def_map.contains_key(&id) { - span_bug!(path.span, "def_map has no key for {} in visit_expr", id); - } - let def = def_map.get(&id).unwrap().full_def(); + let def = self.tcx.expect_def(id); let sub_span = self.span_utils.span_for_last_ident(path.span); filter!(self.span_utils, sub_span, path.span, None); match def { @@ -637,13 +633,9 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } fn lookup_ref_id(&self, ref_id: NodeId) -> Option { - if !self.tcx.def_map.borrow().contains_key(&ref_id) { - bug!("def_map has no key for {} in lookup_type_ref", ref_id); - } - let def = self.tcx.def_map.borrow().get(&ref_id).unwrap().full_def(); - match def { + match self.tcx.expect_def(ref_id) { Def::PrimTy(_) | Def::SelfTy(..) => None, - _ => Some(def.def_id()), + def => Some(def.def_id()), } } diff --git a/src/librustc_trans/_match.rs b/src/librustc_trans/_match.rs index 913b0528b2e..8ad1ba2a614 100644 --- a/src/librustc_trans/_match.rs +++ b/src/librustc_trans/_match.rs @@ -657,9 +657,8 @@ fn get_branches<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ConstantValue(ConstantExpr(&l), debug_loc) } PatKind::Path(..) | PatKind::TupleStruct(..) | PatKind::Struct(..) => { - let opt_def = tcx.def_map.borrow().get(&cur.id).map(|d| d.full_def()); - match opt_def { - Some(Def::Variant(enum_id, var_id)) => { + match tcx.expect_def(cur.id) { + Def::Variant(enum_id, var_id) => { let variant = tcx.lookup_adt_def(enum_id).variant_with_id(var_id); Variant(Disr::from(variant.disr_val), adt::represent_node(bcx, cur.id), @@ -796,7 +795,7 @@ fn any_irrefutable_adt_pat(tcx: TyCtxt, m: &[Match], col: usize) -> bool { match pat.node { PatKind::Tuple(..) => true, PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) => { - match tcx.def_map.borrow().get(&pat.id).unwrap().full_def() { + match tcx.expect_def(pat.id) { Def::Struct(..) | Def::TyAlias(..) => true, _ => false, } @@ -1444,19 +1443,19 @@ pub fn trans_match<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, /// Checks whether the binding in `discr` is assigned to anywhere in the expression `body` fn is_discr_reassigned(bcx: Block, discr: &hir::Expr, body: &hir::Expr) -> bool { let (vid, field) = match discr.node { - hir::ExprPath(..) => match bcx.def(discr.id) { + hir::ExprPath(..) => match bcx.tcx().expect_def(discr.id) { Def::Local(_, vid) | Def::Upvar(_, vid, _, _) => (vid, None), _ => return false }, hir::ExprField(ref base, field) => { - let vid = match bcx.tcx().def_map.borrow().get(&base.id).map(|d| d.full_def()) { + let vid = match bcx.tcx().expect_def_or_none(base.id) { Some(Def::Local(_, vid)) | Some(Def::Upvar(_, vid, _, _)) => vid, _ => return false }; (vid, Some(mc::NamedField(field.node))) }, hir::ExprTupField(ref base, field) => { - let vid = match bcx.tcx().def_map.borrow().get(&base.id).map(|d| d.full_def()) { + let vid = match bcx.tcx().expect_def_or_none(base.id) { Some(Def::Local(_, vid)) | Some(Def::Upvar(_, vid, _, _)) => vid, _ => return false }; @@ -1835,9 +1834,8 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } } PatKind::TupleStruct(_, ref sub_pats, ddpos) => { - let opt_def = bcx.tcx().def_map.borrow().get(&pat.id).map(|d| d.full_def()); - match opt_def { - Some(Def::Variant(enum_id, var_id)) => { + match bcx.tcx().expect_def(pat.id) { + Def::Variant(enum_id, var_id) => { let repr = adt::represent_node(bcx, pat.id); let vinfo = ccx.tcx().lookup_adt_def(enum_id).variant_with_id(var_id); let args = extract_variant_args(bcx, @@ -1853,7 +1851,7 @@ pub fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, cleanup_scope); } } - Some(Def::Struct(..)) => { + Def::Struct(..) => { let expected_len = match *ccx.tcx().pat_ty(&pat) { ty::TyS{sty: ty::TyStruct(adt_def, _), ..} => { adt_def.struct_variant().fields.len() diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 884833ca79a..6b8198881c8 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -260,8 +260,7 @@ impl<'a, 'tcx> VariantInfo<'tcx> { /// Return the variant corresponding to a given node (e.g. expr) pub fn of_node(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>, id: ast::NodeId) -> Self { - let node_def = tcx.def_map.borrow().get(&id).map(|v| v.full_def()); - Self::from_ty(tcx, ty, node_def) + Self::from_ty(tcx, ty, Some(tcx.expect_def(id))) } pub fn field_index(&self, name: ast::Name) -> usize { @@ -656,15 +655,6 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> { self.tcx().map.node_to_string(id).to_string() } - pub fn def(&self, nid: ast::NodeId) -> Def { - match self.tcx().def_map.borrow().get(&nid) { - Some(v) => v.full_def(), - None => { - bug!("no def associated with node id {}", nid); - } - } - } - pub fn to_str(&self) -> String { format!("[block {:p}]", self) } diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index 7d3e7f25eaa..e988d2e6ac3 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -297,8 +297,7 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // `def` must be its own statement and cannot be in the `match` // otherwise the `def_map` will be borrowed for the entire match instead // of just to get the `def` value - let def = ccx.tcx().def_map.borrow().get(&expr.id).unwrap().full_def(); - match def { + match ccx.tcx().expect_def(expr.id) { Def::Const(def_id) | Def::AssociatedConst(def_id) => { if !ccx.tcx().tables.borrow().adjustments.contains_key(&expr.id) { debug!("get_const_expr_as_global ({:?}): found const {:?}", @@ -803,8 +802,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, _ => break, } } - let opt_def = cx.tcx().def_map.borrow().get(&cur.id).map(|d| d.full_def()); - if let Some(Def::Static(def_id, _)) = opt_def { + if let Some(Def::Static(def_id, _)) = cx.tcx().expect_def_or_none(cur.id) { get_static(cx, def_id).val } else { // If this isn't the address of a static, then keep going through @@ -891,8 +889,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } }, hir::ExprPath(..) => { - let def = cx.tcx().def_map.borrow().get(&e.id).unwrap().full_def(); - match def { + match cx.tcx().expect_def(e.id) { Def::Local(_, id) => { if let Some(val) = fn_args.and_then(|args| args.get(&id).cloned()) { val @@ -937,9 +934,8 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, _ => break, }; } - let def = cx.tcx().def_map.borrow()[&callee.id].full_def(); let arg_vals = map_list(args)?; - match def { + match cx.tcx().expect_def(callee.id) { Def::Fn(did) | Def::Method(did) => { const_fn_call( cx, diff --git a/src/librustc_trans/controlflow.rs b/src/librustc_trans/controlflow.rs index 0f686227c6f..8845f124218 100644 --- a/src/librustc_trans/controlflow.rs +++ b/src/librustc_trans/controlflow.rs @@ -318,8 +318,8 @@ 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).map(|d| d.full_def()) { - Some(Def::Label(loop_id)) => loop_id, + match bcx.tcx().expect_def(expr.id) { + Def::Label(loop_id) => loop_id, r => { bug!("{:?} in def-map for label", r) } diff --git a/src/librustc_trans/expr.rs b/src/librustc_trans/expr.rs index 4495f6243d5..652886ff2a0 100644 --- a/src/librustc_trans/expr.rs +++ b/src/librustc_trans/expr.rs @@ -153,7 +153,7 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // have side effects. This seems to be reached through tuple struct constructors being // passed zero-size constants. if let hir::ExprPath(..) = expr.node { - match bcx.def(expr.id) { + match bcx.tcx().expect_def(expr.id) { Def::Const(_) | Def::AssociatedConst(_) => { assert!(type_is_zero_size(bcx.ccx(), bcx.tcx().node_id_to_type(expr.id))); return bcx; @@ -172,7 +172,7 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // `[x; N]` somewhere within. match expr.node { hir::ExprPath(..) => { - match bcx.def(expr.id) { + match bcx.tcx().expect_def(expr.id) { Def::Const(did) | Def::AssociatedConst(did) => { let empty_substs = bcx.tcx().mk_substs(Substs::empty()); let const_expr = consts::get_const_expr(bcx.ccx(), did, expr, @@ -651,7 +651,7 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, trans(bcx, &e) } hir::ExprPath(..) => { - let var = trans_var(bcx, bcx.def(expr.id)); + let var = trans_var(bcx, bcx.tcx().expect_def(expr.id)); DatumBlock::new(bcx, var.to_expr_datum()) } hir::ExprField(ref base, name) => { @@ -1073,7 +1073,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, trans_into(bcx, &e, dest) } hir::ExprPath(..) => { - trans_def_dps_unadjusted(bcx, expr, bcx.def(expr.id), dest) + trans_def_dps_unadjusted(bcx, expr, bcx.tcx().expect_def(expr.id), dest) } hir::ExprIf(ref cond, ref thn, ref els) => { controlflow::trans_if(bcx, expr.id, &cond, &thn, els.as_ref().map(|e| &**e), dest) @@ -2373,7 +2373,7 @@ fn expr_kind<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, expr: &hir::Expr) -> ExprKin match expr.node { hir::ExprPath(..) => { - match tcx.resolve_expr(expr) { + match tcx.expect_def(expr.id) { // Put functions and ctors with the ADTs, as they // are zero-sized, so DPS is the cheapest option. Def::Struct(..) | Def::Variant(..) | diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index d492c34a55d..350ebf20165 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -734,7 +734,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { fn trait_def_id(&self, trait_ref: &hir::TraitRef) -> DefId { let path = &trait_ref.path; - match ::lookup_full_def(self.tcx(), path.span, trait_ref.ref_id) { + match self.tcx().expect_def(trait_ref.ref_id) { Def::Trait(trait_def_id) => trait_def_id, Def::Err => { self.tcx().sess.fatal("cannot continue compilation due to previous error"); @@ -1064,12 +1064,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { match ty.node { hir::TyPath(None, ref path) => { - let def = match self.tcx().def_map.borrow().get(&ty.id) { - Some(&def::PathResolution { base_def, depth: 0, .. }) => Some(base_def), - _ => None - }; - match def { - Some(Def::Trait(trait_def_id)) => { + let resolution = self.tcx().expect_resolution(ty.id); + match resolution.base_def { + Def::Trait(trait_def_id) if resolution.depth == 0 => { let mut projection_bounds = Vec::new(); let trait_ref = self.object_path_to_poly_trait_ref(rscope, @@ -1721,11 +1718,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } hir::TyPath(ref maybe_qself, ref path) => { debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path); - let path_res = if let Some(&d) = tcx.def_map.borrow().get(&ast_ty.id) { - d - } else { - span_bug!(ast_ty.span, "unbound path {:?}", ast_ty) - }; + let path_res = tcx.expect_resolution(ast_ty.id); let def = path_res.base_def; let base_ty_end = path.segments.len() - path_res.depth; let opt_self_ty = maybe_qself.as_ref().map(|qself| { @@ -1742,10 +1735,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { if path_res.depth != 0 && ty.sty != ty::TyError { // Write back the new resolution. - tcx.def_map.borrow_mut().insert(ast_ty.id, def::PathResolution { - base_def: def, - depth: 0 - }); + tcx.def_map.borrow_mut().insert(ast_ty.id, def::PathResolution::new(def)); } ty @@ -2226,7 +2216,7 @@ pub fn partition_bounds<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, for ast_bound in ast_bounds { match *ast_bound { hir::TraitTyParamBound(ref b, hir::TraitBoundModifier::None) => { - match ::lookup_full_def(tcx, b.trait_ref.path.span, b.trait_ref.ref_id) { + match tcx.expect_def(b.trait_ref.ref_id) { Def::Trait(trait_did) => { if tcx.try_add_builtin_trait(trait_did, &mut builtin_bounds) { diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index c06aa9f14df..ce8ac2a8dbc 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -150,24 +150,20 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> { self.demand_eqtype(pat.span, expected, lhs_ty); } PatKind::Path(..) if pat_is_resolved_const(&tcx.def_map.borrow(), pat) => { - if let Some(pat_def) = tcx.def_map.borrow().get(&pat.id) { - let const_did = pat_def.def_id(); - let const_scheme = tcx.lookup_item_type(const_did); - assert!(const_scheme.generics.is_empty()); - let const_ty = self.instantiate_type_scheme(pat.span, - &Substs::empty(), - &const_scheme.ty); - self.write_ty(pat.id, const_ty); + let const_did = tcx.expect_def(pat.id).def_id(); + let const_scheme = tcx.lookup_item_type(const_did); + assert!(const_scheme.generics.is_empty()); + let const_ty = self.instantiate_type_scheme(pat.span, + &Substs::empty(), + &const_scheme.ty); + self.write_ty(pat.id, const_ty); - // FIXME(#20489) -- we should limit the types here to scalars or something! + // FIXME(#20489) -- we should limit the types here to scalars or something! - // As with PatKind::Lit, what we really want here is that there - // exist a LUB, but for the cases that can occur, subtype - // is good enough. - self.demand_suptype(pat.span, expected, const_ty); - } else { - self.write_error(pat.id); - } + // As with PatKind::Lit, what we really want here is that there + // exist a LUB, but for the cases that can occur, subtype + // is good enough. + self.demand_suptype(pat.span, expected, const_ty); } PatKind::Binding(bm, ref path, ref sub) => { let typ = self.local_ty(pat.span, pat.id); @@ -217,18 +213,12 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> { } PatKind::QPath(ref qself, ref path) => { let self_ty = self.to_ty(&qself.ty); - let path_res = if let Some(&d) = tcx.def_map.borrow().get(&pat.id) { - if d.base_def == Def::Err { - self.set_tainted_by_errors(); - self.write_error(pat.id); - return; - } - d - } else { - debug!("unbound path {:?}", pat); + let path_res = tcx.expect_resolution(pat.id); + if path_res.base_def == Def::Err { + self.set_tainted_by_errors(); self.write_error(pat.id); return; - }; + } if let Some((opt_ty, segments, def)) = self.resolve_ty_and_def_ufcs(path_res, Some(self_ty), path, pat.span, pat.id) { @@ -582,7 +572,7 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> { etc: bool, expected: Ty<'tcx>) { let tcx = self.tcx; - let def = tcx.def_map.borrow().get(&pat.id).unwrap().full_def(); + let def = tcx.expect_def(pat.id); let variant = match self.def_struct_variant(def, path.span) { Some((_, variant)) => variant, None => { @@ -623,18 +613,16 @@ impl<'a, 'gcx, 'tcx> PatCtxt<'a, 'gcx, 'tcx> { // Typecheck the path. let tcx = self.tcx; - let path_res = match tcx.def_map.borrow().get(&pat.id) { - Some(&path_res) if path_res.base_def != Def::Err => path_res, - _ => { - self.set_tainted_by_errors(); - self.write_error(pat.id); + let path_res = tcx.expect_resolution(pat.id); + if path_res.base_def == Def::Err { + self.set_tainted_by_errors(); + self.write_error(pat.id); - for pat in subpats { - self.check_pat(&pat, tcx.types.err); - } - return; + for pat in subpats { + self.check_pat(&pat, tcx.types.err); } - }; + return; + } let (opt_ty, segments, def) = match self.resolve_ty_and_def_ufcs(path_res, None, path, diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 417b2fafecf..58abf8db2c3 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -222,7 +222,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let tcx = self.tcx; if let Some(pr) = tcx.def_map.borrow().get(&expr.id) { if pr.depth == 0 && pr.base_def != Def::Err { - if let Some(span) = tcx.map.span_if_local(pr.def_id()) { + if let Some(span) = tcx.map.span_if_local(pr.base_def.def_id()) { err.span_note(span, "defined here"); } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c5940176421..5deef3bc19b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -102,7 +102,7 @@ use rustc::ty::util::{Representability, IntTypeExt}; use require_c_abi_if_variadic; use rscope::{ElisionFailureInfo, RegionScope}; use session::{Session, CompileResult}; -use {CrateCtxt, lookup_full_def}; +use CrateCtxt; use TypeAndSubsts; use lint; use util::common::{block_query, ErrorReported, indenter, loop_query}; @@ -3158,7 +3158,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let tcx = self.tcx; // Find the relevant variant - let def = lookup_full_def(tcx, path.span, expr.id); + let def = tcx.expect_def(expr.id); if def == Def::Err { self.set_tainted_by_errors(); self.check_struct_fields_on_error(expr.id, fields, base_expr); @@ -3350,12 +3350,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.to_ty(&qself.ty) }); - let path_res = if let Some(&d) = tcx.def_map.borrow().get(&id) { - d - } else { - span_bug!(expr.span, "unbound path {:?}", expr) - }; - + let path_res = tcx.expect_resolution(id); if let Some((opt_ty, segments, def)) = self.resolve_ty_and_def_ufcs(path_res, opt_self_ty, path, expr.span, expr.id) { @@ -3746,10 +3741,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some(def) = def { // Write back the new resolution. - self.tcx().def_map.borrow_mut().insert(node_id, def::PathResolution { - base_def: def, - depth: 0, - }); + self.tcx().def_map.borrow_mut().insert(node_id, def::PathResolution::new(def)); Some((Some(ty), slice::ref_slice(item_segment), def)) } else { self.write_error(node_id); @@ -4556,7 +4548,7 @@ pub fn may_break(tcx: TyCtxt, id: ast::NodeId, b: &hir::Block) -> bool { // nested anywhere inside the loop? (block_query(b, |e| { if let hir::ExprBreak(Some(_)) = e.node { - lookup_full_def(tcx, e.span, e.id) == Def::Label(id) + tcx.expect_def(e.id) == Def::Label(id) } else { false } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index e65f3f0ff41..586c4f5c185 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -532,17 +532,13 @@ fn is_param<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, -> bool { if let hir::TyPath(None, _) = ast_ty.node { - let path_res = *tcx.def_map.borrow().get(&ast_ty.id).unwrap(); + let path_res = tcx.expect_resolution(ast_ty.id); match path_res.base_def { - Def::SelfTy(Some(def_id), None) => { - path_res.depth == 0 && def_id == tcx.map.local_def_id(param_id) - } - Def::TyParam(_, _, def_id, _) => { - path_res.depth == 0 && def_id == tcx.map.local_def_id(param_id) - } - _ => { - false + Def::SelfTy(Some(def_id), None) | + Def::TyParam(_, _, def_id, _) if path_res.depth == 0 => { + def_id == tcx.map.local_def_id(param_id) } + _ => false } } else { false @@ -1719,7 +1715,7 @@ fn add_unsized_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>, match unbound { Some(ref tpb) => { // FIXME(#8559) currently requires the unbound to be built-in. - let trait_def_id = tcx.trait_ref_to_def_id(tpb); + let trait_def_id = tcx.expect_def(tpb.ref_id).def_id(); match kind_id { Ok(kind_id) if trait_def_id != kind_id => { tcx.sess.span_warn(span, diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 86717da24c5..7017cb9f6a2 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -4125,7 +4125,7 @@ register_diagnostics! { // E0239, // `next` method of `Iterator` trait has unexpected type // E0240, // E0241, - E0242, // internal error looking up a definition +// E0242, E0245, // not a trait // E0246, // invalid recursive type // E0247, diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 0b23951db36..c6c575719c0 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -103,7 +103,6 @@ pub use rustc::util; use dep_graph::DepNode; use hir::map as hir_map; -use hir::def::Def; use rustc::infer::TypeOrigin; use rustc::ty::subst::Substs; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; @@ -176,15 +175,6 @@ fn write_substs_to_tcx<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } } -fn lookup_full_def(tcx: TyCtxt, sp: Span, id: ast::NodeId) -> Def { - match tcx.def_map.borrow().get(&id) { - Some(x) => x.full_def(), - None => { - span_fatal!(tcx.sess, sp, E0242, "internal error looking up a definition") - } - } -} - fn require_c_abi_if_variadic(tcx: TyCtxt, decl: &hir::FnDecl, abi: Abi, diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index f5ca125aca9..e49b96cbfd0 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -50,8 +50,8 @@ pub fn try_inline(cx: &DocContext, id: ast::NodeId, into: Option) Some(tcx) => tcx, None => return None, }; - let def = match tcx.def_map.borrow().get(&id) { - Some(d) => d.full_def(), + let def = match tcx.expect_def_or_none(id) { + Some(def) => def, None => return None, }; let did = def.def_id(); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index d7b4ad1128c..14ca6340316 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2631,7 +2631,7 @@ fn resolve_type(cx: &DocContext, }; } }; - let def = tcx.def_map.borrow().get(&id).expect("unresolved id not in defmap").full_def(); + let def = tcx.expect_def(id); debug!("resolve_type: def={:?}", def); let is_generic = match def { @@ -2700,7 +2700,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(|d| register_def(cx, d.full_def())) + tcx.expect_def_or_none(id).map(|def| register_def(cx, def)) }) } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index d5309d74334..c7b571c2d19 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -241,7 +241,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { Some(tcx) => tcx, None => return false }; - let def = tcx.def_map.borrow()[&id]; + let def = tcx.expect_def(id); let def_did = def.def_id(); let use_attrs = tcx.map.attrs(id).clean(self.cx); @@ -251,10 +251,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { // reachable in documentation - a previously nonreachable item can be // made reachable by cross-crate inlining which we're checking here. // (this is done here because we need to know this upfront) - if !def.def_id().is_local() && !is_no_inline { + if !def_did.is_local() && !is_no_inline { let attrs = clean::inline::load_attrs(self.cx, tcx, def_did); let self_is_hidden = attrs.list("doc").has_word("hidden"); - match def.base_def { + match def { Def::Trait(did) | Def::Struct(did) | Def::Enum(did) |