rustc: replace body exprs by their ids

This commit is contained in:
Florian Diebold 2016-10-28 22:58:32 +02:00 committed by Florian Diebold
parent 069a2442b8
commit f55482e7c9
22 changed files with 327 additions and 195 deletions

View File

@ -67,6 +67,14 @@ impl<'a> FnKind<'a> {
}
}
/// Specifies what nested things a visitor wants to visit. Currently there are
/// two modes: `OnlyBodies` descends into item bodies, but not into nested
/// items; `All` descends into item bodies and nested items.
pub enum NestedVisitMode {
OnlyBodies,
All
}
/// Each method of the Visitor trait is a hook to be potentially
/// overridden. Each method's default implementation recursively visits
/// the substructure of the input via the corresponding `walk` method;
@ -102,7 +110,7 @@ pub trait Visitor<'v> : Sized {
/// `panic!()`. This way, if a new `visit_nested_XXX` variant is
/// added in the future, we will see the panic in your code and
/// fix it appropriately.
fn nested_visit_map(&mut self) -> Option<&Map<'v>> {
fn nested_visit_map(&mut self) -> Option<(&Map<'v>, NestedVisitMode)> {
None
}
@ -116,7 +124,7 @@ pub trait Visitor<'v> : Sized {
/// but cannot supply a `Map`; see `nested_visit_map` for advice.
#[allow(unused_variables)]
fn visit_nested_item(&mut self, id: ItemId) {
let opt_item = self.nested_visit_map()
let opt_item = map_for_item(self)
.map(|map| map.expect_item(id.id));
if let Some(item) = opt_item {
self.visit_item(item);
@ -128,13 +136,25 @@ pub trait Visitor<'v> : Sized {
/// method.
#[allow(unused_variables)]
fn visit_nested_impl_item(&mut self, id: ImplItemId) {
let opt_item = self.nested_visit_map()
let opt_item = map_for_item(self)
.map(|map| map.impl_item(id));
if let Some(item) = opt_item {
self.visit_impl_item(item);
}
}
/// Invoked to visit the body of a function, method or closure. Like
/// visit_nested_item, does nothing by default unless you override
/// `nested_visit_map` to return `Some(_)`, in which case it will walk the
/// body.
fn visit_body(&mut self, id: ExprId) {
let opt_expr = map_for_body(self)
.map(|map| map.expr(id));
if let Some(expr) = opt_expr {
self.visit_expr(expr);
}
}
/// Visit the top-level item and (optionally) nested items / impl items. See
/// `visit_nested_item` for details.
fn visit_item(&mut self, i: &'v Item) {
@ -200,7 +220,7 @@ pub trait Visitor<'v> : Sized {
fn visit_where_predicate(&mut self, predicate: &'v WherePredicate) {
walk_where_predicate(self, predicate)
}
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Expr, s: Span, id: NodeId) {
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: ExprId, s: Span, id: NodeId) {
walk_fn(self, fk, fd, b, s, id)
}
fn visit_trait_item(&mut self, ti: &'v TraitItem) {
@ -279,6 +299,19 @@ pub trait Visitor<'v> : Sized {
}
}
fn map_for_body<'v, V: Visitor<'v>>(visitor: &mut V) -> Option<&Map<'v>> {
visitor.nested_visit_map().map(|(map, _mode)| map)
}
fn map_for_item<'v, V: Visitor<'v>>(visitor: &mut V) -> Option<&Map<'v>> {
visitor.nested_visit_map().and_then(|(map, mode)| {
match mode {
NestedVisitMode::OnlyBodies => None,
NestedVisitMode::All => Some(map)
}
})
}
pub fn walk_opt_name<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_name: Option<Name>) {
if let Some(name) = opt_name {
visitor.visit_name(span, name);
@ -363,7 +396,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
visitor.visit_ty(typ);
visitor.visit_expr(expr);
}
ItemFn(ref declaration, unsafety, constness, abi, ref generics, ref body) => {
ItemFn(ref declaration, unsafety, constness, abi, ref generics, body_id) => {
visitor.visit_fn(FnKind::ItemFn(item.name,
generics,
unsafety,
@ -372,7 +405,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
&item.vis,
&item.attrs),
declaration,
body,
body_id,
item.span,
item.id)
}
@ -697,13 +730,25 @@ pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'
pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
function_kind: FnKind<'v>,
function_declaration: &'v FnDecl,
function_body: &'v Expr,
body_id: ExprId,
_span: Span,
id: NodeId) {
visitor.visit_id(id);
walk_fn_decl(visitor, function_declaration);
walk_fn_kind(visitor, function_kind);
visitor.visit_expr(function_body)
visitor.visit_body(body_id)
}
pub fn walk_fn_with_body<'v, V: Visitor<'v>>(visitor: &mut V,
function_kind: FnKind<'v>,
function_declaration: &'v FnDecl,
body: &'v Expr,
_span: Span,
id: NodeId) {
visitor.visit_id(id);
walk_fn_decl(visitor, function_declaration);
walk_fn_kind(visitor, function_kind);
visitor.visit_expr(body)
}
pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) {
@ -720,13 +765,13 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
visitor.visit_generics(&sig.generics);
walk_fn_decl(visitor, &sig.decl);
}
MethodTraitItem(ref sig, Some(ref body)) => {
MethodTraitItem(ref sig, Some(body_id)) => {
visitor.visit_fn(FnKind::Method(trait_item.name,
sig,
None,
&trait_item.attrs),
&sig.decl,
body,
body_id,
trait_item.span,
trait_item.id);
}
@ -752,13 +797,13 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
visitor.visit_ty(ty);
visitor.visit_expr(expr);
}
ImplItemKind::Method(ref sig, ref body) => {
ImplItemKind::Method(ref sig, body_id) => {
visitor.visit_fn(FnKind::Method(impl_item.name,
sig,
Some(&impl_item.vis),
&impl_item.attrs),
&sig.decl,
body,
body_id,
impl_item.span,
impl_item.id);
}
@ -883,7 +928,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
visitor.visit_expr(subexpression);
walk_list!(visitor, visit_arm, arms);
}
ExprClosure(_, ref function_declaration, ref body, _fn_decl_span) => {
ExprClosure(_, ref function_declaration, body, _fn_decl_span) => {
visitor.visit_fn(FnKind::Closure(&expression.attrs),
function_declaration,
body,
@ -998,13 +1043,14 @@ impl IdRange {
}
pub struct IdRangeComputingVisitor {
pub result: IdRange,
pub struct IdRangeComputingVisitor<'a, 'ast: 'a> {
result: IdRange,
map: &'a map::Map<'ast>,
}
impl IdRangeComputingVisitor {
pub fn new() -> IdRangeComputingVisitor {
IdRangeComputingVisitor { result: IdRange::max() }
impl<'a, 'ast> IdRangeComputingVisitor<'a, 'ast> {
pub fn new(map: &'a map::Map<'ast>) -> IdRangeComputingVisitor<'a, 'ast> {
IdRangeComputingVisitor { result: IdRange::max(), map: map }
}
pub fn result(&self) -> IdRange {
@ -1012,20 +1058,25 @@ impl IdRangeComputingVisitor {
}
}
impl<'v> Visitor<'v> for IdRangeComputingVisitor {
impl<'a, 'ast> Visitor<'ast> for IdRangeComputingVisitor<'a, 'ast> {
fn nested_visit_map(&mut self) -> Option<(&Map<'ast>, NestedVisitMode)> {
Some((&self.map, NestedVisitMode::OnlyBodies))
}
fn visit_id(&mut self, id: NodeId) {
self.result.add(id);
}
}
/// Computes the id range for a single fn body, ignoring nested items.
pub fn compute_id_range_for_fn_body(fk: FnKind,
decl: &FnDecl,
body: &Expr,
sp: Span,
id: NodeId)
-> IdRange {
let mut visitor = IdRangeComputingVisitor::new();
visitor.visit_fn(fk, decl, body, sp, id);
pub fn compute_id_range_for_fn_body<'v>(fk: FnKind<'v>,
decl: &'v FnDecl,
body: &'v Expr,
sp: Span,
id: NodeId,
map: &map::Map<'v>)
-> IdRange {
let mut visitor = IdRangeComputingVisitor::new(map);
walk_fn_with_body(&mut visitor, fk, decl, body, sp, id);
visitor.result()
}

View File

@ -845,12 +845,14 @@ impl<'a> LoweringContext<'a> {
}
ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => {
let body = self.lower_block(body);
let body = self.expr_block(body, ThinVec::new());
let body_id = self.record_expr(body);
hir::ItemFn(self.lower_fn_decl(decl),
self.lower_unsafety(unsafety),
self.lower_constness(constness),
abi,
self.lower_generics(generics),
P(self.expr_block(body, ThinVec::new())))
body_id)
}
ItemKind::Mod(ref m) => hir::ItemMod(self.lower_mod(m)),
ItemKind::ForeignMod(ref nm) => hir::ItemForeignMod(self.lower_foreign_mod(nm)),
@ -917,7 +919,8 @@ impl<'a> LoweringContext<'a> {
hir::MethodTraitItem(this.lower_method_sig(sig),
body.as_ref().map(|x| {
let body = this.lower_block(x);
P(this.expr_block(body, ThinVec::new()))
let expr = this.expr_block(body, ThinVec::new());
this.record_expr(expr)
}))
}
TraitItemKind::Type(ref bounds, ref default) => {
@ -945,8 +948,9 @@ impl<'a> LoweringContext<'a> {
}
ImplItemKind::Method(ref sig, ref body) => {
let body = this.lower_block(body);
hir::ImplItemKind::Method(this.lower_method_sig(sig),
P(this.expr_block(body, ThinVec::new())))
let expr = this.expr_block(body, ThinVec::new());
let expr_id = this.record_expr(expr);
hir::ImplItemKind::Method(this.lower_method_sig(sig), expr_id)
}
ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(this.lower_ty(ty)),
ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
@ -1395,9 +1399,10 @@ impl<'a> LoweringContext<'a> {
}
ExprKind::Closure(capture_clause, ref decl, ref body, fn_decl_span) => {
self.with_parent_def(e.id, |this| {
let expr = this.lower_expr(body);
hir::ExprClosure(this.lower_capture_clause(capture_clause),
this.lower_fn_decl(decl),
P(this.lower_expr(body)),
this.record_expr(expr),
fn_decl_span)
})
}

View File

@ -48,7 +48,7 @@ pub trait MaybeFnLike { fn is_fn_like(&self) -> bool; }
/// Components shared by fn-like things (fn items, methods, closures).
pub struct FnParts<'a> {
pub decl: &'a FnDecl,
pub body: &'a Expr,
pub body: ast::ExprId,
pub kind: FnKind<'a>,
pub span: Span,
pub id: NodeId,
@ -115,7 +115,7 @@ struct ItemFnParts<'a> {
abi: abi::Abi,
vis: &'a ast::Visibility,
generics: &'a ast::Generics,
body: &'a Expr,
body: ast::ExprId,
id: NodeId,
span: Span,
attrs: &'a [Attribute],
@ -125,14 +125,14 @@ struct ItemFnParts<'a> {
/// for use when implementing FnLikeNode operations.
struct ClosureParts<'a> {
decl: &'a FnDecl,
body: &'a Expr,
body: ast::ExprId,
id: NodeId,
span: Span,
attrs: &'a [Attribute],
}
impl<'a> ClosureParts<'a> {
fn new(d: &'a FnDecl, b: &'a Expr, id: NodeId, s: Span, attrs: &'a [Attribute]) -> Self {
fn new(d: &'a FnDecl, b: ast::ExprId, id: NodeId, s: Span, attrs: &'a [Attribute]) -> Self {
ClosureParts {
decl: d,
body: b,
@ -172,9 +172,9 @@ impl<'a> FnLikeNode<'a> {
}
}
pub fn body(self) -> &'a Expr {
self.handle(|i: ItemFnParts<'a>| &*i.body,
|_, _, _: &'a ast::MethodSig, _, body: &'a ast::Expr, _, _| body,
pub fn body(self) -> ast::ExprId {
self.handle(|i: ItemFnParts<'a>| i.body,
|_, _, _: &'a ast::MethodSig, _, body: ast::ExprId, _, _| body,
|c: ClosureParts<'a>| c.body)
}
@ -215,7 +215,7 @@ impl<'a> FnLikeNode<'a> {
Name,
&'a ast::MethodSig,
Option<&'a ast::Visibility>,
&'a ast::Expr,
ast::ExprId,
Span,
&'a [Attribute])
-> A,
@ -223,13 +223,13 @@ impl<'a> FnLikeNode<'a> {
{
match self.node {
map::NodeItem(i) => match i.node {
ast::ItemFn(ref decl, unsafety, constness, abi, ref generics, ref block) =>
ast::ItemFn(ref decl, unsafety, constness, abi, ref generics, block) =>
item_fn(ItemFnParts {
id: i.id,
name: i.name,
decl: &decl,
unsafety: unsafety,
body: &block,
body: block,
generics: generics,
abi: abi,
vis: &i.vis,
@ -240,14 +240,14 @@ impl<'a> FnLikeNode<'a> {
_ => bug!("item FnLikeNode that is not fn-like"),
},
map::NodeTraitItem(ti) => match ti.node {
ast::MethodTraitItem(ref sig, Some(ref body)) => {
ast::MethodTraitItem(ref sig, Some(body)) => {
method(ti.id, ti.name, sig, None, body, ti.span, &ti.attrs)
}
_ => bug!("trait method FnLikeNode that is not fn-like"),
},
map::NodeImplItem(ii) => {
match ii.node {
ast::ImplItemKind::Method(ref sig, ref body) => {
ast::ImplItemKind::Method(ref sig, body) => {
method(ii.id, ii.name, sig, Some(&ii.vis), body, ii.span, &ii.attrs)
}
_ => {
@ -256,8 +256,8 @@ impl<'a> FnLikeNode<'a> {
}
}
map::NodeExpr(e) => match e.node {
ast::ExprClosure(_, ref decl, ref block, _fn_decl_span) =>
closure(ClosureParts::new(&decl, &block, e.id, e.span, &e.attrs)),
ast::ExprClosure(_, ref decl, block, _fn_decl_span) =>
closure(ClosureParts::new(&decl, block, e.id, e.span, &e.attrs)),
_ => bug!("expr FnLikeNode that is not fn-like"),
},
_ => bug!("other FnLikeNode that is not fn-like"),

View File

@ -10,7 +10,8 @@
use super::*;
use hir::intravisit::Visitor;
use hir::*;
use hir::intravisit::{Visitor, NestedVisitMode};
use hir::def_id::DefId;
use middle::cstore::InlinedItem;
use std::iter::repeat;
@ -91,7 +92,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
/// deep walking so that we walk nested items in the context of
/// their outer items.
fn nested_visit_map(&mut self) -> Option<&map::Map<'ast>> {
fn nested_visit_map(&mut self) -> Option<(&map::Map<'ast>, NestedVisitMode)> {
panic!("visit_nested_xxx must be manually implemented in this visitor")
}
@ -106,6 +107,10 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
self.visit_impl_item(self.krate.impl_item(item_id))
}
fn visit_body(&mut self, id: ExprId) {
self.visit_expr(self.krate.expr(id))
}
fn visit_item(&mut self, i: &'ast Item) {
debug!("visit_item: {:?}", i);
@ -209,7 +214,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
}
fn visit_fn(&mut self, fk: intravisit::FnKind<'ast>, fd: &'ast FnDecl,
b: &'ast Expr, s: Span, id: NodeId) {
b: ExprId, s: Span, id: NodeId) {
assert_eq!(self.parent_node, id);
intravisit::walk_fn(self, fk, fd, b, s, id);
}

View File

@ -327,6 +327,12 @@ impl<'a> visit::Visitor for DefCollector<'a> {
// We walk the HIR rather than the AST when reading items from metadata.
impl<'ast> intravisit::Visitor<'ast> for DefCollector<'ast> {
fn visit_body(&mut self, id: hir::ExprId) {
if let Some(krate) = self.hir_crate {
self.visit_expr(krate.expr(id));
}
}
fn visit_item(&mut self, i: &'ast hir::Item) {
debug!("visit_item: {:?}", i);

View File

@ -655,6 +655,10 @@ impl<'ast> Map<'ast> {
}
}
pub fn expr(&self, id: ExprId) -> &'ast Expr {
self.expect_expr(id.node_id())
}
/// Returns the name associated with the given NodeId's AST.
pub fn name(&self, id: NodeId) -> Name {
match self.get(id) {

View File

@ -460,6 +460,10 @@ impl Crate {
visitor.visit_impl_item(impl_item);
}
}
pub fn expr(&self, id: ExprId) -> &Expr {
&self.exprs[&id]
}
}
/// A macro definition, in this crate or imported from another.
@ -925,7 +929,7 @@ pub enum Expr_ {
/// A closure (for example, `move |a, b, c| {a + b + c}`).
///
/// The final span is the span of the argument block `|...|`
ExprClosure(CaptureClause, P<FnDecl>, P<Expr>, Span),
ExprClosure(CaptureClause, P<FnDecl>, ExprId, Span),
/// A block (`{ ... }`)
ExprBlock(P<Block>),
@ -1079,7 +1083,7 @@ pub enum TraitItem_ {
/// must contain a value)
ConstTraitItem(P<Ty>, Option<P<Expr>>),
/// A method with an optional body
MethodTraitItem(MethodSig, Option<P<Expr>>),
MethodTraitItem(MethodSig, Option<ExprId>),
/// An associated type with (possibly empty) bounds and optional concrete
/// type
TypeTraitItem(TyParamBounds, Option<P<Ty>>),
@ -1112,7 +1116,7 @@ pub enum ImplItemKind {
/// of the expression
Const(P<Ty>, P<Expr>),
/// A method implementation with the given signature and body
Method(MethodSig, P<Expr>),
Method(MethodSig, ExprId),
/// An associated type
Type(P<Ty>),
}
@ -1557,7 +1561,7 @@ pub enum Item_ {
/// A `const` item
ItemConst(P<Ty>, P<Expr>),
/// A function declaration
ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, P<Expr>),
ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, ExprId),
/// A module
ItemMod(Mod),
/// An external module

View File

@ -644,6 +644,15 @@ impl<'a> State<'a> {
}
}
pub fn print_expr_id(&mut self, expr_id: &hir::ExprId) -> io::Result<()> {
if let Some(krate) = self.krate {
let expr = &krate.exprs[expr_id];
self.print_expr(expr)
} else {
Ok(())
}
}
/// Pretty-print an item
pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> {
self.hardbreak_if_not_bol()?;
@ -729,7 +738,7 @@ impl<'a> State<'a> {
word(&mut self.s, " ")?;
self.end()?; // need to close a box
self.end()?; // need to close a box
self.print_expr(&body)?;
self.print_expr_id(body)?;
}
hir::ItemMod(ref _mod) => {
self.head(&visibility_qualified(&item.vis, "mod"))?;
@ -1020,7 +1029,7 @@ impl<'a> State<'a> {
self.nbsp()?;
self.end()?; // need to close a box
self.end()?; // need to close a box
self.print_expr(body)?;
self.print_expr_id(body)?;
} else {
word(&mut self.s, ";")?;
}
@ -1065,7 +1074,7 @@ impl<'a> State<'a> {
self.nbsp()?;
self.end()?; // need to close a box
self.end()?; // need to close a box
self.print_expr(body)?;
self.print_expr_id(body)?;
}
hir::ImplItemKind::Type(ref ty) => {
self.print_associated_type(ii.name, None, Some(ty))?;
@ -1432,7 +1441,7 @@ impl<'a> State<'a> {
space(&mut self.s)?;
// this is a bare expression
self.print_expr(body)?;
self.print_expr_id(body)?;
self.end()?; // need to close a box
// a box will be closed by print_expr, but we didn't want an overall

View File

@ -719,10 +719,10 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
}
}
fn visit_ids<F>(&mut self, f: F)
where F: FnOnce(&mut IdVisitor)
fn visit_ids<'b, F: 'b>(&'b mut self, f: F)
where F: FnOnce(&mut IdVisitor<'b, 'a, 'tcx>)
{
let mut v = IdVisitor {
let mut v = IdVisitor::<'b, 'a, 'tcx> {
cx: self
};
f(&mut v);
@ -791,8 +791,8 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
/// Because lints are scoped lexically, we want to walk nested
/// items in the context of the outer item, so enable
/// deep-walking.
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
Some(&self.tcx.map)
fn nested_visit_map(&mut self) -> Option<(&hir::map::Map<'tcx>, hir_visit::NestedVisitMode)> {
Some((&self.tcx.map, hir_visit::NestedVisitMode::All))
}
fn visit_item(&mut self, it: &'tcx hir::Item) {
@ -835,9 +835,10 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
}
fn visit_fn(&mut self, fk: hir_visit::FnKind<'tcx>, decl: &'tcx hir::FnDecl,
body: &'tcx hir::Expr, span: Span, id: ast::NodeId) {
body_id: hir::ExprId, span: Span, id: ast::NodeId) {
let body = self.tcx.map.expr(body_id);
run_lints!(self, check_fn, late_passes, fk, decl, body, span, id);
hir_visit::walk_fn(self, fk, decl, body, span, id);
hir_visit::walk_fn(self, fk, decl, body_id, span, id);
run_lints!(self, check_fn_post, late_passes, fk, decl, body, span, id);
}
@ -1107,7 +1108,11 @@ struct IdVisitor<'a, 'b: 'a, 'tcx: 'a+'b> {
}
// Output any lints that were previously added to the session.
impl<'a, 'b, 'tcx, 'v> hir_visit::Visitor<'v> for IdVisitor<'a, 'b, 'tcx> {
impl<'a, 'b, 'tcx> hir_visit::Visitor<'tcx> for IdVisitor<'a, 'b, 'tcx> {
fn nested_visit_map(&mut self) -> Option<(&hir::map::Map<'tcx>, hir_visit::NestedVisitMode)> {
Some((&self.cx.tcx.map, hir_visit::NestedVisitMode::OnlyBodies))
}
fn visit_id(&mut self, id: ast::NodeId) {
if let Some(lints) = self.cx.sess().lints.borrow_mut().remove(&id) {
debug!("LateContext::visit_id: id={:?} lints={:?}", id, lints);
@ -1117,12 +1122,12 @@ impl<'a, 'b, 'tcx, 'v> hir_visit::Visitor<'v> for IdVisitor<'a, 'b, 'tcx> {
}
}
fn visit_trait_item(&mut self, _ti: &hir::TraitItem) {
fn visit_trait_item(&mut self, _ti: &'tcx hir::TraitItem) {
// Do not recurse into trait or impl items automatically. These are
// processed separately by calling hir_visit::walk_trait_item()
}
fn visit_impl_item(&mut self, _ii: &hir::ImplItem) {
fn visit_impl_item(&mut self, _ii: &'tcx hir::ImplItem) {
// See visit_trait_item()
}
}

View File

@ -15,7 +15,7 @@
use dep_graph::DepNode;
use hir::map as ast_map;
use hir::{self, PatKind};
use hir::intravisit::{self, Visitor};
use hir::intravisit::{self, Visitor, NestedVisitMode};
use hir::itemlikevisit::ItemLikeVisitor;
use middle::privacy;
@ -175,7 +175,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
}
}
fn visit_node(&mut self, node: &ast_map::Node) {
fn visit_node(&mut self, node: &ast_map::Node<'tcx>) {
let had_extern_repr = self.struct_has_extern_repr;
self.struct_has_extern_repr = false;
let had_inherited_pub_visibility = self.inherited_pub_visibility;
@ -220,9 +220,12 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
}
}
impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
fn nested_visit_map(&mut self) -> Option<(&hir::map::Map<'tcx>, NestedVisitMode)> {
Some((&self.tcx.map, NestedVisitMode::OnlyBodies))
}
fn visit_variant_data(&mut self, def: &hir::VariantData, _: ast::Name,
fn visit_variant_data(&mut self, def: &'tcx hir::VariantData, _: ast::Name,
_: &hir::Generics, _: ast::NodeId, _: syntax_pos::Span) {
let has_extern_repr = self.struct_has_extern_repr;
let inherited_pub_visibility = self.inherited_pub_visibility;
@ -234,7 +237,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
intravisit::walk_struct_def(self, def);
}
fn visit_expr(&mut self, expr: &hir::Expr) {
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
match expr.node {
hir::ExprPath(ref qpath @ hir::QPath::TypeRelative(..)) => {
let def = self.tcx.tables().qpath_def(qpath, expr.id);
@ -255,7 +258,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
intravisit::walk_expr(self, expr);
}
fn visit_arm(&mut self, arm: &hir::Arm) {
fn visit_arm(&mut self, arm: &'tcx hir::Arm) {
if arm.pats.len() == 1 {
let variants = arm.pats[0].necessary_variants();
@ -271,7 +274,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
}
}
fn visit_pat(&mut self, pat: &hir::Pat) {
fn visit_pat(&mut self, pat: &'tcx hir::Pat) {
match pat.node {
PatKind::Struct(hir::QPath::Resolved(_, ref path), ref fields, _) => {
self.handle_field_pattern_match(pat, path.def, fields);
@ -288,8 +291,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
self.ignore_non_const_paths = false;
}
fn visit_path(&mut self, path: &hir::Path, id: ast::NodeId) {
self.handle_definition(id, path.def);
fn visit_path(&mut self, path: &'tcx hir::Path, id: ast::NodeId) {
self.lookup_and_handle_definition(id);
intravisit::walk_path(self, path);
}
}
@ -507,8 +510,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
/// on inner functions when the outer function is already getting
/// an error. We could do this also by checking the parents, but
/// this is how the code is setup and it seems harmless enough.
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
Some(&self.tcx.map)
fn nested_visit_map(&mut self) -> Option<(&hir::map::Map<'tcx>, NestedVisitMode)> {
Some((&self.tcx.map, NestedVisitMode::All))
}
fn visit_item(&mut self, item: &'tcx hir::Item) {
@ -562,12 +565,12 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
}
intravisit::walk_expr(self, expr)
}
hir::ImplItemKind::Method(_, ref body) => {
hir::ImplItemKind::Method(_, body_id) => {
if !self.symbol_is_live(impl_item.id, None) {
self.warn_dead_code(impl_item.id, impl_item.span,
impl_item.name, "method");
}
intravisit::walk_expr(self, body)
self.visit_body(body_id)
}
hir::ImplItemKind::Type(..) => {}
}
@ -576,10 +579,12 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
// Overwrite so that we don't warn the trait item itself.
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
match trait_item.node {
hir::ConstTraitItem(_, Some(ref body))|
hir::MethodTraitItem(_, Some(ref body)) => {
hir::ConstTraitItem(_, Some(ref body)) => {
intravisit::walk_expr(self, body)
}
hir::MethodTraitItem(_, Some(body_id)) => {
self.visit_body(body_id)
}
hir::ConstTraitItem(_, None) |
hir::MethodTraitItem(_, None) |
hir::TypeTraitItem(..) => {}

View File

@ -21,7 +21,7 @@ use syntax::ast;
use syntax_pos::Span;
use hir::{self, PatKind};
use hir::def::Def;
use hir::intravisit::{self, FnKind, Visitor};
use hir::intravisit::{self, FnKind, Visitor, NestedVisitMode};
#[derive(Copy, Clone)]
struct UnsafeContext {
@ -92,9 +92,13 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> {
}
}
impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
fn visit_fn(&mut self, fn_kind: FnKind<'v>, fn_decl: &'v hir::FnDecl,
block: &'v hir::Expr, span: Span, id: ast::NodeId) {
impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
fn nested_visit_map(&mut self) -> Option<(&hir::map::Map<'tcx>, NestedVisitMode)> {
Some((&self.tcx.map, NestedVisitMode::OnlyBodies))
}
fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, fn_decl: &'tcx hir::FnDecl,
body_id: hir::ExprId, span: Span, id: ast::NodeId) {
let (is_item_fn, is_unsafe_fn) = match fn_kind {
FnKind::ItemFn(_, _, unsafety, ..) =>
@ -111,12 +115,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
self.unsafe_context = UnsafeContext::new(SafeContext)
}
intravisit::walk_fn(self, fn_kind, fn_decl, block, span, id);
intravisit::walk_fn(self, fn_kind, fn_decl, body_id, span, id);
self.unsafe_context = old_unsafe_context
}
fn visit_block(&mut self, block: &hir::Block) {
fn visit_block(&mut self, block: &'tcx hir::Block) {
let old_unsafe_context = self.unsafe_context;
match block.rules {
hir::UnsafeBlock(source) => {
@ -155,7 +159,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
self.unsafe_context = old_unsafe_context
}
fn visit_expr(&mut self, expr: &hir::Expr) {
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
match expr.node {
hir::ExprMethodCall(..) => {
let method_call = MethodCall::expr(expr.id);
@ -212,7 +216,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
intravisit::walk_expr(self, expr);
}
fn visit_pat(&mut self, pat: &hir::Pat) {
fn visit_pat(&mut self, pat: &'tcx hir::Pat) {
if let PatKind::Struct(_, ref fields, _) = pat.node {
if let ty::TyAdt(adt, ..) = self.tcx.tables().pat_ty(pat).sty {
if adt.is_union() {

View File

@ -47,6 +47,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> {
find_item(item, self, at_root);
}
fn visit_impl_item(&mut self, _impl_item: &'tcx ImplItem) {
// entry fn is never an impl item
}

View File

@ -19,7 +19,7 @@ use ty::layout::{LayoutError, Pointer, SizeSkeleton};
use syntax::abi::Abi::RustIntrinsic;
use syntax::ast;
use syntax_pos::Span;
use hir::intravisit::{self, Visitor, FnKind};
use hir::intravisit::{self, Visitor, FnKind, NestedVisitMode};
use hir;
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
@ -34,7 +34,7 @@ struct ItemVisitor<'a, 'tcx: 'a> {
}
impl<'a, 'tcx> ItemVisitor<'a, 'tcx> {
fn visit_const(&mut self, item_id: ast::NodeId, expr: &hir::Expr) {
fn visit_const(&mut self, item_id: ast::NodeId, expr: &'tcx hir::Expr) {
let param_env = ty::ParameterEnvironment::for_item(self.tcx, item_id);
self.tcx.infer_ctxt(None, Some(param_env), Reveal::All).enter(|infcx| {
let mut visitor = ExprVisitor {
@ -116,9 +116,13 @@ impl<'a, 'gcx, 'tcx> ExprVisitor<'a, 'gcx, 'tcx> {
}
}
impl<'a, 'tcx, 'v> Visitor<'v> for ItemVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for ItemVisitor<'a, 'tcx> {
fn nested_visit_map(&mut self) -> Option<(&hir::map::Map<'tcx>, NestedVisitMode)> {
Some((&self.tcx.map, NestedVisitMode::OnlyBodies))
}
// const, static and N in [T; N].
fn visit_expr(&mut self, expr: &hir::Expr) {
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
self.tcx.infer_ctxt(None, None, Reveal::All).enter(|infcx| {
let mut visitor = ExprVisitor {
infcx: &infcx
@ -127,7 +131,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ItemVisitor<'a, 'tcx> {
});
}
fn visit_trait_item(&mut self, item: &hir::TraitItem) {
fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem) {
if let hir::ConstTraitItem(_, Some(ref expr)) = item.node {
self.visit_const(item.id, expr);
} else {
@ -135,7 +139,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ItemVisitor<'a, 'tcx> {
}
}
fn visit_impl_item(&mut self, item: &hir::ImplItem) {
fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem) {
if let hir::ImplItemKind::Const(_, ref expr) = item.node {
self.visit_const(item.id, expr);
} else {
@ -143,8 +147,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ItemVisitor<'a, 'tcx> {
}
}
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
b: &'v hir::Expr, s: Span, id: ast::NodeId) {
fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
b: hir::ExprId, s: Span, id: ast::NodeId) {
if let FnKind::Closure(..) = fk {
span_bug!(s, "intrinsicck: closure outside of function")
}
@ -158,8 +162,12 @@ 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) {
impl<'a, 'gcx, 'tcx> Visitor<'gcx> for ExprVisitor<'a, 'gcx, 'tcx> {
fn nested_visit_map(&mut self) -> Option<(&hir::map::Map<'gcx>, NestedVisitMode)> {
Some((&self.infcx.tcx.map, NestedVisitMode::OnlyBodies))
}
fn visit_expr(&mut self, expr: &'gcx hir::Expr) {
let def = if let hir::ExprPath(ref qpath) = expr.node {
self.infcx.tcx.tables().qpath_def(qpath, expr.id)
} else {

View File

@ -128,7 +128,7 @@ use syntax_pos::Span;
use hir::Expr;
use hir;
use hir::print::{expr_to_string, block_to_string};
use hir::intravisit::{self, Visitor, FnKind};
use hir::intravisit::{self, Visitor, FnKind, NestedVisitMode};
/// For use with `propagate_through_loop`.
enum LoopKind<'a> {
@ -182,14 +182,17 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt) -> String {
}
}
impl<'a, 'tcx, 'v> Visitor<'v> for IrMaps<'a, 'tcx> {
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v hir::FnDecl,
b: &'v hir::Expr, s: Span, id: NodeId) {
impl<'a, 'tcx> Visitor<'tcx> for IrMaps<'a, 'tcx> {
fn nested_visit_map(&mut self) -> Option<(&hir::map::Map<'tcx>, NestedVisitMode)> {
Some((&self.tcx.map, NestedVisitMode::OnlyBodies))
}
fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
b: hir::ExprId, s: Span, id: NodeId) {
visit_fn(self, fk, fd, b, s, id);
}
fn visit_local(&mut self, l: &hir::Local) { visit_local(self, l); }
fn visit_expr(&mut self, ex: &Expr) { visit_expr(self, ex); }
fn visit_arm(&mut self, a: &hir::Arm) { visit_arm(self, a); }
fn visit_local(&mut self, l: &'tcx hir::Local) { visit_local(self, l); }
fn visit_expr(&mut self, ex: &'tcx Expr) { visit_expr(self, ex); }
fn visit_arm(&mut self, a: &'tcx hir::Arm) { visit_arm(self, a); }
}
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
@ -348,28 +351,31 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
}
}
impl<'a, 'tcx, 'v> Visitor<'v> for Liveness<'a, 'tcx> {
fn visit_fn(&mut self, _: FnKind<'v>, _: &'v hir::FnDecl,
_: &'v hir::Expr, _: Span, _: NodeId) {
impl<'a, 'tcx> Visitor<'tcx> for Liveness<'a, 'tcx> {
fn nested_visit_map(&mut self) -> Option<(&hir::map::Map<'tcx>, NestedVisitMode)> {
Some((&self.ir.tcx.map, NestedVisitMode::OnlyBodies))
}
fn visit_fn(&mut self, _: FnKind<'tcx>, _: &'tcx hir::FnDecl,
_: hir::ExprId, _: Span, _: NodeId) {
// do not check contents of nested fns
}
fn visit_local(&mut self, l: &hir::Local) {
fn visit_local(&mut self, l: &'tcx hir::Local) {
check_local(self, l);
}
fn visit_expr(&mut self, ex: &Expr) {
fn visit_expr(&mut self, ex: &'tcx Expr) {
check_expr(self, ex);
}
fn visit_arm(&mut self, a: &hir::Arm) {
fn visit_arm(&mut self, a: &'tcx hir::Arm) {
check_arm(self, a);
}
}
fn visit_fn(ir: &mut IrMaps,
fk: FnKind,
decl: &hir::FnDecl,
body: &hir::Expr,
sp: Span,
id: ast::NodeId) {
fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
fk: FnKind<'tcx>,
decl: &'tcx hir::FnDecl,
body_id: hir::ExprId,
sp: Span,
id: ast::NodeId) {
debug!("visit_fn");
// swap in a new set of IR maps for this function body:
@ -387,7 +393,7 @@ fn visit_fn(ir: &mut IrMaps,
// gather up the various local variables, significant expressions,
// and so forth:
intravisit::walk_fn(&mut fn_maps, fk, decl, body, sp, id);
intravisit::walk_fn(&mut fn_maps, fk, decl, body_id, sp, id);
// Special nodes and variables:
// - exit_ln represents the end of the fn, either by return or panic
@ -400,6 +406,8 @@ fn visit_fn(ir: &mut IrMaps,
clean_exit_var: fn_maps.add_variable(CleanExit)
};
let body = ir.tcx.map.expr(body_id);
// compute liveness
let mut lsets = Liveness::new(&mut fn_maps, specials);
let entry_ln = lsets.compute(body);
@ -410,7 +418,7 @@ fn visit_fn(ir: &mut IrMaps,
lsets.warn_about_unused_args(decl, entry_ln);
}
fn visit_local(ir: &mut IrMaps, local: &hir::Local) {
fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) {
local.pat.each_binding(|_, p_id, sp, path1| {
debug!("adding local variable {}", p_id);
let name = path1.node;
@ -423,7 +431,7 @@ fn visit_local(ir: &mut IrMaps, local: &hir::Local) {
intravisit::walk_local(ir, local);
}
fn visit_arm(ir: &mut IrMaps, arm: &hir::Arm) {
fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) {
for pat in &arm.pats {
pat.each_binding(|bm, p_id, sp, path1| {
debug!("adding local variable {} from match with bm {:?}",
@ -439,7 +447,7 @@ fn visit_arm(ir: &mut IrMaps, arm: &hir::Arm) {
intravisit::walk_arm(ir, arm);
}
fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
match expr.node {
// live nodes required for uses or definitions of variables:
hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
@ -923,7 +931,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.propagate_through_expr(&e, succ)
}
hir::ExprClosure(.., ref blk, _) => {
hir::ExprClosure(.., blk_id, _) => {
debug!("{} is an ExprClosure",
expr_to_string(expr));
@ -932,7 +940,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
loop. The next-node for a continue is the top of this loop.
*/
let node = self.live_node(expr.id, expr.span);
self.with_loop_nodes(blk.id, succ, node, |this| {
self.with_loop_nodes(blk_id.node_id(), succ, node, |this| {
// the construction of a closure itself is not important,
// but we have to consider the closed over variables.
@ -1354,7 +1362,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
// _______________________________________________________________________
// Checking for error conditions
fn check_local(this: &mut Liveness, local: &hir::Local) {
fn check_local<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, local: &'tcx hir::Local) {
match local.init {
Some(_) => {
this.warn_about_unused_or_dead_vars_in_pat(&local.pat);
@ -1369,7 +1377,7 @@ fn check_local(this: &mut Liveness, local: &hir::Local) {
intravisit::walk_local(this, local);
}
fn check_arm(this: &mut Liveness, arm: &hir::Arm) {
fn check_arm<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, arm: &'tcx hir::Arm) {
// only consider the first pattern; any later patterns must have
// the same bindings, and we also consider the first pattern to be
// the "authoritative" set of ids
@ -1379,7 +1387,7 @@ fn check_arm(this: &mut Liveness, arm: &hir::Arm) {
intravisit::walk_arm(this, arm);
}
fn check_expr(this: &mut Liveness, expr: &Expr) {
fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) {
match expr.node {
hir::ExprAssign(ref l, _) => {
this.check_lvalue(&l);
@ -1469,7 +1477,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
}
}
fn check_lvalue(&mut self, expr: &Expr) {
fn check_lvalue(&mut self, expr: &'tcx Expr) {
match expr.node {
hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
if let Def::Local(def_id) = path.def {

View File

@ -705,7 +705,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
};
match fn_expr.node {
hir::ExprClosure(.., ref body, _) => body.id,
hir::ExprClosure(.., body_id, _) => body_id.node_id(),
_ => bug!()
}
};

View File

@ -28,7 +28,7 @@ use syntax::abi::Abi;
use syntax::ast;
use syntax::attr;
use hir;
use hir::intravisit::Visitor;
use hir::intravisit::{Visitor, NestedVisitMode};
use hir::itemlikevisit::ItemLikeVisitor;
use hir::intravisit;
@ -88,8 +88,12 @@ struct ReachableContext<'a, 'tcx: 'a> {
any_library: bool,
}
impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
fn visit_expr(&mut self, expr: &hir::Expr) {
impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> {
fn nested_visit_map(&mut self) -> Option<(&hir::map::Map<'tcx>, NestedVisitMode)> {
Some((&self.tcx.map, NestedVisitMode::OnlyBodies))
}
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
let def = match expr.node {
hir::ExprPath(ref qpath) => {
Some(self.tcx.tables().qpath_def(qpath, expr.id))
@ -216,7 +220,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
}
}
fn propagate_node(&mut self, node: &ast_map::Node,
fn propagate_node(&mut self, node: &ast_map::Node<'tcx>,
search_item: ast::NodeId) {
if !self.any_library {
// If we are building an executable, only explicitly extern
@ -244,9 +248,9 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
match *node {
ast_map::NodeItem(item) => {
match item.node {
hir::ItemFn(.., ref body) => {
hir::ItemFn(.., body) => {
if item_might_be_inlined(&item) {
self.visit_expr(body);
self.visit_body(body);
}
}
@ -274,10 +278,12 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
hir::MethodTraitItem(_, None) => {
// Keep going, nothing to get exported
}
hir::ConstTraitItem(_, Some(ref body)) |
hir::MethodTraitItem(_, Some(ref body)) => {
hir::ConstTraitItem(_, Some(ref body)) => {
self.visit_expr(body);
}
hir::MethodTraitItem(_, Some(body_id)) => {
self.visit_body(body_id);
}
hir::TypeTraitItem(..) => {}
}
}
@ -286,10 +292,10 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
hir::ImplItemKind::Const(_, ref expr) => {
self.visit_expr(&expr);
}
hir::ImplItemKind::Method(ref sig, ref body) => {
hir::ImplItemKind::Method(ref sig, body) => {
let did = self.tcx.map.get_parent_did(search_item);
if method_might_be_inlined(self.tcx, sig, impl_item, did) {
self.visit_expr(body)
self.visit_body(body)
}
}
hir::ImplItemKind::Type(_) => {}

View File

@ -31,7 +31,7 @@ use syntax::ast::{self, NodeId};
use syntax_pos::Span;
use hir;
use hir::intravisit::{self, Visitor, FnKind};
use hir::intravisit::{self, Visitor, FnKind, NestedVisitMode};
use hir::{Block, Item, FnDecl, Arm, Pat, PatKind, Stmt, Expr, Local};
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, RustcEncodable,
@ -302,7 +302,7 @@ pub struct Context {
parent: CodeExtent
}
struct RegionResolutionVisitor<'a> {
struct RegionResolutionVisitor<'ast: 'a, 'a> {
sess: &'a Session,
// Generated maps:
@ -310,6 +310,8 @@ struct RegionResolutionVisitor<'a> {
cx: Context,
map: &'a ast_map::Map<'ast>,
/// `terminating_scopes` is a set containing the ids of each
/// statement, or conditional/repeating expression. These scopes
/// are calling "terminating scopes" because, when attempting to
@ -660,7 +662,7 @@ fn record_var_lifetime(visitor: &mut RegionResolutionVisitor,
}
}
fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &hir::Block) {
fn resolve_block<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, blk: &'tcx hir::Block) {
debug!("resolve_block(blk.id={:?})", blk.id);
let prev_cx = visitor.cx;
@ -731,7 +733,7 @@ fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &hir::Block) {
visitor.cx = prev_cx;
}
fn resolve_arm(visitor: &mut RegionResolutionVisitor, arm: &hir::Arm) {
fn resolve_arm<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, arm: &'tcx hir::Arm) {
visitor.terminating_scopes.insert(arm.body.id);
if let Some(ref expr) = arm.guard {
@ -741,7 +743,7 @@ fn resolve_arm(visitor: &mut RegionResolutionVisitor, arm: &hir::Arm) {
intravisit::walk_arm(visitor, arm);
}
fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: &hir::Pat) {
fn resolve_pat<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, pat: &'tcx hir::Pat) {
visitor.new_node_extent(pat.id);
// If this is a binding then record the lifetime of that binding.
@ -752,7 +754,7 @@ fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: &hir::Pat) {
intravisit::walk_pat(visitor, pat);
}
fn resolve_stmt(visitor: &mut RegionResolutionVisitor, stmt: &hir::Stmt) {
fn resolve_stmt<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, stmt: &'tcx hir::Stmt) {
let stmt_id = stmt.node.id();
debug!("resolve_stmt(stmt.id={:?})", stmt_id);
@ -770,7 +772,7 @@ fn resolve_stmt(visitor: &mut RegionResolutionVisitor, stmt: &hir::Stmt) {
visitor.cx.parent = prev_parent;
}
fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &hir::Expr) {
fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, expr: &'tcx hir::Expr) {
debug!("resolve_expr(expr.id={:?})", expr.id);
let expr_extent = visitor.new_node_extent_with_dtor(expr.id);
@ -848,7 +850,7 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &hir::Expr) {
visitor.cx = prev_cx;
}
fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &hir::Local) {
fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, local: &'tcx hir::Local) {
debug!("resolve_local(local.id={:?},local.init={:?})",
local.id,local.init.is_some());
@ -1063,7 +1065,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &hir::Local) {
}
}
fn resolve_item(visitor: &mut RegionResolutionVisitor, item: &hir::Item) {
fn resolve_item<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>, item: &'tcx hir::Item) {
// Items create a new outer block scope as far as we're concerned.
let prev_cx = visitor.cx;
let prev_ts = mem::replace(&mut visitor.terminating_scopes, NodeSet());
@ -1078,38 +1080,38 @@ fn resolve_item(visitor: &mut RegionResolutionVisitor, item: &hir::Item) {
visitor.terminating_scopes = prev_ts;
}
fn resolve_fn(visitor: &mut RegionResolutionVisitor,
kind: FnKind,
decl: &hir::FnDecl,
body: &hir::Expr,
sp: Span,
id: ast::NodeId) {
fn resolve_fn<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'tcx, 'a>,
kind: FnKind<'tcx>,
decl: &'tcx hir::FnDecl,
body_id: hir::ExprId,
sp: Span,
id: ast::NodeId) {
debug!("region::resolve_fn(id={:?}, \
span={:?}, \
body.id={:?}, \
cx.parent={:?})",
id,
visitor.sess.codemap().span_to_string(sp),
body.id,
body_id,
visitor.cx.parent);
visitor.cx.parent = visitor.new_code_extent(
CodeExtentData::CallSiteScope { fn_id: id, body_id: body.id });
CodeExtentData::CallSiteScope { fn_id: id, body_id: body_id.node_id() });
let fn_decl_scope = visitor.new_code_extent(
CodeExtentData::ParameterScope { fn_id: id, body_id: body.id });
CodeExtentData::ParameterScope { fn_id: id, body_id: body_id.node_id() });
if let Some(root_id) = visitor.cx.root_id {
visitor.region_maps.record_fn_parent(body.id, root_id);
visitor.region_maps.record_fn_parent(body_id.node_id(), root_id);
}
let outer_cx = visitor.cx;
let outer_ts = mem::replace(&mut visitor.terminating_scopes, NodeSet());
visitor.terminating_scopes.insert(body.id);
visitor.terminating_scopes.insert(body_id.node_id());
// The arguments and `self` are parented to the fn.
visitor.cx = Context {
root_id: Some(body.id),
root_id: Some(body_id.node_id()),
parent: ROOT_CODE_EXTENT,
var_parent: fn_decl_scope,
};
@ -1119,18 +1121,18 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor,
// The body of the every fn is a root scope.
visitor.cx = Context {
root_id: Some(body.id),
root_id: Some(body_id.node_id()),
parent: fn_decl_scope,
var_parent: fn_decl_scope
};
visitor.visit_expr(body);
visitor.visit_body(body_id);
// Restore context we had at the start.
visitor.cx = outer_cx;
visitor.terminating_scopes = outer_ts;
}
impl<'a> RegionResolutionVisitor<'a> {
impl<'ast, 'a> RegionResolutionVisitor<'ast, 'a> {
/// Records the current parent (if any) as the parent of `child_scope`.
fn new_code_extent(&mut self, child_scope: CodeExtentData) -> CodeExtent {
self.region_maps.intern_code_extent(child_scope, self.cx.parent)
@ -1166,42 +1168,46 @@ impl<'a> RegionResolutionVisitor<'a> {
}
}
impl<'a, 'v> Visitor<'v> for RegionResolutionVisitor<'a> {
fn visit_block(&mut self, b: &Block) {
impl<'ast, 'a> Visitor<'ast> for RegionResolutionVisitor<'ast, 'a> {
fn nested_visit_map(&mut self) -> Option<(&hir::map::Map<'ast>, NestedVisitMode)> {
Some((&self.map, NestedVisitMode::OnlyBodies))
}
fn visit_block(&mut self, b: &'ast Block) {
resolve_block(self, b);
}
fn visit_item(&mut self, i: &Item) {
fn visit_item(&mut self, i: &'ast Item) {
resolve_item(self, i);
}
fn visit_impl_item(&mut self, ii: &hir::ImplItem) {
fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) {
intravisit::walk_impl_item(self, ii);
self.create_item_scope_if_needed(ii.id);
}
fn visit_trait_item(&mut self, ti: &hir::TraitItem) {
fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) {
intravisit::walk_trait_item(self, ti);
self.create_item_scope_if_needed(ti.id);
}
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl,
b: &'v Expr, s: Span, n: NodeId) {
fn visit_fn(&mut self, fk: FnKind<'ast>, fd: &'ast FnDecl,
b: hir::ExprId, s: Span, n: NodeId) {
resolve_fn(self, fk, fd, b, s, n);
}
fn visit_arm(&mut self, a: &Arm) {
fn visit_arm(&mut self, a: &'ast Arm) {
resolve_arm(self, a);
}
fn visit_pat(&mut self, p: &Pat) {
fn visit_pat(&mut self, p: &'ast Pat) {
resolve_pat(self, p);
}
fn visit_stmt(&mut self, s: &Stmt) {
fn visit_stmt(&mut self, s: &'ast Stmt) {
resolve_stmt(self, s);
}
fn visit_expr(&mut self, ex: &Expr) {
fn visit_expr(&mut self, ex: &'ast Expr) {
resolve_expr(self, ex);
}
fn visit_local(&mut self, l: &Local) {
fn visit_local(&mut self, l: &'ast Local) {
resolve_local(self, l);
}
}
@ -1228,6 +1234,7 @@ pub fn resolve_crate(sess: &Session, map: &ast_map::Map) -> RegionMaps {
let mut visitor = RegionResolutionVisitor {
sess: sess,
region_maps: &maps,
map: map,
cx: Context {
root_id: None,
parent: ROOT_CODE_EXTENT,

View File

@ -34,7 +34,7 @@ use util::nodemap::NodeMap;
use rustc_data_structures::fx::FxHashSet;
use hir;
use hir::print::lifetime_to_string;
use hir::intravisit::{self, Visitor, FnKind};
use hir::intravisit::{self, Visitor, FnKind, NestedVisitMode};
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
pub enum DefRegion {
@ -132,8 +132,8 @@ pub fn krate(sess: &Session,
impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
// Override the nested functions -- lifetimes follow lexical scope,
// so it's convenient to walk the tree in lexical order.
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
Some(&self.hir_map)
fn nested_visit_map(&mut self) -> Option<(&hir::map::Map<'tcx>, NestedVisitMode)> {
Some((&self.hir_map, NestedVisitMode::All))
}
fn visit_item(&mut self, item: &'tcx hir::Item) {
@ -206,7 +206,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
}
fn visit_fn(&mut self, fk: FnKind<'tcx>, decl: &'tcx hir::FnDecl,
b: &'tcx hir::Expr, s: Span, fn_id: ast::NodeId) {
b: hir::ExprId, s: Span, fn_id: ast::NodeId) {
match fk {
FnKind::ItemFn(_, generics, ..) => {
self.visit_early_late(fn_id,decl, generics, |this| {
@ -407,7 +407,7 @@ fn signal_shadowing_problem(sess: &Session, name: ast::Name, orig: Original, sha
// Adds all labels in `b` to `ctxt.labels_in_fn`, signalling a warning
// if one of the label shadows a lifetime or another label.
fn extract_labels(ctxt: &mut LifetimeContext, b: &hir::Expr) {
fn extract_labels(ctxt: &mut LifetimeContext, b: hir::ExprId) {
struct GatherLabels<'a> {
sess: &'a Session,
scope: Scope<'a>,
@ -419,7 +419,7 @@ fn extract_labels(ctxt: &mut LifetimeContext, b: &hir::Expr) {
scope: ctxt.scope,
labels_in_fn: &mut ctxt.labels_in_fn,
};
gather.visit_expr(b);
gather.visit_expr(ctxt.hir_map.expr(b));
return;
impl<'v, 'a> Visitor<'v> for GatherLabels<'a> {
@ -497,7 +497,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
fn add_scope_and_walk_fn(&mut self,
fk: FnKind<'tcx>,
fd: &'tcx hir::FnDecl,
fb: &'tcx hir::Expr,
fb: hir::ExprId,
_span: Span,
fn_id: ast::NodeId) {
match fk {
@ -518,8 +518,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
// `self.labels_in_fn`.
extract_labels(self, fb);
self.with(FnScope { fn_id: fn_id, body_id: fb.id, s: self.scope },
|_old_scope, this| this.visit_expr(fb))
self.with(FnScope { fn_id: fn_id, body_id: fb.node_id(), s: self.scope },
|_old_scope, this| this.visit_body(fb))
}
// FIXME(#37666) this works around a limitation in the region inferencer

View File

@ -30,7 +30,7 @@ use util::nodemap::{DefIdMap, FxHashSet, FxHashMap};
use hir;
use hir::{Item, Generics, StructField, Variant};
use hir::intravisit::{self, Visitor};
use hir::intravisit::{self, Visitor, NestedVisitMode};
use hir::itemlikevisit::DeepVisitor;
use std::mem::replace;
@ -234,8 +234,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
/// Because stability levels are scoped lexically, we want to walk
/// nested items in the context of the outer item, so enable
/// deep-walking.
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
Some(&self.tcx.map)
fn nested_visit_map(&mut self) -> Option<(&hir::map::Map<'tcx>, NestedVisitMode)> {
Some((&self.tcx.map, NestedVisitMode::All))
}
fn visit_item(&mut self, i: &'tcx Item) {
@ -534,6 +534,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
fn nested_visit_map(&mut self) -> Option<(&hir::map::Map<'tcx>, NestedVisitMode)> {
Some((&self.tcx.map, NestedVisitMode::OnlyBodies))
}
fn visit_item(&mut self, item: &'tcx hir::Item) {
match item.node {
hir::ItemExternCrate(_) => {

View File

@ -1208,7 +1208,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
tcx.construct_parameter_environment(
impl_item.span,
tcx.map.local_def_id(id),
tcx.region_maps.call_site_extent(id, body.id))
tcx.region_maps.call_site_extent(id, body.node_id()))
}
}
}
@ -1227,9 +1227,9 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
// Use call-site for extent (unless this is a
// trait method with no default; then fallback
// to the method id).
let extent = if let Some(ref body) = *body {
let extent = if let Some(body_id) = *body {
// default impl: use call_site extent as free_id_outlive bound.
tcx.region_maps.call_site_extent(id, body.id)
tcx.region_maps.call_site_extent(id, body_id.node_id())
} else {
// no default impl: use item extent as free_id_outlive bound.
tcx.region_maps.item_extent(id)
@ -1243,14 +1243,14 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> {
}
Some(ast_map::NodeItem(item)) => {
match item.node {
hir::ItemFn(.., ref body) => {
hir::ItemFn(.., body_id) => {
// We assume this is a function.
let fn_def_id = tcx.map.local_def_id(id);
tcx.construct_parameter_environment(
item.span,
fn_def_id,
tcx.region_maps.call_site_extent(id, body.id))
tcx.region_maps.call_site_extent(id, body_id.node_id()))
}
hir::ItemEnum(..) |
hir::ItemStruct(..) |

View File

@ -205,7 +205,7 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
{
// Check the body of fn items.
let tcx = this.tcx;
let id_range = intravisit::compute_id_range_for_fn_body(fk, decl, body, sp, id);
let id_range = intravisit::compute_id_range_for_fn_body(fk, decl, body, sp, id, &tcx.map);
let (all_loans, move_data) =
gather_loans::gather_loans_in_fn(this, id, decl, body);

View File

@ -44,7 +44,7 @@ enum TableEntry<'tcx> {
impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
pub fn encode_inlined_item(&mut self, ii: InlinedItemRef) -> Lazy<Ast<'tcx>> {
let mut id_visitor = IdRangeComputingVisitor::new();
let mut id_visitor = IdRangeComputingVisitor::new(&self.tcx.map);
match ii {
InlinedItemRef::Item(_, i) => id_visitor.visit_item(i),
InlinedItemRef::TraitItem(_, ti) => id_visitor.visit_trait_item(ti),