2016-11-02 22:22:59 +00:00
|
|
|
//! HIR walker for walking the contents of nodes.
|
|
|
|
//!
|
2022-05-07 20:22:52 +00:00
|
|
|
//! Here are the three available patterns for the visitor strategy,
|
|
|
|
//! in roughly the order of desirability:
|
|
|
|
//!
|
|
|
|
//! 1. **Shallow visit**: Get a simple callback for every item (or item-like thing) in the HIR.
|
|
|
|
//! - Example: find all items with a `#[foo]` attribute on them.
|
|
|
|
//! - How: Use the `hir_crate_items` or `hir_module_items` query to traverse over item-like ids
|
|
|
|
//! (ItemId, TraitItemId, etc.) and use tcx.def_kind and `tcx.hir().item*(id)` to filter and
|
|
|
|
//! access actual item-like thing, respectively.
|
|
|
|
//! - Pro: Efficient; just walks the lists of item ids and gives users control whether to access
|
|
|
|
//! the hir_owners themselves or not.
|
|
|
|
//! - Con: Don't get information about nesting
|
|
|
|
//! - Con: Don't have methods for specific bits of HIR, like "on
|
|
|
|
//! every expr, do this".
|
|
|
|
//! 2. **Deep visit**: Want to scan for specific kinds of HIR nodes within
|
|
|
|
//! an item, but don't care about how item-like things are nested
|
|
|
|
//! within one another.
|
|
|
|
//! - Example: Examine each expression to look for its type and do some check or other.
|
|
|
|
//! - How: Implement `intravisit::Visitor` and override the `NestedFilter` type to
|
|
|
|
//! `nested_filter::OnlyBodies` (and implement `nested_visit_map`), and use
|
2022-07-03 13:28:57 +00:00
|
|
|
//! `tcx.hir().visit_all_item_likes_in_crate(&mut visitor)`. Within your
|
2022-05-07 20:22:52 +00:00
|
|
|
//! `intravisit::Visitor` impl, implement methods like `visit_expr()` (don't forget to invoke
|
|
|
|
//! `intravisit::walk_expr()` to keep walking the subparts).
|
|
|
|
//! - Pro: Visitor methods for any kind of HIR node, not just item-like things.
|
|
|
|
//! - Pro: Integrates well into dependency tracking.
|
|
|
|
//! - Con: Don't get information about nesting between items
|
|
|
|
//! 3. **Nested visit**: Want to visit the whole HIR and you care about the nesting between
|
|
|
|
//! item-like things.
|
|
|
|
//! - Example: Lifetime resolution, which wants to bring lifetimes declared on the
|
|
|
|
//! impl into scope while visiting the impl-items, and then back out again.
|
|
|
|
//! - How: Implement `intravisit::Visitor` and override the `NestedFilter` type to
|
|
|
|
//! `nested_filter::All` (and implement `nested_visit_map`). Walk your crate with
|
|
|
|
//! `tcx.hir().walk_toplevel_module(visitor)` invoked on `tcx.hir().krate()`.
|
|
|
|
//! - Pro: Visitor methods for any kind of HIR node, not just item-like things.
|
|
|
|
//! - Pro: Preserves nesting information
|
|
|
|
//! - Con: Does not integrate well into dependency tracking.
|
2016-11-02 22:22:59 +00:00
|
|
|
//!
|
|
|
|
//! If you have decided to use this visitor, here are some general
|
2019-02-08 13:53:55 +00:00
|
|
|
//! notes on how to do so:
|
2016-11-02 22:22:59 +00:00
|
|
|
//!
|
|
|
|
//! Each overridden visit method has full control over what
|
2015-07-31 07:04:06 +00:00
|
|
|
//! happens with its node, it can do its own traversal of the node's children,
|
2015-12-10 09:52:32 +00:00
|
|
|
//! call `intravisit::walk_*` to apply the default traversal algorithm, or prevent
|
2015-07-31 07:04:06 +00:00
|
|
|
//! deeper traversal by doing nothing.
|
|
|
|
//!
|
2015-11-18 02:44:39 +00: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 07:04:06 +00:00
|
|
|
//!
|
2015-11-18 02:44:39 +00:00
|
|
|
//! Note: it is an important invariant that the default visitor walks
|
2017-09-12 22:09:56 +00: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 07:04:06 +00:00
|
|
|
|
2020-01-07 16:30:29 +00:00
|
|
|
use crate::hir::*;
|
2020-02-29 17:37:32 +00:00
|
|
|
use rustc_ast::walk_list;
|
2020-04-27 17:56:11 +00:00
|
|
|
use rustc_ast::{Attribute, Label};
|
2020-04-19 11:00:18 +00:00
|
|
|
use rustc_span::symbol::{Ident, Symbol};
|
2019-12-31 17:15:40 +00:00
|
|
|
use rustc_span::Span;
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2020-01-02 03:18:51 +00:00
|
|
|
pub trait IntoVisitor<'hir> {
|
|
|
|
type Visitor: Visitor<'hir>;
|
|
|
|
fn into_visitor(&self) -> Self::Visitor;
|
|
|
|
}
|
|
|
|
|
2021-04-07 11:30:37 +00:00
|
|
|
#[derive(Copy, Clone, Debug)]
|
2015-07-31 07:04:06 +00:00
|
|
|
pub enum FnKind<'a> {
|
2019-01-03 19:28:20 +00:00
|
|
|
/// `#[xxx] pub async/const/extern "Abi" fn foo()`
|
2022-02-13 14:40:08 +00:00
|
|
|
ItemFn(Ident, &'a Generics<'a>, FnHeader),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2019-01-03 19:28:20 +00:00
|
|
|
/// `fn foo(&self)`
|
2022-02-13 14:40:08 +00:00
|
|
|
Method(Ident, &'a FnSig<'a>),
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2019-01-03 19:28:20 +00:00
|
|
|
/// `|x, y| {}`
|
2020-11-27 08:24:42 +00:00
|
|
|
Closure,
|
2016-01-25 13:11:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> FnKind<'a> {
|
2019-03-12 16:00:20 +00:00
|
|
|
pub fn header(&self) -> Option<&FnHeader> {
|
2019-04-18 17:44:55 +00:00
|
|
|
match *self {
|
2022-02-13 14:40:08 +00:00
|
|
|
FnKind::ItemFn(_, _, ref header) => Some(header),
|
|
|
|
FnKind::Method(_, ref sig) => Some(&sig.header),
|
2020-11-27 08:24:42 +00:00
|
|
|
FnKind::Closure => None,
|
2019-04-18 17:44:55 +00:00
|
|
|
}
|
|
|
|
}
|
2021-10-19 21:31:51 +00:00
|
|
|
|
|
|
|
pub fn constness(self) -> Constness {
|
|
|
|
self.header().map_or(Constness::NotConst, |header| header.constness)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn asyncness(self) -> IsAsync {
|
|
|
|
self.header().map_or(IsAsync::NotAsync, |header| header.asyncness)
|
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2020-03-29 14:41:09 +00:00
|
|
|
/// An abstract representation of the HIR `rustc_middle::hir::map::Map`.
|
2020-01-07 16:25:33 +00:00
|
|
|
pub trait Map<'hir> {
|
2020-03-24 01:44:41 +00:00
|
|
|
/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
|
|
|
|
fn find(&self, hir_id: HirId) -> Option<Node<'hir>>;
|
2020-01-07 16:25:33 +00:00
|
|
|
fn body(&self, id: BodyId) -> &'hir Body<'hir>;
|
2021-01-30 11:06:04 +00:00
|
|
|
fn item(&self, id: ItemId) -> &'hir Item<'hir>;
|
2020-01-07 16:25:33 +00:00
|
|
|
fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir>;
|
|
|
|
fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir>;
|
2020-11-11 20:57:54 +00:00
|
|
|
fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir>;
|
2020-01-07 16:25:33 +00:00
|
|
|
}
|
|
|
|
|
2021-09-12 01:19:18 +00:00
|
|
|
// Used when no map is actually available, forcing manual implementation of nested visitors.
|
2021-12-14 04:33:53 +00:00
|
|
|
impl<'hir> Map<'hir> for ! {
|
2021-09-12 01:19:18 +00:00
|
|
|
fn find(&self, _: HirId) -> Option<Node<'hir>> {
|
2022-02-10 10:42:02 +00:00
|
|
|
*self;
|
2021-09-12 01:19:18 +00:00
|
|
|
}
|
|
|
|
fn body(&self, _: BodyId) -> &'hir Body<'hir> {
|
2022-02-10 10:42:02 +00:00
|
|
|
*self;
|
2021-09-12 01:19:18 +00:00
|
|
|
}
|
|
|
|
fn item(&self, _: ItemId) -> &'hir Item<'hir> {
|
2022-02-10 10:42:02 +00:00
|
|
|
*self;
|
2021-09-12 01:19:18 +00:00
|
|
|
}
|
|
|
|
fn trait_item(&self, _: TraitItemId) -> &'hir TraitItem<'hir> {
|
2022-02-10 10:42:02 +00:00
|
|
|
*self;
|
2021-09-12 01:19:18 +00:00
|
|
|
}
|
|
|
|
fn impl_item(&self, _: ImplItemId) -> &'hir ImplItem<'hir> {
|
2022-02-10 10:42:02 +00:00
|
|
|
*self;
|
2021-09-12 01:19:18 +00:00
|
|
|
}
|
|
|
|
fn foreign_item(&self, _: ForeignItemId) -> &'hir ForeignItem<'hir> {
|
2022-02-10 10:42:02 +00:00
|
|
|
*self;
|
2021-09-12 01:19:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-03 23:03:12 +00:00
|
|
|
pub mod nested_filter {
|
|
|
|
use super::Map;
|
2020-03-11 11:05:32 +00:00
|
|
|
|
2022-04-30 17:27:01 +00:00
|
|
|
/// Specifies what nested things a visitor wants to visit. By "nested
|
|
|
|
/// things", 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.
|
|
|
|
///
|
|
|
|
/// The most common choice is `OnlyBodies`, which will cause the visitor to
|
|
|
|
/// visit fn bodies for fns that it encounters, and closure bodies, but
|
|
|
|
/// skip over nested item-like things.
|
2021-11-03 23:03:12 +00:00
|
|
|
///
|
|
|
|
/// See the comments on `ItemLikeVisitor` for more details on the overall
|
|
|
|
/// visit strategy.
|
|
|
|
pub trait NestedFilter<'hir> {
|
|
|
|
type Map: Map<'hir>;
|
|
|
|
|
|
|
|
/// Whether the visitor visits nested "item-like" things.
|
|
|
|
/// E.g., item, impl-item.
|
|
|
|
const INTER: bool;
|
|
|
|
/// Whether the visitor visits "intra item-like" things.
|
|
|
|
/// E.g., function body, closure, `AnonConst`
|
|
|
|
const INTRA: bool;
|
2020-11-11 20:57:54 +00:00
|
|
|
}
|
2020-03-11 11:05:32 +00:00
|
|
|
|
2016-11-28 19:00:26 +00: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 19:51:19 +00: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.
|
2021-11-03 23:03:12 +00:00
|
|
|
pub struct None(());
|
|
|
|
impl NestedFilter<'_> for None {
|
|
|
|
type Map = !;
|
|
|
|
const INTER: bool = false;
|
|
|
|
const INTRA: bool = false;
|
2016-11-28 19:00:26 +00:00
|
|
|
}
|
2016-10-28 20:58:32 +00:00
|
|
|
}
|
|
|
|
|
2021-11-03 23:03:12 +00:00
|
|
|
use nested_filter::NestedFilter;
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
/// Each method of the Visitor trait is a hook to be potentially
|
2019-02-08 13:53:55 +00:00
|
|
|
/// overridden. Each method's default implementation recursively visits
|
2015-07-31 07:04:06 +00:00
|
|
|
/// the substructure of the input via the corresponding `walk` method;
|
2018-11-27 02:59:49 +00:00
|
|
|
/// e.g., the `visit_mod` method by default calls `intravisit::walk_mod`.
|
2015-07-31 07:04:06 +00:00
|
|
|
///
|
2015-11-18 02:44:39 +00: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
|
2022-07-03 13:28:57 +00:00
|
|
|
/// should call `tcx.hir().visit_all_item_likes_in_crate`. Otherwise, see the comment
|
2015-11-17 22:32:12 +00:00
|
|
|
/// on `visit_nested_item` for details on how to visit nested items.
|
|
|
|
///
|
2015-07-31 07:04:06 +00:00
|
|
|
/// If you want to ensure that your code handles every variant
|
2019-02-08 13:53:55 +00:00
|
|
|
/// explicitly, you need to override each method. (And you also need
|
2015-07-31 07:04:06 +00:00
|
|
|
/// to monitor future changes to `Visitor` in case a new method with a
|
|
|
|
/// new default implementation gets introduced.)
|
2019-09-06 02:57:44 +00:00
|
|
|
pub trait Visitor<'v>: Sized {
|
2021-11-03 23:03:12 +00:00
|
|
|
// this type should not be overridden, it exists for convenient usage as `Self::Map`
|
|
|
|
type Map: Map<'v> = <Self::NestedFilter as NestedFilter<'v>>::Map;
|
2020-01-07 16:25:33 +00:00
|
|
|
|
2015-11-17 22:32:12 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Nested items.
|
|
|
|
|
2022-04-30 17:27:01 +00:00
|
|
|
/// Override this type to control which nested HIR are visited; see
|
|
|
|
/// [`NestedFilter`] for details. If you override this type, you
|
|
|
|
/// must also override [`nested_visit_map`](Self::nested_visit_map).
|
2016-11-09 21:45:26 +00:00
|
|
|
///
|
|
|
|
/// **If for some reason you want the nested behavior, but don't
|
2022-04-30 17:27:01 +00:00
|
|
|
/// have a `Map` at your disposal:** then override the
|
|
|
|
/// `visit_nested_XXX` methods. If a new `visit_nested_XXX` variant is
|
|
|
|
/// added in the future, it will cause a panic which can be detected
|
|
|
|
/// and fixed appropriately.
|
|
|
|
type NestedFilter: NestedFilter<'v> = nested_filter::None;
|
|
|
|
|
|
|
|
/// If `type NestedFilter` is set to visit nested items, this method
|
|
|
|
/// must also be overridden to provide a map to retrieve nested items.
|
2021-11-03 23:03:12 +00:00
|
|
|
fn nested_visit_map(&mut self) -> Self::Map {
|
|
|
|
panic!(
|
|
|
|
"nested_visit_map must be implemented or consider using \
|
|
|
|
`type NestedFilter = nested_filter::None` (the default)"
|
|
|
|
);
|
|
|
|
}
|
2016-11-09 21:45:26 +00:00
|
|
|
|
2022-04-30 17:27:01 +00:00
|
|
|
/// Invoked when a nested item is encountered. By default, when
|
|
|
|
/// `Self::NestedFilter` is `nested_filter::None`, this method does
|
|
|
|
/// nothing. **You probably don't want to override this method** --
|
|
|
|
/// instead, override [`Self::NestedFilter`] 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 22:32:12 +00:00
|
|
|
fn visit_nested_item(&mut self, id: ItemId) {
|
2021-11-03 23:03:12 +00:00
|
|
|
if Self::NestedFilter::INTER {
|
|
|
|
let item = self.nested_visit_map().item(id);
|
|
|
|
self.visit_item(item);
|
|
|
|
}
|
2015-11-17 22:32:12 +00:00
|
|
|
}
|
|
|
|
|
2016-12-04 02:21:06 +00:00
|
|
|
/// Like `visit_nested_item()`, but for trait items. See
|
|
|
|
/// `visit_nested_item()` for advice on when to override this
|
|
|
|
/// method.
|
|
|
|
fn visit_nested_trait_item(&mut self, id: TraitItemId) {
|
2021-11-03 23:03:12 +00:00
|
|
|
if Self::NestedFilter::INTER {
|
|
|
|
let item = self.nested_visit_map().trait_item(id);
|
|
|
|
self.visit_trait_item(item);
|
|
|
|
}
|
2016-12-04 02:21:06 +00:00
|
|
|
}
|
|
|
|
|
2016-11-09 21:45:26 +00:00
|
|
|
/// Like `visit_nested_item()`, but for impl items. See
|
|
|
|
/// `visit_nested_item()` for advice on when to override this
|
|
|
|
/// method.
|
2016-11-02 22:25:31 +00:00
|
|
|
fn visit_nested_impl_item(&mut self, id: ImplItemId) {
|
2021-11-03 23:03:12 +00:00
|
|
|
if Self::NestedFilter::INTER {
|
|
|
|
let item = self.nested_visit_map().impl_item(id);
|
|
|
|
self.visit_impl_item(item);
|
|
|
|
}
|
2016-11-02 22:25:31 +00:00
|
|
|
}
|
|
|
|
|
2020-11-26 18:11:43 +00:00
|
|
|
/// Like `visit_nested_item()`, but for foreign items. See
|
2020-11-11 20:57:54 +00:00
|
|
|
/// `visit_nested_item()` for advice on when to override this
|
|
|
|
/// method.
|
|
|
|
fn visit_nested_foreign_item(&mut self, id: ForeignItemId) {
|
2021-11-03 23:03:12 +00:00
|
|
|
if Self::NestedFilter::INTER {
|
|
|
|
let item = self.nested_visit_map().foreign_item(id);
|
|
|
|
self.visit_foreign_item(item);
|
|
|
|
}
|
2020-11-11 20:57:54 +00:00
|
|
|
}
|
|
|
|
|
2016-10-28 20:58:32 +00:00
|
|
|
/// Invoked to visit the body of a function, method or closure. Like
|
2022-04-30 17:27:01 +00:00
|
|
|
/// `visit_nested_item`, does nothing by default unless you override
|
|
|
|
/// `Self::NestedFilter`.
|
2016-12-21 10:32:59 +00:00
|
|
|
fn visit_nested_body(&mut self, id: BodyId) {
|
2021-11-03 23:03:12 +00:00
|
|
|
if Self::NestedFilter::INTRA {
|
|
|
|
let body = self.nested_visit_map().body(id);
|
|
|
|
self.visit_body(body);
|
|
|
|
}
|
2016-10-28 20:58:32 +00:00
|
|
|
}
|
|
|
|
|
2019-11-29 12:43:03 +00:00
|
|
|
fn visit_param(&mut self, param: &'v Param<'v>) {
|
2019-08-27 11:24:32 +00:00
|
|
|
walk_param(self, param)
|
2019-07-26 22:52:37 +00:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:53:55 +00:00
|
|
|
/// Visits the top-level item and (optionally) nested items / impl items. See
|
2015-11-17 22:32:12 +00:00
|
|
|
/// `visit_nested_item` for details.
|
2019-11-28 18:28:50 +00:00
|
|
|
fn visit_item(&mut self, i: &'v Item<'v>) {
|
2015-11-17 22:32:12 +00:00
|
|
|
walk_item(self, i)
|
|
|
|
}
|
|
|
|
|
2019-11-29 10:09:23 +00:00
|
|
|
fn visit_body(&mut self, b: &'v Body<'v>) {
|
2016-12-21 10:32:59 +00:00
|
|
|
walk_body(self, b);
|
|
|
|
}
|
|
|
|
|
2015-11-17 22:32:12 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2019-02-06 13:16:11 +00:00
|
|
|
fn visit_id(&mut self, _hir_id: HirId) {
|
2016-07-28 09:58:45 +00:00
|
|
|
// Nothing to do.
|
|
|
|
}
|
2022-09-12 03:30:15 +00:00
|
|
|
fn visit_name(&mut self, _name: Symbol) {
|
2015-07-31 07:04:06 +00:00
|
|
|
// Nothing to do.
|
|
|
|
}
|
2018-05-25 23:50:15 +00:00
|
|
|
fn visit_ident(&mut self, ident: Ident) {
|
|
|
|
walk_ident(self, ident)
|
|
|
|
}
|
2019-11-29 09:24:47 +00:00
|
|
|
fn visit_mod(&mut self, m: &'v Mod<'v>, _s: Span, n: HirId) {
|
2016-07-28 09:58:45 +00:00
|
|
|
walk_mod(self, m, n)
|
2015-09-27 19:23:31 +00:00
|
|
|
}
|
2019-11-28 19:18:29 +00:00
|
|
|
fn visit_foreign_item(&mut self, i: &'v ForeignItem<'v>) {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_foreign_item(self, i)
|
|
|
|
}
|
2022-07-05 21:31:18 +00:00
|
|
|
fn visit_local(&mut self, l: &'v Local<'v>) {
|
|
|
|
walk_local(self, l)
|
2015-09-27 19:23:31 +00:00
|
|
|
}
|
2019-11-29 12:43:03 +00:00
|
|
|
fn visit_block(&mut self, b: &'v Block<'v>) {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_block(self, b)
|
|
|
|
}
|
2019-11-29 12:43:03 +00:00
|
|
|
fn visit_stmt(&mut self, s: &'v Stmt<'v>) {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_stmt(self, s)
|
|
|
|
}
|
2019-11-29 12:43:03 +00:00
|
|
|
fn visit_arm(&mut self, a: &'v Arm<'v>) {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_arm(self, a)
|
|
|
|
}
|
2019-11-29 12:43:03 +00:00
|
|
|
fn visit_pat(&mut self, p: &'v Pat<'v>) {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_pat(self, p)
|
|
|
|
}
|
2022-05-23 01:34:37 +00:00
|
|
|
fn visit_pat_field(&mut self, f: &'v PatField<'v>) {
|
|
|
|
walk_pat_field(self, f)
|
|
|
|
}
|
2021-12-23 09:01:51 +00:00
|
|
|
fn visit_array_length(&mut self, len: &'v ArrayLen) {
|
|
|
|
walk_array_len(self, len)
|
|
|
|
}
|
2018-05-17 18:28:50 +00:00
|
|
|
fn visit_anon_const(&mut self, c: &'v AnonConst) {
|
|
|
|
walk_anon_const(self, c)
|
|
|
|
}
|
2019-11-29 12:43:03 +00:00
|
|
|
fn visit_expr(&mut self, ex: &'v Expr<'v>) {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_expr(self, ex)
|
|
|
|
}
|
2021-10-13 05:39:06 +00:00
|
|
|
fn visit_let_expr(&mut self, lex: &'v Let<'v>) {
|
|
|
|
walk_let_expr(self, lex)
|
|
|
|
}
|
2022-05-23 01:34:37 +00:00
|
|
|
fn visit_expr_field(&mut self, field: &'v ExprField<'v>) {
|
|
|
|
walk_expr_field(self, field)
|
|
|
|
}
|
2019-11-30 16:46:46 +00:00
|
|
|
fn visit_ty(&mut self, t: &'v Ty<'v>) {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_ty(self, t)
|
|
|
|
}
|
2019-11-30 16:46:46 +00:00
|
|
|
fn visit_generic_param(&mut self, p: &'v GenericParam<'v>) {
|
2017-10-16 19:07:26 +00:00
|
|
|
walk_generic_param(self, p)
|
|
|
|
}
|
2021-03-01 11:50:09 +00:00
|
|
|
fn visit_const_param_default(&mut self, _param: HirId, ct: &'v AnonConst) {
|
|
|
|
walk_const_param_default(self, ct)
|
|
|
|
}
|
2019-11-30 16:46:46 +00:00
|
|
|
fn visit_generics(&mut self, g: &'v Generics<'v>) {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_generics(self, g)
|
|
|
|
}
|
2019-11-30 16:46:46 +00:00
|
|
|
fn visit_where_predicate(&mut self, predicate: &'v WherePredicate<'v>) {
|
2016-04-21 09:10:10 +00:00
|
|
|
walk_where_predicate(self, predicate)
|
|
|
|
}
|
2019-11-30 16:46:46 +00:00
|
|
|
fn visit_fn_decl(&mut self, fd: &'v FnDecl<'v>) {
|
2016-12-19 22:51:27 +00:00
|
|
|
walk_fn_decl(self, fd)
|
|
|
|
}
|
2022-09-12 03:13:22 +00:00
|
|
|
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl<'v>, b: BodyId, _: Span, id: HirId) {
|
|
|
|
walk_fn(self, fk, fd, b, id)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2019-11-30 16:46:46 +00:00
|
|
|
fn visit_use(&mut self, path: &'v Path<'v>, hir_id: HirId) {
|
2019-02-06 13:16:11 +00:00
|
|
|
walk_use(self, path, hir_id)
|
2018-10-11 08:15:18 +00:00
|
|
|
}
|
2019-11-28 20:47:10 +00:00
|
|
|
fn visit_trait_item(&mut self, ti: &'v TraitItem<'v>) {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_trait_item(self, ti)
|
|
|
|
}
|
2016-12-04 02:21:06 +00:00
|
|
|
fn visit_trait_item_ref(&mut self, ii: &'v TraitItemRef) {
|
|
|
|
walk_trait_item_ref(self, ii)
|
|
|
|
}
|
2019-11-28 21:16:44 +00:00
|
|
|
fn visit_impl_item(&mut self, ii: &'v ImplItem<'v>) {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_impl_item(self, ii)
|
|
|
|
}
|
2021-07-15 20:19:39 +00:00
|
|
|
fn visit_foreign_item_ref(&mut self, ii: &'v ForeignItemRef) {
|
2020-11-11 20:57:54 +00:00
|
|
|
walk_foreign_item_ref(self, ii)
|
|
|
|
}
|
2021-07-15 20:19:39 +00:00
|
|
|
fn visit_impl_item_ref(&mut self, ii: &'v ImplItemRef) {
|
2016-11-10 14:47:00 +00:00
|
|
|
walk_impl_item_ref(self, ii)
|
|
|
|
}
|
2019-11-30 16:46:46 +00:00
|
|
|
fn visit_trait_ref(&mut self, t: &'v TraitRef<'v>) {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_trait_ref(self, t)
|
|
|
|
}
|
2019-11-30 16:46:46 +00:00
|
|
|
fn visit_param_bound(&mut self, bounds: &'v GenericBound<'v>) {
|
2018-05-28 14:23:16 +00:00
|
|
|
walk_param_bound(self, bounds)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2022-09-12 03:37:18 +00:00
|
|
|
fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef<'v>) {
|
|
|
|
walk_poly_trait_ref(self, t)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2022-08-10 01:22:01 +00:00
|
|
|
fn visit_variant_data(&mut self, s: &'v VariantData<'v>) {
|
2015-07-31 07:04:06 +00:00
|
|
|
walk_struct_def(self, s)
|
|
|
|
}
|
2021-03-15 21:36:07 +00:00
|
|
|
fn visit_field_def(&mut self, s: &'v FieldDef<'v>) {
|
|
|
|
walk_field_def(self, s)
|
2015-09-27 19:23:31 +00:00
|
|
|
}
|
2022-08-11 01:07:34 +00:00
|
|
|
fn visit_enum_def(&mut self, enum_definition: &'v EnumDef<'v>, item_id: HirId) {
|
2022-08-10 01:22:01 +00:00
|
|
|
walk_enum_def(self, enum_definition, item_id)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2022-08-10 01:22:01 +00:00
|
|
|
fn visit_variant(&mut self, v: &'v Variant<'v>) {
|
|
|
|
walk_variant(self, v)
|
2015-09-27 19:23:31 +00:00
|
|
|
}
|
2018-01-15 22:44:32 +00:00
|
|
|
fn visit_label(&mut self, label: &'v Label) {
|
|
|
|
walk_label(self, label)
|
|
|
|
}
|
2021-04-24 21:41:57 +00:00
|
|
|
fn visit_infer(&mut self, inf: &'v InferArg) {
|
2021-04-26 18:19:23 +00:00
|
|
|
walk_inf(self, inf);
|
2021-04-24 21:41:57 +00:00
|
|
|
}
|
2019-11-30 16:46:46 +00:00
|
|
|
fn visit_generic_arg(&mut self, generic_arg: &'v GenericArg<'v>) {
|
2018-02-13 11:32:37 +00:00
|
|
|
match generic_arg {
|
|
|
|
GenericArg::Lifetime(lt) => self.visit_lifetime(lt),
|
|
|
|
GenericArg::Type(ty) => self.visit_ty(ty),
|
2019-02-15 22:25:42 +00:00
|
|
|
GenericArg::Const(ct) => self.visit_anon_const(&ct.value),
|
2021-04-24 21:41:57 +00:00
|
|
|
GenericArg::Infer(inf) => self.visit_infer(inf),
|
2018-02-25 13:46:45 +00:00
|
|
|
}
|
|
|
|
}
|
2015-09-28 21:23:54 +00:00
|
|
|
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
|
|
|
|
walk_lifetime(self, lifetime)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2022-09-12 00:43:34 +00:00
|
|
|
// The span is that of the surrounding type/pattern/expr/whatever.
|
|
|
|
fn visit_qpath(&mut self, qpath: &'v QPath<'v>, id: HirId, _span: Span) {
|
|
|
|
walk_qpath(self, qpath, id)
|
2016-10-27 02:17:42 +00:00
|
|
|
}
|
2019-11-30 16:46:46 +00:00
|
|
|
fn visit_path(&mut self, path: &'v Path<'v>, _id: HirId) {
|
2015-07-31 07:04:06 +00:00
|
|
|
walk_path(self, path)
|
|
|
|
}
|
2022-09-12 00:43:34 +00:00
|
|
|
fn visit_path_segment(&mut self, path_segment: &'v PathSegment<'v>) {
|
|
|
|
walk_path_segment(self, path_segment)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2022-09-12 00:43:34 +00:00
|
|
|
fn visit_generic_args(&mut self, generic_args: &'v GenericArgs<'v>) {
|
|
|
|
walk_generic_args(self, generic_args)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2019-11-30 16:46:46 +00:00
|
|
|
fn visit_assoc_type_binding(&mut self, type_binding: &'v TypeBinding<'v>) {
|
2015-07-31 07:04:06 +00:00
|
|
|
walk_assoc_type_binding(self, type_binding)
|
|
|
|
}
|
2022-06-15 21:54:03 +00:00
|
|
|
fn visit_attribute(&mut self, _attr: &'v Attribute) {}
|
2019-05-19 08:26:08 +00:00
|
|
|
fn visit_associated_item_kind(&mut self, kind: &'v AssocItemKind) {
|
2016-11-14 16:00:02 +00:00
|
|
|
walk_associated_item_kind(self, kind);
|
|
|
|
}
|
|
|
|
fn visit_defaultness(&mut self, defaultness: &'v Defaultness) {
|
|
|
|
walk_defaultness(self, defaultness);
|
|
|
|
}
|
2022-03-01 00:50:56 +00:00
|
|
|
fn visit_inline_asm(&mut self, asm: &'v InlineAsm<'v>, id: HirId) {
|
|
|
|
walk_inline_asm(self, asm, id);
|
|
|
|
}
|
2015-09-28 21:23:54 +00:00
|
|
|
}
|
|
|
|
|
2019-11-29 09:24:47 +00:00
|
|
|
pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod<'v>, mod_hir_id: HirId) {
|
2019-02-06 13:16:11 +00:00
|
|
|
visitor.visit_id(mod_hir_id);
|
2019-11-29 09:24:47 +00:00
|
|
|
for &item_id in module.item_ids {
|
2015-11-17 22:32:12 +00:00
|
|
|
visitor.visit_nested_item(item_id);
|
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-29 10:09:23 +00:00
|
|
|
pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body<'v>) {
|
|
|
|
walk_list!(visitor, visit_param, body.params);
|
2016-12-21 10:32:59 +00:00
|
|
|
visitor.visit_expr(&body.value);
|
|
|
|
}
|
|
|
|
|
2022-07-05 21:31:18 +00:00
|
|
|
pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local<'v>) {
|
2017-09-20 13:36:20 +00:00
|
|
|
// Intentionally visiting the expr first - the initialization expr
|
|
|
|
// dominates the local's definition.
|
|
|
|
walk_list!(visitor, visit_expr, &local.init);
|
2019-02-06 13:16:11 +00:00
|
|
|
visitor.visit_id(local.hir_id);
|
2015-09-28 21:23:54 +00:00
|
|
|
visitor.visit_pat(&local.pat);
|
2022-07-05 21:31:18 +00:00
|
|
|
if let Some(els) = local.els {
|
2022-06-02 14:39:47 +00:00
|
|
|
visitor.visit_block(els);
|
|
|
|
}
|
2015-09-28 21:23:54 +00:00
|
|
|
walk_list!(visitor, visit_ty, &local.ty);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2018-05-25 23:50:15 +00:00
|
|
|
pub fn walk_ident<'v, V: Visitor<'v>>(visitor: &mut V, ident: Ident) {
|
2022-09-12 03:30:15 +00:00
|
|
|
visitor.visit_name(ident.name);
|
2018-05-25 23:50:15 +00:00
|
|
|
}
|
|
|
|
|
2018-01-15 22:44:32 +00:00
|
|
|
pub fn walk_label<'v, V: Visitor<'v>>(visitor: &mut V, label: &'v Label) {
|
2018-06-10 16:33:30 +00:00
|
|
|
visitor.visit_ident(label.ident);
|
2018-01-15 22:44:32 +00:00
|
|
|
}
|
|
|
|
|
2015-09-28 21:23:54 +00:00
|
|
|
pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) {
|
2019-02-06 13:16:11 +00:00
|
|
|
visitor.visit_id(lifetime.hir_id);
|
2017-09-19 23:36:54 +00:00
|
|
|
match lifetime.name {
|
2022-04-27 20:15:58 +00:00
|
|
|
LifetimeName::Param(_, ParamName::Plain(ident)) => {
|
2018-06-09 20:25:33 +00:00
|
|
|
visitor.visit_ident(ident);
|
2017-09-19 23:36:54 +00:00
|
|
|
}
|
2022-04-27 20:15:58 +00:00
|
|
|
LifetimeName::Param(_, ParamName::Fresh)
|
|
|
|
| LifetimeName::Param(_, ParamName::Error)
|
2018-03-21 21:12:39 +00:00
|
|
|
| LifetimeName::Static
|
2018-10-11 19:51:44 +00:00
|
|
|
| LifetimeName::Error
|
2019-08-08 07:36:24 +00:00
|
|
|
| LifetimeName::ImplicitObjectLifetimeDefault
|
2022-06-13 06:22:06 +00:00
|
|
|
| LifetimeName::Infer => {}
|
2017-09-19 23:36:54 +00:00
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2022-09-12 03:37:18 +00:00
|
|
|
pub fn walk_poly_trait_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_ref: &'v PolyTraitRef<'v>) {
|
2019-11-30 23:17:43 +00:00
|
|
|
walk_list!(visitor, visit_generic_param, trait_ref.bound_generic_params);
|
2015-07-31 07:04:06 +00:00
|
|
|
visitor.visit_trait_ref(&trait_ref.trait_ref);
|
|
|
|
}
|
|
|
|
|
2020-01-07 16:25:33 +00:00
|
|
|
pub fn walk_trait_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_ref: &'v TraitRef<'v>) {
|
2019-02-06 13:16:11 +00:00
|
|
|
visitor.visit_id(trait_ref.hir_ref_id);
|
2018-07-31 16:43:51 +00:00
|
|
|
visitor.visit_path(&trait_ref.path, trait_ref.hir_ref_id)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-29 12:43:03 +00:00
|
|
|
pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param<'v>) {
|
2019-08-27 11:24:32 +00:00
|
|
|
visitor.visit_id(param.hir_id);
|
|
|
|
visitor.visit_pat(¶m.pat);
|
2019-07-26 22:52:37 +00:00
|
|
|
}
|
|
|
|
|
2019-11-28 18:28:50 +00:00
|
|
|
pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
|
2018-12-01 02:47:08 +00:00
|
|
|
visitor.visit_ident(item.ident);
|
2019-09-26 16:51:36 +00:00
|
|
|
match item.kind {
|
2018-07-11 15:36:06 +00:00
|
|
|
ItemKind::ExternCrate(orig_name) => {
|
2021-01-30 16:47:51 +00:00
|
|
|
visitor.visit_id(item.hir_id());
|
2018-03-09 15:51:48 +00:00
|
|
|
if let Some(orig_name) = orig_name {
|
2022-09-12 03:30:15 +00:00
|
|
|
visitor.visit_name(orig_name);
|
2018-01-15 22:44:32 +00:00
|
|
|
}
|
2015-09-28 21:23:54 +00:00
|
|
|
}
|
2018-07-11 15:36:06 +00:00
|
|
|
ItemKind::Use(ref path, _) => {
|
2021-01-30 16:47:51 +00:00
|
|
|
visitor.visit_use(path, item.hir_id());
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2018-07-11 15:36:06 +00:00
|
|
|
ItemKind::Static(ref typ, _, body) | ItemKind::Const(ref typ, body) => {
|
2021-01-30 16:47:51 +00:00
|
|
|
visitor.visit_id(item.hir_id());
|
2015-09-28 21:23:54 +00:00
|
|
|
visitor.visit_ty(typ);
|
2016-12-21 10:32:59 +00:00
|
|
|
visitor.visit_nested_body(body);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2019-11-07 11:57:52 +00:00
|
|
|
ItemKind::Fn(ref sig, ref generics, body_id) => visitor.visit_fn(
|
2022-02-13 14:40:08 +00:00
|
|
|
FnKind::ItemFn(item.ident, generics, sig.header),
|
2019-11-07 11:57:52 +00:00
|
|
|
&sig.decl,
|
2016-10-28 20:58:32 +00:00
|
|
|
body_id,
|
2015-07-31 07:04:06 +00:00
|
|
|
item.span,
|
2021-01-30 16:47:51 +00:00
|
|
|
item.hir_id(),
|
2019-12-22 22:42:04 +00:00
|
|
|
),
|
2021-12-11 11:52:23 +00:00
|
|
|
ItemKind::Macro(..) => {
|
2021-07-31 06:50:57 +00:00
|
|
|
visitor.visit_id(item.hir_id());
|
|
|
|
}
|
2018-07-11 15:36:06 +00:00
|
|
|
ItemKind::Mod(ref module) => {
|
2019-02-06 13:16:11 +00:00
|
|
|
// `visit_mod()` takes care of visiting the `Item`'s `HirId`.
|
2021-01-30 16:47:51 +00:00
|
|
|
visitor.visit_mod(module, item.span, item.hir_id())
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2020-11-11 21:40:09 +00:00
|
|
|
ItemKind::ForeignMod { abi: _, items } => {
|
2021-01-30 16:47:51 +00:00
|
|
|
visitor.visit_id(item.hir_id());
|
2020-11-11 21:40:09 +00:00
|
|
|
walk_list!(visitor, visit_foreign_item_ref, items);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2021-04-11 19:51:28 +00:00
|
|
|
ItemKind::GlobalAsm(asm) => {
|
2021-01-30 16:47:51 +00:00
|
|
|
visitor.visit_id(item.hir_id());
|
2022-03-01 00:50:56 +00:00
|
|
|
visitor.visit_inline_asm(asm, item.hir_id());
|
2017-03-30 04:32:20 +00:00
|
|
|
}
|
2019-08-02 10:02:08 +00:00
|
|
|
ItemKind::TyAlias(ref ty, ref generics) => {
|
2021-01-30 16:47:51 +00:00
|
|
|
visitor.visit_id(item.hir_id());
|
2019-03-29 00:28:07 +00:00
|
|
|
visitor.visit_ty(ty);
|
|
|
|
visitor.visit_generics(generics)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2019-11-30 23:17:43 +00:00
|
|
|
ItemKind::OpaqueTy(OpaqueTy { ref generics, bounds, .. }) => {
|
2021-01-30 16:47:51 +00:00
|
|
|
visitor.visit_id(item.hir_id());
|
2018-05-22 12:31:56 +00:00
|
|
|
walk_generics(visitor, generics);
|
2018-06-20 11:34:39 +00:00
|
|
|
walk_list!(visitor, visit_param_bound, bounds);
|
2018-05-22 12:31:56 +00:00
|
|
|
}
|
2019-03-29 00:28:07 +00:00
|
|
|
ItemKind::Enum(ref enum_definition, ref generics) => {
|
|
|
|
visitor.visit_generics(generics);
|
2019-02-06 13:16:11 +00:00
|
|
|
// `visit_enum_def()` takes care of visiting the `Item`'s `HirId`.
|
2022-08-11 01:07:34 +00:00
|
|
|
visitor.visit_enum_def(enum_definition, item.hir_id())
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2020-11-22 22:46:21 +00:00
|
|
|
ItemKind::Impl(Impl {
|
2020-01-18 00:14:29 +00:00
|
|
|
unsafety: _,
|
|
|
|
defaultness: _,
|
|
|
|
polarity: _,
|
2020-01-14 04:30:24 +00:00
|
|
|
constness: _,
|
2020-03-02 23:26:00 +00:00
|
|
|
defaultness_span: _,
|
2020-01-18 00:14:29 +00:00
|
|
|
ref generics,
|
|
|
|
ref of_trait,
|
|
|
|
ref self_ty,
|
|
|
|
items,
|
2020-11-22 22:46:21 +00:00
|
|
|
}) => {
|
2021-01-30 16:47:51 +00:00
|
|
|
visitor.visit_id(item.hir_id());
|
2019-03-29 00:28:07 +00:00
|
|
|
visitor.visit_generics(generics);
|
2020-01-18 00:14:29 +00:00
|
|
|
walk_list!(visitor, visit_trait_ref, of_trait);
|
|
|
|
visitor.visit_ty(self_ty);
|
2022-02-05 14:26:49 +00:00
|
|
|
walk_list!(visitor, visit_impl_item_ref, *items);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2018-07-11 15:36:06 +00:00
|
|
|
ItemKind::Struct(ref struct_definition, ref generics)
|
|
|
|
| ItemKind::Union(ref struct_definition, ref generics) => {
|
2015-07-31 07:04:06 +00:00
|
|
|
visitor.visit_generics(generics);
|
2021-01-30 16:47:51 +00:00
|
|
|
visitor.visit_id(item.hir_id());
|
2022-08-10 01:22:01 +00:00
|
|
|
visitor.visit_variant_data(struct_definition);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2019-11-30 23:17:43 +00:00
|
|
|
ItemKind::Trait(.., ref generics, bounds, trait_item_refs) => {
|
2021-01-30 16:47:51 +00:00
|
|
|
visitor.visit_id(item.hir_id());
|
2015-07-31 07:04:06 +00:00
|
|
|
visitor.visit_generics(generics);
|
2018-05-28 14:23:16 +00:00
|
|
|
walk_list!(visitor, visit_param_bound, bounds);
|
2016-12-04 02:21:06 +00:00
|
|
|
walk_list!(visitor, visit_trait_item_ref, trait_item_refs);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2019-11-30 23:17:43 +00:00
|
|
|
ItemKind::TraitAlias(ref generics, bounds) => {
|
2021-01-30 16:47:51 +00:00
|
|
|
visitor.visit_id(item.hir_id());
|
2017-10-02 12:28:16 +00:00
|
|
|
visitor.visit_generics(generics);
|
2018-05-28 14:23:16 +00:00
|
|
|
walk_list!(visitor, visit_param_bound, bounds);
|
2017-10-02 12:28:16 +00:00
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-01 00:50:56 +00:00
|
|
|
pub fn walk_inline_asm<'v, V: Visitor<'v>>(visitor: &mut V, asm: &'v InlineAsm<'v>, id: HirId) {
|
|
|
|
for (op, op_sp) in asm.operands {
|
2021-04-11 19:51:28 +00:00
|
|
|
match op {
|
2022-03-01 00:50:56 +00:00
|
|
|
InlineAsmOperand::In { expr, .. } | InlineAsmOperand::InOut { expr, .. } => {
|
|
|
|
visitor.visit_expr(expr)
|
|
|
|
}
|
2021-04-11 19:51:28 +00:00
|
|
|
InlineAsmOperand::Out { expr, .. } => {
|
|
|
|
if let Some(expr) = expr {
|
|
|
|
visitor.visit_expr(expr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
|
|
|
|
visitor.visit_expr(in_expr);
|
|
|
|
if let Some(out_expr) = out_expr {
|
|
|
|
visitor.visit_expr(out_expr);
|
|
|
|
}
|
|
|
|
}
|
2022-03-01 00:50:56 +00:00
|
|
|
InlineAsmOperand::Const { anon_const, .. }
|
|
|
|
| InlineAsmOperand::SymFn { anon_const, .. } => visitor.visit_anon_const(anon_const),
|
|
|
|
InlineAsmOperand::SymStatic { path, .. } => visitor.visit_qpath(path, id, *op_sp),
|
2021-04-11 19:51:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
pub fn walk_use<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path<'v>, hir_id: HirId) {
|
2019-02-06 13:16:11 +00:00
|
|
|
visitor.visit_id(hir_id);
|
2018-10-11 08:15:18 +00:00
|
|
|
visitor.visit_path(path, hir_id);
|
|
|
|
}
|
|
|
|
|
2015-07-31 07:04:06 +00:00
|
|
|
pub fn walk_enum_def<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
2019-11-29 08:26:18 +00:00
|
|
|
enum_definition: &'v EnumDef<'v>,
|
2019-02-06 13:16:11 +00:00
|
|
|
item_id: HirId,
|
|
|
|
) {
|
2016-07-28 09:58:45 +00:00
|
|
|
visitor.visit_id(item_id);
|
2022-08-10 01:22:01 +00:00
|
|
|
walk_list!(visitor, visit_variant, enum_definition.variants);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2022-08-10 01:22:01 +00:00
|
|
|
pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V, variant: &'v Variant<'v>) {
|
2019-08-14 00:40:21 +00:00
|
|
|
visitor.visit_ident(variant.ident);
|
|
|
|
visitor.visit_id(variant.id);
|
2022-08-10 01:22:01 +00:00
|
|
|
visitor.visit_variant_data(&variant.data);
|
2019-08-14 00:40:21 +00:00
|
|
|
walk_list!(visitor, visit_anon_const, &variant.disr_expr);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) {
|
2019-02-06 13:16:11 +00:00
|
|
|
visitor.visit_id(typ.hir_id);
|
2016-07-28 09:58:45 +00:00
|
|
|
|
2019-09-26 16:25:31 +00:00
|
|
|
match typ.kind {
|
2018-07-11 14:41:03 +00:00
|
|
|
TyKind::Slice(ref ty) => visitor.visit_ty(ty),
|
2015-09-28 21:23:54 +00:00
|
|
|
TyKind::Ptr(ref mutable_type) => visitor.visit_ty(&mutable_type.ty),
|
2018-07-11 14:41:03 +00:00
|
|
|
TyKind::Rptr(ref lifetime, ref mutable_type) => {
|
2017-01-09 15:46:11 +00:00
|
|
|
visitor.visit_lifetime(lifetime);
|
2015-09-28 21:23:54 +00:00
|
|
|
visitor.visit_ty(&mutable_type.ty)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2019-09-06 02:57:44 +00:00
|
|
|
TyKind::Never => {}
|
2019-11-30 23:17:43 +00:00
|
|
|
TyKind::Tup(tuple_element_types) => {
|
2015-09-28 21:23:54 +00:00
|
|
|
walk_list!(visitor, visit_ty, tuple_element_types);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2018-07-11 14:41:03 +00:00
|
|
|
TyKind::BareFn(ref function_declaration) => {
|
2019-11-30 23:17:43 +00:00
|
|
|
walk_list!(visitor, visit_generic_param, function_declaration.generic_params);
|
2018-05-30 11:36:53 +00:00
|
|
|
visitor.visit_fn_decl(&function_declaration.decl);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2018-07-11 14:41:03 +00:00
|
|
|
TyKind::Path(ref qpath) => {
|
2018-07-31 16:43:51 +00:00
|
|
|
visitor.visit_qpath(qpath, typ.hir_id, typ.span);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2022-09-06 15:37:00 +00:00
|
|
|
TyKind::OpaqueDef(item_id, lifetimes, _in_trait) => {
|
2018-10-02 08:54:34 +00:00
|
|
|
visitor.visit_nested_item(item_id);
|
|
|
|
walk_list!(visitor, visit_generic_arg, lifetimes);
|
|
|
|
}
|
2018-07-11 14:41:03 +00:00
|
|
|
TyKind::Array(ref ty, ref length) => {
|
2015-09-28 21:23:54 +00:00
|
|
|
visitor.visit_ty(ty);
|
2021-12-23 09:01:51 +00:00
|
|
|
visitor.visit_array_length(length)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2021-03-13 12:44:29 +00:00
|
|
|
TyKind::TraitObject(bounds, ref lifetime, _syntax) => {
|
2017-01-24 15:17:06 +00:00
|
|
|
for bound in bounds {
|
2022-09-12 03:37:18 +00:00
|
|
|
visitor.visit_poly_trait_ref(bound);
|
2017-01-24 15:17:06 +00:00
|
|
|
}
|
|
|
|
visitor.visit_lifetime(lifetime);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2018-05-17 18:28:50 +00:00
|
|
|
TyKind::Typeof(ref expression) => visitor.visit_anon_const(expression),
|
2018-07-11 14:41:03 +00:00
|
|
|
TyKind::Infer | TyKind::Err => {}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-24 21:41:57 +00:00
|
|
|
pub fn walk_inf<'v, V: Visitor<'v>>(visitor: &mut V, inf: &'v InferArg) {
|
|
|
|
visitor.visit_id(inf.hir_id);
|
|
|
|
}
|
|
|
|
|
2022-09-12 00:43:34 +00:00
|
|
|
pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V, qpath: &'v QPath<'v>, id: HirId) {
|
2016-10-27 02:17:42 +00:00
|
|
|
match *qpath {
|
|
|
|
QPath::Resolved(ref maybe_qself, ref path) => {
|
2020-01-07 16:38:38 +00:00
|
|
|
walk_list!(visitor, visit_ty, maybe_qself);
|
2016-10-27 02:17:42 +00:00
|
|
|
visitor.visit_path(path, id)
|
|
|
|
}
|
|
|
|
QPath::TypeRelative(ref qself, ref segment) => {
|
|
|
|
visitor.visit_ty(qself);
|
2022-09-12 00:43:34 +00:00
|
|
|
visitor.visit_path_segment(segment);
|
2016-10-27 02:17:42 +00:00
|
|
|
}
|
2020-08-04 13:34:24 +00:00
|
|
|
QPath::LangItem(..) => {}
|
2016-10-27 02:17:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path<'v>) {
|
2019-11-30 23:17:43 +00:00
|
|
|
for segment in path.segments {
|
2022-09-12 00:43:34 +00:00
|
|
|
visitor.visit_path_segment(segment);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-12 00:43:34 +00:00
|
|
|
pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V, segment: &'v PathSegment<'v>) {
|
2018-06-10 14:40:45 +00:00
|
|
|
visitor.visit_ident(segment.ident);
|
2022-08-30 06:54:42 +00:00
|
|
|
visitor.visit_id(segment.hir_id);
|
2018-02-23 17:48:54 +00:00
|
|
|
if let Some(ref args) = segment.args {
|
2022-09-12 00:43:34 +00:00
|
|
|
visitor.visit_generic_args(args);
|
2017-09-21 20:24:26 +00:00
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2022-09-12 00:43:34 +00:00
|
|
|
pub fn walk_generic_args<'v, V: Visitor<'v>>(visitor: &mut V, generic_args: &'v GenericArgs<'v>) {
|
2019-12-01 16:10:12 +00:00
|
|
|
walk_list!(visitor, visit_generic_arg, generic_args.args);
|
2019-11-30 23:17:43 +00:00
|
|
|
walk_list!(visitor, visit_assoc_type_binding, generic_args.bindings);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
type_binding: &'v TypeBinding<'v>,
|
|
|
|
) {
|
2019-02-06 13:16:11 +00:00
|
|
|
visitor.visit_id(type_binding.hir_id);
|
2018-06-10 12:55:48 +00:00
|
|
|
visitor.visit_ident(type_binding.ident);
|
2022-09-12 00:43:34 +00:00
|
|
|
visitor.visit_generic_args(type_binding.gen_args);
|
2019-05-08 19:57:06 +00:00
|
|
|
match type_binding.kind {
|
2022-01-08 09:28:12 +00:00
|
|
|
TypeBindingKind::Equality { ref term } => match term {
|
|
|
|
Term::Ty(ref ty) => visitor.visit_ty(ty),
|
|
|
|
Term::Const(ref c) => visitor.visit_anon_const(c),
|
|
|
|
},
|
|
|
|
TypeBindingKind::Constraint { bounds } => walk_list!(visitor, visit_param_bound, bounds),
|
2019-05-08 19:57:06 +00:00
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-29 12:43:03 +00:00
|
|
|
pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) {
|
2019-02-06 13:16:11 +00:00
|
|
|
visitor.visit_id(pattern.hir_id);
|
2019-09-26 15:18:31 +00:00
|
|
|
match pattern.kind {
|
2019-11-29 13:08:03 +00:00
|
|
|
PatKind::TupleStruct(ref qpath, children, _) => {
|
2018-07-31 16:43:51 +00:00
|
|
|
visitor.visit_qpath(qpath, pattern.hir_id, pattern.span);
|
2016-03-06 12:54:44 +00:00
|
|
|
walk_list!(visitor, visit_pat, children);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2016-10-27 02:17:42 +00:00
|
|
|
PatKind::Path(ref qpath) => {
|
2018-07-31 16:43:51 +00:00
|
|
|
visitor.visit_qpath(qpath, pattern.hir_id, pattern.span);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2019-11-29 13:08:03 +00:00
|
|
|
PatKind::Struct(ref qpath, fields, _) => {
|
2018-07-31 16:43:51 +00:00
|
|
|
visitor.visit_qpath(qpath, pattern.hir_id, pattern.span);
|
2022-05-23 01:34:37 +00:00
|
|
|
walk_list!(visitor, visit_pat_field, fields);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2019-11-29 13:08:03 +00:00
|
|
|
PatKind::Or(pats) => walk_list!(visitor, visit_pat, pats),
|
|
|
|
PatKind::Tuple(tuple_elements, _) => {
|
2015-09-28 21:23:54 +00:00
|
|
|
walk_list!(visitor, visit_pat, tuple_elements);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2016-02-14 12:25:12 +00:00
|
|
|
PatKind::Box(ref subpattern) | PatKind::Ref(ref subpattern, _) => {
|
2015-09-28 21:23:54 +00:00
|
|
|
visitor.visit_pat(subpattern)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2019-03-07 11:18:59 +00:00
|
|
|
PatKind::Binding(_, _hir_id, ident, ref optional_subpattern) => {
|
2018-06-10 16:33:30 +00:00
|
|
|
visitor.visit_ident(ident);
|
2015-09-28 21:23:54 +00:00
|
|
|
walk_list!(visitor, visit_pat, optional_subpattern);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2016-02-14 12:25:12 +00:00
|
|
|
PatKind::Lit(ref expression) => visitor.visit_expr(expression),
|
2017-01-10 21:13:53 +00:00
|
|
|
PatKind::Range(ref lower_bound, ref upper_bound, _) => {
|
2019-12-11 09:04:34 +00:00
|
|
|
walk_list!(visitor, visit_expr, lower_bound);
|
|
|
|
walk_list!(visitor, visit_expr, upper_bound);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2016-02-14 12:25:12 +00:00
|
|
|
PatKind::Wild => (),
|
2019-11-29 13:08:03 +00:00
|
|
|
PatKind::Slice(prepatterns, ref slice_pattern, postpatterns) => {
|
2015-09-28 21:23:54 +00:00
|
|
|
walk_list!(visitor, visit_pat, prepatterns);
|
|
|
|
walk_list!(visitor, visit_pat, slice_pattern);
|
|
|
|
walk_list!(visitor, visit_pat, postpatterns);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-23 01:34:37 +00:00
|
|
|
pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<'v>) {
|
|
|
|
visitor.visit_id(field.hir_id);
|
|
|
|
visitor.visit_ident(field.ident);
|
|
|
|
visitor.visit_pat(&field.pat)
|
|
|
|
}
|
|
|
|
|
2019-11-28 19:18:29 +00:00
|
|
|
pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem<'v>) {
|
2021-01-31 23:33:38 +00:00
|
|
|
visitor.visit_id(foreign_item.hir_id());
|
2018-12-01 02:47:08 +00:00
|
|
|
visitor.visit_ident(foreign_item.ident);
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2019-09-26 16:58:14 +00:00
|
|
|
match foreign_item.kind {
|
2019-11-28 19:18:29 +00:00
|
|
|
ForeignItemKind::Fn(ref function_declaration, param_names, ref generics) => {
|
2016-12-20 20:46:11 +00:00
|
|
|
visitor.visit_generics(generics);
|
2016-12-19 22:51:27 +00:00
|
|
|
visitor.visit_fn_decl(function_declaration);
|
2018-06-10 16:33:30 +00:00
|
|
|
for ¶m_name in param_names {
|
|
|
|
visitor.visit_ident(param_name);
|
2016-12-20 20:46:11 +00:00
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2018-07-11 14:56:44 +00:00
|
|
|
ForeignItemKind::Static(ref typ, _) => visitor.visit_ty(typ),
|
|
|
|
ForeignItemKind::Type => (),
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericBound<'v>) {
|
2015-07-31 07:04:06 +00:00
|
|
|
match *bound {
|
2022-09-12 03:37:18 +00:00
|
|
|
GenericBound::Trait(ref typ, _modifier) => {
|
|
|
|
visitor.visit_poly_trait_ref(typ);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2022-09-12 00:43:34 +00:00
|
|
|
GenericBound::LangItemTrait(_, _span, hir_id, args) => {
|
2020-08-04 13:34:24 +00:00
|
|
|
visitor.visit_id(hir_id);
|
2022-09-12 00:43:34 +00:00
|
|
|
visitor.visit_generic_args(args);
|
2020-08-04 13:34:24 +00:00
|
|
|
}
|
2018-06-14 11:08:58 +00:00
|
|
|
GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime),
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v GenericParam<'v>) {
|
2019-02-06 13:16:11 +00:00
|
|
|
visitor.visit_id(param.hir_id);
|
2018-06-01 22:23:48 +00:00
|
|
|
match param.name {
|
2018-06-09 20:25:33 +00:00
|
|
|
ParamName::Plain(ident) => visitor.visit_ident(ident),
|
2022-04-27 20:15:58 +00:00
|
|
|
ParamName::Error | ParamName::Fresh => {}
|
2018-06-01 22:23:48 +00:00
|
|
|
}
|
2018-05-25 23:27:54 +00:00
|
|
|
match param.kind {
|
2018-06-01 22:23:48 +00:00
|
|
|
GenericParamKind::Lifetime { .. } => {}
|
2018-06-14 10:42:12 +00:00
|
|
|
GenericParamKind::Type { ref default, .. } => walk_list!(visitor, visit_ty, default),
|
2020-12-31 00:58:27 +00:00
|
|
|
GenericParamKind::Const { ref ty, ref default } => {
|
|
|
|
visitor.visit_ty(ty);
|
|
|
|
if let Some(ref default) = default {
|
2021-03-01 11:50:09 +00:00
|
|
|
visitor.visit_const_param_default(param.hir_id, default);
|
2020-12-31 00:58:27 +00:00
|
|
|
}
|
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2017-10-16 19:07:26 +00:00
|
|
|
}
|
|
|
|
|
2021-03-01 11:50:09 +00:00
|
|
|
pub fn walk_const_param_default<'v, V: Visitor<'v>>(visitor: &mut V, ct: &'v AnonConst) {
|
|
|
|
visitor.visit_anon_const(ct)
|
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics<'v>) {
|
2019-12-01 16:10:12 +00:00
|
|
|
walk_list!(visitor, visit_generic_param, generics.params);
|
2022-02-05 14:48:02 +00:00
|
|
|
walk_list!(visitor, visit_where_predicate, generics.predicates);
|
2016-04-21 09:10:10 +00:00
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
pub fn walk_where_predicate<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
predicate: &'v WherePredicate<'v>,
|
|
|
|
) {
|
2021-01-02 19:09:17 +00:00
|
|
|
match *predicate {
|
|
|
|
WherePredicate::BoundPredicate(WhereBoundPredicate {
|
2022-09-05 15:21:19 +00:00
|
|
|
hir_id,
|
2016-04-21 09:10:10 +00:00
|
|
|
ref bounded_ty,
|
2019-11-30 23:17:43 +00:00
|
|
|
bounds,
|
|
|
|
bound_generic_params,
|
2022-09-05 15:21:19 +00:00
|
|
|
origin: _,
|
|
|
|
span: _,
|
2016-04-21 09:10:10 +00:00
|
|
|
}) => {
|
2022-09-05 15:21:19 +00:00
|
|
|
visitor.visit_id(hir_id);
|
2016-04-21 09:10:10 +00:00
|
|
|
visitor.visit_ty(bounded_ty);
|
2018-05-28 14:23:16 +00:00
|
|
|
walk_list!(visitor, visit_param_bound, bounds);
|
2017-10-16 19:07:26 +00:00
|
|
|
walk_list!(visitor, visit_generic_param, bound_generic_params);
|
2016-04-21 09:10:10 +00:00
|
|
|
}
|
2022-09-05 15:21:19 +00:00
|
|
|
WherePredicate::RegionPredicate(WhereRegionPredicate {
|
|
|
|
ref lifetime,
|
|
|
|
bounds,
|
|
|
|
span: _,
|
|
|
|
in_where_clause: _,
|
|
|
|
}) => {
|
2016-04-21 09:10:10 +00:00
|
|
|
visitor.visit_lifetime(lifetime);
|
2018-05-28 14:23:16 +00:00
|
|
|
walk_list!(visitor, visit_param_bound, bounds);
|
2016-04-21 09:10:10 +00:00
|
|
|
}
|
2022-09-05 15:21:19 +00:00
|
|
|
WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, span: _ }) => {
|
2017-01-16 18:32:13 +00:00
|
|
|
visitor.visit_ty(lhs_ty);
|
|
|
|
visitor.visit_ty(rhs_ty);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-15 03:10:59 +00:00
|
|
|
pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FnRetTy<'v>) {
|
|
|
|
if let FnRetTy::Return(ref output_ty) = *ret_ty {
|
2015-09-28 21:23:54 +00:00
|
|
|
visitor.visit_ty(output_ty)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-30 16:46:46 +00:00
|
|
|
pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl<'v>) {
|
2019-11-30 23:17:43 +00:00
|
|
|
for ty in function_declaration.inputs {
|
2016-12-20 20:46:11 +00:00
|
|
|
visitor.visit_ty(ty)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
walk_fn_ret_ty(visitor, &function_declaration.output)
|
|
|
|
}
|
|
|
|
|
2015-09-27 19:23:31 +00:00
|
|
|
pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'v>) {
|
2015-07-31 07:04:06 +00:00
|
|
|
match function_kind {
|
2016-08-26 16:23:42 +00:00
|
|
|
FnKind::ItemFn(_, generics, ..) => {
|
2015-07-31 07:04:06 +00:00
|
|
|
visitor.visit_generics(generics);
|
|
|
|
}
|
2022-07-12 09:34:24 +00:00
|
|
|
FnKind::Closure | FnKind::Method(..) => {}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2015-09-03 10:35:41 +00:00
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2015-09-03 10:35:41 +00:00
|
|
|
pub fn walk_fn<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
function_kind: FnKind<'v>,
|
2019-11-30 16:46:46 +00:00
|
|
|
function_declaration: &'v FnDecl<'v>,
|
2016-12-21 10:32:59 +00:00
|
|
|
body_id: BodyId,
|
2019-02-06 13:16:11 +00:00
|
|
|
id: HirId,
|
|
|
|
) {
|
2016-07-28 09:58:45 +00:00
|
|
|
visitor.visit_id(id);
|
2016-12-19 22:51:27 +00:00
|
|
|
visitor.visit_fn_decl(function_declaration);
|
2015-09-03 10:35:41 +00:00
|
|
|
walk_fn_kind(visitor, function_kind);
|
2016-12-21 10:32:59 +00:00
|
|
|
visitor.visit_nested_body(body_id)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-28 20:47:10 +00:00
|
|
|
pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem<'v>) {
|
2022-08-01 17:46:10 +00:00
|
|
|
// N.B., deliberately force a compilation error if/when new fields are added.
|
|
|
|
let TraitItem { ident, generics, ref defaultness, ref kind, span, def_id: _ } = *trait_item;
|
|
|
|
let hir_id = trait_item.hir_id();
|
|
|
|
visitor.visit_ident(ident);
|
|
|
|
visitor.visit_generics(&generics);
|
|
|
|
visitor.visit_defaultness(&defaultness);
|
|
|
|
match *kind {
|
2016-12-21 10:32:59 +00:00
|
|
|
TraitItemKind::Const(ref ty, default) => {
|
2022-08-01 17:46:10 +00:00
|
|
|
visitor.visit_id(hir_id);
|
2015-07-31 07:04:06 +00:00
|
|
|
visitor.visit_ty(ty);
|
2016-12-21 10:32:59 +00:00
|
|
|
walk_list!(visitor, visit_nested_body, default);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2020-03-05 15:57:34 +00:00
|
|
|
TraitItemKind::Fn(ref sig, TraitFn::Required(param_names)) => {
|
2022-08-01 17:46:10 +00:00
|
|
|
visitor.visit_id(hir_id);
|
2016-12-19 22:51:27 +00:00
|
|
|
visitor.visit_fn_decl(&sig.decl);
|
2018-06-10 16:33:30 +00:00
|
|
|
for ¶m_name in param_names {
|
|
|
|
visitor.visit_ident(param_name);
|
2016-12-20 20:46:11 +00:00
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2020-03-05 15:57:34 +00:00
|
|
|
TraitItemKind::Fn(ref sig, TraitFn::Provided(body_id)) => {
|
2022-08-01 17:46:10 +00:00
|
|
|
visitor.visit_fn(FnKind::Method(ident, sig), &sig.decl, body_id, span, hir_id);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2019-11-30 23:17:43 +00:00
|
|
|
TraitItemKind::Type(bounds, ref default) => {
|
2022-08-01 17:46:10 +00:00
|
|
|
visitor.visit_id(hir_id);
|
2018-05-28 14:23:16 +00:00
|
|
|
walk_list!(visitor, visit_param_bound, bounds);
|
2015-09-28 21:23:54 +00:00
|
|
|
walk_list!(visitor, visit_ty, default);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-04 02:21:06 +00:00
|
|
|
pub fn walk_trait_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_item_ref: &'v TraitItemRef) {
|
2018-11-27 02:59:49 +00:00
|
|
|
// N.B., deliberately force a compilation error if/when new fields are added.
|
2022-03-12 18:36:11 +00:00
|
|
|
let TraitItemRef { id, ident, ref kind, span: _ } = *trait_item_ref;
|
2016-12-04 02:21:06 +00:00
|
|
|
visitor.visit_nested_trait_item(id);
|
2018-06-10 19:24:24 +00:00
|
|
|
visitor.visit_ident(ident);
|
2016-12-04 02:21:06 +00:00
|
|
|
visitor.visit_associated_item_kind(kind);
|
|
|
|
}
|
|
|
|
|
2019-11-28 21:16:44 +00:00
|
|
|
pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem<'v>) {
|
2018-11-27 02:59:49 +00:00
|
|
|
// N.B., deliberately force a compilation error if/when new fields are added.
|
2022-03-12 18:36:11 +00:00
|
|
|
let ImplItem {
|
|
|
|
def_id: _,
|
|
|
|
ident,
|
|
|
|
ref generics,
|
|
|
|
ref kind,
|
|
|
|
ref defaultness,
|
|
|
|
span: _,
|
|
|
|
vis_span: _,
|
|
|
|
} = *impl_item;
|
2016-11-14 16:00:02 +00:00
|
|
|
|
2018-06-10 19:24:24 +00:00
|
|
|
visitor.visit_ident(ident);
|
2017-09-25 21:24:20 +00:00
|
|
|
visitor.visit_generics(generics);
|
2022-03-12 18:36:11 +00:00
|
|
|
visitor.visit_defaultness(defaultness);
|
2019-09-26 15:38:13 +00:00
|
|
|
match *kind {
|
2016-12-21 10:32:59 +00:00
|
|
|
ImplItemKind::Const(ref ty, body) => {
|
2021-01-30 22:25:03 +00:00
|
|
|
visitor.visit_id(impl_item.hir_id());
|
2015-07-31 07:04:06 +00:00
|
|
|
visitor.visit_ty(ty);
|
2016-12-21 10:32:59 +00:00
|
|
|
visitor.visit_nested_body(body);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2020-03-05 15:57:34 +00:00
|
|
|
ImplItemKind::Fn(ref sig, body_id) => {
|
2018-06-10 19:24:24 +00:00
|
|
|
visitor.visit_fn(
|
2022-02-13 14:40:08 +00:00
|
|
|
FnKind::Method(impl_item.ident, sig),
|
2015-09-27 19:23:31 +00:00
|
|
|
&sig.decl,
|
2016-10-28 20:58:32 +00:00
|
|
|
body_id,
|
2015-09-27 19:23:31 +00:00
|
|
|
impl_item.span,
|
2021-01-30 22:25:03 +00:00
|
|
|
impl_item.hir_id(),
|
2019-02-06 13:16:11 +00:00
|
|
|
);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2022-10-09 07:09:57 +00:00
|
|
|
ImplItemKind::Type(ref ty) => {
|
2021-01-30 22:25:03 +00:00
|
|
|
visitor.visit_id(impl_item.hir_id());
|
2015-07-31 07:04:06 +00:00
|
|
|
visitor.visit_ty(ty);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-11 20:57:54 +00:00
|
|
|
pub fn walk_foreign_item_ref<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
2021-07-15 20:19:39 +00:00
|
|
|
foreign_item_ref: &'v ForeignItemRef,
|
2020-11-11 20:57:54 +00:00
|
|
|
) {
|
|
|
|
// N.B., deliberately force a compilation error if/when new fields are added.
|
2021-07-15 20:19:39 +00:00
|
|
|
let ForeignItemRef { id, ident, span: _ } = *foreign_item_ref;
|
2020-11-11 20:57:54 +00:00
|
|
|
visitor.visit_nested_foreign_item(id);
|
|
|
|
visitor.visit_ident(ident);
|
|
|
|
}
|
|
|
|
|
2021-07-15 20:19:39 +00:00
|
|
|
pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'v ImplItemRef) {
|
2018-11-27 02:59:49 +00:00
|
|
|
// N.B., deliberately force a compilation error if/when new fields are added.
|
2022-03-12 18:36:11 +00:00
|
|
|
let ImplItemRef { id, ident, ref kind, span: _, trait_item_def_id: _ } = *impl_item_ref;
|
2016-11-14 16:00:02 +00:00
|
|
|
visitor.visit_nested_impl_item(id);
|
2018-06-10 19:24:24 +00:00
|
|
|
visitor.visit_ident(ident);
|
2016-11-14 16:00:02 +00:00
|
|
|
visitor.visit_associated_item_kind(kind);
|
2016-11-10 14:47:00 +00:00
|
|
|
}
|
|
|
|
|
2019-12-01 11:49:54 +00:00
|
|
|
pub fn walk_struct_def<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
struct_definition: &'v VariantData<'v>,
|
|
|
|
) {
|
2020-01-07 16:38:38 +00:00
|
|
|
walk_list!(visitor, visit_id, struct_definition.ctor_hir_id());
|
2021-03-15 21:36:07 +00:00
|
|
|
walk_list!(visitor, visit_field_def, struct_definition.fields());
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2021-03-15 21:36:07 +00:00
|
|
|
pub fn walk_field_def<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v FieldDef<'v>) {
|
|
|
|
visitor.visit_id(field.hir_id);
|
|
|
|
visitor.visit_ident(field.ident);
|
|
|
|
visitor.visit_ty(&field.ty);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-29 12:43:03 +00:00
|
|
|
pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block<'v>) {
|
2019-02-06 13:16:11 +00:00
|
|
|
visitor.visit_id(block.hir_id);
|
2019-11-29 13:08:03 +00:00
|
|
|
walk_list!(visitor, visit_stmt, block.stmts);
|
2015-09-28 21:23:54 +00:00
|
|
|
walk_list!(visitor, visit_expr, &block.expr);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2019-11-29 12:43:03 +00:00
|
|
|
pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt<'v>) {
|
2019-02-06 13:16:11 +00:00
|
|
|
visitor.visit_id(statement.hir_id);
|
2022-07-11 21:20:27 +00:00
|
|
|
match statement.kind {
|
2022-07-05 21:31:18 +00:00
|
|
|
StmtKind::Local(ref local) => visitor.visit_local(local),
|
2022-07-11 21:20:27 +00:00
|
|
|
StmtKind::Item(item) => visitor.visit_nested_item(item),
|
2019-01-16 22:45:02 +00:00
|
|
|
StmtKind::Expr(ref expression) | StmtKind::Semi(ref expression) => {
|
2015-09-28 21:23:54 +00:00
|
|
|
visitor.visit_expr(expression)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-23 09:01:51 +00:00
|
|
|
pub fn walk_array_len<'v, V: Visitor<'v>>(visitor: &mut V, len: &'v ArrayLen) {
|
|
|
|
match len {
|
|
|
|
&ArrayLen::Infer(hir_id, _span) => visitor.visit_id(hir_id),
|
|
|
|
ArrayLen::Body(c) => visitor.visit_anon_const(c),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-17 18:28:50 +00:00
|
|
|
pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonConst) {
|
2019-02-06 13:16:11 +00:00
|
|
|
visitor.visit_id(constant.hir_id);
|
2018-05-17 18:28:50 +00:00
|
|
|
visitor.visit_nested_body(constant.body);
|
|
|
|
}
|
|
|
|
|
2021-10-13 05:39:06 +00:00
|
|
|
pub fn walk_let_expr<'v, V: Visitor<'v>>(visitor: &mut V, let_expr: &'v Let<'v>) {
|
|
|
|
// match the visit order in walk_local
|
|
|
|
visitor.visit_expr(let_expr.init);
|
|
|
|
visitor.visit_id(let_expr.hir_id);
|
|
|
|
visitor.visit_pat(let_expr.pat);
|
|
|
|
walk_list!(visitor, visit_ty, let_expr.ty);
|
|
|
|
}
|
|
|
|
|
2022-05-23 01:34:37 +00:00
|
|
|
pub fn walk_expr_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v ExprField<'v>) {
|
|
|
|
visitor.visit_id(field.hir_id);
|
|
|
|
visitor.visit_ident(field.ident);
|
|
|
|
visitor.visit_expr(&field.expr)
|
|
|
|
}
|
|
|
|
|
2019-11-29 12:43:03 +00:00
|
|
|
pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) {
|
2019-02-06 13:16:11 +00:00
|
|
|
visitor.visit_id(expression.hir_id);
|
2019-09-26 13:39:48 +00:00
|
|
|
match expression.kind {
|
2018-07-11 12:05:29 +00:00
|
|
|
ExprKind::Box(ref subexpression) => visitor.visit_expr(subexpression),
|
2019-11-29 13:08:03 +00:00
|
|
|
ExprKind::Array(subexpressions) => {
|
2015-09-28 21:23:54 +00:00
|
|
|
walk_list!(visitor, visit_expr, subexpressions);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2020-10-06 20:51:15 +00:00
|
|
|
ExprKind::ConstBlock(ref anon_const) => visitor.visit_anon_const(anon_const),
|
2018-07-11 12:05:29 +00:00
|
|
|
ExprKind::Repeat(ref element, ref count) => {
|
2015-09-28 21:23:54 +00:00
|
|
|
visitor.visit_expr(element);
|
2021-12-23 09:01:51 +00:00
|
|
|
visitor.visit_array_length(count)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2019-11-29 13:08:03 +00:00
|
|
|
ExprKind::Struct(ref qpath, fields, ref optional_base) => {
|
2018-07-31 16:43:51 +00:00
|
|
|
visitor.visit_qpath(qpath, expression.hir_id, expression.span);
|
2022-05-23 01:34:37 +00:00
|
|
|
walk_list!(visitor, visit_expr_field, fields);
|
2015-09-28 21:23:54 +00:00
|
|
|
walk_list!(visitor, visit_expr, optional_base);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2019-11-29 13:08:03 +00:00
|
|
|
ExprKind::Tup(subexpressions) => {
|
2015-09-28 21:23:54 +00:00
|
|
|
walk_list!(visitor, visit_expr, subexpressions);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2019-11-29 13:08:03 +00:00
|
|
|
ExprKind::Call(ref callee_expression, arguments) => {
|
2018-02-09 08:48:54 +00:00
|
|
|
visitor.visit_expr(callee_expression);
|
2015-09-28 21:23:54 +00:00
|
|
|
walk_list!(visitor, visit_expr, arguments);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2022-09-01 04:27:31 +00:00
|
|
|
ExprKind::MethodCall(ref segment, receiver, arguments, _) => {
|
2022-09-12 00:43:34 +00:00
|
|
|
visitor.visit_path_segment(segment);
|
2022-09-01 04:27:31 +00:00
|
|
|
visitor.visit_expr(receiver);
|
2015-09-28 21:23:54 +00:00
|
|
|
walk_list!(visitor, visit_expr, arguments);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2018-07-11 12:05:29 +00:00
|
|
|
ExprKind::Binary(_, ref left_expression, ref right_expression) => {
|
2015-09-28 21:23:54 +00:00
|
|
|
visitor.visit_expr(left_expression);
|
|
|
|
visitor.visit_expr(right_expression)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2019-11-23 14:15:49 +00:00
|
|
|
ExprKind::AddrOf(_, _, ref subexpression) | ExprKind::Unary(_, ref subexpression) => {
|
2015-09-28 21:23:54 +00:00
|
|
|
visitor.visit_expr(subexpression)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2018-07-11 12:05:29 +00:00
|
|
|
ExprKind::Cast(ref subexpression, ref typ) | ExprKind::Type(ref subexpression, ref typ) => {
|
2015-09-28 21:23:54 +00:00
|
|
|
visitor.visit_expr(subexpression);
|
|
|
|
visitor.visit_ty(typ)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2019-04-30 15:46:59 +00:00
|
|
|
ExprKind::DropTemps(ref subexpression) => {
|
2019-04-24 04:39:40 +00:00
|
|
|
visitor.visit_expr(subexpression);
|
|
|
|
}
|
2021-10-13 05:39:06 +00:00
|
|
|
ExprKind::Let(ref let_expr) => visitor.visit_let_expr(let_expr),
|
2021-01-01 18:38:11 +00:00
|
|
|
ExprKind::If(ref cond, ref then, ref else_opt) => {
|
|
|
|
visitor.visit_expr(cond);
|
|
|
|
visitor.visit_expr(then);
|
|
|
|
walk_list!(visitor, visit_expr, else_opt);
|
|
|
|
}
|
2021-01-21 01:15:08 +00:00
|
|
|
ExprKind::Loop(ref block, ref opt_label, _, _) => {
|
2018-01-15 22:44:32 +00:00
|
|
|
walk_list!(visitor, visit_label, opt_label);
|
2015-09-28 21:23:54 +00:00
|
|
|
visitor.visit_block(block);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2019-11-29 13:08:03 +00:00
|
|
|
ExprKind::Match(ref subexpression, arms, _) => {
|
2015-09-28 21:23:54 +00:00
|
|
|
visitor.visit_expr(subexpression);
|
|
|
|
walk_list!(visitor, visit_arm, arms);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2022-07-11 19:39:53 +00:00
|
|
|
ExprKind::Closure(&Closure {
|
2022-07-12 09:34:24 +00:00
|
|
|
binder: _,
|
2022-05-23 13:50:02 +00:00
|
|
|
bound_generic_params,
|
2022-07-11 19:39:53 +00:00
|
|
|
fn_decl,
|
2022-06-11 19:25:25 +00:00
|
|
|
body,
|
|
|
|
capture_clause: _,
|
|
|
|
fn_decl_span: _,
|
|
|
|
movability: _,
|
2022-07-11 19:39:53 +00:00
|
|
|
}) => {
|
2022-05-23 13:50:02 +00:00
|
|
|
walk_list!(visitor, visit_generic_param, bound_generic_params);
|
|
|
|
visitor.visit_fn(FnKind::Closure, fn_decl, body, expression.span, expression.hir_id)
|
|
|
|
}
|
2018-07-11 12:05:29 +00:00
|
|
|
ExprKind::Block(ref block, ref opt_label) => {
|
2018-04-16 03:44:39 +00:00
|
|
|
walk_list!(visitor, visit_label, opt_label);
|
|
|
|
visitor.visit_block(block);
|
|
|
|
}
|
2019-12-22 21:08:53 +00:00
|
|
|
ExprKind::Assign(ref lhs, ref rhs, _) => {
|
|
|
|
visitor.visit_expr(rhs);
|
|
|
|
visitor.visit_expr(lhs)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2018-07-11 12:05:29 +00:00
|
|
|
ExprKind::AssignOp(_, ref left_expression, ref right_expression) => {
|
2015-09-28 21:23:54 +00: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-07 02:23:28 +00:00
|
|
|
visitor.visit_expr(left_expression);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2018-07-11 12:05:29 +00:00
|
|
|
ExprKind::Field(ref subexpression, ident) => {
|
2015-09-28 21:23:54 +00:00
|
|
|
visitor.visit_expr(subexpression);
|
2018-05-25 23:50:15 +00:00
|
|
|
visitor.visit_ident(ident);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2018-07-11 12:05:29 +00:00
|
|
|
ExprKind::Index(ref main_expression, ref index_expression) => {
|
2015-09-28 21:23:54 +00:00
|
|
|
visitor.visit_expr(main_expression);
|
|
|
|
visitor.visit_expr(index_expression)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2018-07-11 12:05:29 +00:00
|
|
|
ExprKind::Path(ref qpath) => {
|
2018-07-31 16:43:51 +00:00
|
|
|
visitor.visit_qpath(qpath, expression.hir_id, expression.span);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2018-07-11 12:05:29 +00:00
|
|
|
ExprKind::Break(ref destination, ref opt_expr) => {
|
2020-01-07 16:38:38 +00:00
|
|
|
walk_list!(visitor, visit_label, &destination.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 22:15:06 +00:00
|
|
|
walk_list!(visitor, visit_expr, opt_expr);
|
|
|
|
}
|
2018-07-11 12:05:29 +00:00
|
|
|
ExprKind::Continue(ref destination) => {
|
2020-01-07 16:38:38 +00:00
|
|
|
walk_list!(visitor, visit_label, &destination.label);
|
2015-09-28 21:23:54 +00:00
|
|
|
}
|
2018-07-11 12:05:29 +00:00
|
|
|
ExprKind::Ret(ref optional_expression) => {
|
2015-09-28 21:23:54 +00:00
|
|
|
walk_list!(visitor, visit_expr, optional_expression);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2020-02-12 17:32:41 +00:00
|
|
|
ExprKind::InlineAsm(ref asm) => {
|
2022-03-01 00:50:56 +00:00
|
|
|
visitor.visit_inline_asm(asm, expression.hir_id);
|
2020-02-12 17:32:41 +00:00
|
|
|
}
|
2019-06-18 21:34:51 +00:00
|
|
|
ExprKind::Yield(ref subexpression, _) => {
|
2016-12-26 13:34:03 +00:00
|
|
|
visitor.visit_expr(subexpression);
|
|
|
|
}
|
2019-06-07 09:53:33 +00:00
|
|
|
ExprKind::Lit(_) | ExprKind::Err => {}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-29 12:43:03 +00:00
|
|
|
pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) {
|
2019-03-30 22:54:29 +00:00
|
|
|
visitor.visit_id(arm.hir_id);
|
2019-09-07 14:01:12 +00:00
|
|
|
visitor.visit_pat(&arm.pat);
|
2018-08-30 04:18:11 +00:00
|
|
|
if let Some(ref g) = arm.guard {
|
|
|
|
match g {
|
|
|
|
Guard::If(ref e) => visitor.visit_expr(e),
|
2022-05-09 12:35:58 +00:00
|
|
|
Guard::IfLet(ref l) => {
|
|
|
|
visitor.visit_let_expr(l);
|
2020-10-24 19:13:54 +00:00
|
|
|
}
|
2018-08-30 04:18:11 +00:00
|
|
|
}
|
|
|
|
}
|
2015-09-28 21:23:54 +00:00
|
|
|
visitor.visit_expr(&arm.body);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2016-03-29 06:32:58 +00:00
|
|
|
|
2019-05-19 08:26:08 +00:00
|
|
|
pub fn walk_associated_item_kind<'v, V: Visitor<'v>>(_: &mut V, _: &'v AssocItemKind) {
|
2016-11-14 16:00:02 +00: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.
|
|
|
|
}
|