diff options
55 files changed, 927 insertions, 925 deletions
diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index 609d492a93a..f21d98a0fc7 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -10,8 +10,6 @@ use rustc_data_structures::graph; use cfg::*; -use hir::def::Def; -use hir::pat_util; use ty::{self, TyCtxt}; use syntax::ast; use syntax::ptr::P; @@ -284,7 +282,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { hir::ExprBreak(label, ref opt_expr) => { let v = self.opt_expr(opt_expr, pred); - let loop_scope = self.find_scope(expr, label.map(|l| l.node)); + let loop_scope = self.find_scope(expr, label); let b = self.add_ast_node(expr.id, &[v]); self.add_exiting_edge(expr, b, loop_scope, loop_scope.break_index); @@ -292,7 +290,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { } hir::ExprAgain(label) => { - let loop_scope = self.find_scope(expr, label.map(|l| l.node)); + let loop_scope = self.find_scope(expr, label); let a = self.add_ast_node(expr.id, &[pred]); self.add_exiting_edge(expr, a, loop_scope, loop_scope.continue_index); @@ -457,7 +455,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { // Visit the guard expression let guard_exit = self.expr(&guard, guard_start); - let this_has_bindings = pat_util::pat_contains_bindings_or_wild(&pat); + let this_has_bindings = pat.contains_bindings_or_wild(); // If both this pattern and the previous pattern // were free of bindings, they must consist only @@ -570,23 +568,16 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { fn find_scope(&self, expr: &hir::Expr, - label: Option<ast::Name>) -> LoopScope { - if label.is_none() { - return *self.loop_scopes.last().unwrap(); - } - - match self.tcx.expect_def(expr.id) { - Def::Label(loop_id) => { + label: Option<hir::Label>) -> LoopScope { + match label { + None => *self.loop_scopes.last().unwrap(), + Some(label) => { for l in &self.loop_scopes { - if l.loop_id == loop_id { + if l.loop_id == label.loop_id { return *l; } } - span_bug!(expr.span, "no loop scope for id {}", loop_id); - } - - r => { - span_bug!(expr.span, "bad entry `{:?}` in def_map for label", r); + span_bug!(expr.span, "no loop scope for id {}", label.loop_id); } } } diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index feefc43f401..b6fce2d6ca0 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -83,14 +83,6 @@ impl 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 { - bug!("path not fully resolved: {:?}", self); - } - self.base_def - } - pub fn kind_name(&self) -> &'static str { if self.depth != 0 { "associated item" diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 3de788b8c1a..94da10d33f8 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -38,6 +38,7 @@ use syntax::ast::{NodeId, CRATE_NODE_ID, Name, Attribute}; use syntax::codemap::Spanned; use syntax_pos::Span; use hir::*; +use hir::def::Def; use hir::map::Map; use super::itemlikevisit::DeepVisitor; @@ -155,6 +156,9 @@ pub trait Visitor<'v> : Sized { fn visit_id(&mut self, _node_id: NodeId) { // Nothing to do. } + fn visit_def_mention(&mut self, _def: Def) { + // Nothing to do. + } fn visit_name(&mut self, _span: Span, _name: Name) { // Nothing to do. } @@ -507,6 +511,7 @@ pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V, qpath: &'v QPath, id: Nod } pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) { + visitor.visit_def_mention(path.def); for segment in &path.segments { visitor.visit_path_segment(path.span, segment); } @@ -566,7 +571,8 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) { PatKind::Ref(ref subpattern, _) => { visitor.visit_pat(subpattern) } - PatKind::Binding(_, ref pth1, ref optional_subpattern) => { + PatKind::Binding(_, def_id, ref pth1, ref optional_subpattern) => { + visitor.visit_def_mention(Def::Local(def_id)); visitor.visit_name(pth1.span, pth1.node); walk_list!(visitor, visit_pat, optional_subpattern); } @@ -907,12 +913,18 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { ExprPath(ref qpath) => { visitor.visit_qpath(qpath, expression.id, expression.span); } - ExprBreak(ref opt_sp_name, ref opt_expr) => { - walk_opt_sp_name(visitor, opt_sp_name); + ExprBreak(None, ref opt_expr) => { walk_list!(visitor, visit_expr, opt_expr); } - ExprAgain(ref opt_sp_name) => { - walk_opt_sp_name(visitor, opt_sp_name); + ExprBreak(Some(label), ref opt_expr) => { + visitor.visit_def_mention(Def::Label(label.loop_id)); + visitor.visit_name(label.span, label.name); + walk_list!(visitor, visit_expr, opt_expr); + } + ExprAgain(None) => {} + ExprAgain(Some(label)) => { + visitor.visit_def_mention(Def::Label(label.loop_id)); + visitor.visit_name(label.span, label.name); } ExprRet(ref optional_expression) => { walk_list!(visitor, visit_expr, optional_expression); diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index af0448cc277..aea05357a84 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -77,7 +77,7 @@ pub struct LoweringContext<'a> { pub trait Resolver { // Resolve a global hir path generated by the lowerer when expanding `for`, `if let`, etc. - fn resolve_generated_global_path(&mut self, path: &hir::Path, is_value: bool) -> Def; + fn resolve_generated_global_path(&mut self, path: &mut hir::Path, is_value: bool); // Obtain the resolution for a node id fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution>; @@ -154,6 +154,15 @@ impl<'a> LoweringContext<'a> { self.sess.next_node_id() } + fn expect_full_def(&mut self, id: NodeId) -> Def { + self.resolver.get_resolution(id).map_or(Def::Err, |pr| { + if pr.depth != 0 { + bug!("path not fully resolved: {:?}", pr); + } + pr.base_def + }) + } + fn diagnostic(&self) -> &errors::Handler { self.sess.diagnostic() } @@ -181,6 +190,19 @@ impl<'a> LoweringContext<'a> { o_id.map(|sp_ident| respan(sp_ident.span, sp_ident.node.name)) } + fn lower_label(&mut self, id: NodeId, label: Option<Spanned<Ident>>) -> Option<hir::Label> { + label.map(|sp_ident| { + hir::Label { + span: sp_ident.span, + name: sp_ident.node.name, + loop_id: match self.expect_full_def(id) { + Def::Label(loop_id) => loop_id, + _ => DUMMY_NODE_ID + } + } + }) + } + fn lower_attrs(&mut self, attrs: &Vec<Attribute>) -> hir::HirVec<Attribute> { attrs.clone().into() } @@ -286,6 +308,7 @@ impl<'a> LoweringContext<'a> { let proj_start = p.segments.len() - resolution.depth; let path = P(hir::Path { global: p.global, + def: resolution.base_def, segments: p.segments[..proj_start].iter().enumerate().map(|(i, segment)| { let param_mode = match (qself_position, param_mode) { (Some(j), ParamMode::Optional) if i < j => { @@ -353,12 +376,14 @@ impl<'a> LoweringContext<'a> { } fn lower_path_extra(&mut self, + id: NodeId, p: &Path, name: Option<Name>, param_mode: ParamMode) -> hir::Path { hir::Path { global: p.global, + def: self.expect_full_def(id), segments: p.segments.iter().map(|segment| { self.lower_path_segment(segment, param_mode) }).chain(name.map(|name| { @@ -372,10 +397,11 @@ impl<'a> LoweringContext<'a> { } fn lower_path(&mut self, + id: NodeId, p: &Path, param_mode: ParamMode) -> hir::Path { - self.lower_path_extra(p, None, param_mode) + self.lower_path_extra(id, p, None, param_mode) } fn lower_path_segment(&mut self, @@ -569,7 +595,7 @@ impl<'a> LoweringContext<'a> { span}) => { hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { id: id, - path: self.lower_path(path, ParamMode::Explicit), + path: self.lower_path(id, path, ParamMode::Explicit), ty: self.lower_ty(ty), span: span, }) @@ -599,7 +625,7 @@ impl<'a> LoweringContext<'a> { fn lower_trait_ref(&mut self, p: &TraitRef) -> hir::TraitRef { hir::TraitRef { - path: self.lower_path(&p.path, ParamMode::Explicit), + path: self.lower_path(p.ref_id, &p.path, ParamMode::Explicit), ref_id: p.ref_id, } } @@ -665,6 +691,7 @@ impl<'a> LoweringContext<'a> { } fn lower_item_kind(&mut self, + id: NodeId, name: &mut Name, attrs: &hir::HirVec<Attribute>, vis: &mut hir::Visibility, @@ -690,7 +717,7 @@ impl<'a> LoweringContext<'a> { Some(ident.name) }; - let mut path = self.lower_path_extra(path, suffix, + let mut path = self.lower_path_extra(import.id, path, suffix, ParamMode::Explicit); path.span = span; self.items.insert(import.id, hir::Item { @@ -705,7 +732,7 @@ impl<'a> LoweringContext<'a> { path } }; - let path = P(self.lower_path(path, ParamMode::Explicit)); + let path = P(self.lower_path(id, path, ParamMode::Explicit)); let kind = match view_path.node { ViewPathSimple(ident, _) => { *name = ident.name; @@ -901,7 +928,7 @@ impl<'a> LoweringContext<'a> { let attrs = self.lower_attrs(&i.attrs); let mut vis = self.lower_visibility(&i.vis); let node = self.with_parent_def(i.id, |this| { - this.lower_item_kind(&mut name, &attrs, &mut vis, &i.node) + this.lower_item_kind(i.id, &mut name, &attrs, &mut vis, &i.node) }); hir::Item { @@ -1012,14 +1039,24 @@ impl<'a> LoweringContext<'a> { self.with_parent_def(p.id, |this| { match this.resolver.get_resolution(p.id).map(|d| d.base_def) { // `None` can occur in body-less function signatures - None | Some(Def::Local(..)) => { + def @ None | def @ Some(Def::Local(_)) => { + let def_id = def.map(|d| d.def_id()).unwrap_or_else(|| { + this.resolver.definitions().local_def_id(p.id) + }); hir::PatKind::Binding(this.lower_binding_mode(binding_mode), + def_id, respan(pth1.span, pth1.node.name), sub.as_ref().map(|x| this.lower_pat(x))) } - _ => { - let path = hir::Path::from_name(pth1.span, pth1.node.name); - hir::PatKind::Path(hir::QPath::Resolved(None, P(path))) + Some(def) => { + hir::PatKind::Path(hir::QPath::Resolved(None, P(hir::Path { + span: pth1.span, + global: false, + def: def, + segments: hir_vec![ + hir::PathSegment::from_name(pth1.node.name) + ], + }))) } } }) @@ -1120,8 +1157,7 @@ impl<'a> LoweringContext<'a> { let inplace_finalize = ["ops", "InPlace", "finalize"]; let make_call = |this: &mut LoweringContext, p, args| { - let path = this.std_path(e.span, p); - let path = this.expr_path(path, ThinVec::new()); + let path = this.expr_std_path(e.span, p, ThinVec::new()); P(this.expr_call(e.span, path, args)) }; @@ -1315,13 +1351,12 @@ impl<'a> LoweringContext<'a> { ast_expr: &Expr, path: &[&str], fields: &[(&str, &P<Expr>)]) -> hir::Expr { - let struct_path = this.std_path(ast_expr.span, - &iter::once(&"ops").chain(path) - .map(|s| *s) - .collect::<Vec<_>>()); + let struct_path = &iter::once(&"ops").chain(path).map(|s| *s) + .collect::<Vec<_>>(); let hir_expr = if fields.len() == 0 { - this.expr_path(struct_path, ast_expr.attrs.clone()) + this.expr_std_path(ast_expr.span, struct_path, + ast_expr.attrs.clone()) } else { let fields = fields.into_iter().map(|&(s, e)| { let expr = P(this.lower_expr(&e)); @@ -1334,7 +1369,7 @@ impl<'a> LoweringContext<'a> { }).collect(); let attrs = ast_expr.attrs.clone(); - this.expr_struct(ast_expr.span, struct_path, fields, None, attrs) + this.expr_std_struct(ast_expr.span, struct_path, fields, None, attrs) }; this.signal_block_expr(hir_vec![], @@ -1378,10 +1413,10 @@ impl<'a> LoweringContext<'a> { hir::ExprPath(self.lower_qpath(e.id, qself, path, ParamMode::Optional)) } ExprKind::Break(opt_ident, ref opt_expr) => { - hir::ExprBreak(self.lower_opt_sp_ident(opt_ident), + hir::ExprBreak(self.lower_label(e.id, opt_ident), opt_expr.as_ref().map(|x| P(self.lower_expr(x)))) } - ExprKind::Continue(opt_ident) => hir::ExprAgain(self.lower_opt_sp_ident(opt_ident)), + ExprKind::Continue(opt_ident) => hir::ExprAgain(self.lower_label(e.id, opt_ident)), ExprKind::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| P(self.lower_expr(x)))), ExprKind::InlineAsm(ref asm) => { let hir_asm = hir::InlineAsm { @@ -1608,10 +1643,10 @@ impl<'a> LoweringContext<'a> { // `match ::std::iter::Iterator::next(&mut iter) { ... }` let match_expr = { - let next_path = self.std_path(e.span, &["iter", "Iterator", "next"]); let iter = P(self.expr_ident(e.span, iter, iter_pat.id)); let ref_mut_iter = self.expr_mut_addr_of(e.span, iter); - let next_path = self.expr_path(next_path, ThinVec::new()); + let next_path = &["iter", "Iterator", "next"]; + let next_path = self.expr_std_path(e.span, next_path, ThinVec::new()); let next_expr = P(self.expr_call(e.span, next_path, hir_vec![ref_mut_iter])); let arms = hir_vec![pat_arm, break_arm]; @@ -1638,10 +1673,8 @@ impl<'a> LoweringContext<'a> { // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }` let into_iter_expr = { - let into_iter_path = self.std_path(e.span, - &["iter", "IntoIterator", "into_iter"]); - - let into_iter = self.expr_path(into_iter_path, ThinVec::new()); + let into_iter_path = &["iter", "IntoIterator", "into_iter"]; + let into_iter = self.expr_std_path(e.span, into_iter_path, ThinVec::new()); P(self.expr_call(e.span, into_iter, hir_vec![head])) }; @@ -1684,8 +1717,8 @@ impl<'a> LoweringContext<'a> { hir::PopUnstableBlock, ThinVec::new()); - let path = self.std_path(e.span, &["ops", "Carrier", "translate"]); - let path = self.expr_path(path, ThinVec::new()); + let path = &["ops", "Carrier", "translate"]; + let path = self.expr_std_path(e.span,path, ThinVec::new()); let call = P(self.expr_call(e.span, path, hir_vec![sub_expr])); P(self.signal_block_expr(hir_vec![], @@ -1710,15 +1743,15 @@ impl<'a> LoweringContext<'a> { let err_ident = self.str_to_ident("err"); let err_local = self.pat_ident(e.span, err_ident); let from_expr = { - let path = self.std_path(e.span, &["convert", "From", "from"]); - let from = self.expr_path(path, ThinVec::new()); + let path = &["convert", "From", "from"]; + let from = self.expr_std_path(e.span, path, ThinVec::new()); let err_expr = self.expr_ident(e.span, err_ident, err_local.id); self.expr_call(e.span, from, hir_vec![err_expr]) }; let from_err_expr = { - let path = self.std_path(e.span, &["ops", "Carrier", "from_error"]); - let from_err = self.expr_path(path, ThinVec::new()); + let path = &["ops", "Carrier", "from_error"]; + let from_err = self.expr_std_path(e.span, path, ThinVec::new()); P(self.expr_call(e.span, from_err, hir_vec![from_expr])) }; @@ -1794,7 +1827,7 @@ impl<'a> LoweringContext<'a> { Visibility::Crate(_) => hir::Visibility::Crate, Visibility::Restricted { ref path, id } => { hir::Visibility::Restricted { - path: P(self.lower_path(path, ParamMode::Explicit)), + path: P(self.lower_path(id, path, ParamMode::Explicit)), id: id } } @@ -1880,14 +1913,18 @@ impl<'a> LoweringContext<'a> { } fn expr_ident(&mut self, span: Span, id: Name, binding: NodeId) -> hir::Expr { - let path = self.path_ident(span, id); - let expr_path = hir::ExprPath(hir::QPath::Resolved(None, P(path))); - let expr = self.expr(span, expr_path, ThinVec::new()); - let def = { let defs = self.resolver.definitions(); Def::Local(defs.local_def_id(binding)) }; + + let expr_path = hir::ExprPath(hir::QPath::Resolved(None, P(hir::Path { + span: span, + global: false, + def: def, + segments: hir_vec![hir::PathSegment::from_name(id)], + }))); + let expr = self.expr(span, expr_path, ThinVec::new()); self.resolver.record_resolution(expr.id, def); expr @@ -1897,9 +1934,14 @@ impl<'a> LoweringContext<'a> { self.expr(span, hir::ExprAddrOf(hir::MutMutable, e), ThinVec::new()) } - fn expr_path(&mut self, path: hir::Path, attrs: ThinVec<Attribute>) -> P<hir::Expr> { - let def = self.resolver.resolve_generated_global_path(&path, true); - let expr = self.expr(path.span, hir::ExprPath(hir::QPath::Resolved(None, P(path))), attrs); + fn expr_std_path(&mut self, + span: Span, + components: &[&str], + attrs: ThinVec<Attribute>) + -> P<hir::Expr> { + let path = self.std_path(span, components, true); + let def = path.def; + let expr = self.expr(span, hir::ExprPath(hir::QPath::Resolved(None, P(path))), attrs); self.resolver.record_resolution(expr.id, def); P(expr) } @@ -1921,15 +1963,16 @@ impl<'a> LoweringContext<'a> { P(self.expr(sp, hir::ExprTup(exprs), ThinVec::new())) } - fn expr_struct(&mut self, - sp: Span, - path: hir::Path, - fields: hir::HirVec<hir::Field>, - e: Option<P<hir::Expr>>, - attrs: ThinVec<Attribute>) -> P<hir::Expr> { - let def = self.resolver.resolve_generated_global_path(&path, false); + fn expr_std_struct(&mut self, + span: Span, + components: &[&str], + fields: hir::HirVec<hir::Field>, + e: Option<P<hir::Expr>>, + attrs: ThinVec<Attribute>) -> P<hir::Expr> { + let path = self.std_path(span, components, false); + let def = path.def; let qpath = hir::QPath::Resolved(None, P(path)); - let expr = self.expr(sp, hir::ExprStruct(qpath, fields, e), attrs); + let expr = self.expr(span, hir::ExprStruct(qpath, fields, e), attrs); self.resolver.record_resolution(expr.id, def); P(expr) } @@ -1988,28 +2031,28 @@ impl<'a> LoweringContext<'a> { } fn pat_ok(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> { - let path = self.std_path(span, &["result", "Result", "Ok"]); - self.pat_enum(span, path, hir_vec![pat]) + self.pat_std_enum(span, &["result", "Result", "Ok"], hir_vec![pat]) } fn pat_err(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> { - let path = self.std_path(span, &["result", "Result", "Err"]); - self.pat_enum(span, path, hir_vec![pat]) + self.pat_std_enum(span, &["result", "Result", "Err"], hir_vec![pat]) } fn pat_some(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> { - let path = self.std_path(span, &["option", "Option", "Some"]); - self.pat_enum(span, path, hir_vec![pat]) + self.pat_std_enum(span, &["option", "Option", "Some"], hir_vec![pat]) } fn pat_none(&mut self, span: Span) -> P<hir::Pat> { - let path = self.std_path(span, &["option", "Option", "None"]); - self.pat_enum(span, path, hir_vec![]) + self.pat_std_enum(span, &["option", "Option", "None"], hir_vec![]) } - fn pat_enum(&mut self, span: Span, path: hir::Path, subpats: hir::HirVec<P<hir::Pat>>) - -> P<hir::Pat> { - let def = self.resolver.resolve_generated_global_path(&path, true); + fn pat_std_enum(&mut self, + span: Span, + components: &[&str], + subpats: hir::HirVec<P<hir::Pat>>) + -> P<hir::Pat> { + let path = self.std_path(span, components, true); + let def = path.def; let qpath = hir::QPath::Resolved(None, P(path)); let pt = if subpats.is_empty() { hir::PatKind::Path(qpath) @@ -2027,25 +2070,27 @@ impl<'a> LoweringContext<'a> { fn pat_ident_binding_mode(&mut self, span: Span, name: Name, bm: hir::BindingMode) -> P<hir::Pat> { - let pat_ident = hir::PatKind::Binding(bm, - Spanned { - span: span, - node: name, - }, - None); - - let pat = self.pat(span, pat_ident); - + let id = self.next_id(); let parent_def = self.parent_def; - let def = { + let def_id = { let defs = self.resolver.definitions(); let def_path_data = DefPathData::Binding(name.as_str()); - let def_index = defs.create_def_with_parent(parent_def, pat.id, def_path_data); - Def::Local(DefId::local(def_index)) + let def_index = defs.create_def_with_parent(parent_def, id, def_path_data); + DefId::local(def_index) }; - self.resolver.record_resolution(pat.id, def); + self.resolver.record_resolution(id, Def::Local(def_id)); - pat + P(hir::Pat { + id: id, + node: hir::PatKind::Binding(bm, + def_id, + Spanned { + span: span, + node: name, + }, + None), + span: span, + }) } fn pat_wild(&mut self, span: Span) -> P<hir::Pat> { @@ -2060,64 +2105,25 @@ impl<'a> LoweringContext<'a> { }) } - fn path_ident(&mut self, span: Span, id: Name) -> hir::Path { - self.path(span, vec![id]) - } - - fn path(&mut self, span: Span, strs: Vec<Name>) -> hir::Path { - self.path_all(span, false, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new()) - } - - fn path_global(&mut self, span: Span, strs: Vec<Name>) -> hir::Path { - self.path_all(span, true, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new()) - } + /// Given suffix ["b","c","d"], returns path `::std::b::c::d` when + /// `fld.cx.use_std`, and `::core::b::c::d` otherwise. + /// The path is also resolved according to `is_value`. + fn std_path(&mut self, span: Span, components: &[&str], is_value: bool) -> hir::Path { + let idents = self.crate_root.iter().chain(components); - fn path_all(&mut self, - sp: Span, - global: bool, - mut names: Vec<Name>, - lifetimes: hir::HirVec<hir::Lifetime>, - types: hir::HirVec<P<hir::Ty>>, - bindings: hir::HirVec<hir::TypeBinding>) - -> hir::Path { - let last_identifier = names.pop().unwrap(); - let mut segments: Vec<hir::PathSegment> = names.into_iter().map(|name| { - hir::PathSegment { - name: name, - parameters: hir::PathParameters::none(), - } + let segments: Vec<_> = idents.map(|name| { + hir::PathSegment::from_name(Symbol::intern(name)) }).collect(); - segments.push(hir::PathSegment { - name: last_identifier, - parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData { - lifetimes: lifetimes, - types: types, - infer_types: true, - bindings: bindings, - }), - }); - hir::Path { - span: sp, - global: global, + let mut path = hir::Path { + span: span, + global: true, + def: Def::Err, segments: segments.into(), - } - } - - fn std_path_components(&mut self, components: &[&str]) -> Vec<Name> { - let mut v = Vec::new(); - if let Some(s) = self.crate_root { - v.push(Symbol::intern(s)); - } - v.extend(components.iter().map(|s| Symbol::intern(s))); - return v; - } + }; - // Given suffix ["b","c","d"], returns path `::std::b::c::d` when - // `fld.cx.use_std`, and `::core::b::c::d` otherwise. - fn std_path(&mut self, span: Span, components: &[&str]) -> hir::Path { - let idents = self.std_path_components(components); - self.path_global(span, idents) + self.resolver.resolve_generated_global_path(&mut path, is_value); + path } fn signal_block_expr(&mut self, diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index 9d1c7d41faa..a08060e7927 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -436,7 +436,7 @@ impl<'ast> intravisit::Visitor<'ast> for DefCollector<'ast> { fn visit_pat(&mut self, pat: &'ast hir::Pat) { let parent_def = self.parent_def; - if let hir::PatKind::Binding(_, name, _) = pat.node { + if let hir::PatKind::Binding(_, _, name, _) = pat.node { let def = self.create_def(pat.id, DefPathData::Binding(name.node.as_str())); self.parent_def = Some(def); } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index a8986530d1d..c4ed98ce6e0 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -658,7 +658,7 @@ impl<'ast> Map<'ast> { NodeVariant(v) => v.node.name, NodeLifetime(lt) => lt.name, NodeTyParam(tp) => tp.name, - NodeLocal(&Pat { node: PatKind::Binding(_,l,_), .. }) => l.node, + NodeLocal(&Pat { node: PatKind::Binding(_,_,l,_), .. }) => l.node, NodeStructCtor(_) => self.name(self.get_parent(id)), _ => bug!("no name for {}", self.node_to_string(id)) } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index da759b2d4da..1e70ebf5851 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -107,6 +107,8 @@ pub struct Path { /// A `::foo` path, is relative to the crate root rather than current /// module (like paths in an import). pub global: bool, + /// The definition that the path resolved to. + pub def: Def, /// The segments in the path: the things separated by `::`. pub segments: HirVec<PathSegment>, } @@ -123,21 +125,6 @@ impl fmt::Display for Path { } } -impl Path { - /// Convert a span and an identifier to the corresponding - /// 1-segment path. - pub fn from_name(s: Span, name: Name) -> Path { - Path { - span: s, - global: false, - segments: hir_vec![PathSegment { - name: name, - parameters: PathParameters::none() - }], - } - } -} - /// A segment of a path: an identifier, an optional lifetime, and a set of /// types. #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] @@ -153,6 +140,16 @@ pub struct PathSegment { pub parameters: PathParameters, } +impl PathSegment { + /// Convert an identifier to the corresponding segment. + pub fn from_name(name: Name) -> PathSegment { + PathSegment { + name: name, + parameters: PathParameters::none() + } + } +} + #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum PathParameters { /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>` @@ -571,7 +568,8 @@ pub enum PatKind { Wild, /// A fresh binding `ref mut binding @ OPT_SUBPATTERN`. - Binding(BindingMode, Spanned<Name>, Option<P<Pat>>), + /// The `DefId` is for the definition of the variable being bound. + Binding(BindingMode, DefId, Spanned<Name>, Option<P<Pat>>), /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`. /// The `bool` is `true` in the presence of a `..`. @@ -944,9 +942,9 @@ pub enum Expr_ { /// A referencing operation (`&a` or `&mut a`) ExprAddrOf(Mutability, P<Expr>), /// A `break`, with an optional label to break - ExprBreak(Option<Spanned<Name>>, Option<P<Expr>>), + ExprBreak(Option<Label>, Option<P<Expr>>), /// A `continue`, with an optional label - ExprAgain(Option<Spanned<Name>>), + ExprAgain(Option<Label>), /// A `return`, with an optional value to be returned ExprRet(Option<P<Expr>>), @@ -1023,6 +1021,13 @@ pub enum LoopSource { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] +pub struct Label { + pub span: Span, + pub name: Name, + pub loop_id: NodeId +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] pub enum CaptureClause { CaptureByValue, CaptureByRef, @@ -1225,7 +1230,7 @@ pub type ExplicitSelf = Spanned<SelfKind>; impl Arg { pub fn to_self(&self) -> Option<ExplicitSelf> { - if let PatKind::Binding(BindByValue(mutbl), name, _) = self.pat.node { + if let PatKind::Binding(BindByValue(mutbl), _, name, _) = self.pat.node { if name.node == keywords::SelfValue.name() { return match self.ty.node { TyInfer => Some(respan(self.pat.span, SelfKind::Value(mutbl))), @@ -1241,7 +1246,7 @@ impl Arg { } pub fn is_self(&self) -> bool { - if let PatKind::Binding(_, name, _) = self.pat.node { + if let PatKind::Binding(_, _, name, _) = self.pat.node { name.node == keywords::SelfValue.name() } else { false diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs index 8e39fde367b..0190e74df69 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -8,13 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use hir::def::*; +use hir::def::Def; use hir::def_id::DefId; use hir::{self, PatKind}; -use ty::TyCtxt; use syntax::ast; use syntax::codemap::Spanned; -use syntax_pos::{Span, DUMMY_SP}; +use syntax_pos::Span; use std::iter::{Enumerate, ExactSizeIterator}; @@ -51,144 +50,144 @@ impl<T: ExactSizeIterator> EnumerateAndAdjustIterator for T { } } -pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool { - match pat.node { - PatKind::Lit(_) | - PatKind::Range(..) | - PatKind::Path(hir::QPath::Resolved(Some(..), _)) | - PatKind::Path(hir::QPath::TypeRelative(..)) => true, - - PatKind::TupleStruct(..) | - PatKind::Path(hir::QPath::Resolved(..)) | - PatKind::Struct(..) => { - match dm.get(&pat.id).map(|d| d.full_def()) { - Some(Def::Variant(..)) | Some(Def::VariantCtor(..)) => true, - _ => false +impl hir::Pat { + pub fn is_refutable(&self) -> bool { + match self.node { + PatKind::Lit(_) | + PatKind::Range(..) | + PatKind::Path(hir::QPath::Resolved(Some(..), _)) | + PatKind::Path(hir::QPath::TypeRelative(..)) => true, + + PatKind::Path(hir::QPath::Resolved(_, ref path)) | + PatKind::TupleStruct(hir::QPath::Resolved(_, ref path), ..) | + PatKind::Struct(hir::QPath::Resolved(_, ref path), ..) => { + match path.def { + Def::Variant(..) | Def::VariantCtor(..) => true, + _ => false + } } + PatKind::Slice(..) => true, + _ => false } - PatKind::Slice(..) => true, - _ => false } -} -pub fn pat_is_const(dm: &DefMap, pat: &hir::Pat) -> bool { - match pat.node { - PatKind::Path(hir::QPath::TypeRelative(..)) => true, - PatKind::Path(hir::QPath::Resolved(..)) => { - match dm.get(&pat.id).map(|d| d.full_def()) { - Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => true, - _ => false + pub fn is_const(&self) -> bool { + match self.node { + PatKind::Path(hir::QPath::TypeRelative(..)) => true, + PatKind::Path(hir::QPath::Resolved(_, ref path)) => { + match path.def { + Def::Const(..) | Def::AssociatedConst(..) => true, + _ => false + } } + _ => false } - _ => false } -} -/// Call `f` on every "binding" in a pattern, e.g., on `a` in -/// `match foo() { Some(a) => (), None => () }` -pub fn pat_bindings<F>(pat: &hir::Pat, mut f: F) - where F: FnMut(hir::BindingMode, ast::NodeId, Span, &Spanned<ast::Name>), -{ - pat.walk(|p| { - if let PatKind::Binding(binding_mode, ref pth, _) = p.node { - f(binding_mode, p.id, p.span, pth); - } - true - }); -} - -/// Checks if the pattern contains any patterns that bind something to -/// an ident, e.g. `foo`, or `Foo(foo)` or `foo @ Bar(..)`. -pub fn pat_contains_bindings(pat: &hir::Pat) -> bool { - let mut contains_bindings = false; - pat.walk(|p| { - if let PatKind::Binding(..) = p.node { - contains_bindings = true; - false // there's at least one binding, can short circuit now. - } else { + /// Call `f` on every "binding" in a pattern, e.g., on `a` in + /// `match foo() { Some(a) => (), None => () }` + pub fn each_binding<F>(&self, mut f: F) + where F: FnMut(hir::BindingMode, ast::NodeId, Span, &Spanned<ast::Name>), + { + self.walk(|p| { + if let PatKind::Binding(binding_mode, _, ref pth, _) = p.node { + f(binding_mode, p.id, p.span, pth); + } true - } - }); - contains_bindings -} + }); + } -/// Checks if the pattern contains any `ref` or `ref mut` bindings, -/// and if yes whether its containing mutable ones or just immutables ones. -pub fn pat_contains_ref_binding(pat: &hir::Pat) -> Option<hir::Mutability> { - let mut result = None; - pat_bindings(pat, |mode, _, _, _| { - if let hir::BindingMode::BindByRef(m) = mode { - // Pick Mutable as maximum - match result { - None | Some(hir::MutImmutable) => result = Some(m), - _ => (), + /// Checks if the pattern contains any patterns that bind something to + /// an ident, e.g. `foo`, or `Foo(foo)` or `foo @ Bar(..)`. + pub fn contains_bindings(&self) -> bool { + let mut contains_bindings = false; + self.walk(|p| { + if let PatKind::Binding(..) = p.node { + contains_bindings = true; + false // there's at least one binding, can short circuit now. + } else { + true } - } - }); - result -} - -/// Checks if the patterns for this arm contain any `ref` or `ref mut` -/// bindings, and if yes whether its containing mutable ones or just immutables ones. -pub fn arm_contains_ref_binding(arm: &hir::Arm) -> Option<hir::Mutability> { - arm.pats.iter() - .filter_map(|pat| pat_contains_ref_binding(pat)) - .max_by_key(|m| match *m { - hir::MutMutable => 1, - hir::MutImmutable => 0, - }) -} + }); + contains_bindings + } -/// Checks if the pattern contains any patterns that bind something to -/// an ident or wildcard, e.g. `foo`, or `Foo(_)`, `foo @ Bar(..)`, -pub fn pat_contains_bindings_or_wild(pat: &hir::Pat) -> bool { - let mut contains_bindings = false; - pat.walk(|p| { - match p.node { - PatKind::Binding(..) | PatKind::Wild => { - contains_bindings = true; - false // there's at least one binding/wildcard, can short circuit now. + /// Checks if the pattern contains any patterns that bind something to + /// an ident or wildcard, e.g. `foo`, or `Foo(_)`, `foo @ Bar(..)`, + pub fn contains_bindings_or_wild(&self) -> bool { + let mut contains_bindings = false; + self.walk(|p| { + match p.node { + PatKind::Binding(..) | PatKind::Wild => { + contains_bindings = true; + false // there's at least one binding/wildcard, can short circuit now. + } + _ => true } - _ => true - } - }); - contains_bindings -} + }); + contains_bindings + } -pub fn simple_name<'a>(pat: &'a hir::Pat) -> Option<ast::Name> { - match pat.node { - PatKind::Binding(hir::BindByValue(..), ref path1, None) => { - Some(path1.node) - } - _ => { - None + pub fn simple_name(&self) -> Option<ast::Name> { + match self.node { + PatKind::Binding(hir::BindByValue(..), _, ref path1, None) => { + Some(path1.node) + } + _ => { + None + } } } -} -pub fn def_to_path<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> hir::Path { - hir::Path::from_name(DUMMY_SP, tcx.item_name(id)) -} + /// Return variants that are necessary to exist for the pattern to match. + pub fn necessary_variants(&self) -> Vec<DefId> { + let mut variants = vec![]; + self.walk(|p| { + match p.node { + PatKind::Path(hir::QPath::Resolved(_, ref path)) | + PatKind::TupleStruct(hir::QPath::Resolved(_, ref path), ..) | + PatKind::Struct(hir::QPath::Resolved(_, ref path), ..) => { + match path.def { + Def::Variant(id) | + Def::VariantCtor(id, ..) => variants.push(id), + _ => () + } + } + _ => () + } + true + }); + variants.sort(); + variants.dedup(); + variants + } -/// Return variants that are necessary to exist for the pattern to match. -pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec<DefId> { - let mut variants = vec![]; - pat.walk(|p| { - match p.node { - PatKind::TupleStruct(..) | - PatKind::Path(hir::QPath::Resolved(..)) | - PatKind::Struct(..) => { - match dm.get(&p.id).map(|d| d.full_def()) { - Some(Def::Variant(id)) | - Some(Def::VariantCtor(id, ..)) => variants.push(id), - _ => () + /// Checks if the pattern contains any `ref` or `ref mut` bindings, + /// and if yes whether its containing mutable ones or just immutables ones. + pub fn contains_ref_binding(&self) -> Option<hir::Mutability> { + let mut result = None; + self.each_binding(|mode, _, _, _| { + if let hir::BindingMode::BindByRef(m) = mode { + // Pick Mutable as maximum + match result { + None | Some(hir::MutImmutable) => result = Some(m), + _ => (), } } - _ => () - } - true - }); - variants.sort(); - variants.dedup(); - variants + }); + result + } +} + +impl hir::Arm { + /// Checks if the patterns for this arm contain any `ref` or `ref mut` + /// bindings, and if yes whether its containing mutable ones or just immutables ones. + pub fn contains_ref_binding(&self) -> Option<hir::Mutability> { + self.pats.iter() + .filter_map(|pat| pat.contains_ref_binding()) + .max_by_key(|m| match *m { + hir::MutMutable => 1, + hir::MutImmutable => 0, + }) + } } diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 4dd08def251..49a1dc92f13 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1481,11 +1481,11 @@ impl<'a> State<'a> { hir::ExprPath(ref qpath) => { self.print_qpath(qpath, true)? } - hir::ExprBreak(opt_name, ref opt_expr) => { + hir::ExprBreak(opt_label, ref opt_expr) => { word(&mut self.s, "break")?; space(&mut self.s)?; - if let Some(name) = opt_name { - self.print_name(name.node)?; + if let Some(label) = opt_label { + self.print_name(label.name)?; space(&mut self.s)?; } if let Some(ref expr) = *opt_expr { @@ -1493,11 +1493,11 @@ impl<'a> State<'a> { space(&mut self.s)?; } } - hir::ExprAgain(opt_name) => { + hir::ExprAgain(opt_label) => { word(&mut self.s, "continue")?; space(&mut self.s)?; - if let Some(name) = opt_name { - self.print_name(name.node)?; + if let Some(label) = opt_label { + self.print_name(label.name)?; space(&mut self.s)? } } @@ -1782,7 +1782,7 @@ impl<'a> State<'a> { // is that it doesn't matter match pat.node { PatKind::Wild => word(&mut self.s, "_")?, - PatKind::Binding(binding_mode, ref path1, ref sub) => { + PatKind::Binding(binding_mode, _, ref path1, ref sub) => { match binding_mode { hir::BindByRef(mutbl) => { self.word_nbsp("ref")?; @@ -2185,7 +2185,7 @@ impl<'a> State<'a> { if let Some(eself) = input.to_self() { self.print_explicit_self(&eself)?; } else { - let invalid = if let PatKind::Binding(_, name, _) = input.pat.node { + let invalid = if let PatKind::Binding(_, _, name, _) = input.pat.node { name.node == keywords::Invalid.name() } else { false diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index 406d345992a..90d752ae6ee 100644 --- a/src/librustc/infer/error_reporting.rs +++ b/src/librustc/infer/error_reporting.rs @@ -1441,7 +1441,7 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> { ty_queue.push(&mut_ty.ty); } hir::TyPath(hir::QPath::Resolved(ref maybe_qself, ref path)) => { - match self.tcx.expect_def(cur_ty.id) { + match path.def { Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) | Def::Union(did) => { let generics = self.tcx.item_generics(did); @@ -1621,6 +1621,7 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> { hir::Path { span: path.span, global: path.global, + def: path.def, segments: new_segs.into() } } diff --git a/src/librustc/middle/astconv_util.rs b/src/librustc/middle/astconv_util.rs index 5b0f241f8a8..3418034b069 100644 --- a/src/librustc/middle/astconv_util.rs +++ b/src/librustc/middle/astconv_util.rs @@ -71,7 +71,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// to it. pub fn ast_ty_to_prim_ty(self, ast_ty: &hir::Ty) -> Option<Ty<'tcx>> { if let hir::TyPath(hir::QPath::Resolved(None, ref path)) = ast_ty.node { - if let Def::PrimTy(nty) = self.expect_def(ast_ty.id) { + if let Def::PrimTy(nty) = path.def { 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 ec064e264ab..618e2b05f13 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -14,7 +14,7 @@ use dep_graph::DepNode; use hir::map as ast_map; -use hir::{self, pat_util, PatKind}; +use hir::{self, PatKind}; use hir::intravisit::{self, Visitor}; use hir::itemlikevisit::ItemLikeVisitor; @@ -86,9 +86,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } } - fn lookup_and_handle_definition(&mut self, id: ast::NodeId) { - let def = self.tcx.expect_def(id); - + fn handle_definition(&mut self, id: ast::NodeId, def: Def) { // If `bar` is a trait item, make sure to mark Foo as alive in `Foo::bar` match def { Def::AssociatedTy(..) | Def::Method(_) | Def::AssociatedConst(_) @@ -147,12 +145,10 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } } - fn handle_field_pattern_match(&mut self, lhs: &hir::Pat, + fn handle_field_pattern_match(&mut self, lhs: &hir::Pat, def: Def, pats: &[codemap::Spanned<hir::FieldPat>]) { let variant = match self.tcx.tables().node_id_to_type(lhs.id).sty { - ty::TyAdt(adt, _) => { - adt.variant_of_def(self.tcx.expect_def(lhs.id)) - } + ty::TyAdt(adt, _) => adt.variant_of_def(def), _ => span_bug!(lhs.span, "non-ADT in struct pattern") }; for pat in pats { @@ -240,8 +236,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> { fn visit_expr(&mut self, expr: &hir::Expr) { match expr.node { - hir::ExprPath(hir::QPath::TypeRelative(..)) => { - self.lookup_and_handle_definition(expr.id); + hir::ExprPath(ref qpath @ hir::QPath::TypeRelative(..)) => { + let def = self.tcx.tables().qpath_def(qpath, expr.id); + self.handle_definition(expr.id, def); } hir::ExprMethodCall(..) => { self.lookup_and_handle_method(expr.id); @@ -260,8 +257,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> { fn visit_arm(&mut self, arm: &hir::Arm) { if arm.pats.len() == 1 { - let pat = &*arm.pats[0]; - let variants = pat_util::necessary_variants(&self.tcx.def_map.borrow(), pat); + let variants = arm.pats[0].necessary_variants(); // Inside the body, ignore constructions of variants // necessary for the pattern to match. Those construction sites @@ -276,14 +272,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> { } fn visit_pat(&mut self, pat: &hir::Pat) { - let def_map = &self.tcx.def_map; match pat.node { - PatKind::Struct(_, ref fields, _) => { - self.handle_field_pattern_match(pat, fields); + PatKind::Struct(hir::QPath::Resolved(_, ref path), ref fields, _) => { + self.handle_field_pattern_match(pat, path.def, fields); } - _ 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) + PatKind::Path(ref qpath @ hir::QPath::TypeRelative(..)) => { + let def = self.tcx.tables().qpath_def(qpath, pat.id); + self.handle_definition(pat.id, def); } _ => () } @@ -294,7 +289,7 @@ 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.handle_definition(id, path.def); intravisit::walk_path(self, path); } } diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index 2892f249c5e..ad3607a5bb8 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -186,8 +186,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { hir::ExprInlineAsm(..) => { self.require_unsafe(expr.span, "use of inline assembly"); } - hir::ExprPath(hir::QPath::Resolved(..)) => { - if let Def::Static(def_id, mutbl) = self.tcx.expect_def(expr.id) { + hir::ExprPath(hir::QPath::Resolved(_, ref path)) => { + if let Def::Static(def_id, mutbl) = path.def { if mutbl { self.require_unsafe(expr.span, "use of mutable static"); } else if match self.tcx.map.get_if_local(def_id) { diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 6c952825554..01d5792441f 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -19,7 +19,6 @@ pub use self::MatchMode::*; use self::TrackMatchMode::*; use self::OverloadedCallType::*; -use hir::pat_util; use hir::def::Def; use hir::def_id::{DefId}; use infer::InferCtxt; @@ -622,7 +621,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { match local.init { None => { let delegate = &mut self.delegate; - pat_util::pat_bindings(&local.pat, |_, id, span, _| { + local.pat.each_binding(|_, id, span, _| { delegate.decl_without_init(id, span); }) } @@ -957,7 +956,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { let infcx = self.mc.infcx; let delegate = &mut self.delegate; return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |mc, cmt_pat, pat| { - if let PatKind::Binding(bmode, ..) = pat.node { + if let PatKind::Binding(bmode, def_id, ..) = pat.node { debug!("binding cmt_pat={:?} pat={:?} match_mode={:?}", cmt_pat, pat, match_mode); // pat_ty: the type of the binding being produced. @@ -965,8 +964,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { // Each match binding is effectively an assignment to the // binding being produced. - if let Ok(binding_cmt) = mc.cat_def(pat.id, pat.span, pat_ty, - tcx.expect_def(pat.id)) { + let def = Def::Local(def_id); + if let Ok(binding_cmt) = mc.cat_def(pat.id, pat.span, pat_ty, def) { delegate.mutate(pat.id, pat.span, binding_cmt, MutateMode::Init); } @@ -992,9 +991,16 @@ 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| { - match tcx.expect_def_or_none(pat.id) { - Some(Def::Variant(variant_did)) | - Some(Def::VariantCtor(variant_did, ..)) => { + let qpath = match pat.node { + PatKind::Path(ref qpath) | + PatKind::TupleStruct(ref qpath, ..) | + PatKind::Struct(ref qpath, ..) => qpath, + _ => return + }; + let def = tcx.tables().qpath_def(qpath, pat.id); + match def { + Def::Variant(variant_did) | + Def::VariantCtor(variant_did, ..) => { let enum_did = tcx.parent_def_id(variant_did).unwrap(); let downcast_cmt = if tcx.lookup_adt_def(enum_did).is_univariant() { cmt_pat @@ -1006,14 +1012,12 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { debug!("variant downcast_cmt={:?} pat={:?}", downcast_cmt, pat); delegate.matched_pat(pat, downcast_cmt, match_mode); } - Some(Def::Struct(..)) | Some(Def::StructCtor(..)) | Some(Def::Union(..)) | - Some(Def::TyAlias(..)) | Some(Def::AssociatedTy(..)) | Some(Def::SelfTy(..)) => { + Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) | + Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => { debug!("struct cmt_pat={:?} pat={:?}", cmt_pat, pat); delegate.matched_pat(pat, cmt_pat, match_mode); } - None | Some(Def::Local(..)) | - Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => {} - def => bug!("unexpected definition: {:?}", def) + _ => {} } })); } diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index c610c6f75b0..0014d17abb7 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -160,11 +160,10 @@ 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) { - let def = match expr.node { - hir::ExprPath(_) => { - self.infcx.tcx.expect_def(expr.id) - } - _ => Def::Err + let def = if let hir::ExprPath(ref qpath) = expr.node { + self.infcx.tcx.tables().qpath_def(qpath, expr.id) + } else { + Def::Err }; match def { Def::Fn(did) if self.def_id_is_transmute(did) => { diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index eefed0a5a74..eb00238492e 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -111,7 +111,6 @@ use self::VarKind::*; use dep_graph::DepNode; use hir::def::*; -use hir::pat_util; use ty::{self, TyCtxt, ParameterEnvironment}; use traits::{self, Reveal}; use ty::subst::Subst; @@ -379,7 +378,7 @@ fn visit_fn(ir: &mut IrMaps, debug!("creating fn_maps: {:?}", &fn_maps as *const IrMaps); for arg in &decl.inputs { - pat_util::pat_bindings(&arg.pat, |_bm, arg_id, _x, path1| { + arg.pat.each_binding(|_bm, arg_id, _x, path1| { debug!("adding argument {}", arg_id); let name = path1.node; fn_maps.add_variable(Arg(arg_id, name)); @@ -412,7 +411,7 @@ fn visit_fn(ir: &mut IrMaps, } fn visit_local(ir: &mut IrMaps, local: &hir::Local) { - pat_util::pat_bindings(&local.pat, |_, p_id, sp, path1| { + local.pat.each_binding(|_, p_id, sp, path1| { debug!("adding local variable {}", p_id); let name = path1.node; ir.add_live_node_for_node(p_id, VarDefNode(sp)); @@ -426,7 +425,7 @@ fn visit_local(ir: &mut IrMaps, local: &hir::Local) { fn visit_arm(ir: &mut IrMaps, arm: &hir::Arm) { for pat in &arm.pats { - pat_util::pat_bindings(&pat, |bm, p_id, sp, path1| { + pat.each_binding(|bm, p_id, sp, path1| { debug!("adding local variable {} from match with bm {:?}", p_id, bm); let name = path1.node; @@ -443,10 +442,9 @@ fn visit_arm(ir: &mut IrMaps, arm: &hir::Arm) { 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.expect_def(expr.id); - debug!("expr {}: path that leads to {:?}", expr.id, def); - if let Def::Local(..) = def { + hir::ExprPath(hir::QPath::Resolved(_, ref path)) => { + debug!("expr {}: path that leads to {:?}", expr.id, path.def); + if let Def::Local(..) = path.def { ir.add_live_node_for_node(expr.id, ExprNode(expr.span)); } intravisit::walk_expr(ir, expr); @@ -495,7 +493,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) { hir::ExprBlock(..) | hir::ExprAssign(..) | hir::ExprAssignOp(..) | hir::ExprStruct(..) | hir::ExprRepeat(..) | hir::ExprInlineAsm(..) | hir::ExprBox(..) | - hir::ExprType(..) => { + hir::ExprType(..) | hir::ExprPath(hir::QPath::TypeRelative(..)) => { intravisit::walk_expr(ir, expr); } } @@ -587,7 +585,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn pat_bindings<F>(&mut self, pat: &hir::Pat, mut f: F) where F: FnMut(&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId), { - pat_util::pat_bindings(pat, |_bm, p_id, sp, _n| { + pat.each_binding(|_bm, p_id, sp, _n| { let ln = self.live_node(p_id, sp); let var = self.variable(p_id, sp); f(self, ln, var, sp, p_id); @@ -684,22 +682,13 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } fn find_loop_scope(&self, - opt_label: Option<ast::Name>, - id: NodeId, + opt_label: Option<hir::Label>, sp: Span) -> NodeId { match opt_label { - Some(_) => { - // Refers to a labeled loop. Use the results of resolve - // to find with one - 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") - } - } + Some(label) => label.loop_id, None => { - // Vanilla 'break' or 'loop', so use the enclosing + // Vanilla 'break' or 'continue', so use the enclosing // loop scope if self.loop_scope.is_empty() { span_bug!(sp, "break outside loop"); @@ -922,8 +911,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { match expr.node { // Interesting cases with control flow or which gen/kill - hir::ExprPath(hir::QPath::Resolved(..)) => { - self.access_path(expr, succ, ACC_READ | ACC_USE) + hir::ExprPath(hir::QPath::Resolved(_, ref path)) => { + self.access_path(expr.id, path, succ, ACC_READ | ACC_USE) } hir::ExprField(ref e, _) => { @@ -1037,7 +1026,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { hir::ExprBreak(opt_label, ref opt_expr) => { // Find which label this break jumps to - let sc = self.find_loop_scope(opt_label.map(|l| l.node), expr.id, expr.span); + let sc = self.find_loop_scope(opt_label, expr.span); // Now that we know the label we're going to, // look it up in the break loop nodes table @@ -1050,7 +1039,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { hir::ExprAgain(opt_label) => { // Find which label this expr continues to - let sc = self.find_loop_scope(opt_label.map(|l| l.node), expr.id, expr.span); + let sc = self.find_loop_scope(opt_label, expr.span); // Now that we know the label we're going to, // look it up in the continue loop nodes table @@ -1246,8 +1235,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: u32) -> LiveNode { match expr.node { - hir::ExprPath(hir::QPath::Resolved(..)) => { - self.access_path(expr, succ, acc) + hir::ExprPath(hir::QPath::Resolved(_, ref path)) => { + self.access_path(expr.id, path, succ, acc) } // We do not track other lvalues, so just propagate through @@ -1258,15 +1247,15 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } } - fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: u32) + fn access_path(&mut self, id: NodeId, path: &hir::Path, succ: LiveNode, acc: u32) -> LiveNode { - match self.ir.tcx.expect_def(expr.id) { + match path.def { Def::Local(def_id) => { let nid = self.ir.tcx.map.as_local_node_id(def_id).unwrap(); - let ln = self.live_node(expr.id, expr.span); + let ln = self.live_node(id, path.span); if acc != 0 { self.init_from_succ(ln, succ); - let var = self.variable(nid, expr.span); + let var = self.variable(nid, path.span); self.acc(ln, var, acc); } ln @@ -1482,8 +1471,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn check_lvalue(&mut self, expr: &Expr) { match expr.node { - hir::ExprPath(hir::QPath::Resolved(..)) => { - if let Def::Local(def_id) = self.ir.tcx.expect_def(expr.id) { + hir::ExprPath(hir::QPath::Resolved(_, ref path)) => { + if let Def::Local(def_id) = path.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 @@ -1513,7 +1502,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn warn_about_unused_args(&self, decl: &hir::FnDecl, entry_ln: LiveNode) { for arg in &decl.inputs { - pat_util::pat_bindings(&arg.pat, |_bm, p_id, sp, path1| { + arg.pat.each_binding(|_bm, p_id, sp, path1| { let var = self.variable(p_id, sp); // Ignore unused self. let name = path1.node; diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 1ca078dcd2e..b9542d6fc5c 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -488,8 +488,9 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { } } - hir::ExprPath(_) => { - self.cat_def(expr.id, expr.span, expr_ty, self.tcx().expect_def(expr.id)) + hir::ExprPath(ref qpath) => { + let def = self.tcx().tables().qpath_def(qpath, expr.id); + self.cat_def(expr.id, expr.span, expr_ty, def) } hir::ExprType(ref e, _) => { @@ -1062,24 +1063,32 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // Note: This goes up here (rather than within the PatKind::TupleStruct arm // alone) because PatKind::Struct can also refer to variants. - let cmt = match self.tcx().expect_def_or_none(pat.id) { - Some(Def::Err) => return Err(()), - Some(Def::Variant(variant_did)) | - Some(Def::VariantCtor(variant_did, ..)) => { - // univariant enums do not need downcasts - let enum_did = self.tcx().parent_def_id(variant_did).unwrap(); - if !self.tcx().lookup_adt_def(enum_did).is_univariant() { - self.cat_downcast(pat, cmt.clone(), cmt.ty, variant_did) - } else { - cmt + let cmt = match pat.node { + PatKind::Path(hir::QPath::Resolved(_, ref path)) | + PatKind::TupleStruct(hir::QPath::Resolved(_, ref path), ..) | + PatKind::Struct(hir::QPath::Resolved(_, ref path), ..) => { + match path.def { + Def::Err => return Err(()), + Def::Variant(variant_did) | + Def::VariantCtor(variant_did, ..) => { + // univariant enums do not need downcasts + let enum_did = self.tcx().parent_def_id(variant_did).unwrap(); + if !self.tcx().lookup_adt_def(enum_did).is_univariant() { + self.cat_downcast(pat, cmt.clone(), cmt.ty, variant_did) + } else { + cmt + } + } + _ => cmt } } _ => cmt }; match pat.node { - PatKind::TupleStruct(_, ref subpats, ddpos) => { - let expected_len = match self.tcx().expect_def(pat.id) { + PatKind::TupleStruct(ref qpath, ref subpats, ddpos) => { + let def = self.tcx().tables().qpath_def(qpath, pat.id); + let expected_len = match def { Def::VariantCtor(def_id, CtorKind::Fn) => { let enum_def = self.tcx().parent_def_id(def_id).unwrap(); self.tcx().lookup_adt_def(enum_def).variant_with_id(def_id).fields.len() diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 91c1c63d890..e9b731ebaf2 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -90,45 +90,40 @@ struct ReachableContext<'a, 'tcx: 'a> { 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 = 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) { - self.worklist.push(node_id); - } else { - match def { - // If this path leads to a constant, then we need to - // recurse into the constant to continue finding - // items that are reachable. - Def::Const(..) | Def::AssociatedConst(..) => { - self.worklist.push(node_id); - } - - // If this wasn't a static, then the destination is - // surely reachable. - _ => { - self.reachable_symbols.insert(node_id); - } - } - } - } + let def = match expr.node { + hir::ExprPath(ref qpath) => { + Some(self.tcx.tables().qpath_def(qpath, expr.id)) } hir::ExprMethodCall(..) => { let method_call = ty::MethodCall::expr(expr.id); - let def_id = self.tcx.tables().method_map[&method_call].def_id; + let def_id = self.tcx.tables.borrow().method_map[&method_call].def_id; + Some(Def::Method(def_id)) + } + _ => None + }; + + if let Some(def) = def { + 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) { + self.worklist.push(node_id); + } else { + match def { + // If this path leads to a constant, then we need to + // recurse into the constant to continue finding + // items that are reachable. + Def::Const(..) | Def::AssociatedConst(..) => { + self.worklist.push(node_id); + } - // Mark the trait item (and, possibly, its default impl) as reachable - // Or mark inherent impl item as reachable - if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) { - if self.def_id_represents_local_inlined_item(def_id) { - self.worklist.push(node_id) + // If this wasn't a static, then the destination is + // surely reachable. + _ => { + self.reachable_symbols.insert(node_id); + } } - self.reachable_symbols.insert(node_id); } } - _ => {} } intravisit::walk_expr(self, expr) diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index f256d6d9b4f..d07062f98a9 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -21,7 +21,7 @@ use self::ScopeChain::*; use dep_graph::DepNode; use hir::map::Map; use session::Session; -use hir::def::{Def, DefMap}; +use hir::def::Def; use hir::def_id::DefId; use middle::region; use ty; @@ -65,7 +65,6 @@ struct LifetimeContext<'a, 'tcx: 'a> { hir_map: &'a Map<'tcx>, map: &'a mut NamedRegionMap, scope: Scope<'a>, - def_map: &'a DefMap, // Deep breath. Our representation for poly trait refs contains a single // binder and thus we only allow a single level of quantification. However, // the syntax of Rust permits quantification in two places, e.g., `T: for <'a> Foo<'a>` @@ -109,8 +108,7 @@ type Scope<'a> = &'a ScopeChain<'a>; static ROOT_SCOPE: ScopeChain<'static> = RootScope; pub fn krate(sess: &Session, - hir_map: &Map, - def_map: &DefMap) + hir_map: &Map) -> Result<NamedRegionMap, usize> { let _task = hir_map.dep_graph.in_task(DepNode::ResolveLifetimes); let krate = hir_map.krate(); @@ -124,7 +122,6 @@ pub fn krate(sess: &Session, hir_map: hir_map, map: &mut map, scope: &ROOT_SCOPE, - def_map: def_map, trait_ref_hack: false, labels_in_fn: vec![], }, krate); @@ -247,8 +244,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { hir::TyPath(hir::QPath::Resolved(None, 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.get(&ty.id).map(|d| (d.base_def, d.depth)) { - Some((Def::Trait(..), 0)) => { + match path.def { + Def::Trait(..) => { self.with(LateScope(&[], self.scope), |_, this| { this.visit_path(path, ty.id); }); @@ -541,7 +538,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { hir_map: hir_map, map: *map, scope: &wrap_scope, - def_map: self.def_map, trait_ref_hack: self.trait_ref_hack, labels_in_fn: self.labels_in_fn.clone(), }; diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index d7a29e190a8..29af505f9dc 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -468,8 +468,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { intravisit::walk_expr(self, ex); } - fn visit_path(&mut self, path: &'tcx hir::Path, id: ast::NodeId) { - check_path(self.tcx, path, id, + fn visit_path(&mut self, path: &'tcx hir::Path, _: ast::NodeId) { + check_path(self.tcx, path, &mut |id, sp, stab, depr| self.check(id, sp, stab, depr)); intravisit::walk_path(self, path) } @@ -526,7 +526,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_item_refs) => { - let trait_did = tcx.expect_def(t.ref_id).def_id(); + let trait_did = t.path.def.def_id(); for impl_item_ref in impl_item_refs { let impl_item = tcx.map.impl_item(impl_item_ref.id); let item = tcx.associated_items(trait_did) @@ -553,9 +553,9 @@ pub fn check_expr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, e: &hir::Expr, let method_call = ty::MethodCall::expr(e.id); tcx.tables().method_map[&method_call].def_id } - hir::ExprPath(hir::QPath::TypeRelative(..)) => { + hir::ExprPath(ref qpath @ hir::QPath::TypeRelative(..)) => { span = e.span; - tcx.expect_def(e.id).def_id() + tcx.tables().qpath_def(qpath, e.id).def_id() } hir::ExprField(ref base_e, ref field) => { span = field.span; @@ -611,14 +611,13 @@ pub fn check_expr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, e: &hir::Expr, } pub fn check_path<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - path: &hir::Path, id: ast::NodeId, + path: &hir::Path, cb: &mut FnMut(DefId, Span, &Option<&Stability>, &Option<DeprecationEntry>)) { - // Paths in import prefixes may have no resolution. - match tcx.expect_def_or_none(id) { - None | Some(Def::PrimTy(..)) | Some(Def::SelfTy(..)) => {} - Some(def) => maybe_do_stability_check(tcx, def.def_id(), path.span, cb) + match path.def { + Def::PrimTy(..) | Def::SelfTy(..) | Def::Err => {} + _ => maybe_do_stability_check(tcx, path.def.def_id(), path.span, cb) } } @@ -629,8 +628,8 @@ pub fn check_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat: &hir::Pat, debug!("check_pat(pat = {:?})", pat); if is_internal(tcx, pat.span) { return; } - if let PatKind::Path(hir::QPath::TypeRelative(..)) = pat.node { - let def_id = tcx.expect_def(pat.id).def_id(); + if let PatKind::Path(ref qpath @ hir::QPath::TypeRelative(..)) = pat.node { + let def_id = tcx.tables().qpath_def(qpath, pat.id).def_id(); maybe_do_stability_check(tcx, def_id, pat.span, cb) } @@ -665,7 +664,7 @@ pub fn check_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: &hir::Ty, if is_internal(tcx, ty.span) { return; } if let hir::TyPath(hir::QPath::TypeRelative(..)) = ty.node { - let def_id = tcx.expect_def(ty.id).def_id(); + let def_id = tcx.tables().type_relative_path_defs[&ty.id].def_id(); maybe_do_stability_check(tcx, def_id, ty.span, cb); } } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 20855c46b68..ea81c85ba6a 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -14,7 +14,7 @@ use dep_graph::{DepGraph, DepTrackingMap}; use session::Session; use middle; use hir::TraitMap; -use hir::def::DefMap; +use hir::def::Def; use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE}; use hir::map as ast_map; use hir::map::{DefKey, DefPathData, DisambiguatedDefPathData}; @@ -201,6 +201,9 @@ pub struct CommonTypes<'tcx> { } pub struct Tables<'tcx> { + /// Resolved definitions for `<T>::X` associated paths. + pub type_relative_path_defs: NodeMap<Def>, + /// Stores the types for various nodes in the AST. Note that this table /// is not guaranteed to be populated until after typeck. See /// typeck::check::fn_ctxt for details. @@ -244,6 +247,7 @@ pub struct Tables<'tcx> { impl<'a, 'gcx, 'tcx> Tables<'tcx> { pub fn empty() -> Tables<'tcx> { Tables { + type_relative_path_defs: NodeMap(), node_types: FxHashMap(), item_substs: NodeMap(), adjustments: NodeMap(), @@ -256,6 +260,16 @@ impl<'a, 'gcx, 'tcx> Tables<'tcx> { } } + /// Returns the final resolution of a `QPath` in an `Expr` or `Pat` node. + pub fn qpath_def(&self, qpath: &hir::QPath, id: NodeId) -> Def { + match *qpath { + hir::QPath::Resolved(_, ref path) => path.def, + hir::QPath::TypeRelative(..) => { + self.type_relative_path_defs.get(&id).cloned().unwrap_or(Def::Err) + } + } + } + pub fn node_id_to_type(&self, id: NodeId) -> Ty<'tcx> { match self.node_id_to_type_opt(id) { Some(ty) => ty, @@ -379,11 +393,6 @@ pub struct GlobalCtxt<'tcx> { pub sess: &'tcx Session, - /// Map from path id to the results from resolve; generated - /// initially by resolve and updated during typeck in some cases - /// (e.g., UFCS paths) - pub def_map: RefCell<DefMap>, - /// Map indicating what traits are in scope for places where this /// is relevant; generated by resolve. pub trait_map: TraitMap, @@ -768,7 +777,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// reference to the context, to allow formatting values that need it. pub fn create_and_enter<F, R>(s: &'tcx Session, arenas: &'tcx CtxtArenas<'tcx>, - def_map: DefMap, trait_map: TraitMap, named_region_map: resolve_lifetime::NamedRegionMap, map: ast_map::Map<'tcx>, @@ -797,7 +805,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { item_variance_map: RefCell::new(DepTrackingMap::new(dep_graph.clone())), variance_computed: Cell::new(false), sess: s, - def_map: RefCell::new(def_map), trait_map: trait_map, tables: RefCell::new(Tables::empty()), impl_trait_refs: RefCell::new(DepTrackingMap::new(dep_graph.clone())), diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 3d02ff4651f..ee7cf0788e5 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -19,7 +19,7 @@ pub use self::fold::TypeFoldable; use dep_graph::{self, DepNode}; use hir::map as ast_map; use middle; -use hir::def::{Def, CtorKind, PathResolution, ExportMap}; +use hir::def::{Def, CtorKind, ExportMap}; use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; use middle::region::{CodeExtent, ROOT_CODE_EXTENT}; @@ -247,7 +247,7 @@ impl Visibility { match *visibility { hir::Public => Visibility::Public, hir::Visibility::Crate => Visibility::Restricted(ast::CRATE_NODE_ID), - hir::Visibility::Restricted { id, .. } => match tcx.expect_def(id) { + hir::Visibility::Restricted { ref path, .. } => match path.def { // 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. Def::Err => Visibility::Public, @@ -2047,7 +2047,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { match self.map.find(id) { Some(ast_map::NodeLocal(pat)) => { match pat.node { - hir::PatKind::Binding(_, ref path1, _) => path1.node.as_str(), + hir::PatKind::Binding(_, _, ref path1, _) => path1.node.as_str(), _ => { bug!("Variable id {} maps to {:?}, not local", id, pat); }, @@ -2059,8 +2059,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn expr_is_lval(self, expr: &hir::Expr) -> bool { match expr.node { - hir::ExprPath(hir::QPath::Resolved(..)) => { - match self.expect_def(expr.id) { + hir::ExprPath(hir::QPath::Resolved(_, ref path)) => { + match path.def { Def::Local(..) | Def::Upvar(..) | Def::Static(..) | Def::Err => true, _ => false, } @@ -2298,22 +2298,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { || self.sess.cstore.impl_trait_ref(self.global_tcx(), 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<Def> { - self.def_map.borrow().get(&id).map(|resolution| resolution.full_def()) - } - // Returns `ty::VariantDef` if `def` refers to a struct, // or variant or their constructors, panics otherwise. pub fn expect_variant_def(self, def: Def) -> VariantDef<'tcx> { diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 7d3e380a3b5..1dde8106ec6 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -14,7 +14,6 @@ use hir::def_id::DefId; use hir::map::DefPathData; use infer::InferCtxt; use hir::map as ast_map; -use hir::pat_util; use traits::{self, Reveal}; use ty::{self, Ty, AdtKind, TyCtxt, TypeAndMut, TypeFlags, TypeFoldable}; use ty::{Disr, ParameterEnvironment}; @@ -180,14 +179,6 @@ impl<'tcx> ParameterEnvironment<'tcx> { } impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { - pub fn pat_contains_ref_binding(self, pat: &hir::Pat) -> Option<hir::Mutability> { - pat_util::pat_contains_ref_binding(pat) - } - - pub fn arm_contains_ref_binding(self, arm: &hir::Arm) -> Option<hir::Mutability> { - pat_util::arm_contains_ref_binding(arm) - } - pub fn has_error_field(self, ty: Ty<'tcx>) -> bool { match ty.sty { ty::TyAdt(def, substs) => { diff --git a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs index 51574868f9b..2c277c04a52 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs @@ -98,7 +98,7 @@ pub fn gather_move_from_pat<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, move_pat: &hir::Pat, cmt: mc::cmt<'tcx>) { let pat_span_path_opt = match move_pat.node { - PatKind::Binding(_, ref path1, _) => { + PatKind::Binding(_, _, ref path1, _) => { Some(MoveSpanAndPath{span: move_pat.span, name: path1.node}) }, diff --git a/src/librustc_const_eval/_match.rs b/src/librustc_const_eval/_match.rs index 4731cea0206..db24ad0fd67 100644 --- a/src/librustc_const_eval/_match.rs +++ b/src/librustc_const_eval/_match.rs @@ -23,8 +23,8 @@ use rustc_data_structures::indexed_vec::Idx; use pattern::{FieldPattern, Pattern, PatternKind}; use pattern::{PatternFoldable, PatternFolder}; -use rustc::hir::def_id::{DefId}; -use rustc::hir::pat_util::def_to_path; +use rustc::hir::def::Def; +use rustc::hir::def_id::DefId; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::hir; @@ -324,7 +324,12 @@ impl Witness { ty::TyAdt(adt, _) => { let v = ctor.variant_for_adt(adt); - let qpath = hir::QPath::Resolved(None, P(def_to_path(cx.tcx, v.did))); + let qpath = hir::QPath::Resolved(None, P(hir::Path { + span: DUMMY_SP, + global: false, + def: Def::Err, + segments: vec![hir::PathSegment::from_name(v.name)].into(), + })); match v.ctor_kind { CtorKind::Fictive => { let field_pats: hir::HirVec<_> = v.fields.iter() diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 3c94d7d6fd5..b67c2c8ec9c 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -19,8 +19,6 @@ use eval::report_const_eval_err; use rustc::dep_graph::DepNode; -use rustc::hir::pat_util::{pat_bindings, pat_contains_bindings}; - use rustc::middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor}; use rustc::middle::expr_use_visitor::{LoanCause, MutateMode}; use rustc::middle::expr_use_visitor as euv; @@ -262,26 +260,22 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { fn check_for_bindings_named_the_same_as_variants(cx: &MatchVisitor, pat: &Pat) { pat.walk(|p| { - if let PatKind::Binding(hir::BindByValue(hir::MutImmutable), name, None) = p.node { + if let PatKind::Binding(hir::BindByValue(hir::MutImmutable), _, name, None) = p.node { let pat_ty = cx.tcx.tables().pat_ty(p); if let ty::TyAdt(edef, _) = pat_ty.sty { - if edef.is_enum() { - if let Def::Local(..) = cx.tcx.expect_def(p.id) { - if edef.variants.iter().any(|variant| { - variant.name == name.node && variant.ctor_kind == CtorKind::Const - }) { - let ty_path = cx.tcx.item_path_str(edef.did); - let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170, - "pattern binding `{}` is named the same as one \ - of the variants of the type `{}`", - name.node, ty_path); - help!(err, - "if you meant to match on a variant, \ - consider making the path in the pattern qualified: `{}::{}`", - ty_path, name.node); - err.emit(); - } - } + if edef.is_enum() && edef.variants.iter().any(|variant| { + variant.name == name.node && variant.ctor_kind == CtorKind::Const + }) { + let ty_path = cx.tcx.item_path_str(edef.did); + let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170, + "pattern binding `{}` is named the same as one \ + of the variants of the type `{}`", + name.node, ty_path); + help!(err, + "if you meant to match on a variant, \ + consider making the path in the pattern qualified: `{}::{}`", + ty_path, name.node); + err.emit(); } } } @@ -290,13 +284,13 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchVisitor, pat: &Pat) { } /// Checks for common cases of "catchall" patterns that may not be intended as such. -fn pat_is_catchall(dm: &DefMap, pat: &Pat) -> bool { +fn pat_is_catchall(pat: &Pat) -> bool { match pat.node { PatKind::Binding(.., None) => true, - PatKind::Binding(.., Some(ref s)) => pat_is_catchall(dm, s), - PatKind::Ref(ref s, _) => pat_is_catchall(dm, s), + PatKind::Binding(.., Some(ref s)) => pat_is_catchall(s), + PatKind::Ref(ref s, _) => pat_is_catchall(s), PatKind::Tuple(ref v, _) => v.iter().all(|p| { - pat_is_catchall(dm, &p) + pat_is_catchall(&p) }), _ => false } @@ -374,7 +368,7 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>, } if guard.is_none() { seen.push(v); - if catchall.is_none() && pat_is_catchall(&cx.tcx.def_map.borrow(), hir_pat) { + if catchall.is_none() && pat_is_catchall(hir_pat) { catchall = Some(pat.span); } } @@ -454,7 +448,7 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, pats: &[P<Pat>]) { let mut by_ref_span = None; for pat in pats { - pat_bindings(&pat, |bm, _, span, _path| { + pat.each_binding(|bm, _, span, _path| { if let hir::BindByRef(..) = bm { by_ref_span = Some(span); } @@ -465,7 +459,7 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, // check legality of moving out of the enum // x @ Foo(..) is legal, but x @ Foo(y) isn't. - if sub.map_or(false, |p| pat_contains_bindings(&p)) { + if sub.map_or(false, |p| p.contains_bindings()) { struct_span_err!(cx.tcx.sess, p.span, E0007, "cannot bind by-move with sub-bindings") .span_label(p.span, &format!("binds an already bound by-move value by moving it")) @@ -486,7 +480,7 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, for pat in pats { pat.walk(|p| { - if let PatKind::Binding(hir::BindByValue(..), _, ref sub) = p.node { + if let PatKind::Binding(hir::BindByValue(..), _, _, ref sub) = p.node { let pat_ty = cx.tcx.tables().node_id_to_type(p.id); if pat_ty.moves_by_default(cx.tcx, cx.param_env, pat.span) { check_move(p, sub.as_ref().map(|p| &**p)); diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index e8c05ec1a35..053d3072ddf 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -19,9 +19,8 @@ use rustc::hir::map as ast_map; use rustc::hir::map::blocks::FnLikeNode; use rustc::middle::cstore::InlinedItem; use rustc::traits; -use rustc::hir::def::{Def, CtorKind, PathResolution}; +use rustc::hir::def::{Def, CtorKind}; use rustc::hir::def_id::DefId; -use rustc::hir::pat_util::def_to_path; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::util::IntTypeExt; use rustc::ty::subst::Substs; @@ -42,7 +41,6 @@ use syntax_pos::{self, Span}; use std::borrow::Cow; use std::cmp::Ordering; -use std::collections::hash_map::Entry::Vacant; use rustc_const_math::*; use rustc_errors::DiagnosticBuilder; @@ -282,26 +280,34 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, .collect::<Result<_, _>>()?, None), hir::ExprCall(ref callee, ref args) => { - let def = tcx.expect_def(callee.id); - if let Vacant(entry) = tcx.def_map.borrow_mut().entry(expr.id) { - entry.insert(PathResolution::new(def)); - } - let qpath = match def { - Def::StructCtor(def_id, CtorKind::Fn) | - Def::VariantCtor(def_id, CtorKind::Fn) => { - hir::QPath::Resolved(None, P(def_to_path(tcx, def_id))) - } - Def::Fn(..) | Def::Method(..) => return Ok(P(hir::Pat { - id: expr.id, - node: PatKind::Lit(P(expr.clone())), - span: span, - })), + let qpath = match callee.node { + hir::ExprPath(ref qpath) => qpath, _ => bug!() }; - let pats = args.iter() - .map(|expr| const_expr_to_pat(tcx, &*expr, pat_id, span)) - .collect::<Result<_, _>>()?; - PatKind::TupleStruct(qpath, pats, None) + let def = tcx.tables().qpath_def(qpath, callee.id); + let ctor_path = if let hir::QPath::Resolved(_, ref path) = *qpath { + match def { + Def::StructCtor(_, CtorKind::Fn) | + Def::VariantCtor(_, CtorKind::Fn) => { + Some(path.clone()) + } + _ => None + } + } else { + None + }; + match (def, ctor_path) { + (Def::Fn(..), None) | (Def::Method(..), None) => { + PatKind::Lit(P(expr.clone())) + } + (_, Some(ctor_path)) => { + let pats = args.iter() + .map(|expr| const_expr_to_pat(tcx, expr, pat_id, span)) + .collect::<Result<_, _>>()?; + PatKind::TupleStruct(hir::QPath::Resolved(None, ctor_path), pats, None) + } + _ => bug!() + } } hir::ExprStruct(ref qpath, ref fields, None) => { @@ -326,8 +332,9 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, PatKind::Slice(pats, None, hir::HirVec::new()) } - hir::ExprPath(_) => { - match tcx.expect_def(expr.id) { + hir::ExprPath(ref qpath) => { + let def = tcx.tables().qpath_def(qpath, expr.id); + match def { Def::StructCtor(_, CtorKind::Const) | Def::VariantCtor(_, CtorKind::Const) => { match expr.node { @@ -797,13 +804,8 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Err(kind) => return Err(ConstEvalErr { span: e.span, kind: kind }), } } - hir::ExprPath(_) => { - // 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 def = match tcx.expect_def_or_none(e.id) { - Some(def) => def, - None => signal!(e, UnresolvedPath) - }; + hir::ExprPath(ref qpath) => { + let def = tcx.tables().qpath_def(qpath, e.id); match def { Def::Const(def_id) | Def::AssociatedConst(def_id) => { @@ -854,6 +856,7 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } }, Def::Method(id) | Def::Fn(id) => Function(id), + Def::Err => signal!(e, UnresolvedPath), _ => signal!(e, NonConstPath), } } @@ -882,8 +885,9 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn_args )?; debug!("const call arg: {:?}", arg); - let old = call_args.insert(tcx.expect_def(arg.pat.id).def_id(), arg_val); - assert!(old.is_none()); + if let PatKind::Binding(_, def_id, _, _) = arg.pat.node { + assert!(call_args.insert(def_id, arg_val).is_none()); + } } debug!("const call({:?})", call_args); eval_const_expr_partial(tcx, &result, ty_hint, Some(&call_args))? @@ -1368,10 +1372,8 @@ pub fn eval_length<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx, &err, count_expr.span, reason); if let hir::ExprPath(hir::QPath::Resolved(None, ref path)) = count_expr.node { - if !path.global && path.segments.len() == 1 { - if let Some(Def::Local(..)) = tcx.expect_def_or_none(count_expr.id) { - diag.note(&format!("`{}` is a variable", path.segments[0].name)); - } + if let Def::Local(..) = path.def { + diag.note(&format!("`{}` is a variable", path)); } } diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs index 241920f2949..8e803da98f8 100644 --- a/src/librustc_const_eval/pattern.rs +++ b/src/librustc_const_eval/pattern.rs @@ -163,8 +163,9 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { } } - PatKind::Path(..) => { - match self.tcx.expect_def(pat.id) { + PatKind::Path(ref qpath) => { + let def = self.tcx.tables().qpath_def(qpath, pat.id); + match def { Def::Const(def_id) | Def::AssociatedConst(def_id) => { let tcx = self.tcx.global_tcx(); let substs = tcx.tables().node_id_item_substs(pat.id) @@ -188,7 +189,7 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { } } } - _ => self.lower_variant_or_leaf(pat, vec![]) + _ => self.lower_variant_or_leaf(def, vec![]) } } @@ -242,8 +243,7 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { } } - PatKind::Binding(bm, ref ident, ref sub) => { - let def_id = self.tcx.expect_def(pat.id).def_id(); + PatKind::Binding(bm, def_id, ref ident, ref sub) => { let id = self.tcx.map.as_local_node_id(def_id).unwrap(); let var_ty = self.tcx.tables().node_id_to_type(pat.id); let region = match var_ty.sty { @@ -281,13 +281,14 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { } } - PatKind::TupleStruct(_, ref subpatterns, ddpos) => { + PatKind::TupleStruct(ref qpath, ref subpatterns, ddpos) => { + let def = self.tcx.tables().qpath_def(qpath, pat.id); let pat_ty = self.tcx.tables().node_id_to_type(pat.id); let adt_def = match pat_ty.sty { ty::TyAdt(adt_def, _) => adt_def, _ => span_bug!(pat.span, "tuple struct pattern not applied to an ADT"), }; - let variant_def = adt_def.variant_of_def(self.tcx.expect_def(pat.id)); + let variant_def = adt_def.variant_of_def(def); let subpatterns = subpatterns.iter() @@ -297,10 +298,11 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { pattern: self.lower_pattern(field), }) .collect(); - self.lower_variant_or_leaf(pat, subpatterns) + self.lower_variant_or_leaf(def, subpatterns) } - PatKind::Struct(_, ref fields, _) => { + PatKind::Struct(ref qpath, ref fields, _) => { + let def = self.tcx.tables().qpath_def(qpath, pat.id); let pat_ty = self.tcx.tables().node_id_to_type(pat.id); let adt_def = match pat_ty.sty { ty::TyAdt(adt_def, _) => adt_def, @@ -310,7 +312,7 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { "struct pattern not applied to an ADT"); } }; - let variant_def = adt_def.variant_of_def(self.tcx.expect_def(pat.id)); + let variant_def = adt_def.variant_of_def(def); let subpatterns = fields.iter() @@ -329,7 +331,7 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { }) .collect(); - self.lower_variant_or_leaf(pat, subpatterns) + self.lower_variant_or_leaf(def, subpatterns) } }; @@ -418,11 +420,11 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { fn lower_variant_or_leaf( &mut self, - pat: &hir::Pat, + def: Def, subpatterns: Vec<FieldPattern<'tcx>>) -> PatternKind<'tcx> { - match self.tcx.expect_def(pat.id) { + match def { Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => { let enum_id = self.tcx.parent_def_id(variant_id).unwrap(); let adt_def = self.tcx.lookup_adt_def(enum_id); @@ -442,9 +444,7 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { PatternKind::Leaf { subpatterns: subpatterns } } - def => { - span_bug!(pat.span, "inappropriate def for pattern: {:?}", def); - } + _ => bug!() } } } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 9a4ecef0c0e..a1d1d110527 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -840,9 +840,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, let named_region_map = time(time_passes, "lifetime resolution", - || middle::resolve_lifetime::krate(sess, - &hir_map, - &resolutions.def_map))?; + || middle::resolve_lifetime::krate(sess, &hir_map))?; time(time_passes, "looking for entry point", @@ -859,17 +857,16 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, time(time_passes, "loop checking", - || loops::check_crate(sess, &resolutions.def_map, &hir_map)); + || loops::check_crate(sess, &hir_map)); time(time_passes, "static item recursion checking", - || static_recursion::check_crate(sess, &resolutions.def_map, &hir_map))?; + || static_recursion::check_crate(sess, &hir_map))?; let index = stability::Index::new(&hir_map); TyCtxt::create_and_enter(sess, arenas, - resolutions.def_map, resolutions.trait_map, named_region_map, hir_map, diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index a4f0e290384..464e15faeaf 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -131,12 +131,11 @@ fn test_env<F>(source_string: &str, // run just enough stuff to build a tcx: let lang_items = lang_items::collect_language_items(&sess, &ast_map); - let named_region_map = resolve_lifetime::krate(&sess, &ast_map, &resolutions.def_map); + let named_region_map = resolve_lifetime::krate(&sess, &ast_map); let region_map = region::resolve_crate(&sess, &ast_map); let index = stability::Index::new(&ast_map); TyCtxt::create_and_enter(&sess, &arenas, - resolutions.def_map, resolutions.trait_map, named_region_map.unwrap(), ast_map, diff --git a/src/librustc_incremental/calculate_svh/svh_visitor.rs b/src/librustc_incremental/calculate_svh/svh_visitor.rs index 8c6d8dffa1d..e2b141f2ea6 100644 --- a/src/librustc_incremental/calculate_svh/svh_visitor.rs +++ b/src/librustc_incremental/calculate_svh/svh_visitor.rs @@ -23,7 +23,7 @@ use syntax_pos::{Span, NO_EXPANSION, COMMAND_LINE_EXPN, BytePos}; use syntax::tokenstream; use rustc::hir; use rustc::hir::*; -use rustc::hir::def::{Def, PathResolution}; +use rustc::hir::def::Def; use rustc::hir::def_id::DefId; use rustc::hir::intravisit as visit; use rustc::ty::TyCtxt; @@ -335,8 +335,8 @@ fn saw_expr<'a>(node: &'a Expr_, ExprIndex(..) => (SawExprIndex, true), ExprPath(_) => (SawExprPath, false), ExprAddrOf(m, _) => (SawExprAddrOf(m), false), - ExprBreak(id, _) => (SawExprBreak(id.map(|id| id.node.as_str())), false), - ExprAgain(id) => (SawExprAgain(id.map(|id| id.node.as_str())), false), + ExprBreak(label, _) => (SawExprBreak(label.map(|l| l.name.as_str())), false), + ExprAgain(label) => (SawExprAgain(label.map(|l| l.name.as_str())), false), ExprRet(..) => (SawExprRet, false), ExprInlineAsm(ref a,..) => (SawExprInlineAsm(a), false), ExprStruct(..) => (SawExprStruct, false), @@ -669,6 +669,10 @@ impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'has visit::walk_path(self, path) } + fn visit_def_mention(&mut self, def: Def) { + self.hash_def(def); + } + fn visit_block(&mut self, b: &'tcx Block) { debug!("visit_block: st={:?}", self.st); SawBlock.hash(self.st); @@ -799,11 +803,6 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> { // or not an entry was present (we are already hashing what // variant it is above when we visit the HIR). - if let Some(def) = self.tcx.def_map.borrow().get(&id) { - debug!("hash_resolve: id={:?} def={:?} st={:?}", id, def, self.st); - self.hash_partial_def(def); - } - if let Some(traits) = self.tcx.trait_map.get(&id) { debug!("hash_resolve: id={:?} traits={:?} st={:?}", id, traits, self.st); traits.len().hash(self.st); @@ -825,11 +824,6 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> { self.compute_def_id_hash(def_id).hash(self.st); } - fn hash_partial_def(&mut self, def: &PathResolution) { - self.hash_def(def.base_def); - def.depth.hash(self.st); - } - fn hash_def(&mut self, def: Def) { match def { // Crucial point: for all of these variants, the variant + diff --git a/src/librustc_lint/bad_style.rs b/src/librustc_lint/bad_style.rs index 25ea3d65993..7c3ea656124 100644 --- a/src/librustc_lint/bad_style.rs +++ b/src/librustc_lint/bad_style.rs @@ -288,12 +288,17 @@ 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.expect_def_or_none(p.id).is_some() { - self.check_snake_case(cx, "variable", &path1.node.as_str(), Some(p.span)); + // Exclude parameter names from foreign functions + let parent_node = cx.tcx.map.get_parent_node(p.id); + if let hir::map::NodeForeignItem(item) = cx.tcx.map.get(parent_node) { + if let hir::ForeignItemFn(..) = item.node { + return; } } + + if let &PatKind::Binding(_, _, ref path1, _) = &p.node { + self.check_snake_case(cx, "variable", &path1.node.as_str(), Some(p.span)); + } } fn check_struct_def(&mut self, @@ -378,7 +383,7 @@ impl LateLintPass for NonUpperCaseGlobals { // Lint for constants that look like binding identifiers (#7526) if let PatKind::Path(hir::QPath::Resolved(None, ref path)) = p.node { if !path.global && path.segments.len() == 1 && path.segments[0].parameters.is_empty() { - if let Def::Const(..) = cx.tcx.expect_def(p.id) { + if let Def::Const(..) = path.def { NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern", path.segments[0].name, diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index d91327bc86b..490b0028d74 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -167,7 +167,7 @@ impl LateLintPass for NonShorthandFieldPatterns { if fieldpat.node.is_shorthand { continue; } - if let PatKind::Binding(_, ident, None) = fieldpat.node.pat.node { + if let PatKind::Binding(_, _, ident, None) = fieldpat.node.pat.node { if ident.node == fieldpat.node.name { cx.span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span, @@ -391,7 +391,7 @@ impl LateLintPass for MissingDoc { hir::ItemImpl(.., Some(ref trait_ref), _, ref impl_item_refs) => { // 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.expect_def(trait_ref.ref_id).def_id(); + let real_trait = trait_ref.path.def.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)) => { @@ -697,10 +697,9 @@ impl LateLintPass for Deprecated { &mut |id, sp, stab, depr| self.lint(cx, id, sp, &stab, &depr)); } - fn check_path(&mut self, cx: &LateContext, path: &hir::Path, id: ast::NodeId) { + fn check_path(&mut self, cx: &LateContext, path: &hir::Path, _: ast::NodeId) { stability::check_path(cx.tcx, path, - id, &mut |id, sp, stab, depr| self.lint(cx, id, sp, &stab, &depr)); } @@ -926,8 +925,12 @@ impl LateLintPass for UnconditionalRecursion { fn expr_refers_to_this_fn(tcx: TyCtxt, fn_id: ast::NodeId, id: ast::NodeId) -> bool { match tcx.map.get(id) { hir_map::NodeExpr(&hir::Expr { node: hir::ExprCall(ref callee, _), .. }) => { - tcx.expect_def_or_none(callee.id) - .map_or(false, |def| def.def_id() == tcx.map.local_def_id(fn_id)) + let def = if let hir::ExprPath(ref qpath) = callee.node { + tcx.tables().qpath_def(qpath, callee.id) + } else { + return false; + }; + def.def_id() == tcx.map.local_def_id(fn_id) } _ => false, } @@ -965,10 +968,13 @@ 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, _), .. }) => { - // 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 def = if let hir::ExprPath(ref qpath) = callee.node { + tcx.tables().qpath_def(qpath, callee.id) + } else { + return false; + }; + match def { + Def::Method(def_id) => { let substs = tcx.tables().node_id_item_substs(callee.id) .unwrap_or_else(|| tcx.intern_substs(&[])); method_call_refers_to_method( @@ -1201,11 +1207,12 @@ impl LateLintPass for MutableTransmutes { (cx: &LateContext<'a, 'tcx>, expr: &hir::Expr) -> Option<(&'tcx ty::TypeVariants<'tcx>, &'tcx ty::TypeVariants<'tcx>)> { - match expr.node { - hir::ExprPath(_) => (), - _ => return None, - } - if let Def::Fn(did) = cx.tcx.expect_def(expr.id) { + let def = if let hir::ExprPath(ref qpath) = expr.node { + cx.tcx.tables().qpath_def(qpath, expr.id) + } else { + return None; + }; + if let Def::Fn(did) = def { if !def_id_is_transmute(cx, did) { return None; } diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 324cbd17ab3..873c141065e 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc::hir::pat_util; use rustc::ty; use rustc::ty::adjustment; use util::nodemap::FxHashMap; @@ -44,7 +43,7 @@ impl UnusedMut { let mut mutables = FxHashMap(); for p in pats { - pat_util::pat_bindings(p, |mode, id, _, path1| { + p.each_binding(|mode, id, _, path1| { let name = path1.node; if let hir::BindByValue(hir::MutMutable) = mode { if !name.as_str().starts_with("_") { diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index e2fa535bb44..806d20c72dc 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -18,7 +18,7 @@ use schema::*; use rustc::middle::cstore::{InlinedItem, InlinedItemRef}; use rustc::middle::const_qualif::ConstQualif; -use rustc::hir::def::{self, Def}; +use rustc::hir::def::Def; use rustc::hir::def_id::DefId; use rustc::ty::{self, TyCtxt, Ty}; @@ -35,7 +35,7 @@ pub struct Ast<'tcx> { #[derive(RustcEncodable, RustcDecodable)] enum TableEntry<'tcx> { - Def(Def), + TypeRelativeDef(Def), NodeType(Ty<'tcx>), ItemSubsts(ty::ItemSubsts<'tcx>), Adjustment(ty::adjustment::Adjustment<'tcx>), @@ -93,7 +93,8 @@ impl<'a, 'b, 'tcx, 'v> Visitor<'v> for SideTableEncodingIdVisitor<'a, 'b, 'tcx> } }; - encode(tcx.expect_def_or_none(id).map(TableEntry::Def)); + encode(tcx.tables().type_relative_path_defs.get(&id).cloned() + .map(TableEntry::TypeRelativeDef)); encode(tcx.tables().node_types.get(&id).cloned().map(TableEntry::NodeType)); encode(tcx.tables().item_substs.get(&id).cloned().map(TableEntry::ItemSubsts)); encode(tcx.tables().adjustments.get(&id).cloned().map(TableEntry::Adjustment)); @@ -140,8 +141,8 @@ pub fn decode_inlined_item<'a, 'tcx>(cdata: &CrateMetadata, for (id, entry) in ast.side_tables.decode((cdata, tcx, id_ranges)) { match entry { - TableEntry::Def(def) => { - tcx.def_map.borrow_mut().insert(id, def::PathResolution::new(def)); + TableEntry::TypeRelativeDef(def) => { + tcx.tables.borrow_mut().type_relative_path_defs.insert(id, def); } TableEntry::NodeType(ty) => { tcx.tables.borrow_mut().node_types.insert(id, ty); diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 8f3e8a48b1a..a243962b4ee 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -597,7 +597,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_fn_arg_names(&mut self, decl: &hir::FnDecl) -> LazySeq<ast::Name> { self.lazy_seq(decl.inputs.iter().map(|arg| { - if let PatKind::Binding(_, ref path1, _) = arg.pat.node { + if let PatKind::Binding(_, _, ref path1, _) = arg.pat.node { path1.node } else { Symbol::intern("") diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 5713ee45b9d..0e4dbb04777 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -182,7 +182,7 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, by_ref: by_ref }; if let Some(hir::map::NodeLocal(pat)) = tcx.map.find(var_id) { - if let hir::PatKind::Binding(_, ref ident, _) = pat.node { + if let hir::PatKind::Binding(_, _, ref ident, _) = pat.node { decl.debug_name = ident.node; } } @@ -286,7 +286,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // If this is a simple binding pattern, give the local a nice name for debuginfo. let mut name = None; if let Some(pat) = pattern { - if let hir::PatKind::Binding(_, ref ident, _) = pat.node { + if let hir::PatKind::Binding(_, _, ref ident, _) = pat.node { name = Some(ident.node); } } diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 0c796ad42bb..a148ae08c53 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -18,7 +18,6 @@ use rustc::hir::map; use rustc::hir::def::{Def, CtorKind}; use rustc::middle::const_val::ConstVal; use rustc_const_eval as const_eval; -use rustc::middle::region::CodeExtent; use rustc::ty::{self, AdtKind, VariantDef, Ty}; use rustc::ty::cast::CastKind as TyCastKind; use rustc::hir; @@ -265,10 +264,10 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, args: vec![fun.to_ref(), tupled_args.to_ref()] } } else { - let adt_data = if let hir::ExprPath(hir::QPath::Resolved(..)) = fun.node { + let adt_data = if let hir::ExprPath(hir::QPath::Resolved(_, ref path)) = 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.expect_def(fun.id) { + match path.def { Def::VariantCtor(variant_id, CtorKind::Fn) => { Some((adt_def, adt_def.variant_index_with_id(variant_id))) }, @@ -456,7 +455,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } } - hir::ExprStruct(_, ref fields, ref base) => { + hir::ExprStruct(ref qpath, ref fields, ref base) => { match expr_ty.sty { ty::TyAdt(adt, substs) => match adt.adt_kind() { AdtKind::Struct | AdtKind::Union => { @@ -476,7 +475,11 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } } AdtKind::Enum => { - match cx.tcx.expect_def(expr.id) { + let def = match *qpath { + hir::QPath::Resolved(_, ref path) => path.def, + hir::QPath::TypeRelative(..) => Def::Err + }; + match def { Def::Variant(variant_id) => { assert!(base.is_none()); @@ -490,7 +493,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, base: None } } - ref def => { + _ => { span_bug!( expr.span, "unexpected def: {:?}", @@ -531,8 +534,9 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } } - hir::ExprPath(_) => { - convert_path_expr(cx, expr) + hir::ExprPath(ref qpath) => { + let def = cx.tcx.tables().qpath_def(qpath, expr.id); + convert_path_expr(cx, expr, def) } hir::ExprInlineAsm(ref asm, ref outputs, ref inputs) => { @@ -559,10 +563,18 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, hir::ExprRet(ref v) => ExprKind::Return { value: v.to_ref() }, hir::ExprBreak(label, ref value) => - ExprKind::Break { label: label.map(|_| loop_label(cx, expr)), - value: value.to_ref() }, + ExprKind::Break { + label: label.map(|label| { + cx.tcx.region_maps.node_extent(label.loop_id) + }), + value: value.to_ref() + }, hir::ExprAgain(label) => - ExprKind::Continue { label: label.map(|_| loop_label(cx, expr)) }, + ExprKind::Continue { + label: label.map(|label| { + cx.tcx.region_maps.node_extent(label.loop_id) + }) + }, hir::ExprMatch(ref discr, ref arms, _) => ExprKind::Match { discriminant: discr.to_ref(), arms: arms.iter().map(|a| convert_arm(cx, a)).collect() }, @@ -661,11 +673,11 @@ fn convert_arm<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, - expr: &'tcx hir::Expr) + expr: &'tcx hir::Expr, + def: Def) -> ExprKind<'tcx> { let substs = cx.tcx.tables().node_id_item_substs(expr.id) .unwrap_or_else(|| cx.tcx.intern_substs(&[])); - let def = cx.tcx.expect_def(expr.id); let def_id = match def { // A regular function, constructor function or a constant. Def::Fn(def_id) | Def::Method(def_id) | @@ -990,14 +1002,6 @@ 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.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), - } -} - /// Converts a list of named fields (i.e. for struct-like struct/enum ADTs) into FieldExprRef. fn field_refs<'tcx>(variant: VariantDef<'tcx>, fields: &'tcx [hir::Field]) diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index ff46273a997..d9b1f247c72 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -487,8 +487,9 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node _ => {} } } - hir::ExprPath(_) => { - match v.tcx.expect_def(e.id) { + hir::ExprPath(ref qpath) => { + let def = v.tcx.tables().qpath_def(qpath, e.id); + match def { Def::VariantCtor(_, CtorKind::Const) => { // Size is determined by the whole enum, may be non-zero. v.add_qualif(ConstQualif::NON_ZERO_SIZED); @@ -531,17 +532,22 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node }; } // 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::StructCtor(_, CtorKind::Fn)) | - Some(Def::VariantCtor(_, CtorKind::Fn)) => { + let def = if let hir::ExprPath(ref qpath) = callee.node { + v.tcx.tables().qpath_def(qpath, callee.id) + } else { + Def::Err + }; + let is_const = match def { + Def::StructCtor(_, CtorKind::Fn) | + Def::VariantCtor(_, CtorKind::Fn) => { // `NON_ZERO_SIZED` is about the call result, not about the ctor itself. v.add_qualif(ConstQualif::NON_ZERO_SIZED); true } - Some(Def::Fn(did)) => { + Def::Fn(did) => { v.handle_const_fn_call(e, did, node_ty) } - Some(Def::Method(did)) => { + Def::Method(did) => { match v.tcx.associated_item(did).container { ty::ImplContainer(_) => { v.handle_const_fn_call(e, did, node_ty) diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index c909e75afc1..a622a3faf70 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -12,10 +12,10 @@ use self::Context::*; use rustc::session::Session; use rustc::dep_graph::DepNode; -use rustc::hir::def::{Def, DefMap}; use rustc::hir::map::Map; use rustc::hir::intravisit::{self, Visitor}; use rustc::hir; +use syntax::ast; use syntax_pos::Span; #[derive(Clone, Copy, PartialEq)] @@ -45,17 +45,15 @@ enum Context { #[derive(Copy, Clone)] struct CheckLoopVisitor<'a, 'ast: 'a> { sess: &'a Session, - def_map: &'a DefMap, hir_map: &'a Map<'ast>, cx: Context, } -pub fn check_crate(sess: &Session, def_map: &DefMap, map: &Map) { +pub fn check_crate(sess: &Session, map: &Map) { let _task = map.dep_graph.in_task(DepNode::CheckLoops); let krate = map.krate(); krate.visit_all_item_likes(&mut CheckLoopVisitor { sess: sess, - def_map: def_map, hir_map: map, cx: Normal, }.as_deep_visitor()); @@ -84,21 +82,18 @@ impl<'a, 'ast, 'v> Visitor<'v> for CheckLoopVisitor<'a, 'ast> { hir::ExprClosure(.., ref b, _) => { self.with_context(Closure, |v| v.visit_expr(&b)); } - hir::ExprBreak(ref opt_label, ref opt_expr) => { + hir::ExprBreak(label, ref opt_expr) => { if opt_expr.is_some() { - let loop_kind = if opt_label.is_some() { - let loop_def = self.def_map.get(&e.id).unwrap().full_def(); - if loop_def == Def::Err { + let loop_kind = if let Some(label) = label { + if label.loop_id == ast::DUMMY_NODE_ID { None - } else if let Def::Label(loop_id) = loop_def { - Some(match self.hir_map.expect_expr(loop_id).node { + } else { + Some(match self.hir_map.expect_expr(label.loop_id).node { hir::ExprWhile(..) => LoopKind::WhileLoop, hir::ExprLoop(_, _, source) => LoopKind::Loop(source), ref r => span_bug!(e.span, "break label resolved to a non-loop: {:?}", r), }) - } else { - span_bug!(e.span, "break resolved to a non-label") } } else if let Loop(kind) = self.cx { Some(kind) diff --git a/src/librustc_passes/static_recursion.rs b/src/librustc_passes/static_recursion.rs index b98cf7e602b..b5daf0284e1 100644 --- a/src/librustc_passes/static_recursion.rs +++ b/src/librustc_passes/static_recursion.rs @@ -14,7 +14,7 @@ use rustc::dep_graph::DepNode; use rustc::hir::map as ast_map; use rustc::session::{CompileResult, Session}; -use rustc::hir::def::{Def, CtorKind, DefMap}; +use rustc::hir::def::{Def, CtorKind}; use rustc::util::nodemap::NodeMap; use syntax::ast; @@ -27,7 +27,6 @@ use std::cell::RefCell; struct CheckCrateVisitor<'a, 'ast: 'a> { sess: &'a Session, - def_map: &'a DefMap, ast_map: &'a ast_map::Map<'ast>, // `discriminant_map` is a cache that associates the `NodeId`s of local // variant definitions with the discriminant expression that applies to @@ -88,14 +87,12 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckCrateVisitor<'a, 'ast> { } pub fn check_crate<'ast>(sess: &Session, - def_map: &DefMap, ast_map: &ast_map::Map<'ast>) -> CompileResult { let _task = ast_map.dep_graph.in_task(DepNode::CheckStaticRecursion); let mut visitor = CheckCrateVisitor { sess: sess, - def_map: def_map, ast_map: ast_map, discriminant_map: RefCell::new(NodeMap()), }; @@ -109,7 +106,6 @@ struct CheckItemRecursionVisitor<'a, 'ast: 'a> { root_span: &'a Span, sess: &'a Session, ast_map: &'a ast_map::Map<'ast>, - def_map: &'a DefMap, discriminant_map: &'a RefCell<NodeMap<Option<&'ast hir::Expr>>>, idstack: Vec<ast::NodeId>, } @@ -122,7 +118,6 @@ impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> { root_span: span, sess: v.sess, ast_map: v.ast_map, - def_map: v.def_map, discriminant_map: &v.discriminant_map, idstack: Vec::new(), } @@ -250,11 +245,11 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> { fn visit_expr(&mut self, e: &'ast hir::Expr) { match e.node { - hir::ExprPath(_) => { - match self.def_map.get(&e.id).map(|d| d.base_def) { - Some(Def::Static(def_id, _)) | - Some(Def::AssociatedConst(def_id)) | - Some(Def::Const(def_id)) => { + hir::ExprPath(hir::QPath::Resolved(_, ref path)) => { + match path.def { + Def::Static(def_id, _) | + Def::AssociatedConst(def_id) | + Def::Const(def_id) => { if let Some(node_id) = self.ast_map.as_local_node_id(def_id) { match self.ast_map.get(node_id) { ast_map::NodeItem(item) => self.visit_item(item), @@ -273,7 +268,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> { // affect the specific variant used, but we need to check // the whole enum definition to see what expression that // might be (if any). - Some(Def::VariantCtor(variant_id, CtorKind::Const)) => { + Def::VariantCtor(variant_id, CtorKind::Const) => { if let Some(variant_id) = self.ast_map.as_local_node_id(variant_id) { let variant = self.ast_map.expect_variant(variant_id); let enum_id = self.ast_map.get_parent(variant_id); diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 55e11caac6d..29bcb73602e 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -67,8 +67,12 @@ struct ReachEverythingInTheInterfaceVisitor<'b, 'a: 'b, 'tcx: 'a> { impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> { fn ty_level(&self, ty: &hir::Ty) -> Option<AccessLevel> { - if let hir::TyPath(_) = ty.node { - match self.tcx.expect_def(ty.id) { + if let hir::TyPath(ref qpath) = ty.node { + let def = match *qpath { + hir::QPath::Resolved(_, ref path) => path.def, + hir::QPath::TypeRelative(..) => self.tcx.tables().type_relative_path_defs[&ty.id] + }; + match def { Def::PrimTy(..) | Def::SelfTy(..) | Def::TyParam(..) => { Some(AccessLevel::Public) } @@ -86,7 +90,7 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> { } fn trait_level(&self, trait_ref: &hir::TraitRef) -> Option<AccessLevel> { - let did = self.tcx.expect_def(trait_ref.ref_id).def_id(); + let did = trait_ref.path.def.def_id(); if let Some(node_id) = self.tcx.map.as_local_node_id(did) { self.get(node_id) } else { @@ -328,13 +332,16 @@ impl<'b, 'a, 'tcx: 'a> Visitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'b } fn visit_ty(&mut self, ty: &'tcx hir::Ty) { - let path_segment = match ty.node { - hir::TyPath(hir::QPath::Resolved(_, ref path)) => path.segments.last(), - hir::TyPath(hir::QPath::TypeRelative(_, ref segment)) => Some(&**segment), + let def_and_segment = match ty.node { + hir::TyPath(hir::QPath::Resolved(_, ref path)) => { + Some((path.def, path.segments.last().unwrap())) + } + hir::TyPath(hir::QPath::TypeRelative(_, ref segment)) => { + Some((self.ev.tcx.tables().type_relative_path_defs[&ty.id], &**segment)) + } _ => None }; - if let Some(segment) = path_segment { - let def = self.ev.tcx.expect_def(ty.id); + if let Some((def, segment)) = def_and_segment { match def { Def::Struct(def_id) | Def::Union(def_id) | Def::Enum(def_id) | Def::TyAlias(def_id) | Def::Trait(def_id) | Def::AssociatedTy(def_id) => { @@ -365,7 +372,7 @@ impl<'b, 'a, 'tcx: 'a> Visitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'b } fn visit_trait_ref(&mut self, trait_ref: &'tcx hir::TraitRef) { - let def_id = self.ev.tcx.expect_def(trait_ref.ref_id).def_id(); + let def_id = trait_ref.path.def.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)); @@ -446,9 +453,10 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivacyVisitor<'a, 'tcx> { let method = self.tcx.tables().method_map[&method_call]; self.check_method(expr.span, method.def_id); } - hir::ExprStruct(_, ref expr_fields, _) => { + hir::ExprStruct(ref qpath, ref expr_fields, _) => { + let def = self.tcx.tables().qpath_def(qpath, expr.id); let adt = self.tcx.tables().expr_ty(expr).ty_adt_def().unwrap(); - let variant = adt.variant_of_def(self.tcx.expect_def(expr.id)); + let variant = adt.variant_of_def(def); // 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, @@ -466,9 +474,9 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivacyVisitor<'a, 'tcx> { } } } - hir::ExprPath(hir::QPath::Resolved(..)) => { - if let def @ Def::StructCtor(_, CtorKind::Fn) = self.tcx.expect_def(expr.id) { - let adt_def = self.tcx.expect_variant_def(def); + hir::ExprPath(hir::QPath::Resolved(_, ref path)) => { + if let Def::StructCtor(_, CtorKind::Fn) = path.def { + let adt_def = self.tcx.expect_variant_def(path.def); let private_indexes = adt_def.fields.iter().enumerate().filter(|&(_, field)| { !field.vis.is_accessible_from(self.curitem, &self.tcx.map) }).map(|(i, _)| i).collect::<Vec<_>>(); @@ -507,9 +515,10 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivacyVisitor<'a, 'tcx> { if self.in_foreign { return } match pattern.node { - PatKind::Struct(_, ref fields, _) => { + PatKind::Struct(ref qpath, ref fields, _) => { + let def = self.tcx.tables().qpath_def(qpath, pattern.id); let adt = self.tcx.tables().pat_ty(pattern).ty_adt_def().unwrap(); - let variant = adt.variant_of_def(self.tcx.expect_def(pattern.id)); + let variant = adt.variant_of_def(def); for field in fields { self.check_field(field.span, adt, variant.field_named(field.node.name)); } @@ -569,8 +578,8 @@ 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.expect_def(path_id) { + fn path_is_private_type(&self, path: &hir::Path) -> bool { + let did = match path.def { Def::PrimTy(..) | Def::SelfTy(..) => return false, def => def.def_id(), }; @@ -598,7 +607,7 @@ impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { fn check_ty_param_bound(&mut self, ty_param_bound: &hir::TyParamBound) { if let hir::TraitTyParamBound(ref trait_ref, _) = *ty_param_bound { - if self.path_is_private_type(trait_ref.trait_ref.ref_id) { + if self.path_is_private_type(&trait_ref.trait_ref.path) { self.old_error_set.insert(trait_ref.trait_ref.ref_id); } } @@ -611,13 +620,16 @@ impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { impl<'a, 'b, 'tcx, 'v> Visitor<'v> for ObsoleteCheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> { fn visit_ty(&mut self, ty: &hir::Ty) { - if let hir::TyPath(_) = ty.node { - if self.inner.path_is_private_type(ty.id) { + if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = ty.node { + if self.inner.path_is_private_type(path) { self.contains_private = true; // found what we're looking for so let's stop // working. return - } else if self.at_outer_type { + } + } + if let hir::TyPath(_) = ty.node { + if self.at_outer_type { self.outer_type_is_public_path = true; } } @@ -687,7 +699,7 @@ impl<'a, 'tcx> Visitor<'tcx> 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.expect_def(tr.ref_id).def_id(); + let did = tr.path.def.def_id(); if let Some(node_id) = self.tcx.map.as_local_node_id(did) { self.trait_is_public(node_id) @@ -849,8 +861,8 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { } fn visit_ty(&mut self, t: &'tcx hir::Ty) { - if let hir::TyPath(_) = t.node { - if self.path_is_private_type(t.id) { + if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = t.node { + if self.path_is_private_type(path) { self.old_error_set.insert(t.id); } } @@ -941,13 +953,17 @@ 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) { - let path_segment = match ty.node { - hir::TyPath(hir::QPath::Resolved(_, ref path)) => path.segments.last(), - hir::TyPath(hir::QPath::TypeRelative(_, ref segment)) => Some(&**segment), + let def_and_segment = match ty.node { + hir::TyPath(hir::QPath::Resolved(_, ref path)) => { + Some((path.def, path.segments.last().unwrap())) + } + hir::TyPath(hir::QPath::TypeRelative(_, ref segment)) => { + Some((self.tcx.tables().type_relative_path_defs[&ty.id], &**segment)) + } _ => None }; - if let Some(segment) = path_segment { - match self.tcx.expect_def(ty.id) { + if let Some((def, segment)) = def_and_segment { + match def { Def::PrimTy(..) | Def::SelfTy(..) | Def::TyParam(..) => { // Public } @@ -1005,7 +1021,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.expect_def(trait_ref.ref_id).def_id(); + let def_id = trait_ref.path.def.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 30d25c7ccec..058c8266a35 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1201,11 +1201,11 @@ impl<'a> ty::NodeIdTree for Resolver<'a> { } impl<'a> hir::lowering::Resolver for Resolver<'a> { - fn resolve_generated_global_path(&mut self, path: &hir::Path, is_value: bool) -> Def { + fn resolve_generated_global_path(&mut self, path: &mut hir::Path, is_value: bool) { let namespace = if is_value { ValueNS } else { TypeNS }; match self.resolve_crate_relative_path(path.span, &path.segments, namespace) { - Ok(binding) => binding.def(), - Err(true) => Def::Err, + Ok(binding) => path.def = binding.def(), + Err(true) => {} Err(false) => { let path_name = &format!("{}", path); let error = @@ -1218,7 +1218,6 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> { def: Def::Err, }; resolve_error(self, path.span, error); - Def::Err } } } diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 53b05051deb..3e7ca155da0 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -274,12 +274,10 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { } fn lookup_def_id(&self, ref_id: NodeId) -> Option<DefId> { - self.tcx.expect_def_or_none(ref_id).and_then(|def| { - match def { - Def::Label(..) | Def::PrimTy(..) | Def::SelfTy(..) | Def::Err => None, - def => Some(def.def_id()), - } - }) + match self.save_ctxt.get_path_def(ref_id) { + Def::PrimTy(..) | Def::SelfTy(..) | Def::Err => None, + def => Some(def.def_id()), + } } fn process_def_kind(&mut self, @@ -292,7 +290,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { return; } - let def = self.tcx.expect_def(ref_id); + let def = self.save_ctxt.get_path_def(ref_id); match def { Def::Mod(_) => { self.dumper.mod_ref(ModRefData { @@ -919,7 +917,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { } // Modules or types in the path prefix. - match self.tcx.expect_def(id) { + match self.save_ctxt.get_path_def(id) { Def::Method(did) => { let ti = self.tcx.associated_item(did); if ti.kind == ty::AssociatedKind::Method && ti.method_has_self_argument { @@ -998,7 +996,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { return; } }; - let variant = adt.variant_of_def(self.tcx.expect_def(p.id)); + let variant = adt.variant_of_def(self.save_ctxt.get_path_def(p.id)); for &Spanned { node: ref field, span } in fields { let sub_span = self.span.span_for_first_ident(span); @@ -1370,7 +1368,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D> return; } }; - let def = self.tcx.expect_def(hir_expr.id); + let def = self.save_ctxt.get_path_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), @@ -1480,7 +1478,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D> // process collected paths for &(id, ref p, immut, ref_kind) in &collector.collected_paths { - match self.tcx.expect_def(id) { + match self.save_ctxt.get_path_def(id) { Def::Local(def_id) => { let id = self.tcx.map.as_local_node_id(def_id).unwrap(); let mut value = if immut == ast::Mutability::Immutable { diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 3c6f67f0c88..e79ca6721db 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -42,8 +42,8 @@ pub mod external_data; pub mod span_utils; use rustc::hir; -use rustc::hir::map::{Node, NodeItem}; use rustc::hir::def::Def; +use rustc::hir::map::Node; use rustc::hir::def_id::DefId; use rustc::session::config::CrateType::CrateTypeExecutable; use rustc::ty::{self, TyCtxt}; @@ -318,7 +318,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { let (qualname, parent_scope, decl_id, vis, docs) = match self.tcx.impl_of_method(self.tcx.map.local_def_id(id)) { Some(impl_id) => match self.tcx.map.get_if_local(impl_id) { - Some(NodeItem(item)) => { + Some(Node::NodeItem(item)) => { match item.node { hir::ItemImpl(.., ref ty, _) => { let mut result = String::from("<"); @@ -358,7 +358,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { None => match self.tcx.trait_of_item(self.tcx.map.local_def_id(id)) { Some(def_id) => { match self.tcx.map.get_if_local(def_id) { - Some(NodeItem(item)) => { + Some(Node::NodeItem(item)) => { (format!("::{}", self.tcx.item_path_str(def_id)), Some(def_id), None, From::from(&item.vis), @@ -497,13 +497,41 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } } - pub fn get_path_data(&self, id: NodeId, path: &ast::Path) -> Option<Data> { - let resolution = self.tcx.expect_resolution(id); - if resolution.depth != 0 { - return None; + pub fn get_path_def(&self, id: NodeId) -> Def { + match self.tcx.map.get(id) { + Node::NodeTraitRef(tr) => tr.path.def, + + Node::NodeItem(&hir::Item { node: hir::ItemUse(ref path, _), .. }) | + Node::NodeVisibility(&hir::Visibility::Restricted { ref path, .. }) => path.def, + + Node::NodeExpr(&hir::Expr { node: hir::ExprPath(ref qpath), .. }) | + Node::NodeExpr(&hir::Expr { node: hir::ExprStruct(ref qpath, ..), .. }) | + Node::NodePat(&hir::Pat { node: hir::PatKind::Path(ref qpath), .. }) | + Node::NodePat(&hir::Pat { node: hir::PatKind::Struct(ref qpath, ..), .. }) | + Node::NodePat(&hir::Pat { node: hir::PatKind::TupleStruct(ref qpath, ..), .. }) => { + self.tcx.tables().qpath_def(qpath, id) + } + + Node::NodeLocal(&hir::Pat { node: hir::PatKind::Binding(_, def_id, ..), .. }) => { + Def::Local(def_id) + } + + Node::NodeTy(&hir::Ty { node: hir::TyPath(ref qpath), .. }) => { + match *qpath { + hir::QPath::Resolved(_, ref path) => path.def, + hir::QPath::TypeRelative(..) => { + // FIXME(eddyb) Avoid keeping associated type resolutions. + self.tcx.tables().type_relative_path_defs[&id] + } + } + } + + _ => Def::Err } - let def = resolution.base_def; + } + pub fn get_path_data(&self, id: NodeId, path: &ast::Path) -> Option<Data> { + let def = self.get_path_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 { @@ -647,8 +675,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } fn lookup_ref_id(&self, ref_id: NodeId) -> Option<DefId> { - match self.tcx.expect_def(ref_id) { - Def::PrimTy(_) | Def::SelfTy(..) => None, + match self.get_path_def(ref_id) { + Def::PrimTy(_) | Def::SelfTy(..) | Def::Err => None, def => Some(def.def_id()), } } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 7d02678679a..646f941deae 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -50,7 +50,7 @@ use rustc_const_eval::eval_length; use hir::{self, SelfKind}; -use hir::def::{Def, PathResolution}; +use hir::def::Def; use hir::def_id::DefId; use hir::print as pprust; use middle::resolve_lifetime as rl; @@ -678,7 +678,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 self.tcx().expect_def(trait_ref.ref_id) { + match path.def { Def::Trait(trait_def_id) => trait_def_id, Def::Err => { self.tcx().sess.fatal("cannot continue compilation due to previous error"); @@ -953,24 +953,20 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let tcx = self.tcx(); match ty.node { hir::TyPath(hir::QPath::Resolved(None, ref path)) => { - let resolution = tcx.expect_resolution(ty.id); - match resolution.base_def { - Def::Trait(trait_def_id) if resolution.depth == 0 => { - self.trait_path_to_object_type(rscope, - path.span, - trait_def_id, - ty.id, - path.segments.last().unwrap(), - span, - partition_bounds(tcx, span, bounds)) - } - _ => { - struct_span_err!(tcx.sess, ty.span, E0172, - "expected a reference to a trait") - .span_label(ty.span, &format!("expected a trait")) - .emit(); - tcx.types.err - } + if let Def::Trait(trait_def_id) = path.def { + self.trait_path_to_object_type(rscope, + path.span, + trait_def_id, + ty.id, + path.segments.last().unwrap(), + span, + partition_bounds(tcx, span, bounds)) + } else { + struct_span_err!(tcx.sess, ty.span, E0172, + "expected a reference to a trait") + .span_label(ty.span, &format!("expected a trait")) + .emit(); + tcx.types.err } } _ => { @@ -1412,55 +1408,54 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } } - // Check a type Def and convert it to a Ty. + // Check a type Path and convert it to a Ty. pub fn def_to_ty(&self, rscope: &RegionScope, - span: Span, - def: Def, opt_self_ty: Option<Ty<'tcx>>, + path: &hir::Path, path_id: ast::NodeId, - path_segments: &[hir::PathSegment], permit_variants: bool) -> Ty<'tcx> { let tcx = self.tcx(); debug!("base_def_to_ty(def={:?}, opt_self_ty={:?}, path_segments={:?})", - def, opt_self_ty, path_segments); + path.def, opt_self_ty, path.segments); - match def { + let span = path.span; + match path.def { Def::Trait(trait_def_id) => { // N.B. this case overlaps somewhat with // TyObjectSum, see that fn for details assert_eq!(opt_self_ty, None); - tcx.prohibit_type_params(path_segments.split_last().unwrap().1); + tcx.prohibit_type_params(path.segments.split_last().unwrap().1); self.trait_path_to_object_type(rscope, span, trait_def_id, path_id, - path_segments.last().unwrap(), + path.segments.last().unwrap(), span, partition_bounds(tcx, span, &[])) } Def::Enum(did) | Def::TyAlias(did) | Def::Struct(did) | Def::Union(did) => { assert_eq!(opt_self_ty, None); - tcx.prohibit_type_params(path_segments.split_last().unwrap().1); - self.ast_path_to_ty(rscope, span, did, path_segments.last().unwrap()) + tcx.prohibit_type_params(path.segments.split_last().unwrap().1); + self.ast_path_to_ty(rscope, span, did, path.segments.last().unwrap()) } Def::Variant(did) if permit_variants => { // Convert "variant type" as if it were a real type. // The resulting `Ty` is type of the variant's enum for now. assert_eq!(opt_self_ty, None); - tcx.prohibit_type_params(path_segments.split_last().unwrap().1); + tcx.prohibit_type_params(path.segments.split_last().unwrap().1); self.ast_path_to_ty(rscope, span, tcx.parent_def_id(did).unwrap(), - path_segments.last().unwrap()) + path.segments.last().unwrap()) } Def::TyParam(did) => { assert_eq!(opt_self_ty, None); - tcx.prohibit_type_params(path_segments); + tcx.prohibit_type_params(&path.segments); let node_id = tcx.map.as_local_node_id(did).unwrap(); let param = tcx.ty_param_defs.borrow().get(&node_id) @@ -1483,7 +1478,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { // Self in impl (we know the concrete type). assert_eq!(opt_self_ty, None); - tcx.prohibit_type_params(path_segments); + tcx.prohibit_type_params(&path.segments); let ty = tcx.item_type(def_id); if let Some(free_substs) = self.get_free_substs() { ty.subst(tcx, free_substs) @@ -1494,22 +1489,22 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { Def::SelfTy(Some(_), None) => { // Self in trait. assert_eq!(opt_self_ty, None); - tcx.prohibit_type_params(path_segments); + tcx.prohibit_type_params(&path.segments); tcx.mk_self_type() } Def::AssociatedTy(def_id) => { - tcx.prohibit_type_params(&path_segments[..path_segments.len()-2]); + tcx.prohibit_type_params(&path.segments[..path.segments.len()-2]); let trait_did = tcx.parent_def_id(def_id).unwrap(); self.qpath_to_ty(rscope, span, opt_self_ty, trait_did, - &path_segments[path_segments.len()-2], - path_segments.last().unwrap()) + &path.segments[path.segments.len()-2], + path.segments.last().unwrap()) } Def::PrimTy(prim_ty) => { assert_eq!(opt_self_ty, None); - tcx.prim_ty_to_ty(path_segments, prim_ty) + tcx.prim_ty_to_ty(&path.segments, prim_ty) } Def::Err => { self.set_tainted_by_errors(); @@ -1518,7 +1513,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { _ => { struct_span_err!(tcx.sess, span, E0248, "found value `{}` used as a type", - tcx.item_path_str(def.def_id())) + tcx.item_path_str(path.def.def_id())) .span_label(span, &format!("value used as a type")) .emit(); return self.tcx().types.err; @@ -1653,23 +1648,21 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let opt_self_ty = maybe_qself.as_ref().map(|qself| { self.ast_ty_to_ty(rscope, qself) }); - self.def_to_ty(rscope, - ast_ty.span, - tcx.expect_def(ast_ty.id), - opt_self_ty, - ast_ty.id, - &path.segments, - false) + self.def_to_ty(rscope, opt_self_ty, path, ast_ty.id, false) } hir::TyPath(hir::QPath::TypeRelative(ref qself, ref segment)) => { debug!("ast_ty_to_ty: qself={:?} segment={:?}", qself, segment); let ty = self.ast_ty_to_ty(rscope, qself); - let def = tcx.expect_def_or_none(qself.id).unwrap_or(Def::Err); + let def = if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = qself.node { + path.def + } else { + Def::Err + }; let (ty, def) = self.associated_path_def_to_ty(ast_ty.span, ty, def, segment); // Write back the new resolution. - tcx.def_map.borrow_mut().insert(ast_ty.id, PathResolution::new(def)); + tcx.tables.borrow_mut().type_relative_path_defs.insert(ast_ty.id, def); ty } @@ -2007,7 +2000,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 tcx.expect_def(b.trait_ref.ref_id) { + match b.trait_ref.path.def { 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 3e62b22d36f..9381d653ed2 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -103,7 +103,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.demand_eqtype(pat.span, expected, rhs_ty); common_type } - PatKind::Binding(bm, _, ref sub) => { + PatKind::Binding(bm, def_id, _, ref sub) => { let typ = self.local_ty(pat.span, pat.id); match bm { hir::BindByRef(mutbl) => { @@ -130,16 +130,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // if there are multiple arms, make sure they all agree on // what the type of the binding `x` ought to be - match tcx.expect_def(pat.id) { - Def::Err => {} - Def::Local(def_id) => { - let var_id = tcx.map.as_local_node_id(def_id).unwrap(); - if var_id != pat.id { - let vt = self.local_ty(pat.span, var_id); - self.demand_eqtype(pat.span, vt, typ); - } - } - d => bug!("bad def for pattern binding `{:?}`", d) + let var_id = tcx.map.as_local_node_id(def_id).unwrap(); + if var_id != pat.id { + let vt = self.local_ty(pat.span, var_id); + self.demand_eqtype(pat.span, vt, typ); } if let Some(ref p) = *sub { @@ -373,7 +367,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // want to use the *precise* type of the discriminant, *not* some // supertype, as the "discriminant type" (issue #23116). let contains_ref_bindings = arms.iter() - .filter_map(|a| tcx.arm_contains_ref_binding(a)) + .filter_map(|a| a.contains_ref_binding()) .max_by_key(|m| match *m { hir::MutMutable => 1, hir::MutImmutable => 0, diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 3ffbbd1be80..fdf496b7c86 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -218,12 +218,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; if let hir::ExprCall(ref expr, _) = call_expr.node { - 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.base_def.def_id()) { - err.span_note(span, "defined here"); - } + let def = if let hir::ExprPath(ref qpath) = expr.node { + self.tcx.tables().qpath_def(qpath, expr.id) + } else { + Def::Err + }; + if def != Def::Err { + if let Some(span) = self.tcx.map.span_if_local(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 33b123d0a6d..6bc37f5c44d 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -83,9 +83,8 @@ use self::TupleArgumentsFlag::*; use astconv::{AstConv, ast_region_to_region}; use dep_graph::DepNode; use fmt_macros::{Parser, Piece, Position}; -use hir::def::{Def, CtorKind, PathResolution}; +use hir::def::{Def, CtorKind}; use hir::def_id::{DefId, LOCAL_CRATE}; -use hir::pat_util; use rustc::infer::{self, InferCtxt, InferOk, RegionVariableOrigin, TypeTrace, type_variable}; use rustc::ty::subst::{Kind, Subst, Substs}; @@ -711,7 +710,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> { // Add pattern bindings. fn visit_pat(&mut self, p: &'gcx hir::Pat) { - if let PatKind::Binding(_, ref path1, _) = p.node { + if let PatKind::Binding(_, _, ref path1, _) = p.node { let var_ty = self.assign(p.span, p.id, None); self.fcx.require_type_is_sized(var_ty, p.span, @@ -796,7 +795,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, fcx.register_old_wf_obligation(arg_ty, input.ty.span, traits::MiscObligation); // Create type variables for each argument. - pat_util::pat_bindings(&input.pat, |_bm, pat_id, sp, _path| { + input.pat.each_binding(|_bm, pat_id, sp, _path| { let var_ty = visit.assign(sp, pat_id, None); fcx.require_type_is_sized(var_ty, sp, traits::VariableType(pat_id)); }); @@ -3627,72 +3626,58 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } tcx.mk_nil() } - hir::ExprBreak(ref label_opt, ref expr_opt) => { - let loop_id = if label_opt.is_some() { - let loop_def = tcx.expect_def(expr.id); - if let Def::Label(loop_id) = loop_def { - Some(Some(loop_id)) - } else if loop_def == Def::Err { - // an error was already printed, so just ignore it - None + hir::ExprBreak(label, ref expr_opt) => { + let loop_id = label.map(|l| l.loop_id); + let coerce_to = { + let mut enclosing_loops = self.enclosing_loops.borrow_mut(); + enclosing_loops.find_loop(loop_id).map(|ctxt| ctxt.coerce_to) + }; + if let Some(coerce_to) = coerce_to { + let e_ty; + let cause; + if let Some(ref e) = *expr_opt { + // Recurse without `enclosing_loops` borrowed. + e_ty = self.check_expr_with_hint(e, coerce_to); + cause = self.misc(e.span); + // Notably, the recursive call may alter coerce_to - must not keep using it! } else { - span_bug!(expr.span, "break label resolved to a non-label"); + // `break` without argument acts like `break ()`. + e_ty = tcx.mk_nil(); + cause = self.misc(expr.span); } - } else { - Some(None) - }; - if let Some(loop_id) = loop_id { - let coerce_to = { - let mut enclosing_loops = self.enclosing_loops.borrow_mut(); - enclosing_loops.find_loop(loop_id).map(|ctxt| ctxt.coerce_to) - }; - if let Some(coerce_to) = coerce_to { - let e_ty; - let cause; - if let Some(ref e) = *expr_opt { - // Recurse without `enclosing_loops` borrowed. - e_ty = self.check_expr_with_hint(e, coerce_to); - cause = self.misc(e.span); - // Notably, the recursive call may alter coerce_to - must not keep using it! - } else { - // `break` without argument acts like `break ()`. - e_ty = tcx.mk_nil(); - cause = self.misc(expr.span); - } - let mut enclosing_loops = self.enclosing_loops.borrow_mut(); - let ctxt = enclosing_loops.find_loop(loop_id).unwrap(); + let mut enclosing_loops = self.enclosing_loops.borrow_mut(); + let ctxt = enclosing_loops.find_loop(loop_id).unwrap(); - let result = if let Some(ref e) = *expr_opt { - // Special-case the first element, as it has no "previous expressions". - let result = if !ctxt.may_break { - self.try_coerce(e, e_ty, ctxt.coerce_to) - } else { - self.try_find_coercion_lub(&cause, || ctxt.break_exprs.iter().cloned(), - ctxt.unified, e, e_ty) - }; - - ctxt.break_exprs.push(e); - result + let result = if let Some(ref e) = *expr_opt { + // Special-case the first element, as it has no "previous expressions". + let result = if !ctxt.may_break { + self.try_coerce(e, e_ty, ctxt.coerce_to) } else { - self.eq_types(true, &cause, e_ty, ctxt.unified) - .map(|InferOk { obligations, .. }| { - // FIXME(#32730) propagate obligations - assert!(obligations.is_empty()); - e_ty - }) + self.try_find_coercion_lub(&cause, || ctxt.break_exprs.iter().cloned(), + ctxt.unified, e, e_ty) }; - match result { - Ok(ty) => ctxt.unified = ty, - Err(err) => { - self.report_mismatched_types(&cause, ctxt.unified, e_ty, err); - } - } - ctxt.may_break = true; + ctxt.break_exprs.push(e); + result + } else { + self.eq_types(true, &cause, e_ty, ctxt.unified) + .map(|InferOk { obligations, .. }| { + // FIXME(#32730) propagate obligations + assert!(obligations.is_empty()); + e_ty + }) + }; + match result { + Ok(ty) => ctxt.unified = ty, + Err(err) => { + self.report_mismatched_types(&cause, ctxt.unified, e_ty, err); + } } - // Otherwise, we failed to find the enclosing loop; this can only happen if the - // `break` was not inside a loop at all, which is caught by the loop-checking pass. + + ctxt.may_break = true; } + // Otherwise, we failed to find the enclosing loop; this can only happen if the + // `break` was not inside a loop at all, which is caught by the loop-checking pass. tcx.types.never } hir::ExprAgain(_) => { tcx.types.never } @@ -4006,7 +3991,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary. - // The newly resolved definition is written into `def_map`. + // The newly resolved definition is written into `type_relative_path_defs`. fn finish_resolving_struct_path(&self, qpath: &hir::QPath, path_span: Span, @@ -4016,25 +4001,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { match *qpath { hir::QPath::Resolved(ref maybe_qself, ref path) => { let opt_self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself)); - let def = self.tcx.expect_def(node_id); - let ty = AstConv::def_to_ty(self, self, - path.span, - def, - opt_self_ty, - node_id, - &path.segments, - true); - (def, ty) + let ty = AstConv::def_to_ty(self, self, opt_self_ty, path, node_id, true); + (path.def, ty) } hir::QPath::TypeRelative(ref qself, ref segment) => { let ty = self.to_ty(qself); - let def = self.tcx.expect_def_or_none(qself.id).unwrap_or(Def::Err); + let def = if let hir::TyPath(hir::QPath::Resolved(_, ref path)) = qself.node { + path.def + } else { + Def::Err + }; let (ty, def) = AstConv::associated_path_def_to_ty(self, path_span, ty, def, segment); // Write back the new resolution. - self.tcx.def_map.borrow_mut().insert(node_id, PathResolution::new(def)); + self.tcx.tables.borrow_mut().type_relative_path_defs.insert(node_id, def); (def, ty) } @@ -4042,7 +4024,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } // Resolve associated value path into a base type and associated constant or method definition. - // The newly resolved definition is written into `def_map`. + // The newly resolved definition is written into `type_relative_path_defs`. pub fn resolve_ty_and_def_ufcs<'b>(&self, qpath: &'b hir::QPath, node_id: ast::NodeId, @@ -4051,7 +4033,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { { let (ty, item_segment) = match *qpath { hir::QPath::Resolved(ref opt_qself, ref path) => { - return (self.tcx.expect_def(node_id), + return (path.def, opt_qself.as_ref().map(|qself| self.to_ty(qself)), &path.segments[..]); } @@ -4075,7 +4057,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; // Write back the new resolution. - self.tcx.def_map.borrow_mut().insert(node_id, PathResolution::new(def)); + self.tcx.tables.borrow_mut().type_relative_path_defs.insert(node_id, def); (def, Some(ty), slice::ref_slice(&**item_segment)) } @@ -4083,7 +4065,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { local: &'gcx hir::Local, init: &'gcx hir::Expr) -> Ty<'tcx> { - let ref_bindings = self.tcx.pat_contains_ref_binding(&local.pat); + let ref_bindings = local.pat.contains_ref_binding(); let local_ty = self.local_ty(init.span, local.id); if let Some(m) = ref_bindings { diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 2b1bea89c52..ca33682480c 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -92,7 +92,6 @@ use rustc::ty::subst::Substs; use rustc::traits; use rustc::ty::{self, Ty, MethodCall, TypeFoldable}; use rustc::infer::{self, GenericKind, SubregionOrigin, VerifyBound}; -use hir::pat_util; use rustc::ty::adjustment; use rustc::ty::wf::ImpliedBound; @@ -434,7 +433,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { fn constrain_bindings_in_pat(&mut self, pat: &hir::Pat) { let tcx = self.tcx; debug!("regionck::visit_pat(pat={:?})", pat); - pat_util::pat_bindings(pat, |_, id, span, _| { + pat.each_binding(|_, id, span, _| { // If we have a variable that contains region'd data, that // data will be accessible from anywhere that the variable is // accessed. We must be wary of loops like this: diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index b83e453b2de..493f9d96fe0 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -542,11 +542,10 @@ fn is_param<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, param_id: ast::NodeId) -> bool { - if let hir::TyPath(hir::QPath::Resolved(None, _)) = ast_ty.node { - let path_res = tcx.expect_resolution(ast_ty.id); - match path_res.base_def { + if let hir::TyPath(hir::QPath::Resolved(None, ref path)) = ast_ty.node { + match path.def { Def::SelfTy(Some(def_id), None) | - Def::TyParam(def_id) if path_res.depth == 0 => { + Def::TyParam(def_id) => { def_id == tcx.map.local_def_id(param_id) } _ => false @@ -1625,8 +1624,7 @@ fn add_unsized_bound<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>, Some(ref tpb) => { // FIXME(#8559) currently requires the unbound to be built-in. if let Ok(kind_id) = kind_id { - let trait_def = tcx.expect_def(tpb.ref_id); - if trait_def != Def::Trait(kind_id) { + if tpb.path.def != Def::Trait(kind_id) { tcx.sess.span_warn(span, "default bound relaxed for a type parameter, but \ this does nothing because the given bound is not \ diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index c5562ae3b7f..e3274611e5b 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -29,24 +29,21 @@ use clean::{self, GetDefId}; use super::Clean; -/// Attempt to inline the definition of a local node id into this AST. +/// Attempt to inline a definition into this AST. /// -/// This function will fetch the definition of the id specified, and if it is -/// from another crate it will attempt to inline the documentation from the -/// other crate into this crate. +/// This function will fetch the definition specified, and if it is +/// from another crate it will attempt to inline the documentation +/// from the other crate into this crate. /// /// This is primarily used for `pub use` statements which are, in general, /// implementation details. Inlining the documentation should help provide a /// better experience when reading the documentation in this use case. /// -/// The returned value is `None` if the `id` could not be inlined, and `Some` -/// of a vector of items if it was successfully expanded. -pub fn try_inline(cx: &DocContext, id: ast::NodeId, into: Option<ast::Name>) +/// The returned value is `None` if the definition could not be inlined, +/// and `Some` of a vector of items if it was successfully expanded. +pub fn try_inline(cx: &DocContext, def: Def, into: Option<ast::Name>) -> Option<Vec<clean::Item>> { - let def = match cx.tcx.expect_def_or_none(id) { - Some(def) => def, - None => return None, - }; + if def == Def::Err { return None } let did = def.def_id(); if did.is_local() { return None } try_inline_def(cx, def).map(|vec| { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5e1b12e80d4..0fda1f4bf10 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -667,6 +667,7 @@ fn external_path(cx: &DocContext, name: &str, trait_did: Option<DefId>, has_self bindings: Vec<TypeBinding>, substs: &Substs) -> Path { Path { global: false, + def: Def::Err, segments: vec![PathSegment { name: name.to_string(), params: external_path_params(cx, trait_did, has_self, bindings, substs) @@ -1728,13 +1729,12 @@ impl Clean<Type> for hir::Ty { }, TyTup(ref tys) => Tuple(tys.clean(cx)), TyPath(hir::QPath::Resolved(None, ref path)) => { - let def = cx.tcx.expect_def(self.id); - if let Some(new_ty) = cx.ty_substs.borrow().get(&def).cloned() { + if let Some(new_ty) = cx.ty_substs.borrow().get(&path.def).cloned() { return new_ty; } let mut alias = None; - if let Def::TyAlias(def_id) = def { + if let Def::TyAlias(def_id) = path.def { // Substitute private type aliases if let Some(node_id) = cx.tcx.map.as_local_node_id(def_id) { if !cx.access_levels.borrow().is_exported(def_id) { @@ -1748,7 +1748,7 @@ impl Clean<Type> for hir::Ty { let mut ty_substs = FxHashMap(); let mut lt_substs = FxHashMap(); for (i, ty_param) in generics.ty_params.iter().enumerate() { - let ty_param_def = cx.tcx.expect_def(ty_param.id); + let ty_param_def = Def::TyParam(cx.tcx.map.local_def_id(ty_param.id)); if let Some(ty) = provided_params.types().get(i).cloned() .cloned() { ty_substs.insert(ty_param_def, ty.unwrap().clean(cx)); @@ -1772,6 +1772,7 @@ impl Clean<Type> for hir::Ty { let trait_path = hir::Path { span: p.span, global: p.global, + def: Def::Trait(cx.tcx.associated_item(p.def.def_id()).container.id()), segments: segments.into(), }; Type::QPath { @@ -1784,6 +1785,10 @@ impl Clean<Type> for hir::Ty { let trait_path = hir::Path { span: self.span, global: false, + def: cx.tcx_opt().map_or(Def::Err, |tcx| { + let def_id = tcx.tables().type_relative_path_defs[&self.id].def_id(); + Def::Trait(tcx.associated_item(def_id).container.id()) + }), segments: vec![].into(), }; Type::QPath { @@ -2194,6 +2199,7 @@ impl Clean<Span> for syntax_pos::Span { #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)] pub struct Path { pub global: bool, + pub def: Def, pub segments: Vec<PathSegment>, } @@ -2201,6 +2207,7 @@ impl Path { pub fn singleton(name: String) -> Path { Path { global: false, + def: Def::Err, segments: vec![PathSegment { name: name, params: PathParameters::AngleBracketed { @@ -2221,6 +2228,7 @@ impl Clean<Path> for hir::Path { fn clean(&self, cx: &DocContext) -> Path { Path { global: self.global, + def: self.def, segments: self.segments.clean(cx), } } @@ -2591,15 +2599,15 @@ impl Clean<Vec<Item>> for doctree::Import { }); let path = self.path.clean(cx); let inner = if self.glob { - Import::Glob(resolve_use_source(cx, path, self.id)) + Import::Glob(resolve_use_source(cx, path)) } else { let name = self.name; if !denied { - if let Some(items) = inline::try_inline(cx, self.id, Some(name)) { + if let Some(items) = inline::try_inline(cx, path.def, Some(name)) { return items; } } - Import::Simple(name.clean(cx), resolve_use_source(cx, path, self.id)) + Import::Simple(name.clean(cx), resolve_use_source(cx, path)) }; vec![Item { name: None, @@ -2697,7 +2705,7 @@ fn name_from_pat(p: &hir::Pat) -> String { match p.node { PatKind::Wild => "_".to_string(), - PatKind::Binding(_, ref p, _) => p.node.to_string(), + PatKind::Binding(_, _, ref p, _) => p.node.to_string(), PatKind::TupleStruct(ref p, ..) | PatKind::Path(ref p) => qpath_to_string(p), PatKind::Struct(ref name, ref fields, etc) => { format!("{} {{ {}{} }}", qpath_to_string(name), @@ -2727,15 +2735,13 @@ fn name_from_pat(p: &hir::Pat) -> String { } } -/// Given a Type, resolve it using the def_map +/// Given a type Path, resolve it to a Type using the TyCtxt fn resolve_type(cx: &DocContext, path: Path, id: ast::NodeId) -> Type { debug!("resolve_type({:?},{:?})", path, id); - let def = cx.tcx.expect_def(id); - debug!("resolve_type: def={:?}", def); - let is_generic = match def { + let is_generic = match path.def { Def::PrimTy(p) => match p { hir::TyStr => return Primitive(PrimitiveType::Str), hir::TyBool => return Primitive(PrimitiveType::Bool), @@ -2750,7 +2756,7 @@ fn resolve_type(cx: &DocContext, Def::SelfTy(..) | Def::TyParam(..) | Def::AssociatedTy(..) => true, _ => false, }; - let did = register_def(&*cx, def); + let did = register_def(&*cx, path.def); ResolvedPath { path: path, typarams: None, did: did, is_generic: is_generic } } @@ -2782,17 +2788,17 @@ fn register_def(cx: &DocContext, def: Def) -> DefId { did } -fn resolve_use_source(cx: &DocContext, path: Path, id: ast::NodeId) -> ImportSource { +fn resolve_use_source(cx: &DocContext, path: Path) -> ImportSource { ImportSource { + did: if path.def == Def::Err { + None + } else { + Some(register_def(cx, path.def)) + }, path: path, - did: resolve_def(cx, id), } } -fn resolve_def(cx: &DocContext, id: ast::NodeId) -> Option<DefId> { - cx.tcx.expect_def_or_none(id).map(|def| register_def(cx, def)) -} - #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Macro { pub source: String, @@ -2896,6 +2902,7 @@ fn lang_struct(cx: &DocContext, did: Option<DefId>, did: did, path: Path { global: false, + def: Def::Err, segments: vec