rustc: embed path resolutions into the HIR instead of keeping DefMap.

This commit is contained in:
Eduard-Mihai Burtescu 2016-11-25 13:21:19 +02:00
parent bc096549e8
commit 962633cdbb
55 changed files with 951 additions and 949 deletions

View file

@ -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);
}
}
}

View file

@ -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"

View file

@ -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);

View file

@ -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])
}
/// 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(&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())
}
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,

View file

@ -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);
}

View file

@ -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))
}

View file

@ -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>>),
@ -1022,6 +1020,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,
@ -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

View file

@ -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,
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::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
}
}
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
}
}
_ => 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 {
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),
_ => (),
}
}
});
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,
})
}
/// 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.
}
_ => true
}
});
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 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(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),
_ => ()
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
}
true
});
variants.sort();
variants.dedup();
variants
}
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
}
}
/// 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
});
}
/// 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
}
});
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 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
}
});
contains_bindings
}
pub fn simple_name(&self) -> Option<ast::Name> {
match self.node {
PatKind::Binding(hir::BindByValue(..), _, ref path1, None) => {
Some(path1.node)
}
_ => {
None
}
}
}
/// 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
}
/// 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),
_ => (),
}
}
});
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,
})
}
}

View file

@ -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

View file

@ -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()
}
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -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) {

View file

@ -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)
_ => {}
}
}));
}

View file

@ -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) => {

View file

@ -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;

View file

@ -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()

View file

@ -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);
}
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.borrow().method_map[&method_call].def_id;
Some(Def::Method(def_id))
}
_ => None
};
// If this wasn't a static, then the destination is
// surely reachable.
_ => {
self.reachable_symbols.insert(node_id);
}
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);
}
// If this wasn't a static, then the destination is
// surely reachable.
_ => {
self.reachable_symbols.insert(node_id);
}
}
}
}
hir::ExprMethodCall(..) => {
let method_call = ty::MethodCall::expr(expr.id);
let def_id = self.tcx.tables().method_map[&method_call].def_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)
}
self.reachable_symbols.insert(node_id);
}
}
_ => {}
}
intravisit::walk_expr(self, expr)

View file

@ -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(),
};

View file

@ -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);
}
}

View file

@ -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())),

View file

@ -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> {

View file

@ -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) => {