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
|
2019-02-08 07:53:55 -06:00
|
|
|
//! notes on how to do so:
|
2016-11-02 17:22:59 -05:00
|
|
|
//!
|
|
|
|
//! 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
|
|
|
|
2019-09-05 21:57:44 -05:00
|
|
|
use super::itemlikevisit::DeepVisitor;
|
|
|
|
|
2019-02-05 11:20:45 -06:00
|
|
|
use crate::hir::*;
|
|
|
|
use crate::hir::map::Map;
|
2019-09-05 21:57:44 -05:00
|
|
|
|
|
|
|
use syntax::ast::{Ident, Name, Attribute};
|
|
|
|
use syntax_pos::Span;
|
2015-07-31 02:04:06 -05:00
|
|
|
|
2018-03-20 17:58:25 -05:00
|
|
|
#[derive(Copy, Clone)]
|
2015-07-31 02:04:06 -05:00
|
|
|
pub enum FnKind<'a> {
|
2019-01-03 13:28:20 -06:00
|
|
|
/// `#[xxx] pub async/const/extern "Abi" fn foo()`
|
|
|
|
ItemFn(Ident, &'a Generics, FnHeader, &'a Visibility, &'a [Attribute]),
|
2015-07-31 02:04:06 -05:00
|
|
|
|
2019-01-03 13:28:20 -06: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
|
|
|
|
2019-01-03 13:28:20 -06: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,
|
|
|
|
}
|
|
|
|
}
|
2019-04-18 12:44:55 -05:00
|
|
|
|
2019-03-12 11:00:20 -05:00
|
|
|
pub fn header(&self) -> Option<&FnHeader> {
|
2019-04-18 12:44:55 -05:00
|
|
|
match *self {
|
2019-03-12 11:00:20 -05:00
|
|
|
FnKind::ItemFn(_, _, ref header, _, _) => Some(header),
|
|
|
|
FnKind::Method(_, ref sig, _, _) => Some(&sig.header),
|
2019-04-18 12:44:55 -05:00
|
|
|
FnKind::Closure(_) => None,
|
|
|
|
}
|
|
|
|
}
|
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.
|
2019-06-14 11:39:39 -05:00
|
|
|
pub enum NestedVisitorMap<'this, 'tcx> {
|
2016-11-28 13:00:26 -06:00
|
|
|
/// 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>),
|
|
|
|
|
2019-02-08 07:53:55 -06:00
|
|
|
/// Visits 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).
|
2019-02-08 07:53:55 -06:00
|
|
|
/// E.g., function body.
|
2016-11-28 13:00:26 -06:00
|
|
|
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).
|
2019-02-08 07:53:55 -06:00
|
|
|
/// E.g., item, impl-item.
|
2016-11-28 13:00:26 -06:00
|
|
|
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
|
2019-02-08 07:53:55 -06:00
|
|
|
/// overridden. Each method's default implementation recursively visits
|
2015-07-31 02:04:06 -05:00
|
|
|
/// the substructure of the input via the corresponding `walk` method;
|
2018-11-26 20:59:49 -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
|
2019-02-08 07:53:55 -06:00
|
|
|
/// explicitly, you need to override each method. (And you also need
|
2015-07-31 02:04:06 -05:00
|
|
|
/// to monitor future changes to `Visitor` in case a new method with a
|
|
|
|
/// new default implementation gets introduced.)
|
2019-09-05 21:57:44 -05:00
|
|
|
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
|
2019-09-05 21:57:44 -05:00
|
|
|
/// nothing unless you override `nested_visit_map` to return other than
|
|
|
|
/// `None`, in which case it will walk the item. **You probably
|
2016-11-09 15:45:26 -06:00
|
|
|
/// 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) {
|
2019-06-14 11:58:55 -05: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
|
2019-09-05 21:57:44 -05:00
|
|
|
/// `nested_visit_map` to return other htan `None`, 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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-27 06:24:32 -05:00
|
|
|
fn visit_param(&mut self, param: &'v Param) {
|
|
|
|
walk_param(self, param)
|
2019-07-26 17:52:37 -05:00
|
|
|
}
|
|
|
|
|
2019-02-08 07:53:55 -06:00
|
|
|
/// Visits 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
|
2019-02-08 07:53:55 -06:00
|
|
|
/// item-like visitor. This method converts a "intra-visit"
|
2016-11-02 17:22:59 -05:00
|
|
|
/// 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
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2019-02-06 07:16:11 -06:00
|
|
|
fn visit_id(&mut self, _hir_id: HirId) {
|
2016-07-28 04:58:45 -05:00
|
|
|
// 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)
|
|
|
|
}
|
2019-02-06 07:16:11 -06:00
|
|
|
fn visit_mod(&mut self, m: &'v Mod, _s: Span, n: HirId) {
|
2016-07-28 04:58:45 -05:00
|
|
|
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)
|
|
|
|
}
|
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)
|
|
|
|
}
|
2019-02-06 07:16:11 -06:00
|
|
|
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: BodyId, s: Span, id: HirId) {
|
2016-07-28 04:58:45 -05:00
|
|
|
walk_fn(self, fk, fd, b, s, id)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2019-02-06 07:16:11 -06:00
|
|
|
fn visit_use(&mut self, path: &'v Path, hir_id: HirId) {
|
|
|
|
walk_use(self, path, hir_id)
|
2018-10-11 03:15:18 -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,
|
2019-02-06 07:16:11 -06:00
|
|
|
_parent_id: HirId,
|
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,
|
2019-02-06 07:16:11 -06:00
|
|
|
item_id: HirId,
|
2015-11-05 15:17:59 -06:00
|
|
|
_: 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
|
|
|
}
|
2019-02-06 07:16:11 -06:00
|
|
|
fn visit_variant(&mut self, v: &'v Variant, g: &'v Generics, item_id: HirId) {
|
2015-10-02 08:14:20 -05:00
|
|
|
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),
|
2019-02-15 16:25:42 -06:00
|
|
|
GenericArg::Const(ct) => self.visit_anon_const(&ct.value),
|
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)
|
|
|
|
}
|
2019-05-19 03:26:08 -05:00
|
|
|
fn visit_associated_item_kind(&mut self, kind: &'v AssocItemKind) {
|
2016-11-14 10:00:02 -06:00
|
|
|
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) {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_mod(&krate.module, krate.span, CRATE_HIR_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) {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(macro_def.hir_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
|
|
|
}
|
|
|
|
|
2019-02-06 07:16:11 -06:00
|
|
|
pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod, mod_hir_id: HirId) {
|
|
|
|
visitor.visit_id(mod_hir_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) {
|
2019-08-27 06:24:32 -05:00
|
|
|
walk_list!(visitor, visit_param, &body.params);
|
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());
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(local.hir_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) {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(lifetime.hir_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 |
|
2019-08-08 02:36:24 -05:00
|
|
|
LifetimeName::ImplicitObjectLifetimeDefault |
|
2018-03-21 16:12:39 -05:00
|
|
|
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>
|
|
|
|
{
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(trait_ref.hir_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
|
|
|
}
|
|
|
|
|
2019-08-27 06:24:32 -05:00
|
|
|
pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param) {
|
|
|
|
visitor.visit_id(param.hir_id);
|
|
|
|
visitor.visit_pat(¶m.pat);
|
|
|
|
walk_list!(visitor, visit_attribute, ¶m.attrs);
|
2019-07-26 17:52:37 -05:00
|
|
|
}
|
|
|
|
|
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);
|
2018-11-30 20:47:08 -06:00
|
|
|
visitor.visit_ident(item.ident);
|
2015-07-31 02:04:06 -05:00
|
|
|
match item.node {
|
2018-07-11 10:36:06 -05:00
|
|
|
ItemKind::ExternCrate(orig_name) => {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(item.hir_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, _) => {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_use(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) => {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(item.hir_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) => {
|
2019-01-03 13:28:20 -06:00
|
|
|
visitor.visit_fn(FnKind::ItemFn(item.ident,
|
2015-09-27 14:23:31 -05:00
|
|
|
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,
|
2019-02-06 07:16:11 -06:00
|
|
|
item.hir_id)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 10:36:06 -05:00
|
|
|
ItemKind::Mod(ref module) => {
|
2019-02-06 07:16:11 -06:00
|
|
|
// `visit_mod()` takes care of visiting the `Item`'s `HirId`.
|
|
|
|
visitor.visit_mod(module, item.span, item.hir_id)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 10:36:06 -05:00
|
|
|
ItemKind::ForeignMod(ref foreign_module) => {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(item.hir_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(_) => {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(item.hir_id);
|
2017-03-29 23:32:20 -05:00
|
|
|
}
|
2019-08-02 05:02:08 -05:00
|
|
|
ItemKind::TyAlias(ref ty, ref generics) => {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(item.hir_id);
|
2019-03-28 19:28:07 -05:00
|
|
|
visitor.visit_ty(ty);
|
|
|
|
visitor.visit_generics(generics)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2019-08-01 18:08:05 -05:00
|
|
|
ItemKind::OpaqueTy(OpaqueTy {
|
2019-03-13 19:42:23 -05:00
|
|
|
ref generics,
|
|
|
|
ref bounds,
|
|
|
|
..
|
|
|
|
}) => {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(item.hir_id);
|
2018-05-22 07:31:56 -05:00
|
|
|
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
|
|
|
}
|
2019-03-28 19:28:07 -05:00
|
|
|
ItemKind::Enum(ref enum_definition, ref generics) => {
|
|
|
|
visitor.visit_generics(generics);
|
2019-02-06 07:16:11 -06:00
|
|
|
// `visit_enum_def()` takes care of visiting the `Item`'s `HirId`.
|
2019-03-28 19:28:07 -05:00
|
|
|
visitor.visit_enum_def(enum_definition, generics, item.hir_id, item.span)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2018-07-11 19:20:31 -05:00
|
|
|
ItemKind::Impl(
|
|
|
|
..,
|
2019-03-28 19:28:07 -05:00
|
|
|
ref generics,
|
2018-07-11 19:20:31 -05:00
|
|
|
ref opt_trait_reference,
|
|
|
|
ref typ,
|
|
|
|
ref impl_item_refs
|
|
|
|
) => {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(item.hir_id);
|
2019-03-28 19:28:07 -05:00
|
|
|
visitor.visit_generics(generics);
|
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);
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(item.hir_id);
|
|
|
|
visitor.visit_variant_data(struct_definition, item.ident.name, generics, item.hir_id,
|
2018-11-30 20:47:08 -06:00
|
|
|
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) => {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(item.hir_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) => {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(item.hir_id);
|
2017-10-02 07:28:16 -05:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2018-10-11 03:15:18 -05:00
|
|
|
pub fn walk_use<'v, V: Visitor<'v>>(visitor: &mut V,
|
|
|
|
path: &'v Path,
|
|
|
|
hir_id: HirId) {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(hir_id);
|
2018-10-11 03:15:18 -05:00
|
|
|
visitor.visit_path(path, hir_id);
|
|
|
|
}
|
|
|
|
|
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,
|
2019-02-06 07:16:11 -06:00
|
|
|
item_id: HirId) {
|
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,
|
2019-02-06 07:16:11 -06:00
|
|
|
parent_item_id: HirId) {
|
2019-08-13 19:40:21 -05:00
|
|
|
visitor.visit_ident(variant.ident);
|
|
|
|
visitor.visit_id(variant.id);
|
|
|
|
visitor.visit_variant_data(&variant.data,
|
|
|
|
variant.ident.name,
|
2015-11-05 15:17:59 -06:00
|
|
|
generics,
|
2016-07-28 04:58:45 -05:00
|
|
|
parent_item_id,
|
2015-11-05 15:17:59 -06:00
|
|
|
variant.span);
|
2019-08-13 19:40:21 -05:00
|
|
|
walk_list!(visitor, visit_anon_const, &variant.disr_expr);
|
|
|
|
walk_list!(visitor, visit_attribute, &variant.attrs);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(typ.hir_id);
|
2016-07-28 04:58:45 -05:00
|
|
|
|
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
|
|
|
}
|
2019-09-05 21:57:44 -05:00
|
|
|
TyKind::Never => {}
|
2018-07-11 09:41:03 -05:00
|
|
|
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-11-30 09:53:44 -06:00
|
|
|
TyKind::CVarArgs(ref lt) => {
|
|
|
|
visitor.visit_lifetime(lt)
|
|
|
|
}
|
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) {
|
|
|
|
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);
|
2019-02-06 07:16:11 -06:00
|
|
|
if let Some(id) = segment.hir_id {
|
2018-10-11 03:15:18 -05:00
|
|
|
visitor.visit_id(id);
|
|
|
|
}
|
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) {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(type_binding.hir_id);
|
2018-06-10 07:55:48 -05:00
|
|
|
visitor.visit_ident(type_binding.ident);
|
2019-05-08 14:57:06 -05:00
|
|
|
match type_binding.kind {
|
|
|
|
TypeBindingKind::Equality { ref ty } => {
|
|
|
|
visitor.visit_ty(ty);
|
|
|
|
}
|
|
|
|
TypeBindingKind::Constraint { ref bounds } => {
|
|
|
|
walk_list!(visitor, visit_param_bound, bounds);
|
|
|
|
}
|
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(pattern.hir_id);
|
2019-09-26 10:18:31 -05:00
|
|
|
match pattern.kind {
|
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 {
|
2019-08-14 18:35:36 -05:00
|
|
|
visitor.visit_id(field.hir_id);
|
|
|
|
visitor.visit_ident(field.ident);
|
|
|
|
visitor.visit_pat(&field.pat)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
2018-10-19 09:40:07 -05:00
|
|
|
PatKind::Or(ref pats) => walk_list!(visitor, visit_pat, pats),
|
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
|
|
|
}
|
2019-03-07 05:18:59 -06:00
|
|
|
PatKind::Binding(_, _hir_id, ident, ref optional_subpattern) => {
|
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) {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(foreign_item.hir_id);
|
2016-04-02 15:24:02 -05:00
|
|
|
visitor.visit_vis(&foreign_item.vis);
|
2018-11-30 20:47:08 -06:00
|
|
|
visitor.visit_ident(foreign_item.ident);
|
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) {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(param.hir_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),
|
2019-02-15 16:25:42 -06:00
|
|
|
GenericParamKind::Const { ref ty } => visitor.visit_ty(ty),
|
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-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
|
|
|
}
|
2019-02-06 07:16:11 -06:00
|
|
|
&WherePredicate::EqPredicate(WhereEqPredicate{hir_id,
|
2017-01-16 12:32:13 -06:00
|
|
|
ref lhs_ty,
|
|
|
|
ref rhs_ty,
|
2016-04-21 04:10:10 -05:00
|
|
|
..}) => {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(hir_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,
|
2019-02-06 07:16:11 -06:00
|
|
|
id: HirId) {
|
2016-07-28 04:58:45 -05:00
|
|
|
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) => {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(trait_item.hir_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)) => {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(trait_item.hir_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,
|
2019-02-06 07:16:11 -06:00
|
|
|
trait_item.hir_id);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-12-03 20:21:06 -06:00
|
|
|
TraitItemKind::Type(ref bounds, ref default) => {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(trait_item.hir_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) {
|
2018-11-26 20:59:49 -06:00
|
|
|
// N.B., 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) {
|
2018-11-26 20:59:49 -06:00
|
|
|
// N.B., deliberately force a compilation error if/when new fields are added.
|
2017-08-18 13:24:19 -05:00
|
|
|
let ImplItem {
|
|
|
|
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) => {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(impl_item.hir_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,
|
2019-02-06 07:16:11 -06:00
|
|
|
impl_item.hir_id);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2019-08-02 14:59:07 -05:00
|
|
|
ImplItemKind::TyAlias(ref ty) => {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(impl_item.hir_id);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_ty(ty);
|
|
|
|
}
|
2019-07-31 18:41:54 -05:00
|
|
|
ImplItemKind::OpaqueTy(ref bounds) => {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(impl_item.hir_id);
|
2018-07-03 12:38:14 -05:00
|
|
|
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) {
|
2018-11-26 20:59:49 -06:00
|
|
|
// N.B., 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) {
|
2019-03-21 17:38:50 -05:00
|
|
|
if let Some(ctor_hir_id) = struct_definition.ctor_hir_id() {
|
|
|
|
visitor.visit_id(ctor_hir_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) {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(struct_field.hir_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) {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(block.hir_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) {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(statement.hir_id);
|
2015-07-31 02:04:06 -05:00
|
|
|
match statement.node {
|
2019-01-16 17:39:24 -06:00
|
|
|
StmtKind::Local(ref local) => visitor.visit_local(local),
|
2019-02-17 00:23:13 -06:00
|
|
|
StmtKind::Item(item) => visitor.visit_nested_item(item),
|
2019-01-16 16:45:02 -06:00
|
|
|
StmtKind::Expr(ref expression) |
|
|
|
|
StmtKind::Semi(ref expression) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(expression)
|
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) {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(constant.hir_id);
|
2018-05-17 13:28:50 -05:00
|
|
|
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) {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(expression.hir_id);
|
2017-02-03 12:07:15 -06:00
|
|
|
walk_list!(visitor, visit_attribute, expression.attrs.iter());
|
2019-09-26 08:39:48 -05:00
|
|
|
match expression.kind {
|
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 {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(field.hir_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::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
|
|
|
}
|
2019-04-30 10:46:59 -05:00
|
|
|
ExprKind::DropTemps(ref subexpression) => {
|
2019-04-23 23:39:40 -05:00
|
|
|
visitor.visit_expr(subexpression);
|
|
|
|
}
|
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,
|
2019-02-06 07:16:11 -06:00
|
|
|
expression.hir_id)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
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);
|
Change how we compute yield_in_scope
Compound operators (e.g. 'a += b') have two different possible
evaluation orders. When the left-hand side is a primitive type, the
expression is evaluated right-to-left. However, when the left-hand side
is a non-primitive type, the expression is evaluated left-to-right.
This causes problems when we try to determine if a type is live across a
yield point. Since we need to perform this computation before typecheck
has run, we can't simply check the types of the operands.
This commit calculates the most 'pessimistic' scenario - that is,
erring on the side of treating more types as live, rather than fewer.
This is perfectly safe - in fact, this initial liveness computation is
already overly conservative (e.g. issue #57478). The important thing is
that we compute a superset of the types that are actually live across
yield points. When we generate MIR, we'll determine which types actually
need to stay live across a given yield point, and which ones cam
actually be dropped.
Concretely, we force the computed HIR traversal index for
right-hand-side yield expression to be equal to the maximum index for
the left-hand side. This covers both possible execution orders:
* If the expression is evalauted right-to-left, our 'pessismitic' index
is unecessary, but safe. We visit the expressions in an
ExprKind::AssignOp from right to left, so it actually would have been
safe to do nothing. However, while increasing the index of a yield point
might cause the compiler to reject code that could actually compile, it
will never cause incorrect code to be accepted.
* If the expression is evaluated left-to-right, our 'pessimistic' index
correctly ensures that types in the left-hand-side are seen as occuring
before the yield - which is exactly what we want
2019-06-06 21:23:28 -05:00
|
|
|
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);
|
|
|
|
}
|
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);
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
}
|
2019-06-18 16:34:51 -05:00
|
|
|
ExprKind::Yield(ref subexpression, _) => {
|
2016-12-26 07:34:03 -06:00
|
|
|
visitor.visit_expr(subexpression);
|
|
|
|
}
|
2019-06-07 04:53:33 -05:00
|
|
|
ExprKind::Lit(_) | ExprKind::Err => {}
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) {
|
2019-03-30 17:54:29 -05:00
|
|
|
visitor.visit_id(arm.hir_id);
|
2019-09-07 09:01:12 -05:00
|
|
|
visitor.visit_pat(&arm.pat);
|
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) {
|
2019-02-26 08:55:01 -06:00
|
|
|
if let VisibilityKind::Restricted { ref path, hir_id } = vis.node {
|
2019-02-06 07:16:11 -06:00
|
|
|
visitor.visit_id(hir_id);
|
2018-07-31 11:43:51 -05:00
|
|
|
visitor.visit_path(path, hir_id)
|
2016-04-02 15:24:02 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-19 03:26:08 -05:00
|
|
|
pub fn walk_associated_item_kind<'v, V: Visitor<'v>>(_: &mut V, _: &'v AssocItemKind) {
|
2016-11-14 10:00:02 -06:00
|
|
|
// 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.
|
|
|
|
}
|