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
|
2025-02-03 03:42:01 +00:00
|
|
|
//! `nested_filter::OnlyBodies` (and implement `maybe_tcx`), and use
|
2025-02-17 03:17: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
|
2025-02-03 03:42:01 +00:00
|
|
|
//! `nested_filter::All` (and implement `maybe_tcx`). Walk your crate with
|
2025-02-17 03:17:57 +00:00
|
|
|
//! `tcx.hir_walk_toplevel_module(visitor)`.
|
2022-05-07 20:22:52 +00:00
|
|
|
//! - 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
|
2023-10-19 21:46:28 +00:00
|
|
|
//! example coroutine inference, and possibly also HIR borrowck.
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2024-10-16 23:14:01 +00:00
|
|
|
use rustc_ast::Label;
|
2024-09-22 23:05:04 +00:00
|
|
|
use rustc_ast::visit::{VisitorResult, try_visit, visit_opt, walk_list};
|
2023-01-22 18:00:33 +00:00
|
|
|
use rustc_span::def_id::LocalDefId;
|
2024-12-12 23:29:23 +00:00
|
|
|
use rustc_span::{Ident, Span, Symbol};
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2024-07-28 22:13:50 +00:00
|
|
|
use crate::hir::*;
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2025-02-03 03:42:01 +00:00
|
|
|
/// HIR things retrievable from `TyCtxt`, avoiding an explicit dependence on
|
|
|
|
/// `TyCtxt`. The only impls are for `!` (where these functions are never
|
|
|
|
/// called) and `TyCtxt` (in `rustc_middle`).
|
|
|
|
pub trait HirTyCtxt<'hir> {
|
2024-01-21 18:13:15 +00:00
|
|
|
/// Retrieves the `Node` corresponding to `id`.
|
|
|
|
fn hir_node(&self, hir_id: HirId) -> Node<'hir>;
|
2025-02-03 03:42:01 +00:00
|
|
|
fn hir_body(&self, id: BodyId) -> &'hir Body<'hir>;
|
|
|
|
fn hir_item(&self, id: ItemId) -> &'hir Item<'hir>;
|
|
|
|
fn hir_trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir>;
|
|
|
|
fn hir_impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir>;
|
|
|
|
fn hir_foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir>;
|
2020-01-07 16:25:33 +00:00
|
|
|
}
|
|
|
|
|
2025-02-03 03:42:01 +00:00
|
|
|
// Used when no tcx is actually available, forcing manual implementation of nested visitors.
|
|
|
|
impl<'hir> HirTyCtxt<'hir> for ! {
|
2024-01-21 18:13:15 +00:00
|
|
|
fn hir_node(&self, _: HirId) -> Node<'hir> {
|
2025-02-03 04:29:12 +00:00
|
|
|
unreachable!();
|
2021-09-12 01:19:18 +00:00
|
|
|
}
|
2025-02-03 03:42:01 +00:00
|
|
|
fn hir_body(&self, _: BodyId) -> &'hir Body<'hir> {
|
2025-02-03 04:29:12 +00:00
|
|
|
unreachable!();
|
2021-09-12 01:19:18 +00:00
|
|
|
}
|
2025-02-03 03:42:01 +00:00
|
|
|
fn hir_item(&self, _: ItemId) -> &'hir Item<'hir> {
|
2025-02-03 04:29:12 +00:00
|
|
|
unreachable!();
|
2021-09-12 01:19:18 +00:00
|
|
|
}
|
2025-02-03 03:42:01 +00:00
|
|
|
fn hir_trait_item(&self, _: TraitItemId) -> &'hir TraitItem<'hir> {
|
2025-02-03 04:29:12 +00:00
|
|
|
unreachable!();
|
2021-09-12 01:19:18 +00:00
|
|
|
}
|
2025-02-03 03:42:01 +00:00
|
|
|
fn hir_impl_item(&self, _: ImplItemId) -> &'hir ImplItem<'hir> {
|
2025-02-03 04:29:12 +00:00
|
|
|
unreachable!();
|
2021-09-12 01:19:18 +00:00
|
|
|
}
|
2025-02-03 03:42:01 +00:00
|
|
|
fn hir_foreign_item(&self, _: ForeignItemId) -> &'hir ForeignItem<'hir> {
|
2025-02-03 04:29:12 +00:00
|
|
|
unreachable!();
|
2021-09-12 01:19:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-03 23:03:12 +00:00
|
|
|
pub mod nested_filter {
|
2025-02-03 03:42:01 +00:00
|
|
|
use super::HirTyCtxt;
|
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
|
|
|
///
|
2023-09-05 20:29:07 +00:00
|
|
|
/// See the comments at [`rustc_hir::intravisit`] for more details on the overall
|
2021-11-03 23:03:12 +00:00
|
|
|
/// visit strategy.
|
|
|
|
pub trait NestedFilter<'hir> {
|
2025-02-03 03:42:01 +00:00
|
|
|
type MaybeTyCtxt: HirTyCtxt<'hir>;
|
2021-11-03 23:03:12 +00:00
|
|
|
|
|
|
|
/// 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
|
2025-02-03 03:42:01 +00:00
|
|
|
/// `tcx` around.
|
2021-11-03 23:03:12 +00:00
|
|
|
pub struct None(());
|
|
|
|
impl NestedFilter<'_> for None {
|
2025-02-03 03:42:01 +00:00
|
|
|
type MaybeTyCtxt = !;
|
2021-11-03 23:03:12 +00:00
|
|
|
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
|
2025-02-17 03:17: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 {
|
2025-02-03 03:42:01 +00:00
|
|
|
// This type should not be overridden, it exists for convenient usage as `Self::MaybeTyCtxt`.
|
|
|
|
type MaybeTyCtxt: HirTyCtxt<'v> = <Self::NestedFilter as NestedFilter<'v>>::MaybeTyCtxt;
|
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
|
2025-02-03 03:42:01 +00:00
|
|
|
/// must also override [`maybe_tcx`](Self::maybe_tcx).
|
2016-11-09 21:45:26 +00:00
|
|
|
///
|
|
|
|
/// **If for some reason you want the nested behavior, but don't
|
2025-02-03 03:42:01 +00:00
|
|
|
/// have a `tcx` at your disposal:** then override the
|
2022-04-30 17:27:01 +00:00
|
|
|
/// `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;
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
/// The result type of the `visit_*` methods. Can be either `()`,
|
|
|
|
/// or `ControlFlow<T>`.
|
|
|
|
type Result: VisitorResult = ();
|
|
|
|
|
2022-04-30 17:27:01 +00:00
|
|
|
/// If `type NestedFilter` is set to visit nested items, this method
|
|
|
|
/// must also be overridden to provide a map to retrieve nested items.
|
2025-02-03 03:42:01 +00:00
|
|
|
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
|
2021-11-03 23:03:12 +00:00
|
|
|
panic!(
|
2025-02-03 03:42:01 +00:00
|
|
|
"maybe_tcx must be implemented or consider using \
|
2021-11-03 23:03:12 +00:00
|
|
|
`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
|
2023-09-05 20:29:07 +00:00
|
|
|
/// "deep" visit patterns described at
|
|
|
|
/// [`rustc_hir::intravisit`]. The only reason to override
|
2022-04-30 17:27:01 +00:00
|
|
|
/// this method is if you want a nested pattern but cannot supply a
|
2025-02-03 03:42:01 +00:00
|
|
|
/// `TyCtxt`; see `maybe_tcx` for advice.
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_nested_item(&mut self, id: ItemId) -> Self::Result {
|
2021-11-03 23:03:12 +00:00
|
|
|
if Self::NestedFilter::INTER {
|
2025-02-03 03:42:01 +00:00
|
|
|
let item = self.maybe_tcx().hir_item(id);
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(self.visit_item(item));
|
2021-11-03 23:03:12 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
Self::Result::output()
|
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.
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_nested_trait_item(&mut self, id: TraitItemId) -> Self::Result {
|
2021-11-03 23:03:12 +00:00
|
|
|
if Self::NestedFilter::INTER {
|
2025-02-03 03:42:01 +00:00
|
|
|
let item = self.maybe_tcx().hir_trait_item(id);
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(self.visit_trait_item(item));
|
2021-11-03 23:03:12 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
Self::Result::output()
|
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.
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_nested_impl_item(&mut self, id: ImplItemId) -> Self::Result {
|
2021-11-03 23:03:12 +00:00
|
|
|
if Self::NestedFilter::INTER {
|
2025-02-03 03:42:01 +00:00
|
|
|
let item = self.maybe_tcx().hir_impl_item(id);
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(self.visit_impl_item(item));
|
2021-11-03 23:03:12 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
Self::Result::output()
|
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.
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_nested_foreign_item(&mut self, id: ForeignItemId) -> Self::Result {
|
2021-11-03 23:03:12 +00:00
|
|
|
if Self::NestedFilter::INTER {
|
2025-02-03 03:42:01 +00:00
|
|
|
let item = self.maybe_tcx().hir_foreign_item(id);
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(self.visit_foreign_item(item));
|
2021-11-03 23:03:12 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
Self::Result::output()
|
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`.
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_nested_body(&mut self, id: BodyId) -> Self::Result {
|
2021-11-03 23:03:12 +00:00
|
|
|
if Self::NestedFilter::INTRA {
|
2025-02-03 03:42:01 +00:00
|
|
|
let body = self.maybe_tcx().hir_body(id);
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(self.visit_body(body));
|
2021-11-03 23:03:12 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
Self::Result::output()
|
2016-10-28 20:58:32 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_param(&mut self, param: &'v Param<'v>) -> Self::Result {
|
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.
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_item(&mut self, i: &'v Item<'v>) -> Self::Result {
|
2015-11-17 22:32:12 +00:00
|
|
|
walk_item(self, i)
|
|
|
|
}
|
|
|
|
|
2024-05-29 09:08:22 +00:00
|
|
|
fn visit_body(&mut self, b: &Body<'v>) -> Self::Result {
|
2024-02-18 08:12:44 +00:00
|
|
|
walk_body(self, b)
|
2016-12-21 10:32:59 +00:00
|
|
|
}
|
|
|
|
|
2015-11-17 22:32:12 +00:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_id(&mut self, _hir_id: HirId) -> Self::Result {
|
|
|
|
Self::Result::output()
|
2016-07-28 09:58:45 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_name(&mut self, _name: Symbol) -> Self::Result {
|
|
|
|
Self::Result::output()
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_ident(&mut self, ident: Ident) -> Self::Result {
|
2018-05-25 23:50:15 +00:00
|
|
|
walk_ident(self, ident)
|
|
|
|
}
|
2025-03-07 06:02:33 +00:00
|
|
|
fn visit_mod(&mut self, m: &'v Mod<'v>, _s: Span, _n: HirId) -> Self::Result {
|
|
|
|
walk_mod(self, m)
|
2015-09-27 19:23:31 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_foreign_item(&mut self, i: &'v ForeignItem<'v>) -> Self::Result {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_foreign_item(self, i)
|
|
|
|
}
|
2024-03-20 16:50:31 +00:00
|
|
|
fn visit_local(&mut self, l: &'v LetStmt<'v>) -> Self::Result {
|
2022-07-05 21:31:18 +00:00
|
|
|
walk_local(self, l)
|
2015-09-27 19:23:31 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_block(&mut self, b: &'v Block<'v>) -> Self::Result {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_block(self, b)
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_stmt(&mut self, s: &'v Stmt<'v>) -> Self::Result {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_stmt(self, s)
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_arm(&mut self, a: &'v Arm<'v>) -> Self::Result {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_arm(self, a)
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_pat(&mut self, p: &'v Pat<'v>) -> Self::Result {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_pat(self, p)
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_pat_field(&mut self, f: &'v PatField<'v>) -> Self::Result {
|
2022-05-23 01:34:37 +00:00
|
|
|
walk_pat_field(self, f)
|
|
|
|
}
|
2024-12-11 16:50:45 +00:00
|
|
|
fn visit_pat_expr(&mut self, expr: &'v PatExpr<'v>) -> Self::Result {
|
|
|
|
walk_pat_expr(self, expr)
|
|
|
|
}
|
2025-02-01 10:06:35 +00:00
|
|
|
fn visit_lit(&mut self, _hir_id: HirId, _lit: &'v Lit, _negated: bool) -> Self::Result {
|
|
|
|
Self::Result::output()
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_anon_const(&mut self, c: &'v AnonConst) -> Self::Result {
|
2018-05-17 18:28:50 +00:00
|
|
|
walk_anon_const(self, c)
|
|
|
|
}
|
2024-06-03 09:11:58 +00:00
|
|
|
fn visit_inline_const(&mut self, c: &'v ConstBlock) -> Self::Result {
|
|
|
|
walk_inline_const(self, c)
|
|
|
|
}
|
2025-01-11 19:12:36 +00:00
|
|
|
|
|
|
|
fn visit_generic_arg(&mut self, generic_arg: &'v GenericArg<'v>) -> Self::Result {
|
|
|
|
walk_generic_arg(self, generic_arg)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// All types are treated as ambiguous types for the purposes of hir visiting in
|
|
|
|
/// order to ensure that visitors can handle infer vars without it being too error-prone.
|
|
|
|
///
|
2025-01-18 22:47:15 +00:00
|
|
|
/// See the doc comments on [`Ty`] for an explanation of what it means for a type to be
|
|
|
|
/// ambiguous.
|
|
|
|
///
|
2025-03-09 10:31:14 +00:00
|
|
|
/// The [`Visitor::visit_infer`] method should be overridden in order to handle infer vars.
|
2025-01-11 19:12:36 +00:00
|
|
|
fn visit_ty(&mut self, t: &'v Ty<'v, AmbigArg>) -> Self::Result {
|
|
|
|
walk_ty(self, t)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// All consts are treated as ambiguous consts for the purposes of hir visiting in
|
|
|
|
/// order to ensure that visitors can handle infer vars without it being too error-prone.
|
|
|
|
///
|
2025-01-18 22:47:15 +00:00
|
|
|
/// See the doc comments on [`ConstArg`] for an explanation of what it means for a const to be
|
|
|
|
/// ambiguous.
|
|
|
|
///
|
2025-03-09 10:31:14 +00:00
|
|
|
/// The [`Visitor::visit_infer`] method should be overridden in order to handle infer vars.
|
2025-01-11 19:12:36 +00:00
|
|
|
fn visit_const_arg(&mut self, c: &'v ConstArg<'v, AmbigArg>) -> Self::Result {
|
|
|
|
walk_ambig_const_arg(self, c)
|
2024-06-03 06:23:28 +00:00
|
|
|
}
|
2025-01-11 19:12:36 +00:00
|
|
|
|
|
|
|
#[allow(unused_variables)]
|
|
|
|
fn visit_infer(&mut self, inf_id: HirId, inf_span: Span, kind: InferKind<'v>) -> Self::Result {
|
|
|
|
self.visit_id(inf_id)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) -> Self::Result {
|
|
|
|
walk_lifetime(self, lifetime)
|
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_expr(&mut self, ex: &'v Expr<'v>) -> Self::Result {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_expr(self, ex)
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_expr_field(&mut self, field: &'v ExprField<'v>) -> Self::Result {
|
2022-05-23 01:34:37 +00:00
|
|
|
walk_expr_field(self, field)
|
|
|
|
}
|
2025-01-07 10:24:16 +00:00
|
|
|
fn visit_pattern_type_pattern(&mut self, p: &'v TyPat<'v>) -> Self::Result {
|
|
|
|
walk_ty_pat(self, p)
|
2023-02-02 13:57:36 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_generic_param(&mut self, p: &'v GenericParam<'v>) -> Self::Result {
|
2017-10-16 19:07:26 +00:00
|
|
|
walk_generic_param(self, p)
|
|
|
|
}
|
2024-06-08 03:26:50 +00:00
|
|
|
fn visit_const_param_default(&mut self, _param: HirId, ct: &'v ConstArg<'v>) -> Self::Result {
|
2021-03-01 11:50:09 +00:00
|
|
|
walk_const_param_default(self, ct)
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_generics(&mut self, g: &'v Generics<'v>) -> Self::Result {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_generics(self, g)
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_where_predicate(&mut self, predicate: &'v WherePredicate<'v>) -> Self::Result {
|
2016-04-21 09:10:10 +00:00
|
|
|
walk_where_predicate(self, predicate)
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_fn_ret_ty(&mut self, ret_ty: &'v FnRetTy<'v>) -> Self::Result {
|
2022-10-26 17:40:34 +00:00
|
|
|
walk_fn_ret_ty(self, ret_ty)
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_fn_decl(&mut self, fd: &'v FnDecl<'v>) -> Self::Result {
|
2016-12-19 22:51:27 +00:00
|
|
|
walk_fn_decl(self, fd)
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_fn(
|
|
|
|
&mut self,
|
|
|
|
fk: FnKind<'v>,
|
|
|
|
fd: &'v FnDecl<'v>,
|
|
|
|
b: BodyId,
|
|
|
|
_: Span,
|
|
|
|
id: LocalDefId,
|
|
|
|
) -> Self::Result {
|
2022-09-12 03:13:22 +00:00
|
|
|
walk_fn(self, fk, fd, b, id)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_use(&mut self, path: &'v UsePath<'v>, hir_id: HirId) -> Self::Result {
|
2019-02-06 13:16:11 +00:00
|
|
|
walk_use(self, path, hir_id)
|
2018-10-11 08:15:18 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_trait_item(&mut self, ti: &'v TraitItem<'v>) -> Self::Result {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_trait_item(self, ti)
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_trait_item_ref(&mut self, ii: &'v TraitItemRef) -> Self::Result {
|
2016-12-04 02:21:06 +00:00
|
|
|
walk_trait_item_ref(self, ii)
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_impl_item(&mut self, ii: &'v ImplItem<'v>) -> Self::Result {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_impl_item(self, ii)
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_foreign_item_ref(&mut self, ii: &'v ForeignItemRef) -> Self::Result {
|
2020-11-11 20:57:54 +00:00
|
|
|
walk_foreign_item_ref(self, ii)
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_impl_item_ref(&mut self, ii: &'v ImplItemRef) -> Self::Result {
|
2016-11-10 14:47:00 +00:00
|
|
|
walk_impl_item_ref(self, ii)
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_trait_ref(&mut self, t: &'v TraitRef<'v>) -> Self::Result {
|
2015-09-27 19:23:31 +00:00
|
|
|
walk_trait_ref(self, t)
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_param_bound(&mut self, bounds: &'v GenericBound<'v>) -> Self::Result {
|
2018-05-28 14:23:16 +00:00
|
|
|
walk_param_bound(self, bounds)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2024-04-04 14:48:47 +00:00
|
|
|
fn visit_precise_capturing_arg(&mut self, arg: &'v PreciseCapturingArg<'v>) -> Self::Result {
|
|
|
|
walk_precise_capturing_arg(self, arg)
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef<'v>) -> Self::Result {
|
2022-09-12 03:37:18 +00:00
|
|
|
walk_poly_trait_ref(self, t)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2024-08-10 03:43:30 +00:00
|
|
|
fn visit_opaque_ty(&mut self, opaque: &'v OpaqueTy<'v>) -> Self::Result {
|
|
|
|
walk_opaque_ty(self, opaque)
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_variant_data(&mut self, s: &'v VariantData<'v>) -> Self::Result {
|
2015-07-31 07:04:06 +00:00
|
|
|
walk_struct_def(self, s)
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_field_def(&mut self, s: &'v FieldDef<'v>) -> Self::Result {
|
2021-03-15 21:36:07 +00:00
|
|
|
walk_field_def(self, s)
|
2015-09-27 19:23:31 +00:00
|
|
|
}
|
2025-03-07 06:02:33 +00:00
|
|
|
fn visit_enum_def(&mut self, enum_definition: &'v EnumDef<'v>) -> Self::Result {
|
|
|
|
walk_enum_def(self, enum_definition)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_variant(&mut self, v: &'v Variant<'v>) -> Self::Result {
|
2022-08-10 01:22:01 +00:00
|
|
|
walk_variant(self, v)
|
2015-09-27 19:23:31 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_label(&mut self, label: &'v Label) -> Self::Result {
|
2018-01-15 22:44:32 +00:00
|
|
|
walk_label(self, label)
|
|
|
|
}
|
2022-09-12 00:43:34 +00:00
|
|
|
// The span is that of the surrounding type/pattern/expr/whatever.
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_qpath(&mut self, qpath: &'v QPath<'v>, id: HirId, _span: Span) -> Self::Result {
|
2022-09-12 00:43:34 +00:00
|
|
|
walk_qpath(self, qpath, id)
|
2016-10-27 02:17:42 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_path(&mut self, path: &Path<'v>, _id: HirId) -> Self::Result {
|
2015-07-31 07:04:06 +00:00
|
|
|
walk_path(self, path)
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_path_segment(&mut self, path_segment: &'v PathSegment<'v>) -> Self::Result {
|
2022-09-12 00:43:34 +00:00
|
|
|
walk_path_segment(self, path_segment)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_generic_args(&mut self, generic_args: &'v GenericArgs<'v>) -> Self::Result {
|
2022-09-12 00:43:34 +00:00
|
|
|
walk_generic_args(self, generic_args)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2024-05-27 21:53:46 +00:00
|
|
|
fn visit_assoc_item_constraint(
|
|
|
|
&mut self,
|
|
|
|
constraint: &'v AssocItemConstraint<'v>,
|
|
|
|
) -> Self::Result {
|
|
|
|
walk_assoc_item_constraint(self, constraint)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_attribute(&mut self, _attr: &'v Attribute) -> Self::Result {
|
|
|
|
Self::Result::output()
|
|
|
|
}
|
|
|
|
fn visit_associated_item_kind(&mut self, kind: &'v AssocItemKind) -> Self::Result {
|
|
|
|
walk_associated_item_kind(self, kind)
|
2016-11-14 16:00:02 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_defaultness(&mut self, defaultness: &'v Defaultness) -> Self::Result {
|
|
|
|
walk_defaultness(self, defaultness)
|
2016-11-14 16:00:02 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
fn visit_inline_asm(&mut self, asm: &'v InlineAsm<'v>, id: HirId) -> Self::Result {
|
|
|
|
walk_inline_asm(self, asm, id)
|
2022-03-01 00:50:56 +00:00
|
|
|
}
|
2015-09-28 21:23:54 +00:00
|
|
|
}
|
|
|
|
|
2025-01-11 19:12:36 +00:00
|
|
|
pub trait VisitorExt<'v>: Visitor<'v> {
|
|
|
|
/// Extension trait method to visit types in unambiguous positions, this is not
|
|
|
|
/// directly on the [`Visitor`] trait as this method should never be overridden.
|
2025-01-19 00:19:42 +00:00
|
|
|
///
|
|
|
|
/// Named `visit_ty_unambig` instead of `visit_unambig_ty` to aid in discovery
|
|
|
|
/// by IDes when `v.visit_ty` is written.
|
2025-01-18 22:45:41 +00:00
|
|
|
fn visit_ty_unambig(&mut self, t: &'v Ty<'v>) -> Self::Result {
|
2025-01-11 19:12:36 +00:00
|
|
|
walk_unambig_ty(self, t)
|
|
|
|
}
|
|
|
|
/// Extension trait method to visit consts in unambiguous positions, this is not
|
|
|
|
/// directly on the [`Visitor`] trait as this method should never be overridden.
|
2025-01-19 00:19:42 +00:00
|
|
|
///
|
|
|
|
/// Named `visit_const_arg_unambig` instead of `visit_unambig_const_arg` to aid in
|
|
|
|
/// discovery by IDes when `v.visit_const_arg` is written.
|
2025-01-18 22:45:41 +00:00
|
|
|
fn visit_const_arg_unambig(&mut self, c: &'v ConstArg<'v>) -> Self::Result {
|
2025-01-11 19:12:36 +00:00
|
|
|
walk_const_arg(self, c)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
impl<'v, V: Visitor<'v>> VisitorExt<'v> for V {}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param<'v>) -> V::Result {
|
|
|
|
try_visit!(visitor.visit_id(param.hir_id));
|
|
|
|
visitor.visit_pat(param.pat)
|
2019-07-26 22:52:37 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::Result {
|
2025-03-07 06:37:23 +00:00
|
|
|
try_visit!(visitor.visit_id(item.hir_id()));
|
2019-09-26 16:51:36 +00:00
|
|
|
match item.kind {
|
Move `hir::Item::ident` into `hir::ItemKind`.
`hir::Item` has an `ident` field.
- It's always non-empty for these item kinds: `ExternCrate`, `Static`,
`Const`, `Fn`, `Macro`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`,
Trait`, TraitAalis`.
- It's always empty for these item kinds: `ForeignMod`, `GlobalAsm`,
`Impl`.
- For `Use`, it is non-empty for `UseKind::Single` and empty for
`UseKind::{Glob,ListStem}`.
All of this is quite non-obvious; the only documentation is a single
comment saying "The name might be a dummy name in case of anonymous
items". Some sites that handle items check for an empty ident, some
don't. This is a very C-like way of doing things, but this is Rust, we
have sum types, we can do this properly and never forget to check for
the exceptional case and never YOLO possibly empty identifiers (or
possibly dummy spans) around and hope that things will work out.
The commit is large but it's mostly obvious plumbing work. Some notable
things.
- A similar transformation makes sense for `ast::Item`, but this is
already a big change. That can be done later.
- Lots of assertions are added to item lowering to ensure that
identifiers are empty/non-empty as expected. These will be removable
when `ast::Item` is done later.
- `ItemKind::Use` doesn't get an `Ident`, but `UseKind::Single` does.
- `lower_use_tree` is significantly simpler. No more confusing `&mut
Ident` to deal with.
- `ItemKind::ident` is a new method, it returns an `Option<Ident>`. It's
used with `unwrap` in a few places; sometimes it's hard to tell
exactly which item kinds might occur. None of these unwraps fail on
the test suite. It's conceivable that some might fail on alternative
input. We can deal with those if/when they happen.
- In `trait_path` the `find_map`/`if let` is replaced with a loop, and
things end up much clearer that way.
- `named_span` no longer checks for an empty name; instead the call site
now checks for a missing identifier if necessary.
- `maybe_inline_local` doesn't need the `glob` argument, it can be
computed in-function from the `renamed` argument.
- `arbitrary_source_item_ordering::check_mod` had a big `if` statement
that was just getting the ident from the item kinds that had one. It
could be mostly replaced by a single call to the new `ItemKind::ident`
method.
- `ItemKind` grows from 56 to 64 bytes, but `Item` stays the same size,
and that's what matters, because `ItemKind` only occurs within `Item`.
2025-03-06 08:07:36 +00:00
|
|
|
ItemKind::ExternCrate(orig_name, ident) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
visit_opt!(visitor, visit_name, orig_name);
|
Move `hir::Item::ident` into `hir::ItemKind`.
`hir::Item` has an `ident` field.
- It's always non-empty for these item kinds: `ExternCrate`, `Static`,
`Const`, `Fn`, `Macro`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`,
Trait`, TraitAalis`.
- It's always empty for these item kinds: `ForeignMod`, `GlobalAsm`,
`Impl`.
- For `Use`, it is non-empty for `UseKind::Single` and empty for
`UseKind::{Glob,ListStem}`.
All of this is quite non-obvious; the only documentation is a single
comment saying "The name might be a dummy name in case of anonymous
items". Some sites that handle items check for an empty ident, some
don't. This is a very C-like way of doing things, but this is Rust, we
have sum types, we can do this properly and never forget to check for
the exceptional case and never YOLO possibly empty identifiers (or
possibly dummy spans) around and hope that things will work out.
The commit is large but it's mostly obvious plumbing work. Some notable
things.
- A similar transformation makes sense for `ast::Item`, but this is
already a big change. That can be done later.
- Lots of assertions are added to item lowering to ensure that
identifiers are empty/non-empty as expected. These will be removable
when `ast::Item` is done later.
- `ItemKind::Use` doesn't get an `Ident`, but `UseKind::Single` does.
- `lower_use_tree` is significantly simpler. No more confusing `&mut
Ident` to deal with.
- `ItemKind::ident` is a new method, it returns an `Option<Ident>`. It's
used with `unwrap` in a few places; sometimes it's hard to tell
exactly which item kinds might occur. None of these unwraps fail on
the test suite. It's conceivable that some might fail on alternative
input. We can deal with those if/when they happen.
- In `trait_path` the `find_map`/`if let` is replaced with a loop, and
things end up much clearer that way.
- `named_span` no longer checks for an empty name; instead the call site
now checks for a missing identifier if necessary.
- `maybe_inline_local` doesn't need the `glob` argument, it can be
computed in-function from the `renamed` argument.
- `arbitrary_source_item_ordering::check_mod` had a big `if` statement
that was just getting the ident from the item kinds that had one. It
could be mostly replaced by a single call to the new `ItemKind::ident`
method.
- `ItemKind` grows from 56 to 64 bytes, but `Item` stays the same size,
and that's what matters, because `ItemKind` only occurs within `Item`.
2025-03-06 08:07:36 +00:00
|
|
|
try_visit!(visitor.visit_ident(ident));
|
2015-09-28 21:23:54 +00:00
|
|
|
}
|
Move `hir::Item::ident` into `hir::ItemKind`.
`hir::Item` has an `ident` field.
- It's always non-empty for these item kinds: `ExternCrate`, `Static`,
`Const`, `Fn`, `Macro`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`,
Trait`, TraitAalis`.
- It's always empty for these item kinds: `ForeignMod`, `GlobalAsm`,
`Impl`.
- For `Use`, it is non-empty for `UseKind::Single` and empty for
`UseKind::{Glob,ListStem}`.
All of this is quite non-obvious; the only documentation is a single
comment saying "The name might be a dummy name in case of anonymous
items". Some sites that handle items check for an empty ident, some
don't. This is a very C-like way of doing things, but this is Rust, we
have sum types, we can do this properly and never forget to check for
the exceptional case and never YOLO possibly empty identifiers (or
possibly dummy spans) around and hope that things will work out.
The commit is large but it's mostly obvious plumbing work. Some notable
things.
- A similar transformation makes sense for `ast::Item`, but this is
already a big change. That can be done later.
- Lots of assertions are added to item lowering to ensure that
identifiers are empty/non-empty as expected. These will be removable
when `ast::Item` is done later.
- `ItemKind::Use` doesn't get an `Ident`, but `UseKind::Single` does.
- `lower_use_tree` is significantly simpler. No more confusing `&mut
Ident` to deal with.
- `ItemKind::ident` is a new method, it returns an `Option<Ident>`. It's
used with `unwrap` in a few places; sometimes it's hard to tell
exactly which item kinds might occur. None of these unwraps fail on
the test suite. It's conceivable that some might fail on alternative
input. We can deal with those if/when they happen.
- In `trait_path` the `find_map`/`if let` is replaced with a loop, and
things end up much clearer that way.
- `named_span` no longer checks for an empty name; instead the call site
now checks for a missing identifier if necessary.
- `maybe_inline_local` doesn't need the `glob` argument, it can be
computed in-function from the `renamed` argument.
- `arbitrary_source_item_ordering::check_mod` had a big `if` statement
that was just getting the ident from the item kinds that had one. It
could be mostly replaced by a single call to the new `ItemKind::ident`
method.
- `ItemKind` grows from 56 to 64 bytes, but `Item` stays the same size,
and that's what matters, because `ItemKind` only occurs within `Item`.
2025-03-06 08:07:36 +00:00
|
|
|
ItemKind::Use(ref path, kind) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_use(path, item.hir_id()));
|
Move `hir::Item::ident` into `hir::ItemKind`.
`hir::Item` has an `ident` field.
- It's always non-empty for these item kinds: `ExternCrate`, `Static`,
`Const`, `Fn`, `Macro`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`,
Trait`, TraitAalis`.
- It's always empty for these item kinds: `ForeignMod`, `GlobalAsm`,
`Impl`.
- For `Use`, it is non-empty for `UseKind::Single` and empty for
`UseKind::{Glob,ListStem}`.
All of this is quite non-obvious; the only documentation is a single
comment saying "The name might be a dummy name in case of anonymous
items". Some sites that handle items check for an empty ident, some
don't. This is a very C-like way of doing things, but this is Rust, we
have sum types, we can do this properly and never forget to check for
the exceptional case and never YOLO possibly empty identifiers (or
possibly dummy spans) around and hope that things will work out.
The commit is large but it's mostly obvious plumbing work. Some notable
things.
- A similar transformation makes sense for `ast::Item`, but this is
already a big change. That can be done later.
- Lots of assertions are added to item lowering to ensure that
identifiers are empty/non-empty as expected. These will be removable
when `ast::Item` is done later.
- `ItemKind::Use` doesn't get an `Ident`, but `UseKind::Single` does.
- `lower_use_tree` is significantly simpler. No more confusing `&mut
Ident` to deal with.
- `ItemKind::ident` is a new method, it returns an `Option<Ident>`. It's
used with `unwrap` in a few places; sometimes it's hard to tell
exactly which item kinds might occur. None of these unwraps fail on
the test suite. It's conceivable that some might fail on alternative
input. We can deal with those if/when they happen.
- In `trait_path` the `find_map`/`if let` is replaced with a loop, and
things end up much clearer that way.
- `named_span` no longer checks for an empty name; instead the call site
now checks for a missing identifier if necessary.
- `maybe_inline_local` doesn't need the `glob` argument, it can be
computed in-function from the `renamed` argument.
- `arbitrary_source_item_ordering::check_mod` had a big `if` statement
that was just getting the ident from the item kinds that had one. It
could be mostly replaced by a single call to the new `ItemKind::ident`
method.
- `ItemKind` grows from 56 to 64 bytes, but `Item` stays the same size,
and that's what matters, because `ItemKind` only occurs within `Item`.
2025-03-06 08:07:36 +00:00
|
|
|
match kind {
|
|
|
|
UseKind::Single(ident) => try_visit!(visitor.visit_ident(ident)),
|
|
|
|
UseKind::Glob | UseKind::ListStem => {}
|
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
Move `hir::Item::ident` into `hir::ItemKind`.
`hir::Item` has an `ident` field.
- It's always non-empty for these item kinds: `ExternCrate`, `Static`,
`Const`, `Fn`, `Macro`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`,
Trait`, TraitAalis`.
- It's always empty for these item kinds: `ForeignMod`, `GlobalAsm`,
`Impl`.
- For `Use`, it is non-empty for `UseKind::Single` and empty for
`UseKind::{Glob,ListStem}`.
All of this is quite non-obvious; the only documentation is a single
comment saying "The name might be a dummy name in case of anonymous
items". Some sites that handle items check for an empty ident, some
don't. This is a very C-like way of doing things, but this is Rust, we
have sum types, we can do this properly and never forget to check for
the exceptional case and never YOLO possibly empty identifiers (or
possibly dummy spans) around and hope that things will work out.
The commit is large but it's mostly obvious plumbing work. Some notable
things.
- A similar transformation makes sense for `ast::Item`, but this is
already a big change. That can be done later.
- Lots of assertions are added to item lowering to ensure that
identifiers are empty/non-empty as expected. These will be removable
when `ast::Item` is done later.
- `ItemKind::Use` doesn't get an `Ident`, but `UseKind::Single` does.
- `lower_use_tree` is significantly simpler. No more confusing `&mut
Ident` to deal with.
- `ItemKind::ident` is a new method, it returns an `Option<Ident>`. It's
used with `unwrap` in a few places; sometimes it's hard to tell
exactly which item kinds might occur. None of these unwraps fail on
the test suite. It's conceivable that some might fail on alternative
input. We can deal with those if/when they happen.
- In `trait_path` the `find_map`/`if let` is replaced with a loop, and
things end up much clearer that way.
- `named_span` no longer checks for an empty name; instead the call site
now checks for a missing identifier if necessary.
- `maybe_inline_local` doesn't need the `glob` argument, it can be
computed in-function from the `renamed` argument.
- `arbitrary_source_item_ordering::check_mod` had a big `if` statement
that was just getting the ident from the item kinds that had one. It
could be mostly replaced by a single call to the new `ItemKind::ident`
method.
- `ItemKind` grows from 56 to 64 bytes, but `Item` stays the same size,
and that's what matters, because `ItemKind` only occurs within `Item`.
2025-03-06 08:07:36 +00:00
|
|
|
ItemKind::Static(ident, ref typ, _, body) => {
|
|
|
|
try_visit!(visitor.visit_ident(ident));
|
2025-01-18 22:45:41 +00:00
|
|
|
try_visit!(visitor.visit_ty_unambig(typ));
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_nested_body(body));
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
Move `hir::Item::ident` into `hir::ItemKind`.
`hir::Item` has an `ident` field.
- It's always non-empty for these item kinds: `ExternCrate`, `Static`,
`Const`, `Fn`, `Macro`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`,
Trait`, TraitAalis`.
- It's always empty for these item kinds: `ForeignMod`, `GlobalAsm`,
`Impl`.
- For `Use`, it is non-empty for `UseKind::Single` and empty for
`UseKind::{Glob,ListStem}`.
All of this is quite non-obvious; the only documentation is a single
comment saying "The name might be a dummy name in case of anonymous
items". Some sites that handle items check for an empty ident, some
don't. This is a very C-like way of doing things, but this is Rust, we
have sum types, we can do this properly and never forget to check for
the exceptional case and never YOLO possibly empty identifiers (or
possibly dummy spans) around and hope that things will work out.
The commit is large but it's mostly obvious plumbing work. Some notable
things.
- A similar transformation makes sense for `ast::Item`, but this is
already a big change. That can be done later.
- Lots of assertions are added to item lowering to ensure that
identifiers are empty/non-empty as expected. These will be removable
when `ast::Item` is done later.
- `ItemKind::Use` doesn't get an `Ident`, but `UseKind::Single` does.
- `lower_use_tree` is significantly simpler. No more confusing `&mut
Ident` to deal with.
- `ItemKind::ident` is a new method, it returns an `Option<Ident>`. It's
used with `unwrap` in a few places; sometimes it's hard to tell
exactly which item kinds might occur. None of these unwraps fail on
the test suite. It's conceivable that some might fail on alternative
input. We can deal with those if/when they happen.
- In `trait_path` the `find_map`/`if let` is replaced with a loop, and
things end up much clearer that way.
- `named_span` no longer checks for an empty name; instead the call site
now checks for a missing identifier if necessary.
- `maybe_inline_local` doesn't need the `glob` argument, it can be
computed in-function from the `renamed` argument.
- `arbitrary_source_item_ordering::check_mod` had a big `if` statement
that was just getting the ident from the item kinds that had one. It
could be mostly replaced by a single call to the new `ItemKind::ident`
method.
- `ItemKind` grows from 56 to 64 bytes, but `Item` stays the same size,
and that's what matters, because `ItemKind` only occurs within `Item`.
2025-03-06 08:07:36 +00:00
|
|
|
ItemKind::Const(ident, ref typ, ref generics, body) => {
|
|
|
|
try_visit!(visitor.visit_ident(ident));
|
2025-01-18 22:45:41 +00:00
|
|
|
try_visit!(visitor.visit_ty_unambig(typ));
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_generics(generics));
|
|
|
|
try_visit!(visitor.visit_nested_body(body));
|
2023-05-04 14:40:57 +00:00
|
|
|
}
|
Move `hir::Item::ident` into `hir::ItemKind`.
`hir::Item` has an `ident` field.
- It's always non-empty for these item kinds: `ExternCrate`, `Static`,
`Const`, `Fn`, `Macro`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`,
Trait`, TraitAalis`.
- It's always empty for these item kinds: `ForeignMod`, `GlobalAsm`,
`Impl`.
- For `Use`, it is non-empty for `UseKind::Single` and empty for
`UseKind::{Glob,ListStem}`.
All of this is quite non-obvious; the only documentation is a single
comment saying "The name might be a dummy name in case of anonymous
items". Some sites that handle items check for an empty ident, some
don't. This is a very C-like way of doing things, but this is Rust, we
have sum types, we can do this properly and never forget to check for
the exceptional case and never YOLO possibly empty identifiers (or
possibly dummy spans) around and hope that things will work out.
The commit is large but it's mostly obvious plumbing work. Some notable
things.
- A similar transformation makes sense for `ast::Item`, but this is
already a big change. That can be done later.
- Lots of assertions are added to item lowering to ensure that
identifiers are empty/non-empty as expected. These will be removable
when `ast::Item` is done later.
- `ItemKind::Use` doesn't get an `Ident`, but `UseKind::Single` does.
- `lower_use_tree` is significantly simpler. No more confusing `&mut
Ident` to deal with.
- `ItemKind::ident` is a new method, it returns an `Option<Ident>`. It's
used with `unwrap` in a few places; sometimes it's hard to tell
exactly which item kinds might occur. None of these unwraps fail on
the test suite. It's conceivable that some might fail on alternative
input. We can deal with those if/when they happen.
- In `trait_path` the `find_map`/`if let` is replaced with a loop, and
things end up much clearer that way.
- `named_span` no longer checks for an empty name; instead the call site
now checks for a missing identifier if necessary.
- `maybe_inline_local` doesn't need the `glob` argument, it can be
computed in-function from the `renamed` argument.
- `arbitrary_source_item_ordering::check_mod` had a big `if` statement
that was just getting the ident from the item kinds that had one. It
could be mostly replaced by a single call to the new `ItemKind::ident`
method.
- `ItemKind` grows from 56 to 64 bytes, but `Item` stays the same size,
and that's what matters, because `ItemKind` only occurs within `Item`.
2025-03-06 08:07:36 +00:00
|
|
|
ItemKind::Fn { ident, sig, generics, body: body_id, .. } => {
|
|
|
|
try_visit!(visitor.visit_ident(ident));
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_fn(
|
Move `hir::Item::ident` into `hir::ItemKind`.
`hir::Item` has an `ident` field.
- It's always non-empty for these item kinds: `ExternCrate`, `Static`,
`Const`, `Fn`, `Macro`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`,
Trait`, TraitAalis`.
- It's always empty for these item kinds: `ForeignMod`, `GlobalAsm`,
`Impl`.
- For `Use`, it is non-empty for `UseKind::Single` and empty for
`UseKind::{Glob,ListStem}`.
All of this is quite non-obvious; the only documentation is a single
comment saying "The name might be a dummy name in case of anonymous
items". Some sites that handle items check for an empty ident, some
don't. This is a very C-like way of doing things, but this is Rust, we
have sum types, we can do this properly and never forget to check for
the exceptional case and never YOLO possibly empty identifiers (or
possibly dummy spans) around and hope that things will work out.
The commit is large but it's mostly obvious plumbing work. Some notable
things.
- A similar transformation makes sense for `ast::Item`, but this is
already a big change. That can be done later.
- Lots of assertions are added to item lowering to ensure that
identifiers are empty/non-empty as expected. These will be removable
when `ast::Item` is done later.
- `ItemKind::Use` doesn't get an `Ident`, but `UseKind::Single` does.
- `lower_use_tree` is significantly simpler. No more confusing `&mut
Ident` to deal with.
- `ItemKind::ident` is a new method, it returns an `Option<Ident>`. It's
used with `unwrap` in a few places; sometimes it's hard to tell
exactly which item kinds might occur. None of these unwraps fail on
the test suite. It's conceivable that some might fail on alternative
input. We can deal with those if/when they happen.
- In `trait_path` the `find_map`/`if let` is replaced with a loop, and
things end up much clearer that way.
- `named_span` no longer checks for an empty name; instead the call site
now checks for a missing identifier if necessary.
- `maybe_inline_local` doesn't need the `glob` argument, it can be
computed in-function from the `renamed` argument.
- `arbitrary_source_item_ordering::check_mod` had a big `if` statement
that was just getting the ident from the item kinds that had one. It
could be mostly replaced by a single call to the new `ItemKind::ident`
method.
- `ItemKind` grows from 56 to 64 bytes, but `Item` stays the same size,
and that's what matters, because `ItemKind` only occurs within `Item`.
2025-03-06 08:07:36 +00:00
|
|
|
FnKind::ItemFn(ident, generics, sig.header),
|
2023-01-22 18:00:33 +00:00
|
|
|
sig.decl,
|
|
|
|
body_id,
|
|
|
|
item.span,
|
|
|
|
item.owner_id.def_id,
|
2024-02-18 08:12:44 +00:00
|
|
|
));
|
2023-01-22 18:00:33 +00:00
|
|
|
}
|
Move `hir::Item::ident` into `hir::ItemKind`.
`hir::Item` has an `ident` field.
- It's always non-empty for these item kinds: `ExternCrate`, `Static`,
`Const`, `Fn`, `Macro`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`,
Trait`, TraitAalis`.
- It's always empty for these item kinds: `ForeignMod`, `GlobalAsm`,
`Impl`.
- For `Use`, it is non-empty for `UseKind::Single` and empty for
`UseKind::{Glob,ListStem}`.
All of this is quite non-obvious; the only documentation is a single
comment saying "The name might be a dummy name in case of anonymous
items". Some sites that handle items check for an empty ident, some
don't. This is a very C-like way of doing things, but this is Rust, we
have sum types, we can do this properly and never forget to check for
the exceptional case and never YOLO possibly empty identifiers (or
possibly dummy spans) around and hope that things will work out.
The commit is large but it's mostly obvious plumbing work. Some notable
things.
- A similar transformation makes sense for `ast::Item`, but this is
already a big change. That can be done later.
- Lots of assertions are added to item lowering to ensure that
identifiers are empty/non-empty as expected. These will be removable
when `ast::Item` is done later.
- `ItemKind::Use` doesn't get an `Ident`, but `UseKind::Single` does.
- `lower_use_tree` is significantly simpler. No more confusing `&mut
Ident` to deal with.
- `ItemKind::ident` is a new method, it returns an `Option<Ident>`. It's
used with `unwrap` in a few places; sometimes it's hard to tell
exactly which item kinds might occur. None of these unwraps fail on
the test suite. It's conceivable that some might fail on alternative
input. We can deal with those if/when they happen.
- In `trait_path` the `find_map`/`if let` is replaced with a loop, and
things end up much clearer that way.
- `named_span` no longer checks for an empty name; instead the call site
now checks for a missing identifier if necessary.
- `maybe_inline_local` doesn't need the `glob` argument, it can be
computed in-function from the `renamed` argument.
- `arbitrary_source_item_ordering::check_mod` had a big `if` statement
that was just getting the ident from the item kinds that had one. It
could be mostly replaced by a single call to the new `ItemKind::ident`
method.
- `ItemKind` grows from 56 to 64 bytes, but `Item` stays the same size,
and that's what matters, because `ItemKind` only occurs within `Item`.
2025-03-06 08:07:36 +00:00
|
|
|
ItemKind::Macro(ident, _def, _kind) => {
|
|
|
|
try_visit!(visitor.visit_ident(ident));
|
|
|
|
}
|
|
|
|
ItemKind::Mod(ident, ref module) => {
|
|
|
|
try_visit!(visitor.visit_ident(ident));
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(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 } => {
|
|
|
|
walk_list!(visitor, visit_foreign_item_ref, items);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2025-02-17 16:09:46 +00:00
|
|
|
ItemKind::GlobalAsm { asm: _, fake_body } => {
|
|
|
|
// Visit the fake body, which contains the asm statement.
|
|
|
|
// Therefore we should not visit the asm statement again
|
|
|
|
// outside of the body, or some visitors won't have their
|
|
|
|
// typeck results set correctly.
|
|
|
|
try_visit!(visitor.visit_nested_body(fake_body));
|
2017-03-30 04:32:20 +00:00
|
|
|
}
|
Move `hir::Item::ident` into `hir::ItemKind`.
`hir::Item` has an `ident` field.
- It's always non-empty for these item kinds: `ExternCrate`, `Static`,
`Const`, `Fn`, `Macro`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`,
Trait`, TraitAalis`.
- It's always empty for these item kinds: `ForeignMod`, `GlobalAsm`,
`Impl`.
- For `Use`, it is non-empty for `UseKind::Single` and empty for
`UseKind::{Glob,ListStem}`.
All of this is quite non-obvious; the only documentation is a single
comment saying "The name might be a dummy name in case of anonymous
items". Some sites that handle items check for an empty ident, some
don't. This is a very C-like way of doing things, but this is Rust, we
have sum types, we can do this properly and never forget to check for
the exceptional case and never YOLO possibly empty identifiers (or
possibly dummy spans) around and hope that things will work out.
The commit is large but it's mostly obvious plumbing work. Some notable
things.
- A similar transformation makes sense for `ast::Item`, but this is
already a big change. That can be done later.
- Lots of assertions are added to item lowering to ensure that
identifiers are empty/non-empty as expected. These will be removable
when `ast::Item` is done later.
- `ItemKind::Use` doesn't get an `Ident`, but `UseKind::Single` does.
- `lower_use_tree` is significantly simpler. No more confusing `&mut
Ident` to deal with.
- `ItemKind::ident` is a new method, it returns an `Option<Ident>`. It's
used with `unwrap` in a few places; sometimes it's hard to tell
exactly which item kinds might occur. None of these unwraps fail on
the test suite. It's conceivable that some might fail on alternative
input. We can deal with those if/when they happen.
- In `trait_path` the `find_map`/`if let` is replaced with a loop, and
things end up much clearer that way.
- `named_span` no longer checks for an empty name; instead the call site
now checks for a missing identifier if necessary.
- `maybe_inline_local` doesn't need the `glob` argument, it can be
computed in-function from the `renamed` argument.
- `arbitrary_source_item_ordering::check_mod` had a big `if` statement
that was just getting the ident from the item kinds that had one. It
could be mostly replaced by a single call to the new `ItemKind::ident`
method.
- `ItemKind` grows from 56 to 64 bytes, but `Item` stays the same size,
and that's what matters, because `ItemKind` only occurs within `Item`.
2025-03-06 08:07:36 +00:00
|
|
|
ItemKind::TyAlias(ident, ref ty, ref generics) => {
|
|
|
|
try_visit!(visitor.visit_ident(ident));
|
2025-01-18 22:45:41 +00:00
|
|
|
try_visit!(visitor.visit_ty_unambig(ty));
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_generics(generics));
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
Move `hir::Item::ident` into `hir::ItemKind`.
`hir::Item` has an `ident` field.
- It's always non-empty for these item kinds: `ExternCrate`, `Static`,
`Const`, `Fn`, `Macro`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`,
Trait`, TraitAalis`.
- It's always empty for these item kinds: `ForeignMod`, `GlobalAsm`,
`Impl`.
- For `Use`, it is non-empty for `UseKind::Single` and empty for
`UseKind::{Glob,ListStem}`.
All of this is quite non-obvious; the only documentation is a single
comment saying "The name might be a dummy name in case of anonymous
items". Some sites that handle items check for an empty ident, some
don't. This is a very C-like way of doing things, but this is Rust, we
have sum types, we can do this properly and never forget to check for
the exceptional case and never YOLO possibly empty identifiers (or
possibly dummy spans) around and hope that things will work out.
The commit is large but it's mostly obvious plumbing work. Some notable
things.
- A similar transformation makes sense for `ast::Item`, but this is
already a big change. That can be done later.
- Lots of assertions are added to item lowering to ensure that
identifiers are empty/non-empty as expected. These will be removable
when `ast::Item` is done later.
- `ItemKind::Use` doesn't get an `Ident`, but `UseKind::Single` does.
- `lower_use_tree` is significantly simpler. No more confusing `&mut
Ident` to deal with.
- `ItemKind::ident` is a new method, it returns an `Option<Ident>`. It's
used with `unwrap` in a few places; sometimes it's hard to tell
exactly which item kinds might occur. None of these unwraps fail on
the test suite. It's conceivable that some might fail on alternative
input. We can deal with those if/when they happen.
- In `trait_path` the `find_map`/`if let` is replaced with a loop, and
things end up much clearer that way.
- `named_span` no longer checks for an empty name; instead the call site
now checks for a missing identifier if necessary.
- `maybe_inline_local` doesn't need the `glob` argument, it can be
computed in-function from the `renamed` argument.
- `arbitrary_source_item_ordering::check_mod` had a big `if` statement
that was just getting the ident from the item kinds that had one. It
could be mostly replaced by a single call to the new `ItemKind::ident`
method.
- `ItemKind` grows from 56 to 64 bytes, but `Item` stays the same size,
and that's what matters, because `ItemKind` only occurs within `Item`.
2025-03-06 08:07:36 +00:00
|
|
|
ItemKind::Enum(ident, ref enum_definition, ref generics) => {
|
|
|
|
try_visit!(visitor.visit_ident(ident));
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_generics(generics));
|
2025-03-07 06:02:33 +00:00
|
|
|
try_visit!(visitor.visit_enum_def(enum_definition));
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2020-11-22 22:46:21 +00:00
|
|
|
ItemKind::Impl(Impl {
|
2024-06-14 12:16:15 +00:00
|
|
|
constness: _,
|
2024-05-17 17:17:48 +00:00
|
|
|
safety: _,
|
2020-01-18 00:14:29 +00:00
|
|
|
defaultness: _,
|
|
|
|
polarity: _,
|
2020-03-02 23:26:00 +00:00
|
|
|
defaultness_span: _,
|
2025-02-20 18:28:48 +00:00
|
|
|
generics,
|
|
|
|
of_trait,
|
|
|
|
self_ty,
|
2020-01-18 00:14:29 +00:00
|
|
|
items,
|
2020-11-22 22:46:21 +00:00
|
|
|
}) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_generics(generics));
|
|
|
|
visit_opt!(visitor, visit_trait_ref, of_trait);
|
2025-01-18 22:45:41 +00:00
|
|
|
try_visit!(visitor.visit_ty_unambig(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
|
|
|
}
|
Move `hir::Item::ident` into `hir::ItemKind`.
`hir::Item` has an `ident` field.
- It's always non-empty for these item kinds: `ExternCrate`, `Static`,
`Const`, `Fn`, `Macro`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`,
Trait`, TraitAalis`.
- It's always empty for these item kinds: `ForeignMod`, `GlobalAsm`,
`Impl`.
- For `Use`, it is non-empty for `UseKind::Single` and empty for
`UseKind::{Glob,ListStem}`.
All of this is quite non-obvious; the only documentation is a single
comment saying "The name might be a dummy name in case of anonymous
items". Some sites that handle items check for an empty ident, some
don't. This is a very C-like way of doing things, but this is Rust, we
have sum types, we can do this properly and never forget to check for
the exceptional case and never YOLO possibly empty identifiers (or
possibly dummy spans) around and hope that things will work out.
The commit is large but it's mostly obvious plumbing work. Some notable
things.
- A similar transformation makes sense for `ast::Item`, but this is
already a big change. That can be done later.
- Lots of assertions are added to item lowering to ensure that
identifiers are empty/non-empty as expected. These will be removable
when `ast::Item` is done later.
- `ItemKind::Use` doesn't get an `Ident`, but `UseKind::Single` does.
- `lower_use_tree` is significantly simpler. No more confusing `&mut
Ident` to deal with.
- `ItemKind::ident` is a new method, it returns an `Option<Ident>`. It's
used with `unwrap` in a few places; sometimes it's hard to tell
exactly which item kinds might occur. None of these unwraps fail on
the test suite. It's conceivable that some might fail on alternative
input. We can deal with those if/when they happen.
- In `trait_path` the `find_map`/`if let` is replaced with a loop, and
things end up much clearer that way.
- `named_span` no longer checks for an empty name; instead the call site
now checks for a missing identifier if necessary.
- `maybe_inline_local` doesn't need the `glob` argument, it can be
computed in-function from the `renamed` argument.
- `arbitrary_source_item_ordering::check_mod` had a big `if` statement
that was just getting the ident from the item kinds that had one. It
could be mostly replaced by a single call to the new `ItemKind::ident`
method.
- `ItemKind` grows from 56 to 64 bytes, but `Item` stays the same size,
and that's what matters, because `ItemKind` only occurs within `Item`.
2025-03-06 08:07:36 +00:00
|
|
|
ItemKind::Struct(ident, ref struct_definition, ref generics)
|
|
|
|
| ItemKind::Union(ident, ref struct_definition, ref generics) => {
|
|
|
|
try_visit!(visitor.visit_ident(ident));
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_generics(generics));
|
|
|
|
try_visit!(visitor.visit_variant_data(struct_definition));
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
Move `hir::Item::ident` into `hir::ItemKind`.
`hir::Item` has an `ident` field.
- It's always non-empty for these item kinds: `ExternCrate`, `Static`,
`Const`, `Fn`, `Macro`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`,
Trait`, TraitAalis`.
- It's always empty for these item kinds: `ForeignMod`, `GlobalAsm`,
`Impl`.
- For `Use`, it is non-empty for `UseKind::Single` and empty for
`UseKind::{Glob,ListStem}`.
All of this is quite non-obvious; the only documentation is a single
comment saying "The name might be a dummy name in case of anonymous
items". Some sites that handle items check for an empty ident, some
don't. This is a very C-like way of doing things, but this is Rust, we
have sum types, we can do this properly and never forget to check for
the exceptional case and never YOLO possibly empty identifiers (or
possibly dummy spans) around and hope that things will work out.
The commit is large but it's mostly obvious plumbing work. Some notable
things.
- A similar transformation makes sense for `ast::Item`, but this is
already a big change. That can be done later.
- Lots of assertions are added to item lowering to ensure that
identifiers are empty/non-empty as expected. These will be removable
when `ast::Item` is done later.
- `ItemKind::Use` doesn't get an `Ident`, but `UseKind::Single` does.
- `lower_use_tree` is significantly simpler. No more confusing `&mut
Ident` to deal with.
- `ItemKind::ident` is a new method, it returns an `Option<Ident>`. It's
used with `unwrap` in a few places; sometimes it's hard to tell
exactly which item kinds might occur. None of these unwraps fail on
the test suite. It's conceivable that some might fail on alternative
input. We can deal with those if/when they happen.
- In `trait_path` the `find_map`/`if let` is replaced with a loop, and
things end up much clearer that way.
- `named_span` no longer checks for an empty name; instead the call site
now checks for a missing identifier if necessary.
- `maybe_inline_local` doesn't need the `glob` argument, it can be
computed in-function from the `renamed` argument.
- `arbitrary_source_item_ordering::check_mod` had a big `if` statement
that was just getting the ident from the item kinds that had one. It
could be mostly replaced by a single call to the new `ItemKind::ident`
method.
- `ItemKind` grows from 56 to 64 bytes, but `Item` stays the same size,
and that's what matters, because `ItemKind` only occurs within `Item`.
2025-03-06 08:07:36 +00:00
|
|
|
ItemKind::Trait(_is_auto, _safety, ident, ref generics, bounds, trait_item_refs) => {
|
|
|
|
try_visit!(visitor.visit_ident(ident));
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(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
|
|
|
}
|
Move `hir::Item::ident` into `hir::ItemKind`.
`hir::Item` has an `ident` field.
- It's always non-empty for these item kinds: `ExternCrate`, `Static`,
`Const`, `Fn`, `Macro`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`,
Trait`, TraitAalis`.
- It's always empty for these item kinds: `ForeignMod`, `GlobalAsm`,
`Impl`.
- For `Use`, it is non-empty for `UseKind::Single` and empty for
`UseKind::{Glob,ListStem}`.
All of this is quite non-obvious; the only documentation is a single
comment saying "The name might be a dummy name in case of anonymous
items". Some sites that handle items check for an empty ident, some
don't. This is a very C-like way of doing things, but this is Rust, we
have sum types, we can do this properly and never forget to check for
the exceptional case and never YOLO possibly empty identifiers (or
possibly dummy spans) around and hope that things will work out.
The commit is large but it's mostly obvious plumbing work. Some notable
things.
- A similar transformation makes sense for `ast::Item`, but this is
already a big change. That can be done later.
- Lots of assertions are added to item lowering to ensure that
identifiers are empty/non-empty as expected. These will be removable
when `ast::Item` is done later.
- `ItemKind::Use` doesn't get an `Ident`, but `UseKind::Single` does.
- `lower_use_tree` is significantly simpler. No more confusing `&mut
Ident` to deal with.
- `ItemKind::ident` is a new method, it returns an `Option<Ident>`. It's
used with `unwrap` in a few places; sometimes it's hard to tell
exactly which item kinds might occur. None of these unwraps fail on
the test suite. It's conceivable that some might fail on alternative
input. We can deal with those if/when they happen.
- In `trait_path` the `find_map`/`if let` is replaced with a loop, and
things end up much clearer that way.
- `named_span` no longer checks for an empty name; instead the call site
now checks for a missing identifier if necessary.
- `maybe_inline_local` doesn't need the `glob` argument, it can be
computed in-function from the `renamed` argument.
- `arbitrary_source_item_ordering::check_mod` had a big `if` statement
that was just getting the ident from the item kinds that had one. It
could be mostly replaced by a single call to the new `ItemKind::ident`
method.
- `ItemKind` grows from 56 to 64 bytes, but `Item` stays the same size,
and that's what matters, because `ItemKind` only occurs within `Item`.
2025-03-06 08:07:36 +00:00
|
|
|
ItemKind::TraitAlias(ident, ref generics, bounds) => {
|
|
|
|
try_visit!(visitor.visit_ident(ident));
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(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
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
V::Result::output()
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2024-05-29 09:08:22 +00:00
|
|
|
pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &Body<'v>) -> V::Result {
|
2022-11-01 23:02:45 +00:00
|
|
|
walk_list!(visitor, visit_param, body.params);
|
2024-02-18 08:12:44 +00:00
|
|
|
visitor.visit_expr(body.value)
|
2018-10-11 08:15:18 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_ident<'v, V: Visitor<'v>>(visitor: &mut V, ident: Ident) -> V::Result {
|
|
|
|
visitor.visit_name(ident.name)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2025-03-07 06:02:33 +00:00
|
|
|
pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod<'v>) -> V::Result {
|
2024-02-18 08:12:44 +00:00
|
|
|
walk_list!(visitor, visit_nested_item, module.item_ids.iter().copied());
|
|
|
|
V::Result::output()
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_foreign_item<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
foreign_item: &'v ForeignItem<'v>,
|
|
|
|
) -> V::Result {
|
|
|
|
try_visit!(visitor.visit_id(foreign_item.hir_id()));
|
|
|
|
try_visit!(visitor.visit_ident(foreign_item.ident));
|
2016-07-28 09:58:45 +00:00
|
|
|
|
2022-11-01 23:02:45 +00:00
|
|
|
match foreign_item.kind {
|
2024-08-07 17:01:34 +00:00
|
|
|
ForeignItemKind::Fn(ref sig, param_names, ref generics) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_generics(generics));
|
2024-08-07 17:01:34 +00:00
|
|
|
try_visit!(visitor.visit_fn_decl(sig.decl));
|
2024-02-18 08:12:44 +00:00
|
|
|
walk_list!(visitor, visit_ident, param_names.iter().copied());
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2024-05-23 13:01:05 +00:00
|
|
|
ForeignItemKind::Static(ref typ, _, _) => {
|
2025-01-18 22:45:41 +00:00
|
|
|
try_visit!(visitor.visit_ty_unambig(typ));
|
2024-05-23 13:01:05 +00:00
|
|
|
}
|
2022-11-01 23:02:45 +00:00
|
|
|
ForeignItemKind::Type => (),
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
V::Result::output()
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2024-03-20 16:50:31 +00:00
|
|
|
pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v LetStmt<'v>) -> V::Result {
|
2022-11-01 23:02:45 +00:00
|
|
|
// Intentionally visiting the expr first - the initialization expr
|
|
|
|
// dominates the local's definition.
|
2024-02-18 08:12:44 +00:00
|
|
|
visit_opt!(visitor, visit_expr, local.init);
|
|
|
|
try_visit!(visitor.visit_id(local.hir_id));
|
|
|
|
try_visit!(visitor.visit_pat(local.pat));
|
|
|
|
visit_opt!(visitor, visit_block, local.els);
|
2025-01-18 22:45:41 +00:00
|
|
|
visit_opt!(visitor, visit_ty_unambig, local.ty);
|
2024-02-18 08:12:44 +00:00
|
|
|
V::Result::output()
|
2016-10-27 02:17:42 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block<'v>) -> V::Result {
|
|
|
|
try_visit!(visitor.visit_id(block.hir_id));
|
2022-11-01 23:02:45 +00:00
|
|
|
walk_list!(visitor, visit_stmt, block.stmts);
|
2024-02-18 08:12:44 +00:00
|
|
|
visit_opt!(visitor, visit_expr, block.expr);
|
|
|
|
V::Result::output()
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt<'v>) -> V::Result {
|
|
|
|
try_visit!(visitor.visit_id(statement.hir_id));
|
2022-11-01 23:02:45 +00:00
|
|
|
match statement.kind {
|
2024-03-14 10:53:38 +00:00
|
|
|
StmtKind::Let(ref local) => visitor.visit_local(local),
|
2022-11-01 23:02:45 +00:00
|
|
|
StmtKind::Item(item) => visitor.visit_nested_item(item),
|
|
|
|
StmtKind::Expr(ref expression) | StmtKind::Semi(ref expression) => {
|
|
|
|
visitor.visit_expr(expression)
|
|
|
|
}
|
2017-09-21 20:24:26 +00:00
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) -> V::Result {
|
|
|
|
try_visit!(visitor.visit_id(arm.hir_id));
|
|
|
|
try_visit!(visitor.visit_pat(arm.pat));
|
|
|
|
visit_opt!(visitor, visit_expr, arm.guard);
|
|
|
|
visitor.visit_expr(arm.body)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2025-01-07 10:24:16 +00:00
|
|
|
pub fn walk_ty_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v TyPat<'v>) -> V::Result {
|
|
|
|
try_visit!(visitor.visit_id(pattern.hir_id));
|
|
|
|
match pattern.kind {
|
2025-02-05 15:22:10 +00:00
|
|
|
TyPatKind::Range(lower_bound, upper_bound) => {
|
|
|
|
try_visit!(visitor.visit_const_arg_unambig(lower_bound));
|
|
|
|
try_visit!(visitor.visit_const_arg_unambig(upper_bound));
|
2025-01-07 10:24:16 +00:00
|
|
|
}
|
|
|
|
TyPatKind::Err(_) => (),
|
|
|
|
}
|
|
|
|
V::Result::output()
|
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) -> V::Result {
|
|
|
|
try_visit!(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, _) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(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
|
|
|
}
|
2019-11-29 13:08:03 +00:00
|
|
|
PatKind::Struct(ref qpath, fields, _) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(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
|
|
|
}
|
2024-03-20 20:53:50 +00:00
|
|
|
PatKind::Box(ref subpattern)
|
|
|
|
| PatKind::Deref(ref subpattern)
|
|
|
|
| PatKind::Ref(ref subpattern, _) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(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) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_ident(ident));
|
|
|
|
visit_opt!(visitor, visit_pat, optional_subpattern);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2025-01-07 08:56:23 +00:00
|
|
|
PatKind::Expr(ref expression) => try_visit!(visitor.visit_pat_expr(expression)),
|
2017-01-10 21:13:53 +00:00
|
|
|
PatKind::Range(ref lower_bound, ref upper_bound, _) => {
|
2024-12-11 16:50:45 +00:00
|
|
|
visit_opt!(visitor, visit_pat_expr, lower_bound);
|
|
|
|
visit_opt!(visitor, visit_pat_expr, upper_bound);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2024-01-17 02:14:16 +00:00
|
|
|
PatKind::Never | PatKind::Wild | PatKind::Err(_) => (),
|
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);
|
2024-02-18 08:12:44 +00:00
|
|
|
visit_opt!(visitor, visit_pat, slice_pattern);
|
2015-09-28 21:23:54 +00:00
|
|
|
walk_list!(visitor, visit_pat, postpatterns);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2024-08-25 04:56:12 +00:00
|
|
|
PatKind::Guard(subpat, condition) => {
|
|
|
|
try_visit!(visitor.visit_pat(subpat));
|
|
|
|
try_visit!(visitor.visit_expr(condition));
|
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
V::Result::output()
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<'v>) -> V::Result {
|
|
|
|
try_visit!(visitor.visit_id(field.hir_id));
|
|
|
|
try_visit!(visitor.visit_ident(field.ident));
|
2022-11-29 11:01:17 +00:00
|
|
|
visitor.visit_pat(field.pat)
|
2022-05-23 01:34:37 +00:00
|
|
|
}
|
|
|
|
|
2024-12-11 16:50:45 +00:00
|
|
|
pub fn walk_pat_expr<'v, V: Visitor<'v>>(visitor: &mut V, expr: &'v PatExpr<'v>) -> V::Result {
|
|
|
|
try_visit!(visitor.visit_id(expr.hir_id));
|
|
|
|
match &expr.kind {
|
2025-02-01 10:06:35 +00:00
|
|
|
PatExprKind::Lit { lit, negated } => visitor.visit_lit(expr.hir_id, lit, *negated),
|
2024-12-11 16:50:45 +00:00
|
|
|
PatExprKind::ConstBlock(c) => visitor.visit_inline_const(c),
|
|
|
|
PatExprKind::Path(qpath) => visitor.visit_qpath(qpath, expr.hir_id, expr.span),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonConst) -> V::Result {
|
|
|
|
try_visit!(visitor.visit_id(constant.hir_id));
|
|
|
|
visitor.visit_nested_body(constant.body)
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
|
2024-06-03 09:11:58 +00:00
|
|
|
pub fn walk_inline_const<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
constant: &'v ConstBlock,
|
|
|
|
) -> V::Result {
|
|
|
|
try_visit!(visitor.visit_id(constant.hir_id));
|
|
|
|
visitor.visit_nested_body(constant.body)
|
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) -> V::Result {
|
|
|
|
try_visit!(visitor.visit_id(expression.hir_id));
|
2022-11-01 23:02:45 +00:00
|
|
|
match expression.kind {
|
|
|
|
ExprKind::Array(subexpressions) => {
|
|
|
|
walk_list!(visitor, visit_expr, subexpressions);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
ExprKind::ConstBlock(ref const_block) => {
|
2024-06-03 09:11:58 +00:00
|
|
|
try_visit!(visitor.visit_inline_const(const_block))
|
2024-02-18 08:12:44 +00:00
|
|
|
}
|
2022-11-01 23:02:45 +00:00
|
|
|
ExprKind::Repeat(ref element, ref count) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_expr(element));
|
2025-01-18 22:45:41 +00:00
|
|
|
try_visit!(visitor.visit_const_arg_unambig(count));
|
2020-08-04 13:34:24 +00:00
|
|
|
}
|
2022-11-01 23:02:45 +00:00
|
|
|
ExprKind::Struct(ref qpath, fields, ref optional_base) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_qpath(qpath, expression.hir_id, expression.span));
|
2022-11-01 23:02:45 +00:00
|
|
|
walk_list!(visitor, visit_expr_field, fields);
|
2024-08-24 17:22:48 +00:00
|
|
|
match optional_base {
|
|
|
|
StructTailExpr::Base(base) => try_visit!(visitor.visit_expr(base)),
|
|
|
|
StructTailExpr::None | StructTailExpr::DefaultFields(_) => {}
|
|
|
|
}
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
ExprKind::Tup(subexpressions) => {
|
|
|
|
walk_list!(visitor, visit_expr, subexpressions);
|
|
|
|
}
|
|
|
|
ExprKind::Call(ref callee_expression, arguments) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_expr(callee_expression));
|
2022-11-01 23:02:45 +00:00
|
|
|
walk_list!(visitor, visit_expr, arguments);
|
|
|
|
}
|
|
|
|
ExprKind::MethodCall(ref segment, receiver, arguments, _) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_path_segment(segment));
|
|
|
|
try_visit!(visitor.visit_expr(receiver));
|
2022-11-01 23:02:45 +00:00
|
|
|
walk_list!(visitor, visit_expr, arguments);
|
|
|
|
}
|
2024-10-02 19:35:37 +00:00
|
|
|
ExprKind::Use(expr, _) => {
|
|
|
|
try_visit!(visitor.visit_expr(expr));
|
|
|
|
}
|
2022-11-01 23:02:45 +00:00
|
|
|
ExprKind::Binary(_, ref left_expression, ref right_expression) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_expr(left_expression));
|
|
|
|
try_visit!(visitor.visit_expr(right_expression));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
ExprKind::AddrOf(_, _, ref subexpression) | ExprKind::Unary(_, ref subexpression) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_expr(subexpression));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
ExprKind::Cast(ref subexpression, ref typ) | ExprKind::Type(ref subexpression, ref typ) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_expr(subexpression));
|
2025-01-18 22:45:41 +00:00
|
|
|
try_visit!(visitor.visit_ty_unambig(typ));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
ExprKind::DropTemps(ref subexpression) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_expr(subexpression));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
2024-05-09 08:44:40 +00:00
|
|
|
ExprKind::Let(LetExpr { span: _, pat, ty, init, recovered: _ }) => {
|
2024-01-27 14:46:50 +00:00
|
|
|
// match the visit order in walk_local
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_expr(init));
|
|
|
|
try_visit!(visitor.visit_pat(pat));
|
2025-01-18 22:45:41 +00:00
|
|
|
visit_opt!(visitor, visit_ty_unambig, ty);
|
2024-01-27 14:46:50 +00:00
|
|
|
}
|
2022-11-01 23:02:45 +00:00
|
|
|
ExprKind::If(ref cond, ref then, ref else_opt) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_expr(cond));
|
|
|
|
try_visit!(visitor.visit_expr(then));
|
|
|
|
visit_opt!(visitor, visit_expr, else_opt);
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
ExprKind::Loop(ref block, ref opt_label, _, _) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
visit_opt!(visitor, visit_label, opt_label);
|
|
|
|
try_visit!(visitor.visit_block(block));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
ExprKind::Match(ref subexpression, arms, _) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_expr(subexpression));
|
2022-11-01 23:02:45 +00:00
|
|
|
walk_list!(visitor, visit_arm, arms);
|
|
|
|
}
|
|
|
|
ExprKind::Closure(&Closure {
|
2023-01-22 18:00:33 +00:00
|
|
|
def_id,
|
2022-11-01 23:02:45 +00:00
|
|
|
binder: _,
|
|
|
|
bound_generic_params,
|
|
|
|
fn_decl,
|
|
|
|
body,
|
|
|
|
capture_clause: _,
|
|
|
|
fn_decl_span: _,
|
2022-11-09 15:09:28 +00:00
|
|
|
fn_arg_span: _,
|
2023-12-22 21:29:12 +00:00
|
|
|
kind: _,
|
2022-12-20 16:15:55 +00:00
|
|
|
constness: _,
|
2022-11-01 23:02:45 +00:00
|
|
|
}) => {
|
|
|
|
walk_list!(visitor, visit_generic_param, bound_generic_params);
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_fn(FnKind::Closure, fn_decl, body, expression.span, def_id));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
ExprKind::Block(ref block, ref opt_label) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
visit_opt!(visitor, visit_label, opt_label);
|
|
|
|
try_visit!(visitor.visit_block(block));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
ExprKind::Assign(ref lhs, ref rhs, _) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_expr(rhs));
|
|
|
|
try_visit!(visitor.visit_expr(lhs));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
ExprKind::AssignOp(_, ref left_expression, ref right_expression) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_expr(right_expression));
|
|
|
|
try_visit!(visitor.visit_expr(left_expression));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
ExprKind::Field(ref subexpression, ident) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_expr(subexpression));
|
|
|
|
try_visit!(visitor.visit_ident(ident));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
2023-08-03 19:43:17 +00:00
|
|
|
ExprKind::Index(ref main_expression, ref index_expression, _) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_expr(main_expression));
|
|
|
|
try_visit!(visitor.visit_expr(index_expression));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
ExprKind::Path(ref qpath) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_qpath(qpath, expression.hir_id, expression.span));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
ExprKind::Break(ref destination, ref opt_expr) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
visit_opt!(visitor, visit_label, &destination.label);
|
|
|
|
visit_opt!(visitor, visit_expr, opt_expr);
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
ExprKind::Continue(ref destination) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
visit_opt!(visitor, visit_label, &destination.label);
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
ExprKind::Ret(ref optional_expression) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
visit_opt!(visitor, visit_expr, optional_expression);
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
ExprKind::Become(ref expr) => try_visit!(visitor.visit_expr(expr)),
|
2022-11-01 23:02:45 +00:00
|
|
|
ExprKind::InlineAsm(ref asm) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_inline_asm(asm, expression.hir_id));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
2022-09-11 07:37:49 +00:00
|
|
|
ExprKind::OffsetOf(ref container, ref fields) => {
|
2025-01-18 22:45:41 +00:00
|
|
|
try_visit!(visitor.visit_ty_unambig(container));
|
2022-09-11 07:37:49 +00:00
|
|
|
walk_list!(visitor, visit_ident, fields.iter().copied());
|
|
|
|
}
|
2022-11-01 23:02:45 +00:00
|
|
|
ExprKind::Yield(ref subexpression, _) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_expr(subexpression));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
2024-09-13 18:00:10 +00:00
|
|
|
ExprKind::UnsafeBinderCast(_kind, expr, ty) => {
|
|
|
|
try_visit!(visitor.visit_expr(expr));
|
2025-01-18 22:45:41 +00:00
|
|
|
visit_opt!(visitor, visit_ty_unambig, ty);
|
2024-09-13 18:00:10 +00:00
|
|
|
}
|
2025-02-01 10:06:35 +00:00
|
|
|
ExprKind::Lit(lit) => try_visit!(visitor.visit_lit(expression.hir_id, lit, false)),
|
|
|
|
ExprKind::Err(_) => {}
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
V::Result::output()
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_expr_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v ExprField<'v>) -> V::Result {
|
|
|
|
try_visit!(visitor.visit_id(field.hir_id));
|
|
|
|
try_visit!(visitor.visit_ident(field.ident));
|
2022-11-29 11:01:17 +00:00
|
|
|
visitor.visit_expr(field.expr)
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
2025-01-18 23:01:47 +00:00
|
|
|
/// We track whether an infer var is from a [`Ty`], [`ConstArg`], or [`GenericArg`] so that
|
|
|
|
/// HIR visitors overriding [`Visitor::visit_infer`] can determine what kind of infer is being visited
|
2025-01-11 19:12:36 +00:00
|
|
|
pub enum InferKind<'hir> {
|
|
|
|
Ty(&'hir Ty<'hir>),
|
|
|
|
Const(&'hir ConstArg<'hir>),
|
|
|
|
Ambig(&'hir InferArg),
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_generic_arg<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
generic_arg: &'v GenericArg<'v>,
|
|
|
|
) -> V::Result {
|
|
|
|
match generic_arg {
|
|
|
|
GenericArg::Lifetime(lt) => visitor.visit_lifetime(lt),
|
|
|
|
GenericArg::Type(ty) => visitor.visit_ty(ty),
|
|
|
|
GenericArg::Const(ct) => visitor.visit_const_arg(ct),
|
|
|
|
GenericArg::Infer(inf) => visitor.visit_infer(inf.hir_id, inf.span, InferKind::Ambig(inf)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_unambig_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Result {
|
|
|
|
match typ.try_as_ambig_ty() {
|
|
|
|
Some(ambig_ty) => visitor.visit_ty(ambig_ty),
|
|
|
|
None => {
|
|
|
|
try_visit!(visitor.visit_id(typ.hir_id));
|
|
|
|
visitor.visit_infer(typ.hir_id, typ.span, InferKind::Ty(typ))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v, AmbigArg>) -> V::Result {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_id(typ.hir_id));
|
2022-11-01 23:02:45 +00:00
|
|
|
|
|
|
|
match typ.kind {
|
2025-01-18 22:45:41 +00:00
|
|
|
TyKind::Slice(ref ty) => try_visit!(visitor.visit_ty_unambig(ty)),
|
|
|
|
TyKind::Ptr(ref mutable_type) => try_visit!(visitor.visit_ty_unambig(mutable_type.ty)),
|
2022-12-28 17:06:11 +00:00
|
|
|
TyKind::Ref(ref lifetime, ref mutable_type) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_lifetime(lifetime));
|
2025-01-18 22:45:41 +00:00
|
|
|
try_visit!(visitor.visit_ty_unambig(mutable_type.ty));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
TyKind::Never => {}
|
|
|
|
TyKind::Tup(tuple_element_types) => {
|
2025-01-18 22:45:41 +00:00
|
|
|
walk_list!(visitor, visit_ty_unambig, tuple_element_types);
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
TyKind::BareFn(ref function_declaration) => {
|
|
|
|
walk_list!(visitor, visit_generic_param, function_declaration.generic_params);
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_fn_decl(function_declaration.decl));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
2024-12-10 20:10:56 +00:00
|
|
|
TyKind::UnsafeBinder(ref unsafe_binder) => {
|
|
|
|
walk_list!(visitor, visit_generic_param, unsafe_binder.generic_params);
|
2025-01-18 22:45:41 +00:00
|
|
|
try_visit!(visitor.visit_ty_unambig(unsafe_binder.inner_ty));
|
2024-12-10 20:10:56 +00:00
|
|
|
}
|
2022-11-01 23:02:45 +00:00
|
|
|
TyKind::Path(ref qpath) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_qpath(qpath, typ.hir_id, typ.span));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
2024-08-20 00:48:43 +00:00
|
|
|
TyKind::OpaqueDef(opaque) => {
|
2024-08-10 03:43:30 +00:00
|
|
|
try_visit!(visitor.visit_opaque_ty(opaque));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
2024-12-11 22:18:39 +00:00
|
|
|
TyKind::TraitAscription(bounds) => {
|
|
|
|
walk_list!(visitor, visit_param_bound, bounds);
|
|
|
|
}
|
2022-11-01 23:02:45 +00:00
|
|
|
TyKind::Array(ref ty, ref length) => {
|
2025-01-18 22:45:41 +00:00
|
|
|
try_visit!(visitor.visit_ty_unambig(ty));
|
|
|
|
try_visit!(visitor.visit_const_arg_unambig(length));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
2025-01-10 23:20:31 +00:00
|
|
|
TyKind::TraitObject(bounds, ref lifetime) => {
|
2024-10-13 13:16:03 +00:00
|
|
|
for bound in bounds {
|
2024-02-23 13:39:57 +00:00
|
|
|
try_visit!(visitor.visit_poly_trait_ref(bound));
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_lifetime(lifetime));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
TyKind::Typeof(ref expression) => try_visit!(visitor.visit_anon_const(expression)),
|
2025-01-11 19:12:36 +00:00
|
|
|
TyKind::InferDelegation(..) | TyKind::Err(_) => {}
|
2023-01-31 11:54:06 +00:00
|
|
|
TyKind::Pat(ty, pat) => {
|
2025-01-18 22:45:41 +00:00
|
|
|
try_visit!(visitor.visit_ty_unambig(ty));
|
2023-02-02 13:57:36 +00:00
|
|
|
try_visit!(visitor.visit_pattern_type_pattern(pat));
|
2023-01-31 11:54:06 +00:00
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
V::Result::output()
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2025-01-11 19:12:36 +00:00
|
|
|
pub fn walk_const_arg<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
const_arg: &'v ConstArg<'v>,
|
|
|
|
) -> V::Result {
|
|
|
|
match const_arg.try_as_ambig_ct() {
|
|
|
|
Some(ambig_ct) => visitor.visit_const_arg(ambig_ct),
|
|
|
|
None => {
|
|
|
|
try_visit!(visitor.visit_id(const_arg.hir_id));
|
|
|
|
visitor.visit_infer(const_arg.hir_id, const_arg.span(), InferKind::Const(const_arg))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_ambig_const_arg<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
const_arg: &'v ConstArg<'v, AmbigArg>,
|
|
|
|
) -> V::Result {
|
|
|
|
try_visit!(visitor.visit_id(const_arg.hir_id));
|
|
|
|
match &const_arg.kind {
|
|
|
|
ConstArgKind::Path(qpath) => visitor.visit_qpath(qpath, const_arg.hir_id, qpath.span()),
|
|
|
|
ConstArgKind::Anon(anon) => visitor.visit_anon_const(*anon),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_generic_param<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
param: &'v GenericParam<'v>,
|
|
|
|
) -> V::Result {
|
|
|
|
try_visit!(visitor.visit_id(param.hir_id));
|
2018-06-01 22:23:48 +00:00
|
|
|
match param.name {
|
2025-01-01 16:55:10 +00:00
|
|
|
ParamName::Plain(ident) | ParamName::Error(ident) => try_visit!(visitor.visit_ident(ident)),
|
|
|
|
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 { .. } => {}
|
2025-01-11 19:12:36 +00:00
|
|
|
GenericParamKind::Type { ref default, .. } => {
|
2025-01-18 22:45:41 +00:00
|
|
|
visit_opt!(visitor, visit_ty_unambig, default)
|
2025-01-11 19:12:36 +00:00
|
|
|
}
|
2024-10-20 20:22:11 +00:00
|
|
|
GenericParamKind::Const { ref ty, ref default, synthetic: _ } => {
|
2025-01-18 22:45:41 +00:00
|
|
|
try_visit!(visitor.visit_ty_unambig(ty));
|
2025-02-20 18:28:48 +00:00
|
|
|
if let Some(default) = default {
|
2024-03-18 15:21:06 +00:00
|
|
|
try_visit!(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
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
V::Result::output()
|
2017-10-16 19:07:26 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_const_param_default<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
2024-06-08 03:26:50 +00:00
|
|
|
ct: &'v ConstArg<'v>,
|
2024-02-18 08:12:44 +00:00
|
|
|
) -> V::Result {
|
2025-01-18 22:45:41 +00:00
|
|
|
visitor.visit_const_arg_unambig(ct)
|
2021-03-01 11:50:09 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics<'v>) -> V::Result {
|
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);
|
2024-02-18 08:12:44 +00:00
|
|
|
V::Result::output()
|
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>,
|
2024-02-18 08:12:44 +00:00
|
|
|
) -> V::Result {
|
2024-11-25 08:38:35 +00:00
|
|
|
let &WherePredicate { hir_id, kind, span: _ } = predicate;
|
|
|
|
try_visit!(visitor.visit_id(hir_id));
|
|
|
|
match *kind {
|
|
|
|
WherePredicateKind::BoundPredicate(WhereBoundPredicate {
|
2019-12-22 22:42:04 +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: _,
|
2019-12-22 22:42:04 +00:00
|
|
|
}) => {
|
2025-01-18 22:45:41 +00:00
|
|
|
try_visit!(visitor.visit_ty_unambig(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
|
|
|
}
|
2024-11-25 08:38:35 +00:00
|
|
|
WherePredicateKind::RegionPredicate(WhereRegionPredicate {
|
2022-09-05 15:21:19 +00:00
|
|
|
ref lifetime,
|
|
|
|
bounds,
|
|
|
|
in_where_clause: _,
|
|
|
|
}) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(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
|
|
|
}
|
2024-11-25 08:38:35 +00:00
|
|
|
WherePredicateKind::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty }) => {
|
2025-01-18 22:45:41 +00:00
|
|
|
try_visit!(visitor.visit_ty_unambig(lhs_ty));
|
|
|
|
try_visit!(visitor.visit_ty_unambig(rhs_ty));
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
V::Result::output()
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_fn_decl<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
function_declaration: &'v FnDecl<'v>,
|
|
|
|
) -> V::Result {
|
2025-01-18 22:45:41 +00:00
|
|
|
walk_list!(visitor, visit_ty_unambig, function_declaration.inputs);
|
2022-10-26 17:40:34 +00:00
|
|
|
visitor.visit_fn_ret_ty(&function_declaration.output)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FnRetTy<'v>) -> V::Result {
|
|
|
|
if let FnRetTy::Return(output_ty) = *ret_ty {
|
2025-01-18 22:45:41 +00:00
|
|
|
try_visit!(visitor.visit_ty_unambig(output_ty));
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
V::Result::output()
|
2015-09-03 10:35:41 +00:00
|
|
|
}
|
2015-07-31 07:04:06 +00:00
|
|
|
|
2019-12-22 22:42:04 +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>,
|
2019-12-22 22:42:04 +00:00
|
|
|
body_id: BodyId,
|
2023-01-22 18:00:33 +00:00
|
|
|
_: LocalDefId,
|
2024-02-18 08:12:44 +00:00
|
|
|
) -> V::Result {
|
|
|
|
try_visit!(visitor.visit_fn_decl(function_declaration));
|
|
|
|
try_visit!(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
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'v>) -> V::Result {
|
2022-11-01 23:02:45 +00:00
|
|
|
match function_kind {
|
|
|
|
FnKind::ItemFn(_, generics, ..) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_generics(generics));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
FnKind::Closure | FnKind::Method(..) => {}
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
V::Result::output()
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_use<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
path: &'v UsePath<'v>,
|
|
|
|
hir_id: HirId,
|
|
|
|
) -> V::Result {
|
2022-11-25 14:39:38 +00:00
|
|
|
let UsePath { segments, ref res, span } = *path;
|
|
|
|
for &res in res {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_path(&Path { segments, res, span }, hir_id));
|
2022-11-25 14:39:38 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
V::Result::output()
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_trait_item<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
trait_item: &'v TraitItem<'v>,
|
|
|
|
) -> V::Result {
|
2022-08-01 17:46:10 +00:00
|
|
|
// N.B., deliberately force a compilation error if/when new fields are added.
|
2022-10-27 03:02:18 +00:00
|
|
|
let TraitItem { ident, generics, ref defaultness, ref kind, span, owner_id: _ } = *trait_item;
|
2022-08-01 17:46:10 +00:00
|
|
|
let hir_id = trait_item.hir_id();
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_ident(ident));
|
|
|
|
try_visit!(visitor.visit_generics(&generics));
|
|
|
|
try_visit!(visitor.visit_defaultness(&defaultness));
|
|
|
|
try_visit!(visitor.visit_id(hir_id));
|
2022-08-01 17:46:10 +00:00
|
|
|
match *kind {
|
2016-12-21 10:32:59 +00:00
|
|
|
TraitItemKind::Const(ref ty, default) => {
|
2025-01-18 22:45:41 +00:00
|
|
|
try_visit!(visitor.visit_ty_unambig(ty));
|
2024-02-18 08:12:44 +00:00
|
|
|
visit_opt!(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)) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_fn_decl(sig.decl));
|
|
|
|
walk_list!(visitor, visit_ident, param_names.iter().copied());
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2020-03-05 15:57:34 +00:00
|
|
|
TraitItemKind::Fn(ref sig, TraitFn::Provided(body_id)) => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_fn(
|
2023-01-22 18:00:33 +00:00
|
|
|
FnKind::Method(ident, sig),
|
|
|
|
sig.decl,
|
|
|
|
body_id,
|
|
|
|
span,
|
|
|
|
trait_item.owner_id.def_id,
|
2024-02-18 08:12:44 +00:00
|
|
|
));
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2019-11-30 23:17:43 +00:00
|
|
|
TraitItemKind::Type(bounds, ref default) => {
|
2018-05-28 14:23:16 +00:00
|
|
|
walk_list!(visitor, visit_param_bound, bounds);
|
2025-01-18 22:45:41 +00:00
|
|
|
visit_opt!(visitor, visit_ty_unambig, default);
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
V::Result::output()
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_trait_item_ref<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
trait_item_ref: &'v TraitItemRef,
|
|
|
|
) -> V::Result {
|
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;
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_nested_trait_item(id));
|
|
|
|
try_visit!(visitor.visit_ident(ident));
|
|
|
|
visitor.visit_associated_item_kind(kind)
|
2016-12-04 02:21:06 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_impl_item<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
impl_item: &'v ImplItem<'v>,
|
|
|
|
) -> V::Result {
|
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 {
|
2022-10-27 03:02:18 +00:00
|
|
|
owner_id: _,
|
2022-03-12 18:36:11 +00:00
|
|
|
ident,
|
|
|
|
ref generics,
|
|
|
|
ref kind,
|
|
|
|
ref defaultness,
|
|
|
|
span: _,
|
|
|
|
vis_span: _,
|
|
|
|
} = *impl_item;
|
2016-11-14 16:00:02 +00:00
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_ident(ident));
|
|
|
|
try_visit!(visitor.visit_generics(generics));
|
|
|
|
try_visit!(visitor.visit_defaultness(defaultness));
|
|
|
|
try_visit!(visitor.visit_id(impl_item.hir_id()));
|
2019-09-26 15:38:13 +00:00
|
|
|
match *kind {
|
2016-12-21 10:32:59 +00:00
|
|
|
ImplItemKind::Const(ref ty, body) => {
|
2025-01-18 22:45:41 +00:00
|
|
|
try_visit!(visitor.visit_ty_unambig(ty));
|
2024-02-18 08:12:44 +00:00
|
|
|
visitor.visit_nested_body(body)
|
|
|
|
}
|
|
|
|
ImplItemKind::Fn(ref sig, body_id) => visitor.visit_fn(
|
|
|
|
FnKind::Method(impl_item.ident, sig),
|
|
|
|
sig.decl,
|
|
|
|
body_id,
|
|
|
|
impl_item.span,
|
|
|
|
impl_item.owner_id.def_id,
|
|
|
|
),
|
2025-01-18 22:45:41 +00:00
|
|
|
ImplItemKind::Type(ref ty) => visitor.visit_ty_unambig(ty),
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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,
|
2024-02-18 08:12:44 +00:00
|
|
|
) -> V::Result {
|
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;
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_nested_foreign_item(id));
|
|
|
|
visitor.visit_ident(ident)
|
2020-11-11 20:57:54 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
impl_item_ref: &'v ImplItemRef,
|
|
|
|
) -> V::Result {
|
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;
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_nested_impl_item(id));
|
|
|
|
try_visit!(visitor.visit_ident(ident));
|
|
|
|
visitor.visit_associated_item_kind(kind)
|
2016-11-10 14:47:00 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_trait_ref<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
trait_ref: &'v TraitRef<'v>,
|
|
|
|
) -> V::Result {
|
|
|
|
try_visit!(visitor.visit_id(trait_ref.hir_ref_id));
|
2022-11-29 11:01:17 +00:00
|
|
|
visitor.visit_path(trait_ref.path, trait_ref.hir_ref_id)
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_param_bound<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
bound: &'v GenericBound<'v>,
|
|
|
|
) -> V::Result {
|
2022-11-01 23:02:45 +00:00
|
|
|
match *bound {
|
2024-10-13 13:16:03 +00:00
|
|
|
GenericBound::Trait(ref typ) => visitor.visit_poly_trait_ref(typ),
|
2022-11-01 23:02:45 +00:00
|
|
|
GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime),
|
2024-06-05 20:18:52 +00:00
|
|
|
GenericBound::Use(args, _) => {
|
|
|
|
walk_list!(visitor, visit_precise_capturing_arg, args);
|
|
|
|
V::Result::output()
|
|
|
|
}
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-04 14:48:47 +00:00
|
|
|
pub fn walk_precise_capturing_arg<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
arg: &'v PreciseCapturingArg<'v>,
|
|
|
|
) -> V::Result {
|
|
|
|
match *arg {
|
|
|
|
PreciseCapturingArg::Lifetime(lt) => visitor.visit_lifetime(lt),
|
2024-04-04 18:46:26 +00:00
|
|
|
PreciseCapturingArg::Param(param) => visitor.visit_id(param.hir_id),
|
2024-04-04 14:48:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_poly_trait_ref<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
trait_ref: &'v PolyTraitRef<'v>,
|
|
|
|
) -> V::Result {
|
2022-11-01 23:02:45 +00:00
|
|
|
walk_list!(visitor, visit_generic_param, trait_ref.bound_generic_params);
|
2024-02-18 08:12:44 +00:00
|
|
|
visitor.visit_trait_ref(&trait_ref.trait_ref)
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
|
2024-08-10 03:43:30 +00:00
|
|
|
pub fn walk_opaque_ty<'v, V: Visitor<'v>>(visitor: &mut V, opaque: &'v OpaqueTy<'v>) -> V::Result {
|
2024-08-20 00:48:43 +00:00
|
|
|
let &OpaqueTy { hir_id, def_id: _, bounds, origin: _, span: _ } = opaque;
|
2024-08-10 03:43:30 +00:00
|
|
|
try_visit!(visitor.visit_id(hir_id));
|
|
|
|
walk_list!(visitor, visit_param_bound, bounds);
|
|
|
|
V::Result::output()
|
|
|
|
}
|
|
|
|
|
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>,
|
2024-02-18 08:12:44 +00:00
|
|
|
) -> V::Result {
|
|
|
|
visit_opt!(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());
|
2024-02-18 08:12:44 +00:00
|
|
|
V::Result::output()
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2024-08-24 17:22:48 +00:00
|
|
|
pub fn walk_field_def<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
FieldDef { hir_id, ident, ty, default, span: _, vis_span: _, def_id: _, safety: _ }: &'v FieldDef<'v>,
|
|
|
|
) -> V::Result {
|
|
|
|
try_visit!(visitor.visit_id(*hir_id));
|
|
|
|
try_visit!(visitor.visit_ident(*ident));
|
|
|
|
visit_opt!(visitor, visit_anon_const, default);
|
2025-01-18 22:45:41 +00:00
|
|
|
visitor.visit_ty_unambig(*ty)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2022-11-01 23:02:45 +00:00
|
|
|
pub fn walk_enum_def<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
enum_definition: &'v EnumDef<'v>,
|
2024-02-18 08:12:44 +00:00
|
|
|
) -> V::Result {
|
2022-11-01 23:02:45 +00:00
|
|
|
walk_list!(visitor, visit_variant, enum_definition.variants);
|
2024-02-18 08:12:44 +00:00
|
|
|
V::Result::output()
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V, variant: &'v Variant<'v>) -> V::Result {
|
|
|
|
try_visit!(visitor.visit_ident(variant.ident));
|
|
|
|
try_visit!(visitor.visit_id(variant.hir_id));
|
|
|
|
try_visit!(visitor.visit_variant_data(&variant.data));
|
|
|
|
visit_opt!(visitor, visit_anon_const, &variant.disr_expr);
|
|
|
|
V::Result::output()
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_label<'v, V: Visitor<'v>>(visitor: &mut V, label: &'v Label) -> V::Result {
|
|
|
|
visitor.visit_ident(label.ident)
|
2021-12-23 09:01:51 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_inf<'v, V: Visitor<'v>>(visitor: &mut V, inf: &'v InferArg) -> V::Result {
|
|
|
|
visitor.visit_id(inf.hir_id)
|
2018-05-17 18:28:50 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) -> V::Result {
|
|
|
|
try_visit!(visitor.visit_id(lifetime.hir_id));
|
|
|
|
visitor.visit_ident(lifetime.ident)
|
2022-05-23 01:34:37 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_qpath<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
qpath: &'v QPath<'v>,
|
|
|
|
id: HirId,
|
|
|
|
) -> V::Result {
|
2022-11-01 23:02:45 +00:00
|
|
|
match *qpath {
|
|
|
|
QPath::Resolved(ref maybe_qself, ref path) => {
|
2025-01-18 22:45:41 +00:00
|
|
|
visit_opt!(visitor, visit_ty_unambig, maybe_qself);
|
2022-11-01 23:02:45 +00:00
|
|
|
visitor.visit_path(path, id)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2022-11-01 23:02:45 +00:00
|
|
|
QPath::TypeRelative(ref qself, ref segment) => {
|
2025-01-18 22:45:41 +00:00
|
|
|
try_visit!(visitor.visit_ty_unambig(qself));
|
2024-02-18 08:12:44 +00:00
|
|
|
visitor.visit_path_segment(segment)
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
QPath::LangItem(..) => V::Result::output(),
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &Path<'v>) -> V::Result {
|
|
|
|
walk_list!(visitor, visit_path_segment, path.segments);
|
|
|
|
V::Result::output()
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_path_segment<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
segment: &'v PathSegment<'v>,
|
|
|
|
) -> V::Result {
|
|
|
|
try_visit!(visitor.visit_ident(segment.ident));
|
|
|
|
try_visit!(visitor.visit_id(segment.hir_id));
|
|
|
|
visit_opt!(visitor, visit_generic_args, segment.args);
|
|
|
|
V::Result::output()
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_generic_args<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
generic_args: &'v GenericArgs<'v>,
|
|
|
|
) -> V::Result {
|
2022-11-01 23:02:45 +00:00
|
|
|
walk_list!(visitor, visit_generic_arg, generic_args.args);
|
2024-05-27 21:53:46 +00:00
|
|
|
walk_list!(visitor, visit_assoc_item_constraint, generic_args.constraints);
|
2024-02-18 08:12:44 +00:00
|
|
|
V::Result::output()
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
|
2024-05-27 21:53:46 +00:00
|
|
|
pub fn walk_assoc_item_constraint<'v, V: Visitor<'v>>(
|
2022-11-01 23:02:45 +00:00
|
|
|
visitor: &mut V,
|
2024-05-27 21:53:46 +00:00
|
|
|
constraint: &'v AssocItemConstraint<'v>,
|
2024-02-18 08:12:44 +00:00
|
|
|
) -> V::Result {
|
2024-05-27 21:53:46 +00:00
|
|
|
try_visit!(visitor.visit_id(constraint.hir_id));
|
|
|
|
try_visit!(visitor.visit_ident(constraint.ident));
|
|
|
|
try_visit!(visitor.visit_generic_args(constraint.gen_args));
|
|
|
|
match constraint.kind {
|
|
|
|
AssocItemConstraintKind::Equality { ref term } => match term {
|
2025-02-20 18:28:48 +00:00
|
|
|
Term::Ty(ty) => try_visit!(visitor.visit_ty_unambig(ty)),
|
|
|
|
Term::Const(c) => try_visit!(visitor.visit_const_arg_unambig(c)),
|
2022-11-01 23:02:45 +00:00
|
|
|
},
|
2024-05-27 21:53:46 +00:00
|
|
|
AssocItemConstraintKind::Bound { bounds } => {
|
|
|
|
walk_list!(visitor, visit_param_bound, bounds)
|
|
|
|
}
|
2018-08-30 04:18:11 +00:00
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
V::Result::output()
|
2015-07-31 07:04:06 +00:00
|
|
|
}
|
2016-03-29 06:32:58 +00:00
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_associated_item_kind<'v, V: Visitor<'v>>(_: &mut V, _: &'v AssocItemKind) -> V::Result {
|
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.
|
2024-02-18 08:12:44 +00:00
|
|
|
V::Result::output()
|
2016-11-14 16:00:02 +00:00
|
|
|
}
|
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_defaultness<'v, V: Visitor<'v>>(_: &mut V, _: &'v Defaultness) -> V::Result {
|
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.
|
2024-02-18 08:12:44 +00:00
|
|
|
V::Result::output()
|
2016-11-14 16:00:02 +00:00
|
|
|
}
|
2022-11-01 23:02:45 +00:00
|
|
|
|
2024-02-18 08:12:44 +00:00
|
|
|
pub fn walk_inline_asm<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
asm: &'v InlineAsm<'v>,
|
|
|
|
id: HirId,
|
|
|
|
) -> V::Result {
|
2022-11-01 23:02:45 +00:00
|
|
|
for (op, op_sp) in asm.operands {
|
|
|
|
match op {
|
|
|
|
InlineAsmOperand::In { expr, .. } | InlineAsmOperand::InOut { expr, .. } => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_expr(expr));
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
InlineAsmOperand::Out { expr, .. } => {
|
2024-02-18 08:12:44 +00:00
|
|
|
visit_opt!(visitor, visit_expr, expr);
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
|
2024-02-18 08:12:44 +00:00
|
|
|
try_visit!(visitor.visit_expr(in_expr));
|
|
|
|
visit_opt!(visitor, visit_expr, out_expr);
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
2025-02-17 16:09:46 +00:00
|
|
|
InlineAsmOperand::Const { anon_const, .. } => {
|
2025-02-26 16:28:37 +00:00
|
|
|
try_visit!(visitor.visit_inline_const(anon_const));
|
2024-02-18 08:12:44 +00:00
|
|
|
}
|
2025-02-17 16:09:46 +00:00
|
|
|
InlineAsmOperand::SymFn { expr, .. } => {
|
|
|
|
try_visit!(visitor.visit_expr(expr));
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
InlineAsmOperand::SymStatic { path, .. } => {
|
|
|
|
try_visit!(visitor.visit_qpath(path, id, *op_sp));
|
|
|
|
}
|
2023-12-25 20:53:01 +00:00
|
|
|
InlineAsmOperand::Label { block } => try_visit!(visitor.visit_block(block)),
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|
|
|
|
}
|
2024-02-18 08:12:44 +00:00
|
|
|
V::Result::output()
|
2022-11-01 23:02:45 +00:00
|
|
|
}
|