2015-07-31 02:04:06 -05:00
|
|
|
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2016-11-02 17:22:59 -05:00
|
|
|
//! HIR walker for walking the contents of nodes.
|
|
|
|
//!
|
|
|
|
//! **For an overview of the visitor strategy, see the docs on the
|
|
|
|
//! `super::itemlikevisit::ItemLikeVisitor` trait.**
|
|
|
|
//!
|
|
|
|
//! If you have decided to use this visitor, here are some general
|
|
|
|
//! notes on how to do it:
|
|
|
|
//!
|
|
|
|
//! Each overridden visit method has full control over what
|
2015-07-31 02:04:06 -05:00
|
|
|
//! happens with its node, it can do its own traversal of the node's children,
|
2015-12-10 03:52:32 -06:00
|
|
|
//! call `intravisit::walk_*` to apply the default traversal algorithm, or prevent
|
2015-07-31 02:04:06 -05:00
|
|
|
//! deeper traversal by doing nothing.
|
|
|
|
//!
|
2015-11-17 20:44:39 -06:00
|
|
|
//! When visiting the HIR, the contents of nested items are NOT visited
|
|
|
|
//! by default. This is different from the AST visitor, which does a deep walk.
|
|
|
|
//! Hence this module is called `intravisit`; see the method `visit_nested_item`
|
|
|
|
//! for more details.
|
2015-07-31 02:04:06 -05:00
|
|
|
//!
|
2015-11-17 20:44:39 -06:00
|
|
|
//! Note: it is an important invariant that the default visitor walks
|
2017-09-12 17:09:56 -05:00
|
|
|
//! the body of a function in "execution order" - more concretely, if
|
|
|
|
//! we consider the reverse post-order (RPO) of the CFG implied by the HIR,
|
|
|
|
//! then a pre-order traversal of the HIR is consistent with the CFG RPO
|
|
|
|
//! on the *initial CFG point* of each HIR node, while a post-order traversal
|
|
|
|
//! of the HIR is consistent with the CFG RPO on each *final CFG point* of
|
|
|
|
//! each CFG node.
|
|
|
|
//!
|
|
|
|
//! One thing that follows is that if HIR node A always starts/ends executing
|
|
|
|
//! before HIR node B, then A appears in traversal pre/postorder before B,
|
|
|
|
//! respectively. (This follows from RPO respecting CFG domination).
|
|
|
|
//!
|
|
|
|
//! This order consistency is required in a few places in rustc, for
|
|
|
|
//! example generator inference, and possibly also HIR borrowck.
|
2015-07-31 02:04:06 -05:00
|
|
|
|
2018-05-25 18:50:15 -05:00
|
|
|
use syntax::ast::{NodeId, CRATE_NODE_ID, Ident, Name, Attribute};
|
2016-06-21 17:08:13 -05:00
|
|
|
use syntax_pos::Span;
|
2015-09-28 16:23:54 -05:00
|
|
|
use hir::*;
|
2016-11-25 05:21:19 -06:00
|
|
|
use hir::def::Def;
|
2017-04-10 02:00:08 -05:00
|
|
|
use hir::map::{self, Map};
|
2016-11-02 17:22:59 -05:00
|
|
|
use super::itemlikevisit::DeepVisitor;
|
2015-07-31 02:04:06 -05:00
|
|
|
|
2016-03-29 04:12:01 -05:00
|
|
|
use std::cmp;
|
|
|
|
use std::u32;
|
|
|
|
|
2018-03-20 17:58:25 -05:00
|
|
|
#[derive(Copy, Clone)]
|
2015-07-31 02:04:06 -05:00
|
|
|
pub enum FnKind<'a> {
|
2018-05-17 00:55:18 -05:00
|
|
|
/// #[xxx] pub async/const/extern "Abi" fn foo()
|
|
|
|
ItemFn(Name, &'a Generics, FnHeader, &'a Visibility, &'a [Attribute]),
|
2015-07-31 02:04:06 -05:00
|
|
|
|
|
|
|
/// fn foo(&self)
|
2018-06-10 14:24:24 -05:00
|
|
|
Method(Ident, &'a MethodSig, Option<&'a Visibility>, &'a [Attribute]),
|
2015-07-31 02:04:06 -05:00
|
|
|
|
2015-09-28 16:23:54 -05:00
|
|
|
/// |x, y| {}
|
2016-01-25 07:11:51 -06:00
|
|
|
Closure(&'a [Attribute]),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> FnKind<'a> {
|
|
|
|
pub fn attrs(&self) -> &'a [Attribute] {
|
|
|
|
match *self {
|
2016-08-26 11:23:42 -05:00
|
|
|
FnKind::ItemFn(.., attrs) => attrs,
|
|
|
|
FnKind::Method(.., attrs) => attrs,
|
2016-01-25 07:11:51 -06:00
|
|
|
FnKind::Closure(attrs) => attrs,
|
|
|
|
}
|
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
2016-11-28 13:51:19 -06:00
|
|
|
/// Specifies what nested things a visitor wants to visit. The most
|
|
|
|
/// common choice is `OnlyBodies`, which will cause the visitor to
|
|
|
|
/// visit fn bodies for fns that it encounters, but skip over nested
|
|
|
|
/// item-like things.
|
|
|
|
///
|
|
|
|
/// See the comments on `ItemLikeVisitor` for more details on the overall
|
|
|
|
/// visit strategy.
|
2016-11-28 13:00:26 -06:00
|
|
|
pub enum NestedVisitorMap<'this, 'tcx: 'this> {
|
|
|
|
/// Do not visit any nested things. When you add a new
|
|
|
|
/// "non-nested" thing, you will want to audit such uses to see if
|
|
|
|
/// they remain valid.
|
2016-11-28 13:51:19 -06:00
|
|
|
///
|
|
|
|
/// Use this if you are only walking some particular kind of tree
|
|
|
|
/// (i.e., a type, or fn signature) and you don't want to thread a
|
|
|
|
/// HIR map around.
|
2016-11-28 13:00:26 -06:00
|
|
|
None,
|
|
|
|
|
|
|
|
/// Do not visit nested item-like things, but visit nested things
|
|
|
|
/// that are inside of an item-like.
|
|
|
|
///
|
2017-08-11 13:34:14 -05:00
|
|
|
/// **This is the most common choice.** A very common pattern is
|
2017-05-02 10:22:03 -05:00
|
|
|
/// to use `visit_all_item_likes()` as an outer loop,
|
2016-11-28 13:51:19 -06:00
|
|
|
/// and to have the visitor that visits the contents of each item
|
|
|
|
/// using this setting.
|
2016-11-28 13:00:26 -06:00
|
|
|
OnlyBodies(&'this Map<'tcx>),
|
|
|
|
|
|
|
|
/// Visit all nested things, including item-likes.
|
2016-11-28 13:51:19 -06:00
|
|
|
///
|
|
|
|
/// **This is an unusual choice.** It is used when you want to
|
|
|
|
/// process everything within their lexical context. Typically you
|
|
|
|
/// kick off the visit by doing `walk_krate()`.
|
2016-11-28 13:00:26 -06:00
|
|
|
All(&'this Map<'tcx>),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'this, 'tcx> NestedVisitorMap<'this, 'tcx> {
|
|
|
|
/// Returns the map to use for an "intra item-like" thing (if any).
|
|
|
|
/// e.g., function body.
|
|
|
|
pub fn intra(self) -> Option<&'this Map<'tcx>> {
|
|
|
|
match self {
|
|
|
|
NestedVisitorMap::None => None,
|
|
|
|
NestedVisitorMap::OnlyBodies(map) => Some(map),
|
|
|
|
NestedVisitorMap::All(map) => Some(map),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the map to use for an "item-like" thing (if any).
|
|
|
|
/// e.g., item, impl-item.
|
|
|
|
pub fn inter(self) -> Option<&'this Map<'tcx>> {
|
|
|
|
match self {
|
|
|
|
NestedVisitorMap::None => None,
|
|
|
|
NestedVisitorMap::OnlyBodies(_) => None,
|
|
|
|
NestedVisitorMap::All(map) => Some(map),
|
|
|
|
}
|
|
|
|
}
|
2016-10-28 15:58:32 -05:00
|
|
|
}
|
|
|
|
|
2015-07-31 02:04:06 -05:00
|
|
|
/// 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;
|
2015-12-10 03:52:32 -06:00
|
|
|
/// e.g. the `visit_mod` method by default calls `intravisit::walk_mod`.
|
2015-07-31 02:04:06 -05:00
|
|
|
///
|
2015-11-17 20:44:39 -06:00
|
|
|
/// Note that this visitor does NOT visit nested items by default
|
|
|
|
/// (this is why the module is called `intravisit`, to distinguish it
|
|
|
|
/// from the AST's `visit` module, which acts differently). If you
|
|
|
|
/// simply want to visit all items in the crate in some order, you
|
2015-11-17 16:32:12 -06:00
|
|
|
/// should call `Crate::visit_all_items`. Otherwise, see the comment
|
|
|
|
/// on `visit_nested_item` for details on how to visit nested items.
|
|
|
|
///
|
2015-07-31 02:04:06 -05:00
|
|
|
/// If you want to ensure that your code handles every variant
|
|
|
|
/// explicitly, you need to override each method. (And you also need
|
|
|
|
/// to monitor future changes to `Visitor` in case a new method with a
|
|
|
|
/// new default implementation gets introduced.)
|
|
|
|
pub trait Visitor<'v> : Sized {
|
2015-11-17 16:32:12 -06:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Nested items.
|
|
|
|
|
2016-11-28 13:51:19 -06:00
|
|
|
/// The default versions of the `visit_nested_XXX` routines invoke
|
|
|
|
/// this method to get a map to use. By selecting an enum variant,
|
|
|
|
/// you control which kinds of nested HIR are visited; see
|
|
|
|
/// `NestedVisitorMap` for details. By "nested HIR", we are
|
|
|
|
/// referring to bits of HIR that are not directly embedded within
|
|
|
|
/// one another but rather indirectly, through a table in the
|
|
|
|
/// crate. This is done to control dependencies during incremental
|
|
|
|
/// compilation: the non-inline bits of HIR can be tracked and
|
|
|
|
/// hashed separately.
|
2016-11-09 15:45:26 -06:00
|
|
|
///
|
|
|
|
/// **If for some reason you want the nested behavior, but don't
|
2017-01-24 03:35:19 -06:00
|
|
|
/// have a `Map` at your disposal:** then you should override the
|
2016-11-09 15:45:26 -06:00
|
|
|
/// `visit_nested_XXX` methods, and override this method to
|
|
|
|
/// `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.
|
2016-11-28 13:00:26 -06:00
|
|
|
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v>;
|
2016-11-09 15:45:26 -06:00
|
|
|
|
|
|
|
/// Invoked when a nested item is encountered. By default does
|
|
|
|
/// nothing unless you override `nested_visit_map` to return
|
|
|
|
/// `Some(_)`, in which case it will walk the item. **You probably
|
|
|
|
/// don't want to override this method** -- instead, override
|
|
|
|
/// `nested_visit_map` or use the "shallow" or "deep" visit
|
|
|
|
/// patterns described on `itemlikevisit::ItemLikeVisitor`. The only
|
|
|
|
/// reason to override this method is if you want a nested pattern
|
|
|
|
/// but cannot supply a `Map`; see `nested_visit_map` for advice.
|
2015-11-17 16:32:12 -06:00
|
|
|
#[allow(unused_variables)]
|
|
|
|
fn visit_nested_item(&mut self, id: ItemId) {
|
2016-11-28 13:00:26 -06:00
|
|
|
let opt_item = self.nested_visit_map().inter().map(|map| map.expect_item(id.id));
|
2016-11-09 15:45:26 -06:00
|
|
|
if let Some(item) = opt_item {
|
|
|
|
self.visit_item(item);
|
|
|
|
}
|
2015-11-17 16:32:12 -06:00
|
|
|
}
|
|
|
|
|
2016-12-03 20:21:06 -06:00
|
|
|
/// Like `visit_nested_item()`, but for trait items. See
|
|
|
|
/// `visit_nested_item()` for advice on when to override this
|
|
|
|
/// method.
|
|
|
|
#[allow(unused_variables)]
|
|
|
|
fn visit_nested_trait_item(&mut self, id: TraitItemId) {
|
|
|
|
let opt_item = self.nested_visit_map().inter().map(|map| map.trait_item(id));
|
|
|
|
if let Some(item) = opt_item {
|
|
|
|
self.visit_trait_item(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-09 15:45:26 -06:00
|
|
|
/// Like `visit_nested_item()`, but for impl items. See
|
|
|
|
/// `visit_nested_item()` for advice on when to override this
|
|
|
|
/// method.
|
2016-11-02 17:25:31 -05:00
|
|
|
#[allow(unused_variables)]
|
|
|
|
fn visit_nested_impl_item(&mut self, id: ImplItemId) {
|
2016-11-28 13:00:26 -06:00
|
|
|
let opt_item = self.nested_visit_map().inter().map(|map| map.impl_item(id));
|
2016-11-09 15:45:26 -06:00
|
|
|
if let Some(item) = opt_item {
|
|
|
|
self.visit_impl_item(item);
|
|
|
|
}
|
2016-11-02 17:25:31 -05:00
|
|
|
}
|
|
|
|
|
2016-10-28 15:58:32 -05:00
|
|
|
/// 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.
|
2016-12-21 04:32:59 -06:00
|
|
|
fn visit_nested_body(&mut self, id: BodyId) {
|
|
|
|
let opt_body = self.nested_visit_map().intra().map(|map| map.body(id));
|
|
|
|
if let Some(body) = opt_body {
|
|
|
|
self.visit_body(body);
|
2016-10-28 15:58:32 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-02 17:25:31 -05:00
|
|
|
/// Visit the top-level item and (optionally) nested items / impl items. See
|
2015-11-17 16:32:12 -06:00
|
|
|
/// `visit_nested_item` for details.
|
|
|
|
fn visit_item(&mut self, i: &'v Item) {
|
|
|
|
walk_item(self, i)
|
|
|
|
}
|
|
|
|
|
2016-12-21 04:32:59 -06:00
|
|
|
fn visit_body(&mut self, b: &'v Body) {
|
|
|
|
walk_body(self, b);
|
|
|
|
}
|
|
|
|
|
2016-11-02 17:22:59 -05:00
|
|
|
/// When invoking `visit_all_item_likes()`, you need to supply an
|
|
|
|
/// item-like visitor. This method converts a "intra-visit"
|
|
|
|
/// visitor into an item-like visitor that walks the entire tree.
|
|
|
|
/// If you use this, you probably don't want to process the
|
|
|
|
/// contents of nested item-like things, since the outer loop will
|
|
|
|
/// visit them as well.
|
|
|
|
fn as_deep_visitor<'s>(&'s mut self) -> DeepVisitor<'s, Self> {
|
|
|
|
DeepVisitor::new(self)
|
|
|
|
}
|
|
|
|
|
2015-11-17 16:32:12 -06:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2016-07-28 04:58:45 -05:00
|
|
|
fn visit_id(&mut self, _node_id: NodeId) {
|
|
|
|
// Nothing to do.
|
|
|
|
}
|
2016-11-25 05:21:19 -06:00
|
|
|
fn visit_def_mention(&mut self, _def: Def) {
|
|
|
|
// Nothing to do.
|
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
fn visit_name(&mut self, _span: Span, _name: Name) {
|
|
|
|
// Nothing to do.
|
|
|
|
}
|
2018-05-25 18:50:15 -05:00
|
|
|
fn visit_ident(&mut self, ident: Ident) {
|
|
|
|
walk_ident(self, ident)
|
|
|
|
}
|
2016-07-28 04:58:45 -05:00
|
|
|
fn visit_mod(&mut self, m: &'v Mod, _s: Span, n: NodeId) {
|
|
|
|
walk_mod(self, m, n)
|
2015-09-27 14:23:31 -05:00
|
|
|
}
|
|
|
|
fn visit_foreign_item(&mut self, i: &'v ForeignItem) {
|
|
|
|
walk_foreign_item(self, i)
|
|
|
|
}
|
|
|
|
fn visit_local(&mut self, l: &'v Local) {
|
|
|
|
walk_local(self, l)
|
|
|
|
}
|
|
|
|
fn visit_block(&mut self, b: &'v Block) {
|
|
|
|
walk_block(self, b)
|
|
|
|
}
|
|
|
|
fn visit_stmt(&mut self, s: &'v Stmt) {
|
|
|
|
walk_stmt(self, s)
|
|
|
|
}
|
|
|
|
fn visit_arm(&mut self, a: &'v Arm) {
|
|
|
|
walk_arm(self, a)
|
|
|
|
}
|
|
|
|
fn visit_pat(&mut self, p: &'v Pat) {
|
|
|
|
walk_pat(self, p)
|
|
|
|
}
|
|
|
|
fn visit_decl(&mut self, d: &'v Decl) {
|
|
|
|
walk_decl(self, d)
|
|
|
|
}
|
2018-05-17 13:28:50 -05:00
|
|
|
fn visit_anon_const(&mut self, c: &'v AnonConst) {
|
|
|
|
walk_anon_const(self, c)
|
|
|
|
}
|
2015-09-27 14:23:31 -05:00
|
|
|
fn visit_expr(&mut self, ex: &'v Expr) {
|
|
|
|
walk_expr(self, ex)
|
|
|
|
}
|
|
|
|
fn visit_ty(&mut self, t: &'v Ty) {
|
|
|
|
walk_ty(self, t)
|
|
|
|
}
|
2017-10-16 14:07:26 -05:00
|
|
|
fn visit_generic_param(&mut self, p: &'v GenericParam) {
|
|
|
|
walk_generic_param(self, p)
|
|
|
|
}
|
2015-09-27 14:23:31 -05:00
|
|
|
fn visit_generics(&mut self, g: &'v Generics) {
|
|
|
|
walk_generics(self, g)
|
|
|
|
}
|
2016-04-21 04:10:10 -05:00
|
|
|
fn visit_where_predicate(&mut self, predicate: &'v WherePredicate) {
|
|
|
|
walk_where_predicate(self, predicate)
|
|
|
|
}
|
2016-12-19 16:51:27 -06:00
|
|
|
fn visit_fn_decl(&mut self, fd: &'v FnDecl) {
|
|
|
|
walk_fn_decl(self, fd)
|
|
|
|
}
|
2016-12-21 04:32:59 -06:00
|
|
|
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: BodyId, s: Span, id: NodeId) {
|
2016-07-28 04:58:45 -05:00
|
|
|
walk_fn(self, fk, fd, b, s, id)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2015-09-27 14:23:31 -05:00
|
|
|
fn visit_trait_item(&mut self, ti: &'v TraitItem) {
|
|
|
|
walk_trait_item(self, ti)
|
|
|
|
}
|
2016-12-03 20:21:06 -06:00
|
|
|
fn visit_trait_item_ref(&mut self, ii: &'v TraitItemRef) {
|
|
|
|
walk_trait_item_ref(self, ii)
|
|
|
|
}
|
2015-09-27 14:23:31 -05:00
|
|
|
fn visit_impl_item(&mut self, ii: &'v ImplItem) {
|
|
|
|
walk_impl_item(self, ii)
|
|
|
|
}
|
2016-11-10 08:47:00 -06:00
|
|
|
fn visit_impl_item_ref(&mut self, ii: &'v ImplItemRef) {
|
|
|
|
walk_impl_item_ref(self, ii)
|
|
|
|
}
|
2015-09-27 14:23:31 -05:00
|
|
|
fn visit_trait_ref(&mut self, t: &'v TraitRef) {
|
|
|
|
walk_trait_ref(self, t)
|
|
|
|
}
|
2018-06-14 06:08:58 -05:00
|
|
|
fn visit_param_bound(&mut self, bounds: &'v GenericBound) {
|
2018-05-28 09:23:16 -05:00
|
|
|
walk_param_bound(self, bounds)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2017-01-24 09:17:06 -06:00
|
|
|
fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef, m: TraitBoundModifier) {
|
2015-07-31 02:04:06 -05:00
|
|
|
walk_poly_trait_ref(self, t, m)
|
|
|
|
}
|
2015-11-05 15:17:59 -06:00
|
|
|
fn visit_variant_data(&mut self,
|
|
|
|
s: &'v VariantData,
|
|
|
|
_: Name,
|
|
|
|
_: &'v Generics,
|
2016-07-28 04:58:45 -05:00
|
|
|
_parent_id: NodeId,
|
2015-11-05 15:17:59 -06:00
|
|
|
_: Span) {
|
2015-07-31 02:04:06 -05:00
|
|
|
walk_struct_def(self, s)
|
|
|
|
}
|
2015-09-27 14:23:31 -05:00
|
|
|
fn visit_struct_field(&mut self, s: &'v StructField) {
|
|
|
|
walk_struct_field(self, s)
|
|
|
|
}
|
2015-11-05 15:17:59 -06:00
|
|
|
fn visit_enum_def(&mut self,
|
|
|
|
enum_definition: &'v EnumDef,
|
|
|
|
generics: &'v Generics,
|
|
|
|
item_id: NodeId,
|
|
|
|
_: Span) {
|
2015-10-02 08:14:20 -05:00
|
|
|
walk_enum_def(self, enum_definition, generics, item_id)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2015-10-02 08:14:20 -05:00
|
|
|
fn visit_variant(&mut self, v: &'v Variant, g: &'v Generics, item_id: NodeId) {
|
|
|
|
walk_variant(self, v, g, item_id)
|
2015-09-27 14:23:31 -05:00
|
|
|
}
|
2018-01-15 16:44:32 -06:00
|
|
|
fn visit_label(&mut self, label: &'v Label) {
|
|
|
|
walk_label(self, label)
|
|
|
|
}
|
2018-02-13 05:32:37 -06:00
|
|
|
fn visit_generic_arg(&mut self, generic_arg: &'v GenericArg) {
|
|
|
|
match generic_arg {
|
|
|
|
GenericArg::Lifetime(lt) => self.visit_lifetime(lt),
|
|
|
|
GenericArg::Type(ty) => self.visit_ty(ty),
|
2018-02-25 07:46:45 -06:00
|
|
|
}
|
|
|
|
}
|
2015-09-28 16:23:54 -05:00
|
|
|
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
|
|
|
|
walk_lifetime(self, lifetime)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-31 11:43:51 -05:00
|
|
|
fn visit_qpath(&mut self, qpath: &'v QPath, id: HirId, span: Span) {
|
2016-10-26 21:17:42 -05:00
|
|
|
walk_qpath(self, qpath, id, span)
|
|
|
|
}
|
2018-07-31 11:43:51 -05:00
|
|
|
fn visit_path(&mut self, path: &'v Path, _id: HirId) {
|
2015-07-31 02:04:06 -05:00
|
|
|
walk_path(self, path)
|
|
|
|
}
|
|
|
|
fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) {
|
|
|
|
walk_path_segment(self, path_span, path_segment)
|
|
|
|
}
|
2018-02-13 05:32:37 -06:00
|
|
|
fn visit_generic_args(&mut self, path_span: Span, generic_args: &'v GenericArgs) {
|
|
|
|
walk_generic_args(self, path_span, generic_args)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
fn visit_assoc_type_binding(&mut self, type_binding: &'v TypeBinding) {
|
|
|
|
walk_assoc_type_binding(self, type_binding)
|
|
|
|
}
|
2015-09-27 14:23:31 -05:00
|
|
|
fn visit_attribute(&mut self, _attr: &'v Attribute) {
|
|
|
|
}
|
2015-09-28 16:23:54 -05:00
|
|
|
fn visit_macro_def(&mut self, macro_def: &'v MacroDef) {
|
|
|
|
walk_macro_def(self, macro_def)
|
|
|
|
}
|
2016-04-02 15:24:02 -05:00
|
|
|
fn visit_vis(&mut self, vis: &'v Visibility) {
|
|
|
|
walk_vis(self, vis)
|
|
|
|
}
|
2016-11-14 10:00:02 -06:00
|
|
|
fn visit_associated_item_kind(&mut self, kind: &'v AssociatedItemKind) {
|
|
|
|
walk_associated_item_kind(self, kind);
|
|
|
|
}
|
|
|
|
fn visit_defaultness(&mut self, defaultness: &'v Defaultness) {
|
|
|
|
walk_defaultness(self, defaultness);
|
|
|
|
}
|
2015-09-28 16:23:54 -05:00
|
|
|
}
|
|
|
|
|
2015-11-17 16:32:12 -06:00
|
|
|
/// Walks the contents of a crate. See also `Crate::visit_all_items`.
|
2015-07-31 02:04:06 -05:00
|
|
|
pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) {
|
|
|
|
visitor.visit_mod(&krate.module, krate.span, CRATE_NODE_ID);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_attribute, &krate.attrs);
|
|
|
|
walk_list!(visitor, visit_macro_def, &krate.exported_macros);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
2015-09-28 16:23:54 -05:00
|
|
|
pub fn walk_macro_def<'v, V: Visitor<'v>>(visitor: &mut V, macro_def: &'v MacroDef) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(macro_def.id);
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_name(macro_def.span, macro_def.name);
|
|
|
|
walk_list!(visitor, visit_attribute, ¯o_def.attrs);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
2016-07-28 04:58:45 -05:00
|
|
|
pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod, mod_node_id: NodeId) {
|
|
|
|
visitor.visit_id(mod_node_id);
|
2015-11-17 16:32:12 -06:00
|
|
|
for &item_id in &module.item_ids {
|
|
|
|
visitor.visit_nested_item(item_id);
|
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
2016-12-21 04:32:59 -06:00
|
|
|
pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body) {
|
2016-12-20 14:46:11 -06:00
|
|
|
for argument in &body.arguments {
|
|
|
|
visitor.visit_id(argument.id);
|
|
|
|
visitor.visit_pat(&argument.pat);
|
|
|
|
}
|
2016-12-21 04:32:59 -06:00
|
|
|
visitor.visit_expr(&body.value);
|
|
|
|
}
|
|
|
|
|
2015-09-28 16:23:54 -05:00
|
|
|
pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) {
|
2017-09-20 08:36:20 -05:00
|
|
|
// Intentionally visiting the expr first - the initialization expr
|
|
|
|
// dominates the local's definition.
|
|
|
|
walk_list!(visitor, visit_expr, &local.init);
|
2018-04-18 01:19:21 -05:00
|
|
|
walk_list!(visitor, visit_attribute, local.attrs.iter());
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(local.id);
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_pat(&local.pat);
|
|
|
|
walk_list!(visitor, visit_ty, &local.ty);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
2018-05-25 18:50:15 -05:00
|
|
|
pub fn walk_ident<'v, V: Visitor<'v>>(visitor: &mut V, ident: Ident) {
|
|
|
|
visitor.visit_name(ident.span, ident.name);
|
|
|
|
}
|
|
|
|
|
2018-01-15 16:44:32 -06:00
|
|
|
pub fn walk_label<'v, V: Visitor<'v>>(visitor: &mut V, label: &'v Label) {
|
2018-06-10 11:33:30 -05:00
|
|
|
visitor.visit_ident(label.ident);
|
2018-01-15 16:44:32 -06:00
|
|
|
}
|
|
|
|
|
2015-09-28 16:23:54 -05:00
|
|
|
pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(lifetime.id);
|
2017-09-19 18:36:54 -05:00
|
|
|
match lifetime.name {
|
2018-06-09 15:25:33 -05:00
|
|
|
LifetimeName::Param(ParamName::Plain(ident)) => {
|
|
|
|
visitor.visit_ident(ident);
|
2017-09-19 18:36:54 -05:00
|
|
|
}
|
2018-06-01 17:23:48 -05:00
|
|
|
LifetimeName::Param(ParamName::Fresh(_)) |
|
2018-10-11 14:51:44 -05:00
|
|
|
LifetimeName::Param(ParamName::Error) |
|
2018-03-21 16:12:39 -05:00
|
|
|
LifetimeName::Static |
|
2018-10-11 14:51:44 -05:00
|
|
|
LifetimeName::Error |
|
2018-03-21 16:12:39 -05:00
|
|
|
LifetimeName::Implicit |
|
|
|
|
LifetimeName::Underscore => {}
|
2017-09-19 18:36:54 -05:00
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V,
|
|
|
|
trait_ref: &'v PolyTraitRef,
|
2017-01-24 09:17:06 -06:00
|
|
|
_modifier: TraitBoundModifier)
|
2015-07-31 02:04:06 -05:00
|
|
|
where V: Visitor<'v>
|
|
|
|
{
|
2017-10-16 14:07:26 -05:00
|
|
|
walk_list!(visitor, visit_generic_param, &trait_ref.bound_generic_params);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_trait_ref(&trait_ref.trait_ref);
|
|
|
|
}
|
|
|
|
|
2015-09-27 14:23:31 -05:00
|
|
|
pub fn walk_trait_ref<'v, V>(visitor: &mut V, trait_ref: &'v TraitRef)
|
2015-07-31 02:04:06 -05:00
|
|
|
where V: Visitor<'v>
|
|
|
|
{
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(trait_ref.ref_id);
|
2018-07-31 11:43:51 -05:00
|
|
|
visitor.visit_path(&trait_ref.path, trait_ref.hir_ref_id)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
|
2016-04-02 15:24:02 -05:00
|
|
|
visitor.visit_vis(&item.vis);
|
2015-09-19 20:50:30 -05:00
|
|
|
visitor.visit_name(item.span, item.name);
|
2015-07-31 02:04:06 -05:00
|
|
|
match item.node {
|
2018-07-11 10:36:06 -05:00
|
|
|
ItemKind::ExternCrate(orig_name) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(item.id);
|
2018-03-09 09:51:48 -06:00
|
|
|
if let Some(orig_name) = orig_name {
|
|
|
|
visitor.visit_name(item.span, orig_name);
|
2018-01-15 16:44:32 -06:00
|
|
|
}
|
2015-09-28 16:23:54 -05:00
|
|
|
}
|
2018-07-11 10:36:06 -05:00
|
|
|
ItemKind::Use(ref path, _) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(item.id);
|
2018-07-31 11:43:51 -05:00
|
|
|
visitor.visit_path(path, item.hir_id);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 10:36:06 -05:00
|
|
|
ItemKind::Static(ref typ, _, body) |
|
|
|
|
ItemKind::Const(ref typ, body) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(item.id);
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_ty(typ);
|
2016-12-21 04:32:59 -06:00
|
|
|
visitor.visit_nested_body(body);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 10:36:06 -05:00
|
|
|
ItemKind::Fn(ref declaration, header, ref generics, body_id) => {
|
2015-09-27 14:23:31 -05:00
|
|
|
visitor.visit_fn(FnKind::ItemFn(item.name,
|
|
|
|
generics,
|
2018-05-17 00:55:18 -05:00
|
|
|
header,
|
2016-03-25 01:08:11 -05:00
|
|
|
&item.vis,
|
2016-01-25 07:11:51 -06:00
|
|
|
&item.attrs),
|
2015-09-28 16:23:54 -05:00
|
|
|
declaration,
|
2016-10-28 15:58:32 -05:00
|
|
|
body_id,
|
2015-07-31 02:04:06 -05:00
|
|
|
item.span,
|
|
|
|
item.id)
|
|
|
|
}
|
2018-07-11 10:36:06 -05:00
|
|
|
ItemKind::Mod(ref module) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
// visit_mod() takes care of visiting the Item's NodeId
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_mod(module, item.span, item.id)
|
|
|
|
}
|
2018-07-11 10:36:06 -05:00
|
|
|
ItemKind::ForeignMod(ref foreign_module) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(item.id);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_foreign_item, &foreign_module.items);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 10:36:06 -05:00
|
|
|
ItemKind::GlobalAsm(_) => {
|
2017-03-29 23:32:20 -05:00
|
|
|
visitor.visit_id(item.id);
|
|
|
|
}
|
2018-07-11 10:36:06 -05:00
|
|
|
ItemKind::Ty(ref typ, ref type_parameters) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(item.id);
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_ty(typ);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_generics(type_parameters)
|
|
|
|
}
|
2018-07-11 10:36:06 -05:00
|
|
|
ItemKind::Existential(ExistTy {ref generics, ref bounds, impl_trait_fn}) => {
|
2018-05-22 07:31:56 -05:00
|
|
|
visitor.visit_id(item.id);
|
|
|
|
walk_generics(visitor, generics);
|
2018-06-20 06:34:39 -05:00
|
|
|
walk_list!(visitor, visit_param_bound, bounds);
|
2018-05-22 07:31:56 -05:00
|
|
|
if let Some(impl_trait_fn) = impl_trait_fn {
|
|
|
|
visitor.visit_def_mention(Def::Fn(impl_trait_fn))
|
|
|
|
}
|
|
|
|
}
|
2018-07-11 10:36:06 -05:00
|
|
|
ItemKind::Enum(ref enum_definition, ref type_parameters) => {
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_generics(type_parameters);
|
2016-07-28 04:58:45 -05:00
|
|
|
// visit_enum_def() takes care of visiting the Item's NodeId
|
2015-10-16 09:17:14 -05:00
|
|
|
visitor.visit_enum_def(enum_definition, type_parameters, item.id, item.span)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 19:20:31 -05:00
|
|
|
ItemKind::Impl(
|
|
|
|
..,
|
|
|
|
ref type_parameters,
|
|
|
|
ref opt_trait_reference,
|
|
|
|
ref typ,
|
|
|
|
ref impl_item_refs
|
|
|
|
) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(item.id);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_generics(type_parameters);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_trait_ref, opt_trait_reference);
|
|
|
|
visitor.visit_ty(typ);
|
2016-12-03 20:21:06 -06:00
|
|
|
walk_list!(visitor, visit_impl_item_ref, impl_item_refs);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 10:36:06 -05:00
|
|
|
ItemKind::Struct(ref struct_definition, ref generics) |
|
|
|
|
ItemKind::Union(ref struct_definition, ref generics) => {
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_generics(generics);
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(item.id);
|
2015-11-05 15:17:59 -06:00
|
|
|
visitor.visit_variant_data(struct_definition, item.name, generics, item.id, item.span);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 10:36:06 -05:00
|
|
|
ItemKind::Trait(.., ref generics, ref bounds, ref trait_item_refs) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(item.id);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_generics(generics);
|
2018-05-28 09:23:16 -05:00
|
|
|
walk_list!(visitor, visit_param_bound, bounds);
|
2016-12-03 20:21:06 -06:00
|
|
|
walk_list!(visitor, visit_trait_item_ref, trait_item_refs);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 10:36:06 -05:00
|
|
|
ItemKind::TraitAlias(ref generics, ref bounds) => {
|
2017-10-02 07:28:16 -05:00
|
|
|
visitor.visit_id(item.id);
|
|
|
|
visitor.visit_generics(generics);
|
2018-05-28 09:23:16 -05:00
|
|
|
walk_list!(visitor, visit_param_bound, bounds);
|
2017-10-02 07:28:16 -05:00
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_attribute, &item.attrs);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_enum_def<'v, V: Visitor<'v>>(visitor: &mut V,
|
|
|
|
enum_definition: &'v EnumDef,
|
2015-10-02 08:14:20 -05:00
|
|
|
generics: &'v Generics,
|
|
|
|
item_id: NodeId) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(item_id);
|
2015-11-05 15:17:59 -06:00
|
|
|
walk_list!(visitor,
|
|
|
|
visit_variant,
|
|
|
|
&enum_definition.variants,
|
|
|
|
generics,
|
|
|
|
item_id);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V,
|
|
|
|
variant: &'v Variant,
|
2015-10-02 08:14:20 -05:00
|
|
|
generics: &'v Generics,
|
2016-07-28 04:58:45 -05:00
|
|
|
parent_item_id: NodeId) {
|
2015-09-20 08:47:24 -05:00
|
|
|
visitor.visit_name(variant.span, variant.node.name);
|
2015-11-05 15:17:59 -06:00
|
|
|
visitor.visit_variant_data(&variant.node.data,
|
|
|
|
variant.node.name,
|
|
|
|
generics,
|
2016-07-28 04:58:45 -05:00
|
|
|
parent_item_id,
|
2015-11-05 15:17:59 -06:00
|
|
|
variant.span);
|
2018-05-17 13:28:50 -05:00
|
|
|
walk_list!(visitor, visit_anon_const, &variant.node.disr_expr);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_attribute, &variant.node.attrs);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(typ.id);
|
|
|
|
|
2015-07-31 02:04:06 -05:00
|
|
|
match typ.node {
|
2018-07-11 09:41:03 -05:00
|
|
|
TyKind::Slice(ref ty) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_ty(ty)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 09:41:03 -05:00
|
|
|
TyKind::Ptr(ref mutable_type) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_ty(&mutable_type.ty)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 09:41:03 -05:00
|
|
|
TyKind::Rptr(ref lifetime, ref mutable_type) => {
|
2017-01-09 09:46:11 -06:00
|
|
|
visitor.visit_lifetime(lifetime);
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_ty(&mutable_type.ty)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 09:41:03 -05:00
|
|
|
TyKind::Never => {},
|
|
|
|
TyKind::Tup(ref tuple_element_types) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_ty, tuple_element_types);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 09:41:03 -05:00
|
|
|
TyKind::BareFn(ref function_declaration) => {
|
2017-10-16 14:07:26 -05:00
|
|
|
walk_list!(visitor, visit_generic_param, &function_declaration.generic_params);
|
2018-05-30 06:36:53 -05:00
|
|
|
visitor.visit_fn_decl(&function_declaration.decl);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 09:41:03 -05:00
|
|
|
TyKind::Path(ref qpath) => {
|
2018-07-31 11:43:51 -05:00
|
|
|
visitor.visit_qpath(qpath, typ.hir_id, typ.span);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-10-02 03:54:34 -05:00
|
|
|
TyKind::Def(item_id, ref lifetimes) => {
|
|
|
|
visitor.visit_nested_item(item_id);
|
|
|
|
walk_list!(visitor, visit_generic_arg, lifetimes);
|
|
|
|
}
|
2018-07-11 09:41:03 -05:00
|
|
|
TyKind::Array(ref ty, ref length) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_ty(ty);
|
2018-05-17 13:28:50 -05:00
|
|
|
visitor.visit_anon_const(length)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 09:41:03 -05:00
|
|
|
TyKind::TraitObject(ref bounds, ref lifetime) => {
|
2017-01-24 09:17:06 -06:00
|
|
|
for bound in bounds {
|
|
|
|
visitor.visit_poly_trait_ref(bound, TraitBoundModifier::None);
|
|
|
|
}
|
|
|
|
visitor.visit_lifetime(lifetime);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 09:41:03 -05:00
|
|
|
TyKind::Typeof(ref expression) => {
|
2018-05-17 13:28:50 -05:00
|
|
|
visitor.visit_anon_const(expression)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 09:41:03 -05:00
|
|
|
TyKind::Infer | TyKind::Err => {}
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-31 11:43:51 -05:00
|
|
|
pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V, qpath: &'v QPath, id: HirId, span: Span) {
|
2016-10-26 21:17:42 -05:00
|
|
|
match *qpath {
|
|
|
|
QPath::Resolved(ref maybe_qself, ref path) => {
|
|
|
|
if let Some(ref qself) = *maybe_qself {
|
|
|
|
visitor.visit_ty(qself);
|
|
|
|
}
|
|
|
|
visitor.visit_path(path, id)
|
|
|
|
}
|
|
|
|
QPath::TypeRelative(ref qself, ref segment) => {
|
|
|
|
visitor.visit_ty(qself);
|
|
|
|
visitor.visit_path_segment(span, segment);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 02:04:06 -05:00
|
|
|
pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) {
|
2016-11-25 05:21:19 -06:00
|
|
|
visitor.visit_def_mention(path.def);
|
2015-07-31 02:04:06 -05:00
|
|
|
for segment in &path.segments {
|
|
|
|
visitor.visit_path_segment(path.span, segment);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
|
|
|
|
path_span: Span,
|
|
|
|
segment: &'v PathSegment) {
|
2018-06-10 09:40:45 -05:00
|
|
|
visitor.visit_ident(segment.ident);
|
2018-02-23 11:48:54 -06:00
|
|
|
if let Some(ref args) = segment.args {
|
|
|
|
visitor.visit_generic_args(path_span, args);
|
2017-09-21 15:24:26 -05:00
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
2018-02-13 05:32:37 -06:00
|
|
|
pub fn walk_generic_args<'v, V: Visitor<'v>>(visitor: &mut V,
|
2018-05-27 10:56:01 -05:00
|
|
|
_path_span: Span,
|
|
|
|
generic_args: &'v GenericArgs) {
|
2018-02-23 11:48:54 -06:00
|
|
|
walk_list!(visitor, visit_generic_arg, &generic_args.args);
|
2018-02-13 05:32:37 -06:00
|
|
|
walk_list!(visitor, visit_assoc_type_binding, &generic_args.bindings);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V,
|
|
|
|
type_binding: &'v TypeBinding) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(type_binding.id);
|
2018-06-10 07:55:48 -05:00
|
|
|
visitor.visit_ident(type_binding.ident);
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_ty(&type_binding.ty);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(pattern.id);
|
2015-07-31 02:04:06 -05:00
|
|
|
match pattern.node {
|
2016-10-26 21:17:42 -05:00
|
|
|
PatKind::TupleStruct(ref qpath, ref children, _) => {
|
2018-07-31 11:43:51 -05:00
|
|
|
visitor.visit_qpath(qpath, pattern.hir_id, pattern.span);
|
2016-03-06 06:54:44 -06:00
|
|
|
walk_list!(visitor, visit_pat, children);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-10-26 21:17:42 -05:00
|
|
|
PatKind::Path(ref qpath) => {
|
2018-07-31 11:43:51 -05:00
|
|
|
visitor.visit_qpath(qpath, pattern.hir_id, pattern.span);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-10-26 21:17:42 -05:00
|
|
|
PatKind::Struct(ref qpath, ref fields, _) => {
|
2018-07-31 11:43:51 -05:00
|
|
|
visitor.visit_qpath(qpath, pattern.hir_id, pattern.span);
|
2015-07-31 02:04:06 -05:00
|
|
|
for field in fields {
|
2018-04-04 19:20:21 -05:00
|
|
|
visitor.visit_id(field.node.id);
|
2018-05-25 18:50:15 -05:00
|
|
|
visitor.visit_ident(field.node.ident);
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_pat(&field.node.pat)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
2016-03-06 06:54:44 -06:00
|
|
|
PatKind::Tuple(ref tuple_elements, _) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_pat, tuple_elements);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-02-14 06:25:12 -06:00
|
|
|
PatKind::Box(ref subpattern) |
|
|
|
|
PatKind::Ref(ref subpattern, _) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_pat(subpattern)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-06-10 11:33:30 -05:00
|
|
|
PatKind::Binding(_, canonical_id, ident, ref optional_subpattern) => {
|
2017-04-29 06:39:47 -05:00
|
|
|
visitor.visit_def_mention(Def::Local(canonical_id));
|
2018-06-10 11:33:30 -05:00
|
|
|
visitor.visit_ident(ident);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_pat, optional_subpattern);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-02-14 06:25:12 -06:00
|
|
|
PatKind::Lit(ref expression) => visitor.visit_expr(expression),
|
2017-01-10 15:13:53 -06:00
|
|
|
PatKind::Range(ref lower_bound, ref upper_bound, _) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(lower_bound);
|
|
|
|
visitor.visit_expr(upper_bound)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-02-14 06:25:12 -06:00
|
|
|
PatKind::Wild => (),
|
2016-09-19 19:14:46 -05:00
|
|
|
PatKind::Slice(ref prepatterns, ref slice_pattern, ref postpatterns) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_pat, prepatterns);
|
|
|
|
walk_list!(visitor, visit_pat, slice_pattern);
|
|
|
|
walk_list!(visitor, visit_pat, postpatterns);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-27 14:23:31 -05:00
|
|
|
pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(foreign_item.id);
|
2016-04-02 15:24:02 -05:00
|
|
|
visitor.visit_vis(&foreign_item.vis);
|
2015-09-19 20:50:30 -05:00
|
|
|
visitor.visit_name(foreign_item.span, foreign_item.name);
|
2015-07-31 02:04:06 -05:00
|
|
|
|
|
|
|
match foreign_item.node {
|
2018-07-11 09:56:44 -05:00
|
|
|
ForeignItemKind::Fn(ref function_declaration, ref param_names, ref generics) => {
|
2016-12-20 14:46:11 -06:00
|
|
|
visitor.visit_generics(generics);
|
2016-12-19 16:51:27 -06:00
|
|
|
visitor.visit_fn_decl(function_declaration);
|
2018-06-10 11:33:30 -05:00
|
|
|
for ¶m_name in param_names {
|
|
|
|
visitor.visit_ident(param_name);
|
2016-12-20 14:46:11 -06:00
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 09:56:44 -05:00
|
|
|
ForeignItemKind::Static(ref typ, _) => visitor.visit_ty(typ),
|
|
|
|
ForeignItemKind::Type => (),
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_attribute, &foreign_item.attrs);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
2018-06-14 06:08:58 -05:00
|
|
|
pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericBound) {
|
2015-07-31 02:04:06 -05:00
|
|
|
match *bound {
|
2018-06-14 06:08:58 -05:00
|
|
|
GenericBound::Trait(ref typ, modifier) => {
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_poly_trait_ref(typ, modifier);
|
|
|
|
}
|
2018-06-14 06:08:58 -05:00
|
|
|
GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime),
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-16 14:07:26 -05:00
|
|
|
pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v GenericParam) {
|
2018-05-25 18:27:54 -05:00
|
|
|
visitor.visit_id(param.id);
|
2018-06-15 04:52:46 -05:00
|
|
|
walk_list!(visitor, visit_attribute, ¶m.attrs);
|
2018-06-01 17:23:48 -05:00
|
|
|
match param.name {
|
2018-06-09 15:25:33 -05:00
|
|
|
ParamName::Plain(ident) => visitor.visit_ident(ident),
|
2018-10-11 14:51:44 -05:00
|
|
|
ParamName::Error | ParamName::Fresh(_) => {}
|
2018-06-01 17:23:48 -05:00
|
|
|
}
|
2018-05-25 18:27:54 -05:00
|
|
|
match param.kind {
|
2018-06-01 17:23:48 -05:00
|
|
|
GenericParamKind::Lifetime { .. } => {}
|
2018-06-14 05:42:12 -05:00
|
|
|
GenericParamKind::Type { ref default, .. } => walk_list!(visitor, visit_ty, default),
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-05-28 09:23:16 -05:00
|
|
|
walk_list!(visitor, visit_param_bound, ¶m.bounds);
|
2017-10-16 14:07:26 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) {
|
|
|
|
walk_list!(visitor, visit_generic_param, &generics.params);
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(generics.where_clause.id);
|
2016-04-21 04:10:10 -05:00
|
|
|
walk_list!(visitor, visit_where_predicate, &generics.where_clause.predicates);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_where_predicate<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
predicate: &'v WherePredicate)
|
|
|
|
{
|
|
|
|
match predicate {
|
|
|
|
&WherePredicate::BoundPredicate(WhereBoundPredicate{ref bounded_ty,
|
|
|
|
ref bounds,
|
2017-10-16 14:07:26 -05:00
|
|
|
ref bound_generic_params,
|
2016-04-21 04:10:10 -05:00
|
|
|
..}) => {
|
|
|
|
visitor.visit_ty(bounded_ty);
|
2018-05-28 09:23:16 -05:00
|
|
|
walk_list!(visitor, visit_param_bound, bounds);
|
2017-10-16 14:07:26 -05:00
|
|
|
walk_list!(visitor, visit_generic_param, bound_generic_params);
|
2016-04-21 04:10:10 -05:00
|
|
|
}
|
|
|
|
&WherePredicate::RegionPredicate(WhereRegionPredicate{ref lifetime,
|
|
|
|
ref bounds,
|
|
|
|
..}) => {
|
|
|
|
visitor.visit_lifetime(lifetime);
|
2018-05-28 09:23:16 -05:00
|
|
|
walk_list!(visitor, visit_param_bound, bounds);
|
2016-04-21 04:10:10 -05:00
|
|
|
}
|
|
|
|
&WherePredicate::EqPredicate(WhereEqPredicate{id,
|
2017-01-16 12:32:13 -06:00
|
|
|
ref lhs_ty,
|
|
|
|
ref rhs_ty,
|
2016-04-21 04:10:10 -05:00
|
|
|
..}) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(id);
|
2017-01-16 12:32:13 -06:00
|
|
|
visitor.visit_ty(lhs_ty);
|
|
|
|
visitor.visit_ty(rhs_ty);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FunctionRetTy) {
|
|
|
|
if let Return(ref output_ty) = *ret_ty {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_ty(output_ty)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) {
|
2016-12-20 14:46:11 -06:00
|
|
|
for ty in &function_declaration.inputs {
|
|
|
|
visitor.visit_ty(ty)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
walk_fn_ret_ty(visitor, &function_declaration.output)
|
|
|
|
}
|
|
|
|
|
2015-09-27 14:23:31 -05:00
|
|
|
pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'v>) {
|
2015-07-31 02:04:06 -05:00
|
|
|
match function_kind {
|
2016-08-26 11:23:42 -05:00
|
|
|
FnKind::ItemFn(_, generics, ..) => {
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_generics(generics);
|
|
|
|
}
|
2017-09-25 16:24:20 -05:00
|
|
|
FnKind::Method(..) |
|
2016-01-25 07:11:51 -06:00
|
|
|
FnKind::Closure(_) => {}
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2015-09-03 05:35:41 -05:00
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
|
2015-09-03 05:35:41 -05:00
|
|
|
pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
|
|
|
|
function_kind: FnKind<'v>,
|
|
|
|
function_declaration: &'v FnDecl,
|
2016-12-21 04:32:59 -06:00
|
|
|
body_id: BodyId,
|
2016-07-28 04:58:45 -05:00
|
|
|
_span: Span,
|
|
|
|
id: NodeId) {
|
|
|
|
visitor.visit_id(id);
|
2016-12-19 16:51:27 -06:00
|
|
|
visitor.visit_fn_decl(function_declaration);
|
2015-09-03 05:35:41 -05:00
|
|
|
walk_fn_kind(visitor, function_kind);
|
2016-12-21 04:32:59 -06:00
|
|
|
visitor.visit_nested_body(body_id)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) {
|
2018-06-10 14:24:24 -05:00
|
|
|
visitor.visit_ident(trait_item.ident);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_attribute, &trait_item.attrs);
|
2017-09-25 16:24:20 -05:00
|
|
|
visitor.visit_generics(&trait_item.generics);
|
2015-07-31 02:04:06 -05:00
|
|
|
match trait_item.node {
|
2016-12-21 04:32:59 -06:00
|
|
|
TraitItemKind::Const(ref ty, default) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(trait_item.id);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_ty(ty);
|
2016-12-21 04:32:59 -06:00
|
|
|
walk_list!(visitor, visit_nested_body, default);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-06-10 11:33:30 -05:00
|
|
|
TraitItemKind::Method(ref sig, TraitMethod::Required(ref param_names)) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(trait_item.id);
|
2016-12-19 16:51:27 -06:00
|
|
|
visitor.visit_fn_decl(&sig.decl);
|
2018-06-10 11:33:30 -05:00
|
|
|
for ¶m_name in param_names {
|
|
|
|
visitor.visit_ident(param_name);
|
2016-12-20 14:46:11 -06:00
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-12-20 14:46:11 -06:00
|
|
|
TraitItemKind::Method(ref sig, TraitMethod::Provided(body_id)) => {
|
2018-06-10 14:24:24 -05:00
|
|
|
visitor.visit_fn(FnKind::Method(trait_item.ident,
|
2016-01-25 07:11:51 -06:00
|
|
|
sig,
|
|
|
|
None,
|
|
|
|
&trait_item.attrs),
|
2015-09-27 14:23:31 -05:00
|
|
|
&sig.decl,
|
2016-10-28 15:58:32 -05:00
|
|
|
body_id,
|
2015-09-27 14:23:31 -05:00
|
|
|
trait_item.span,
|
|
|
|
trait_item.id);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-12-03 20:21:06 -06:00
|
|
|
TraitItemKind::Type(ref bounds, ref default) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(trait_item.id);
|
2018-05-28 09:23:16 -05:00
|
|
|
walk_list!(visitor, visit_param_bound, bounds);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_ty, default);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-03 20:21:06 -06:00
|
|
|
pub fn walk_trait_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_item_ref: &'v TraitItemRef) {
|
|
|
|
// NB: Deliberately force a compilation error if/when new fields are added.
|
2018-06-10 14:24:24 -05:00
|
|
|
let TraitItemRef { id, ident, ref kind, span: _, ref defaultness } = *trait_item_ref;
|
2016-12-03 20:21:06 -06:00
|
|
|
visitor.visit_nested_trait_item(id);
|
2018-06-10 14:24:24 -05:00
|
|
|
visitor.visit_ident(ident);
|
2016-12-03 20:21:06 -06:00
|
|
|
visitor.visit_associated_item_kind(kind);
|
|
|
|
visitor.visit_defaultness(defaultness);
|
|
|
|
}
|
|
|
|
|
2015-07-31 02:04:06 -05:00
|
|
|
pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) {
|
2016-11-14 10:00:02 -06:00
|
|
|
// NB: Deliberately force a compilation error if/when new fields are added.
|
2017-08-18 13:24:19 -05:00
|
|
|
let ImplItem {
|
|
|
|
id: _,
|
|
|
|
hir_id: _,
|
2018-06-10 14:24:24 -05:00
|
|
|
ident,
|
2017-08-18 13:24:19 -05:00
|
|
|
ref vis,
|
|
|
|
ref defaultness,
|
|
|
|
ref attrs,
|
2017-09-25 16:24:20 -05:00
|
|
|
ref generics,
|
2017-08-18 13:24:19 -05:00
|
|
|
ref node,
|
2018-06-10 14:24:24 -05:00
|
|
|
span: _,
|
2017-08-18 13:24:19 -05:00
|
|
|
} = *impl_item;
|
2016-11-14 10:00:02 -06:00
|
|
|
|
2018-06-10 14:24:24 -05:00
|
|
|
visitor.visit_ident(ident);
|
2016-11-14 10:00:02 -06:00
|
|
|
visitor.visit_vis(vis);
|
|
|
|
visitor.visit_defaultness(defaultness);
|
|
|
|
walk_list!(visitor, visit_attribute, attrs);
|
2017-09-25 16:24:20 -05:00
|
|
|
visitor.visit_generics(generics);
|
2016-11-14 10:00:02 -06:00
|
|
|
match *node {
|
2016-12-21 04:32:59 -06:00
|
|
|
ImplItemKind::Const(ref ty, body) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(impl_item.id);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_ty(ty);
|
2016-12-21 04:32:59 -06:00
|
|
|
visitor.visit_nested_body(body);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-10-28 15:58:32 -05:00
|
|
|
ImplItemKind::Method(ref sig, body_id) => {
|
2018-06-10 14:24:24 -05:00
|
|
|
visitor.visit_fn(FnKind::Method(impl_item.ident,
|
2016-01-25 07:11:51 -06:00
|
|
|
sig,
|
2016-03-25 01:08:11 -05:00
|
|
|
Some(&impl_item.vis),
|
2016-01-25 07:11:51 -06:00
|
|
|
&impl_item.attrs),
|
2015-09-27 14:23:31 -05:00
|
|
|
&sig.decl,
|
2016-10-28 15:58:32 -05:00
|
|
|
body_id,
|
2015-09-27 14:23:31 -05:00
|
|
|
impl_item.span,
|
|
|
|
impl_item.id);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2015-11-12 08:57:51 -06:00
|
|
|
ImplItemKind::Type(ref ty) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(impl_item.id);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_ty(ty);
|
|
|
|
}
|
2018-07-03 12:38:14 -05:00
|
|
|
ImplItemKind::Existential(ref bounds) => {
|
|
|
|
visitor.visit_id(impl_item.id);
|
|
|
|
walk_list!(visitor, visit_param_bound, bounds);
|
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-10 08:47:00 -06:00
|
|
|
pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'v ImplItemRef) {
|
2016-11-14 10:00:02 -06:00
|
|
|
// NB: Deliberately force a compilation error if/when new fields are added.
|
2018-06-10 14:24:24 -05:00
|
|
|
let ImplItemRef { id, ident, ref kind, span: _, ref vis, ref defaultness } = *impl_item_ref;
|
2016-11-14 10:00:02 -06:00
|
|
|
visitor.visit_nested_impl_item(id);
|
2018-06-10 14:24:24 -05:00
|
|
|
visitor.visit_ident(ident);
|
2016-11-14 10:00:02 -06:00
|
|
|
visitor.visit_associated_item_kind(kind);
|
|
|
|
visitor.visit_vis(vis);
|
|
|
|
visitor.visit_defaultness(defaultness);
|
2016-11-10 08:47:00 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-07 19:20:57 -05:00
|
|
|
pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, struct_definition: &'v VariantData) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(struct_definition.id());
|
2015-10-08 15:45:46 -05:00
|
|
|
walk_list!(visitor, visit_struct_field, struct_definition.fields());
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
2015-09-27 14:23:31 -05:00
|
|
|
pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v StructField) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(struct_field.id);
|
2016-04-02 15:24:02 -05:00
|
|
|
visitor.visit_vis(&struct_field.vis);
|
2018-05-25 18:50:15 -05:00
|
|
|
visitor.visit_ident(struct_field.ident);
|
2016-02-27 02:34:29 -06:00
|
|
|
visitor.visit_ty(&struct_field.ty);
|
|
|
|
walk_list!(visitor, visit_attribute, &struct_field.attrs);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(block.id);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_stmt, &block.stmts);
|
|
|
|
walk_list!(visitor, visit_expr, &block.expr);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) {
|
|
|
|
match statement.node {
|
2018-07-11 05:54:37 -05:00
|
|
|
StmtKind::Decl(ref declaration, id) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(id);
|
|
|
|
visitor.visit_decl(declaration)
|
|
|
|
}
|
2018-07-11 05:54:37 -05:00
|
|
|
StmtKind::Expr(ref expression, id) |
|
|
|
|
StmtKind::Semi(ref expression, id) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(id);
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(expression)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_decl<'v, V: Visitor<'v>>(visitor: &mut V, declaration: &'v Decl) {
|
|
|
|
match declaration.node {
|
2018-07-11 05:59:17 -05:00
|
|
|
DeclKind::Local(ref local) => visitor.visit_local(local),
|
|
|
|
DeclKind::Item(item) => visitor.visit_nested_item(item),
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-17 13:28:50 -05:00
|
|
|
pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonConst) {
|
|
|
|
visitor.visit_id(constant.id);
|
|
|
|
visitor.visit_nested_body(constant.body);
|
|
|
|
}
|
|
|
|
|
2015-07-31 02:04:06 -05:00
|
|
|
pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(expression.id);
|
2017-02-03 12:07:15 -06:00
|
|
|
walk_list!(visitor, visit_attribute, expression.attrs.iter());
|
2015-07-31 02:04:06 -05:00
|
|
|
match expression.node {
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::Box(ref subexpression) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(subexpression)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::Array(ref subexpressions) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_expr, subexpressions);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::Repeat(ref element, ref count) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(element);
|
2018-05-17 13:28:50 -05:00
|
|
|
visitor.visit_anon_const(count)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::Struct(ref qpath, ref fields, ref optional_base) => {
|
2018-07-31 11:43:51 -05:00
|
|
|
visitor.visit_qpath(qpath, expression.hir_id, expression.span);
|
2015-07-31 02:04:06 -05:00
|
|
|
for field in fields {
|
2018-04-04 19:20:21 -05:00
|
|
|
visitor.visit_id(field.id);
|
2018-05-25 18:50:15 -05:00
|
|
|
visitor.visit_ident(field.ident);
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(&field.expr)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_expr, optional_base);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::Tup(ref subexpressions) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_expr, subexpressions);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::Call(ref callee_expression, ref arguments) => {
|
2018-02-09 02:48:54 -06:00
|
|
|
visitor.visit_expr(callee_expression);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_expr, arguments);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::MethodCall(ref segment, _, ref arguments) => {
|
2017-07-07 07:57:51 -05:00
|
|
|
visitor.visit_path_segment(expression.span, segment);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_expr, arguments);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::Binary(_, ref left_expression, ref right_expression) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(left_expression);
|
|
|
|
visitor.visit_expr(right_expression)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::AddrOf(_, ref subexpression) | ExprKind::Unary(_, ref subexpression) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(subexpression)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::Lit(_) => {}
|
|
|
|
ExprKind::Cast(ref subexpression, ref typ) | ExprKind::Type(ref subexpression, ref typ) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(subexpression);
|
|
|
|
visitor.visit_ty(typ)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::If(ref head_expression, ref if_block, ref optional_else) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(head_expression);
|
2017-03-09 08:53:00 -06:00
|
|
|
visitor.visit_expr(if_block);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_expr, optional_else);
|
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::While(ref subexpression, ref block, ref opt_label) => {
|
2018-01-15 16:44:32 -06:00
|
|
|
walk_list!(visitor, visit_label, opt_label);
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(subexpression);
|
|
|
|
visitor.visit_block(block);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::Loop(ref block, ref opt_label, _) => {
|
2018-01-15 16:44:32 -06:00
|
|
|
walk_list!(visitor, visit_label, opt_label);
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_block(block);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::Match(ref subexpression, ref arms, _) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(subexpression);
|
|
|
|
walk_list!(visitor, visit_arm, arms);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::Closure(_, ref function_declaration, body, _fn_decl_span, _gen) => {
|
2016-06-17 23:01:57 -05:00
|
|
|
visitor.visit_fn(FnKind::Closure(&expression.attrs),
|
2015-09-28 16:23:54 -05:00
|
|
|
function_declaration,
|
|
|
|
body,
|
2015-07-31 02:04:06 -05:00
|
|
|
expression.span,
|
|
|
|
expression.id)
|
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::Block(ref block, ref opt_label) => {
|
2018-04-15 22:44:39 -05:00
|
|
|
walk_list!(visitor, visit_label, opt_label);
|
|
|
|
visitor.visit_block(block);
|
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::Assign(ref left_hand_expression, ref right_hand_expression) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(right_hand_expression);
|
|
|
|
visitor.visit_expr(left_hand_expression)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::AssignOp(_, ref left_expression, ref right_expression) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(right_expression);
|
|
|
|
visitor.visit_expr(left_expression)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::Field(ref subexpression, ident) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(subexpression);
|
2018-05-25 18:50:15 -05:00
|
|
|
visitor.visit_ident(ident);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::Index(ref main_expression, ref index_expression) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(main_expression);
|
|
|
|
visitor.visit_expr(index_expression)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::Path(ref qpath) => {
|
2018-07-31 11:43:51 -05:00
|
|
|
visitor.visit_qpath(qpath, expression.hir_id, expression.span);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::Break(ref destination, ref opt_expr) => {
|
2018-01-15 16:44:32 -06:00
|
|
|
if let Some(ref label) = destination.label {
|
|
|
|
visitor.visit_label(label);
|
2018-09-12 05:31:11 -05:00
|
|
|
if let Ok(node_id) = destination.target_id {
|
|
|
|
visitor.visit_def_mention(Def::Label(node_id))
|
|
|
|
}
|
2018-01-15 16:44:32 -06:00
|
|
|
}
|
Implement the `loop_break_value` feature.
This implements RFC 1624, tracking issue #37339.
- `FnCtxt` (in typeck) gets a stack of `LoopCtxt`s, which store the
currently deduced type of that loop, the desired type, and a list of
break expressions currently seen. `loop` loops get a fresh type
variable as their initial type (this logic is stolen from that for
arrays). `while` loops get `()`.
- `break {expr}` looks up the broken loop, and unifies the type of
`expr` with the type of the loop.
- `break` with no expr unifies the loop's type with `()`.
- When building MIR, `loop` loops no longer construct a `()` value at
termination of the loop; rather, the `break` expression assigns the
result of the loop. `while` loops are unchanged.
- `break` respects contexts in which expressions may not end with braced
blocks. That is, `while break { break-value } { while-body }` is
illegal; this preserves backwards compatibility.
- The RFC did not make it clear, but I chose to make `break ()` inside
of a `while` loop illegal, just in case we wanted to do anything with
that design space in the future.
This is my first time dealing with this part of rustc so I'm sure
there's plenty of problems to pick on here ^_^
2016-10-29 17:15:06 -05:00
|
|
|
walk_list!(visitor, visit_expr, opt_expr);
|
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::Continue(ref destination) => {
|
2018-01-15 16:44:32 -06:00
|
|
|
if let Some(ref label) = destination.label {
|
|
|
|
visitor.visit_label(label);
|
2018-09-12 05:31:11 -05:00
|
|
|
if let Ok(node_id) = destination.target_id {
|
|
|
|
visitor.visit_def_mention(Def::Label(node_id))
|
|
|
|
}
|
2018-01-15 16:44:32 -06:00
|
|
|
}
|
2015-09-28 16:23:54 -05:00
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::Ret(ref optional_expression) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_expr, optional_expression);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::InlineAsm(_, ref outputs, ref inputs) => {
|
2018-09-12 05:31:11 -05:00
|
|
|
for expr in outputs.iter().chain(inputs.iter()) {
|
|
|
|
visitor.visit_expr(expr)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
2018-07-11 07:05:29 -05:00
|
|
|
ExprKind::Yield(ref subexpression) => {
|
2016-12-26 07:34:03 -06:00
|
|
|
visitor.visit_expr(subexpression);
|
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) {
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_pat, &arm.pats);
|
2018-08-29 23:18:11 -05:00
|
|
|
if let Some(ref g) = arm.guard {
|
|
|
|
match g {
|
|
|
|
Guard::If(ref e) => visitor.visit_expr(e),
|
|
|
|
}
|
|
|
|
}
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(&arm.body);
|
|
|
|
walk_list!(visitor, visit_attribute, &arm.attrs);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-03-29 01:32:58 -05:00
|
|
|
|
2016-04-02 15:24:02 -05:00
|
|
|
pub fn walk_vis<'v, V: Visitor<'v>>(visitor: &mut V, vis: &'v Visibility) {
|
2018-07-31 11:43:51 -05:00
|
|
|
if let VisibilityKind::Restricted { ref path, id, hir_id } = vis.node {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(id);
|
2018-07-31 11:43:51 -05:00
|
|
|
visitor.visit_path(path, hir_id)
|
2016-04-02 15:24:02 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-14 10:00:02 -06:00
|
|
|
pub fn walk_associated_item_kind<'v, V: Visitor<'v>>(_: &mut V, _: &'v AssociatedItemKind) {
|
|
|
|
// No visitable content here: this fn exists so you can call it if
|
|
|
|
// the right thing to do, should content be added in the future,
|
|
|
|
// would be to walk it.
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_defaultness<'v, V: Visitor<'v>>(_: &mut V, _: &'v Defaultness) {
|
|
|
|
// No visitable content here: this fn exists so you can call it if
|
|
|
|
// the right thing to do, should content be added in the future,
|
|
|
|
// would be to walk it.
|
|
|
|
}
|
|
|
|
|
2018-03-20 17:58:25 -05:00
|
|
|
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
|
2016-03-29 04:12:01 -05:00
|
|
|
pub struct IdRange {
|
|
|
|
pub min: NodeId,
|
|
|
|
pub max: NodeId,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IdRange {
|
|
|
|
pub fn max() -> IdRange {
|
|
|
|
IdRange {
|
2016-08-31 06:00:29 -05:00
|
|
|
min: NodeId::from_u32(u32::MAX),
|
|
|
|
max: NodeId::from_u32(u32::MIN),
|
2016-03-29 04:12:01 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn empty(&self) -> bool {
|
|
|
|
self.min >= self.max
|
|
|
|
}
|
|
|
|
|
2016-07-28 04:58:45 -05:00
|
|
|
pub fn contains(&self, id: NodeId) -> bool {
|
|
|
|
id >= self.min && id < self.max
|
|
|
|
}
|
|
|
|
|
2016-03-29 04:12:01 -05:00
|
|
|
pub fn add(&mut self, id: NodeId) {
|
|
|
|
self.min = cmp::min(self.min, id);
|
2016-08-31 06:00:29 -05:00
|
|
|
self.max = cmp::max(self.max, NodeId::from_u32(id.as_u32() + 1));
|
2016-03-29 04:12:01 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-01-25 19:21:50 -06:00
|
|
|
pub struct IdRangeComputingVisitor<'a, 'hir: 'a> {
|
2016-10-28 15:58:32 -05:00
|
|
|
result: IdRange,
|
2017-01-25 19:21:50 -06:00
|
|
|
map: &'a map::Map<'hir>,
|
2016-03-29 04:12:01 -05:00
|
|
|
}
|
|
|
|
|
2017-01-25 19:21:50 -06:00
|
|
|
impl<'a, 'hir> IdRangeComputingVisitor<'a, 'hir> {
|
|
|
|
pub fn new(map: &'a map::Map<'hir>) -> IdRangeComputingVisitor<'a, 'hir> {
|
2016-10-28 15:58:32 -05:00
|
|
|
IdRangeComputingVisitor { result: IdRange::max(), map: map }
|
2016-03-29 04:12:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn result(&self) -> IdRange {
|
|
|
|
self.result
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-25 19:21:50 -06:00
|
|
|
impl<'a, 'hir> Visitor<'hir> for IdRangeComputingVisitor<'a, 'hir> {
|
|
|
|
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'hir> {
|
2016-11-28 13:00:26 -06:00
|
|
|
NestedVisitorMap::OnlyBodies(&self.map)
|
2016-10-28 15:58:32 -05:00
|
|
|
}
|
|
|
|
|
2016-03-29 04:12:01 -05:00
|
|
|
fn visit_id(&mut self, id: NodeId) {
|
|
|
|
self.result.add(id);
|
|
|
|
}
|
|
|
|
}
|