rustc: replace body exprs by their ids
This commit is contained in:
parent
069a2442b8
commit
f55482e7c9
@ -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()
|
||||
}
|
||||
|
@ -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)
|
||||
})
|
||||
}
|
||||
|
@ -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"),
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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(..) => {}
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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!()
|
||||
}
|
||||
};
|
||||
|
@ -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(_) => {}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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(_) => {
|
||||
|
@ -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(..) |
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user