2015-07-31 02:04:06 -05:00
|
|
|
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2016-11-02 17:22:59 -05:00
|
|
|
//! HIR walker for walking the contents of nodes.
|
|
|
|
//!
|
|
|
|
//! **For an overview of the visitor strategy, see the docs on the
|
|
|
|
//! `super::itemlikevisit::ItemLikeVisitor` trait.**
|
|
|
|
//!
|
|
|
|
//! If you have decided to use this visitor, here are some general
|
|
|
|
//! notes on how to do it:
|
|
|
|
//!
|
|
|
|
//! Each overridden visit method has full control over what
|
2015-07-31 02:04:06 -05:00
|
|
|
//! happens with its node, it can do its own traversal of the node's children,
|
2015-12-10 03:52:32 -06:00
|
|
|
//! call `intravisit::walk_*` to apply the default traversal algorithm, or prevent
|
2015-07-31 02:04:06 -05:00
|
|
|
//! deeper traversal by doing nothing.
|
|
|
|
//!
|
2015-11-17 20:44:39 -06:00
|
|
|
//! When visiting the HIR, the contents of nested items are NOT visited
|
|
|
|
//! by default. This is different from the AST visitor, which does a deep walk.
|
|
|
|
//! Hence this module is called `intravisit`; see the method `visit_nested_item`
|
|
|
|
//! for more details.
|
2015-07-31 02:04:06 -05:00
|
|
|
//!
|
2015-11-17 20:44:39 -06:00
|
|
|
//! Note: it is an important invariant that the default visitor walks
|
|
|
|
//! the body of a function in "execution order" (more concretely,
|
|
|
|
//! reverse post-order with respect to the CFG implied by the AST),
|
|
|
|
//! meaning that if AST node A may execute before AST node B, then A
|
|
|
|
//! is visited first. The borrow checker in particular relies on this
|
|
|
|
//! property.
|
2015-07-31 02:04:06 -05:00
|
|
|
|
|
|
|
use syntax::abi::Abi;
|
2015-12-01 11:38:40 -06:00
|
|
|
use syntax::ast::{NodeId, CRATE_NODE_ID, Name, Attribute};
|
2016-06-21 17:08:13 -05:00
|
|
|
use syntax::codemap::Spanned;
|
|
|
|
use syntax_pos::Span;
|
2015-09-28 16:23:54 -05:00
|
|
|
use hir::*;
|
2016-11-09 15:45:26 -06:00
|
|
|
use hir::map::Map;
|
2016-11-02 17:22:59 -05:00
|
|
|
use super::itemlikevisit::DeepVisitor;
|
2015-07-31 02:04:06 -05:00
|
|
|
|
2016-03-29 04:12:01 -05:00
|
|
|
use std::cmp;
|
|
|
|
use std::u32;
|
|
|
|
|
2015-07-31 02:04:06 -05:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
|
|
|
pub enum FnKind<'a> {
|
|
|
|
/// fn foo() or extern "Abi" fn foo()
|
2016-03-25 01:08:11 -05:00
|
|
|
ItemFn(Name, &'a Generics, Unsafety, Constness, Abi, &'a Visibility, &'a [Attribute]),
|
2015-07-31 02:04:06 -05:00
|
|
|
|
|
|
|
/// fn foo(&self)
|
2016-03-25 01:08:11 -05:00
|
|
|
Method(Name, &'a MethodSig, Option<&'a Visibility>, &'a [Attribute]),
|
2015-07-31 02:04:06 -05:00
|
|
|
|
2015-09-28 16:23:54 -05:00
|
|
|
/// |x, y| {}
|
2016-01-25 07:11:51 -06:00
|
|
|
Closure(&'a [Attribute]),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> FnKind<'a> {
|
|
|
|
pub fn attrs(&self) -> &'a [Attribute] {
|
|
|
|
match *self {
|
2016-08-26 11:23:42 -05:00
|
|
|
FnKind::ItemFn(.., attrs) => attrs,
|
|
|
|
FnKind::Method(.., attrs) => attrs,
|
2016-01-25 07:11:51 -06:00
|
|
|
FnKind::Closure(attrs) => attrs,
|
|
|
|
}
|
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Each method of the Visitor trait is a hook to be potentially
|
|
|
|
/// overridden. Each method's default implementation recursively visits
|
|
|
|
/// the substructure of the input via the corresponding `walk` method;
|
2015-12-10 03:52:32 -06:00
|
|
|
/// e.g. the `visit_mod` method by default calls `intravisit::walk_mod`.
|
2015-07-31 02:04:06 -05:00
|
|
|
///
|
2015-11-17 20:44:39 -06:00
|
|
|
/// Note that this visitor does NOT visit nested items by default
|
|
|
|
/// (this is why the module is called `intravisit`, to distinguish it
|
|
|
|
/// from the AST's `visit` module, which acts differently). If you
|
|
|
|
/// simply want to visit all items in the crate in some order, you
|
2015-11-17 16:32:12 -06:00
|
|
|
/// should call `Crate::visit_all_items`. Otherwise, see the comment
|
|
|
|
/// on `visit_nested_item` for details on how to visit nested items.
|
|
|
|
///
|
2015-07-31 02:04:06 -05:00
|
|
|
/// If you want to ensure that your code handles every variant
|
|
|
|
/// explicitly, you need to override each method. (And you also need
|
|
|
|
/// to monitor future changes to `Visitor` in case a new method with a
|
|
|
|
/// new default implementation gets introduced.)
|
|
|
|
pub trait Visitor<'v> : Sized {
|
2015-11-17 16:32:12 -06:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Nested items.
|
|
|
|
|
2016-11-09 15:45:26 -06:00
|
|
|
/// The default versions of the `visit_nested_XXX` routines invoke
|
|
|
|
/// this method to get a map to use; if they get back `None`, they
|
|
|
|
/// just skip nested things. Otherwise, they will lookup the
|
|
|
|
/// nested item-like things in the map and visit it. So the best
|
|
|
|
/// way to implement a nested visitor is to override this method
|
|
|
|
/// to return a `Map`; one advantage of this is that if we add
|
|
|
|
/// more types of nested things in the future, they will
|
|
|
|
/// automatically work.
|
|
|
|
///
|
|
|
|
/// **If for some reason you want the nested behavior, but don't
|
|
|
|
/// have a `Map` are your disposal:** then you should override the
|
|
|
|
/// `visit_nested_XXX` methods, and override this method to
|
|
|
|
/// `panic!()`. This way, if a new `visit_nested_XXX` variant is
|
|
|
|
/// added in the future, we will see the panic in your code and
|
|
|
|
/// fix it appropriately.
|
|
|
|
fn nested_visit_map(&mut self) -> Option<&Map<'v>> {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Invoked when a nested item is encountered. By default does
|
|
|
|
/// nothing unless you override `nested_visit_map` to return
|
|
|
|
/// `Some(_)`, in which case it will walk the item. **You probably
|
|
|
|
/// don't want to override this method** -- instead, override
|
|
|
|
/// `nested_visit_map` or use the "shallow" or "deep" visit
|
|
|
|
/// patterns described on `itemlikevisit::ItemLikeVisitor`. The only
|
|
|
|
/// reason to override this method is if you want a nested pattern
|
|
|
|
/// but cannot supply a `Map`; see `nested_visit_map` for advice.
|
2015-11-17 16:32:12 -06:00
|
|
|
#[allow(unused_variables)]
|
|
|
|
fn visit_nested_item(&mut self, id: ItemId) {
|
2016-11-09 15:45:26 -06:00
|
|
|
let opt_item = self.nested_visit_map()
|
|
|
|
.map(|map| map.expect_item(id.id));
|
|
|
|
if let Some(item) = opt_item {
|
|
|
|
self.visit_item(item);
|
|
|
|
}
|
2015-11-17 16:32:12 -06:00
|
|
|
}
|
|
|
|
|
2016-11-09 15:45:26 -06:00
|
|
|
/// Like `visit_nested_item()`, but for impl items. See
|
|
|
|
/// `visit_nested_item()` for advice on when to override this
|
|
|
|
/// method.
|
2016-11-02 17:25:31 -05:00
|
|
|
#[allow(unused_variables)]
|
|
|
|
fn visit_nested_impl_item(&mut self, id: ImplItemId) {
|
2016-11-09 15:45:26 -06:00
|
|
|
let opt_item = self.nested_visit_map()
|
|
|
|
.map(|map| map.impl_item(id));
|
|
|
|
if let Some(item) = opt_item {
|
|
|
|
self.visit_impl_item(item);
|
|
|
|
}
|
2016-11-02 17:25:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Visit the top-level item and (optionally) nested items / impl items. See
|
2015-11-17 16:32:12 -06:00
|
|
|
/// `visit_nested_item` for details.
|
|
|
|
fn visit_item(&mut self, i: &'v Item) {
|
|
|
|
walk_item(self, i)
|
|
|
|
}
|
|
|
|
|
2016-11-02 17:22:59 -05:00
|
|
|
/// When invoking `visit_all_item_likes()`, you need to supply an
|
|
|
|
/// item-like visitor. This method converts a "intra-visit"
|
|
|
|
/// visitor into an item-like visitor that walks the entire tree.
|
|
|
|
/// If you use this, you probably don't want to process the
|
|
|
|
/// contents of nested item-like things, since the outer loop will
|
|
|
|
/// visit them as well.
|
|
|
|
fn as_deep_visitor<'s>(&'s mut self) -> DeepVisitor<'s, Self> {
|
|
|
|
DeepVisitor::new(self)
|
|
|
|
}
|
|
|
|
|
2015-11-17 16:32:12 -06:00
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2016-07-28 04:58:45 -05:00
|
|
|
fn visit_id(&mut self, _node_id: NodeId) {
|
|
|
|
// Nothing to do.
|
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
fn visit_name(&mut self, _span: Span, _name: Name) {
|
|
|
|
// Nothing to do.
|
|
|
|
}
|
2016-07-28 04:58:45 -05:00
|
|
|
fn visit_mod(&mut self, m: &'v Mod, _s: Span, n: NodeId) {
|
|
|
|
walk_mod(self, m, n)
|
2015-09-27 14:23:31 -05:00
|
|
|
}
|
|
|
|
fn visit_foreign_item(&mut self, i: &'v ForeignItem) {
|
|
|
|
walk_foreign_item(self, i)
|
|
|
|
}
|
|
|
|
fn visit_local(&mut self, l: &'v Local) {
|
|
|
|
walk_local(self, l)
|
|
|
|
}
|
|
|
|
fn visit_block(&mut self, b: &'v Block) {
|
|
|
|
walk_block(self, b)
|
|
|
|
}
|
|
|
|
fn visit_stmt(&mut self, s: &'v Stmt) {
|
|
|
|
walk_stmt(self, s)
|
|
|
|
}
|
|
|
|
fn visit_arm(&mut self, a: &'v Arm) {
|
|
|
|
walk_arm(self, a)
|
|
|
|
}
|
|
|
|
fn visit_pat(&mut self, p: &'v Pat) {
|
|
|
|
walk_pat(self, p)
|
|
|
|
}
|
|
|
|
fn visit_decl(&mut self, d: &'v Decl) {
|
|
|
|
walk_decl(self, d)
|
|
|
|
}
|
|
|
|
fn visit_expr(&mut self, ex: &'v Expr) {
|
|
|
|
walk_expr(self, ex)
|
|
|
|
}
|
|
|
|
fn visit_expr_post(&mut self, _ex: &'v Expr) {
|
|
|
|
}
|
|
|
|
fn visit_ty(&mut self, t: &'v Ty) {
|
|
|
|
walk_ty(self, t)
|
|
|
|
}
|
|
|
|
fn visit_generics(&mut self, g: &'v Generics) {
|
|
|
|
walk_generics(self, g)
|
|
|
|
}
|
2016-04-21 04:10:10 -05:00
|
|
|
fn visit_where_predicate(&mut self, predicate: &'v WherePredicate) {
|
|
|
|
walk_where_predicate(self, predicate)
|
|
|
|
}
|
2016-10-25 18:27:14 -05:00
|
|
|
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Expr, s: Span, id: NodeId) {
|
2016-07-28 04:58:45 -05:00
|
|
|
walk_fn(self, fk, fd, b, s, id)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2015-09-27 14:23:31 -05:00
|
|
|
fn visit_trait_item(&mut self, ti: &'v TraitItem) {
|
|
|
|
walk_trait_item(self, ti)
|
|
|
|
}
|
|
|
|
fn visit_impl_item(&mut self, ii: &'v ImplItem) {
|
|
|
|
walk_impl_item(self, ii)
|
|
|
|
}
|
2016-11-10 08:47:00 -06:00
|
|
|
fn visit_impl_item_ref(&mut self, ii: &'v ImplItemRef) {
|
|
|
|
walk_impl_item_ref(self, ii)
|
|
|
|
}
|
2015-09-27 14:23:31 -05:00
|
|
|
fn visit_trait_ref(&mut self, t: &'v TraitRef) {
|
|
|
|
walk_trait_ref(self, t)
|
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
fn visit_ty_param_bound(&mut self, bounds: &'v TyParamBound) {
|
|
|
|
walk_ty_param_bound(self, bounds)
|
|
|
|
}
|
|
|
|
fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef, m: &'v TraitBoundModifier) {
|
|
|
|
walk_poly_trait_ref(self, t, m)
|
|
|
|
}
|
2015-11-05 15:17:59 -06:00
|
|
|
fn visit_variant_data(&mut self,
|
|
|
|
s: &'v VariantData,
|
|
|
|
_: Name,
|
|
|
|
_: &'v Generics,
|
2016-07-28 04:58:45 -05:00
|
|
|
_parent_id: NodeId,
|
2015-11-05 15:17:59 -06:00
|
|
|
_: Span) {
|
2015-07-31 02:04:06 -05:00
|
|
|
walk_struct_def(self, s)
|
|
|
|
}
|
2015-09-27 14:23:31 -05:00
|
|
|
fn visit_struct_field(&mut self, s: &'v StructField) {
|
|
|
|
walk_struct_field(self, s)
|
|
|
|
}
|
2015-11-05 15:17:59 -06:00
|
|
|
fn visit_enum_def(&mut self,
|
|
|
|
enum_definition: &'v EnumDef,
|
|
|
|
generics: &'v Generics,
|
|
|
|
item_id: NodeId,
|
|
|
|
_: Span) {
|
2015-10-02 08:14:20 -05:00
|
|
|
walk_enum_def(self, enum_definition, generics, item_id)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2015-10-02 08:14:20 -05:00
|
|
|
fn visit_variant(&mut self, v: &'v Variant, g: &'v Generics, item_id: NodeId) {
|
|
|
|
walk_variant(self, v, g, item_id)
|
2015-09-27 14:23:31 -05:00
|
|
|
}
|
2015-09-28 16:23:54 -05:00
|
|
|
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) {
|
|
|
|
walk_lifetime(self, lifetime)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
fn visit_lifetime_def(&mut self, lifetime: &'v LifetimeDef) {
|
|
|
|
walk_lifetime_def(self, lifetime)
|
|
|
|
}
|
|
|
|
fn visit_path(&mut self, path: &'v Path, _id: NodeId) {
|
|
|
|
walk_path(self, path)
|
|
|
|
}
|
2015-09-12 08:10:12 -05:00
|
|
|
fn visit_path_list_item(&mut self, prefix: &'v Path, item: &'v PathListItem) {
|
|
|
|
walk_path_list_item(self, prefix, item)
|
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) {
|
|
|
|
walk_path_segment(self, path_span, path_segment)
|
|
|
|
}
|
|
|
|
fn visit_path_parameters(&mut self, path_span: Span, path_parameters: &'v PathParameters) {
|
|
|
|
walk_path_parameters(self, path_span, path_parameters)
|
|
|
|
}
|
|
|
|
fn visit_assoc_type_binding(&mut self, type_binding: &'v TypeBinding) {
|
|
|
|
walk_assoc_type_binding(self, type_binding)
|
|
|
|
}
|
2015-09-27 14:23:31 -05:00
|
|
|
fn visit_attribute(&mut self, _attr: &'v Attribute) {
|
|
|
|
}
|
2015-09-28 16:23:54 -05:00
|
|
|
fn visit_macro_def(&mut self, macro_def: &'v MacroDef) {
|
|
|
|
walk_macro_def(self, macro_def)
|
|
|
|
}
|
2016-04-02 15:24:02 -05:00
|
|
|
fn visit_vis(&mut self, vis: &'v Visibility) {
|
|
|
|
walk_vis(self, vis)
|
|
|
|
}
|
2016-11-14 10:00:02 -06:00
|
|
|
fn visit_associated_item_kind(&mut self, kind: &'v AssociatedItemKind) {
|
|
|
|
walk_associated_item_kind(self, kind);
|
|
|
|
}
|
|
|
|
fn visit_defaultness(&mut self, defaultness: &'v Defaultness) {
|
|
|
|
walk_defaultness(self, defaultness);
|
|
|
|
}
|
2015-09-28 16:23:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_opt_name<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_name: Option<Name>) {
|
2016-05-02 11:22:03 -05:00
|
|
|
if let Some(name) = opt_name {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_name(span, name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-02 11:22:03 -05:00
|
|
|
pub fn walk_opt_sp_name<'v, V: Visitor<'v>>(visitor: &mut V, opt_sp_name: &Option<Spanned<Name>>) {
|
|
|
|
if let Some(ref sp_name) = *opt_sp_name {
|
|
|
|
visitor.visit_name(sp_name.span, sp_name.node);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-17 16:32:12 -06:00
|
|
|
/// Walks the contents of a crate. See also `Crate::visit_all_items`.
|
2015-07-31 02:04:06 -05:00
|
|
|
pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) {
|
|
|
|
visitor.visit_mod(&krate.module, krate.span, CRATE_NODE_ID);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_attribute, &krate.attrs);
|
|
|
|
walk_list!(visitor, visit_macro_def, &krate.exported_macros);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
2015-09-28 16:23:54 -05:00
|
|
|
pub fn walk_macro_def<'v, V: Visitor<'v>>(visitor: &mut V, macro_def: &'v MacroDef) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(macro_def.id);
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_name(macro_def.span, macro_def.name);
|
|
|
|
walk_opt_name(visitor, macro_def.span, macro_def.imported_from);
|
|
|
|
walk_list!(visitor, visit_attribute, ¯o_def.attrs);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
2016-07-28 04:58:45 -05:00
|
|
|
pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod, mod_node_id: NodeId) {
|
|
|
|
visitor.visit_id(mod_node_id);
|
2015-11-17 16:32:12 -06:00
|
|
|
for &item_id in &module.item_ids {
|
|
|
|
visitor.visit_nested_item(item_id);
|
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
2015-09-28 16:23:54 -05:00
|
|
|
pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(local.id);
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_pat(&local.pat);
|
|
|
|
walk_list!(visitor, visit_ty, &local.ty);
|
|
|
|
walk_list!(visitor, visit_expr, &local.init);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
2015-09-28 16:23:54 -05:00
|
|
|
pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(lifetime.id);
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_name(lifetime.span, lifetime.name);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
2015-09-27 14:23:31 -05:00
|
|
|
pub fn walk_lifetime_def<'v, V: Visitor<'v>>(visitor: &mut V, lifetime_def: &'v LifetimeDef) {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_lifetime(&lifetime_def.lifetime);
|
|
|
|
walk_list!(visitor, visit_lifetime, &lifetime_def.bounds);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V,
|
|
|
|
trait_ref: &'v PolyTraitRef,
|
|
|
|
_modifier: &'v TraitBoundModifier)
|
|
|
|
where V: Visitor<'v>
|
|
|
|
{
|
2015-11-05 15:17:59 -06:00
|
|
|
walk_list!(visitor, visit_lifetime_def, &trait_ref.bound_lifetimes);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_trait_ref(&trait_ref.trait_ref);
|
|
|
|
}
|
|
|
|
|
2015-09-27 14:23:31 -05:00
|
|
|
pub fn walk_trait_ref<'v, V>(visitor: &mut V, trait_ref: &'v TraitRef)
|
2015-07-31 02:04:06 -05:00
|
|
|
where V: Visitor<'v>
|
|
|
|
{
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(trait_ref.ref_id);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_path(&trait_ref.path, trait_ref.ref_id)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
|
2016-04-02 15:24:02 -05:00
|
|
|
visitor.visit_vis(&item.vis);
|
2015-09-19 20:50:30 -05:00
|
|
|
visitor.visit_name(item.span, item.name);
|
2015-07-31 02:04:06 -05:00
|
|
|
match item.node {
|
2015-09-28 16:23:54 -05:00
|
|
|
ItemExternCrate(opt_name) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(item.id);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_opt_name(visitor, item.span, opt_name)
|
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
ItemUse(ref vp) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(item.id);
|
2015-07-31 02:04:06 -05:00
|
|
|
match vp.node {
|
2015-09-19 19:34:12 -05:00
|
|
|
ViewPathSimple(name, ref path) => {
|
|
|
|
visitor.visit_name(vp.span, name);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_path(path, item.id);
|
|
|
|
}
|
|
|
|
ViewPathGlob(ref path) => {
|
|
|
|
visitor.visit_path(path, item.id);
|
|
|
|
}
|
|
|
|
ViewPathList(ref prefix, ref list) => {
|
2016-03-06 06:54:44 -06:00
|
|
|
visitor.visit_path(prefix, item.id);
|
|
|
|
for item in list {
|
|
|
|
visitor.visit_path_list_item(prefix, item)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ItemStatic(ref typ, _, ref expr) |
|
|
|
|
ItemConst(ref typ, ref expr) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(item.id);
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_ty(typ);
|
|
|
|
visitor.visit_expr(expr);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
ItemFn(ref declaration, unsafety, constness, abi, ref generics, ref body) => {
|
2015-09-27 14:23:31 -05:00
|
|
|
visitor.visit_fn(FnKind::ItemFn(item.name,
|
|
|
|
generics,
|
|
|
|
unsafety,
|
|
|
|
constness,
|
|
|
|
abi,
|
2016-03-25 01:08:11 -05:00
|
|
|
&item.vis,
|
2016-01-25 07:11:51 -06:00
|
|
|
&item.attrs),
|
2015-09-28 16:23:54 -05:00
|
|
|
declaration,
|
|
|
|
body,
|
2015-07-31 02:04:06 -05:00
|
|
|
item.span,
|
|
|
|
item.id)
|
|
|
|
}
|
|
|
|
ItemMod(ref module) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
// visit_mod() takes care of visiting the Item's NodeId
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_mod(module, item.span, item.id)
|
|
|
|
}
|
|
|
|
ItemForeignMod(ref foreign_module) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(item.id);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_foreign_item, &foreign_module.items);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
ItemTy(ref typ, ref type_parameters) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(item.id);
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_ty(typ);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_generics(type_parameters)
|
|
|
|
}
|
|
|
|
ItemEnum(ref enum_definition, ref type_parameters) => {
|
|
|
|
visitor.visit_generics(type_parameters);
|
2016-07-28 04:58:45 -05:00
|
|
|
// visit_enum_def() takes care of visiting the Item's NodeId
|
2015-10-16 09:17:14 -05:00
|
|
|
visitor.visit_enum_def(enum_definition, type_parameters, item.id, item.span)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
ItemDefaultImpl(_, ref trait_ref) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(item.id);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_trait_ref(trait_ref)
|
|
|
|
}
|
2016-11-10 08:47:00 -06:00
|
|
|
ItemImpl(.., ref type_parameters, ref opt_trait_reference, ref typ, ref impl_item_refs) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(item.id);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_generics(type_parameters);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_trait_ref, opt_trait_reference);
|
|
|
|
visitor.visit_ty(typ);
|
2016-11-10 08:47:00 -06:00
|
|
|
for impl_item_ref in impl_item_refs {
|
|
|
|
visitor.visit_impl_item_ref(impl_item_ref);
|
2016-11-02 17:25:31 -05:00
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-08-06 13:36:28 -05:00
|
|
|
ItemStruct(ref struct_definition, ref generics) |
|
|
|
|
ItemUnion(ref struct_definition, ref generics) => {
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_generics(generics);
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(item.id);
|
2015-11-05 15:17:59 -06:00
|
|
|
visitor.visit_variant_data(struct_definition, item.name, generics, item.id, item.span);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
ItemTrait(_, ref generics, ref bounds, ref methods) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(item.id);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_generics(generics);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_ty_param_bound, bounds);
|
|
|
|
walk_list!(visitor, visit_trait_item, methods);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_attribute, &item.attrs);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_enum_def<'v, V: Visitor<'v>>(visitor: &mut V,
|
|
|
|
enum_definition: &'v EnumDef,
|
2015-10-02 08:14:20 -05:00
|
|
|
generics: &'v Generics,
|
|
|
|
item_id: NodeId) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(item_id);
|
2015-11-05 15:17:59 -06:00
|
|
|
walk_list!(visitor,
|
|
|
|
visit_variant,
|
|
|
|
&enum_definition.variants,
|
|
|
|
generics,
|
|
|
|
item_id);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V,
|
|
|
|
variant: &'v Variant,
|
2015-10-02 08:14:20 -05:00
|
|
|
generics: &'v Generics,
|
2016-07-28 04:58:45 -05:00
|
|
|
parent_item_id: NodeId) {
|
2015-09-20 08:47:24 -05:00
|
|
|
visitor.visit_name(variant.span, variant.node.name);
|
2015-11-05 15:17:59 -06:00
|
|
|
visitor.visit_variant_data(&variant.node.data,
|
|
|
|
variant.node.name,
|
|
|
|
generics,
|
2016-07-28 04:58:45 -05:00
|
|
|
parent_item_id,
|
2015-11-05 15:17:59 -06:00
|
|
|
variant.span);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_expr, &variant.node.disr_expr);
|
|
|
|
walk_list!(visitor, visit_attribute, &variant.node.attrs);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(typ.id);
|
|
|
|
|
2015-07-31 02:04:06 -05:00
|
|
|
match typ.node {
|
2016-09-19 19:14:46 -05:00
|
|
|
TySlice(ref ty) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_ty(ty)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
TyPtr(ref mutable_type) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_ty(&mutable_type.ty)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2015-09-28 16:23:54 -05:00
|
|
|
TyRptr(ref opt_lifetime, ref mutable_type) => {
|
|
|
|
walk_list!(visitor, visit_lifetime, opt_lifetime);
|
|
|
|
visitor.visit_ty(&mutable_type.ty)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-08-02 02:56:20 -05:00
|
|
|
TyNever => {},
|
2015-07-31 02:04:06 -05:00
|
|
|
TyTup(ref tuple_element_types) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_ty, tuple_element_types);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
TyBareFn(ref function_declaration) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_fn_decl(visitor, &function_declaration.decl);
|
2015-11-05 15:17:59 -06:00
|
|
|
walk_list!(visitor, visit_lifetime_def, &function_declaration.lifetimes);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
TyPath(ref maybe_qself, ref path) => {
|
2015-09-29 03:33:25 -05:00
|
|
|
if let Some(ref qself) = *maybe_qself {
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_ty(&qself.ty);
|
|
|
|
}
|
|
|
|
visitor.visit_path(path, typ.id);
|
|
|
|
}
|
|
|
|
TyObjectSum(ref ty, ref bounds) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_ty(ty);
|
|
|
|
walk_list!(visitor, visit_ty_param_bound, bounds);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-09-19 19:14:46 -05:00
|
|
|
TyArray(ref ty, ref expression) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_ty(ty);
|
|
|
|
visitor.visit_expr(expression)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
TyPolyTraitRef(ref bounds) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_ty_param_bound, bounds);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-07-31 20:25:32 -05:00
|
|
|
TyImplTrait(ref bounds) => {
|
|
|
|
walk_list!(visitor, visit_ty_param_bound, bounds);
|
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
TyTypeof(ref expression) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(expression)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
TyInfer => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) {
|
|
|
|
for segment in &path.segments {
|
|
|
|
visitor.visit_path_segment(path.span, segment);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-12 04:15:02 -05:00
|
|
|
pub fn walk_path_list_item<'v, V>(visitor: &mut V, _prefix: &'v Path, item: &'v PathListItem)
|
|
|
|
where V: Visitor<'v>,
|
|
|
|
{
|
|
|
|
visitor.visit_id(item.node.id);
|
|
|
|
visitor.visit_name(item.span, item.node.name);
|
|
|
|
walk_opt_name(visitor, item.span, item.node.rename);
|
2015-09-12 08:10:12 -05:00
|
|
|
}
|
|
|
|
|
2015-07-31 02:04:06 -05:00
|
|
|
pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
|
|
|
|
path_span: Span,
|
|
|
|
segment: &'v PathSegment) {
|
2016-03-06 06:54:44 -06:00
|
|
|
visitor.visit_name(path_span, segment.name);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_path_parameters(path_span, &segment.parameters);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_path_parameters<'v, V: Visitor<'v>>(visitor: &mut V,
|
|
|
|
_path_span: Span,
|
|
|
|
path_parameters: &'v PathParameters) {
|
|
|
|
match *path_parameters {
|
2015-09-28 16:23:54 -05:00
|
|
|
AngleBracketedParameters(ref data) => {
|
|
|
|
walk_list!(visitor, visit_ty, &data.types);
|
|
|
|
walk_list!(visitor, visit_lifetime, &data.lifetimes);
|
|
|
|
walk_list!(visitor, visit_assoc_type_binding, &data.bindings);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2015-09-28 16:23:54 -05:00
|
|
|
ParenthesizedParameters(ref data) => {
|
|
|
|
walk_list!(visitor, visit_ty, &data.inputs);
|
|
|
|
walk_list!(visitor, visit_ty, &data.output);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V,
|
|
|
|
type_binding: &'v TypeBinding) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(type_binding.id);
|
2015-09-20 08:47:24 -05:00
|
|
|
visitor.visit_name(type_binding.span, type_binding.name);
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_ty(&type_binding.ty);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(pattern.id);
|
2015-07-31 02:04:06 -05:00
|
|
|
match pattern.node {
|
2016-03-06 06:54:44 -06:00
|
|
|
PatKind::TupleStruct(ref path, ref children, _) => {
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_path(path, pattern.id);
|
2016-03-06 06:54:44 -06:00
|
|
|
walk_list!(visitor, visit_pat, children);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-06-11 10:47:47 -05:00
|
|
|
PatKind::Path(ref opt_qself, ref path) => {
|
|
|
|
if let Some(ref qself) = *opt_qself {
|
|
|
|
visitor.visit_ty(&qself.ty);
|
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_path(path, pattern.id)
|
|
|
|
}
|
2016-02-14 06:25:12 -06:00
|
|
|
PatKind::Struct(ref path, ref fields, _) => {
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_path(path, pattern.id);
|
|
|
|
for field in fields {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_name(field.span, field.node.name);
|
|
|
|
visitor.visit_pat(&field.node.pat)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
2016-03-06 06:54:44 -06:00
|
|
|
PatKind::Tuple(ref tuple_elements, _) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_pat, tuple_elements);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-02-14 06:25:12 -06:00
|
|
|
PatKind::Box(ref subpattern) |
|
|
|
|
PatKind::Ref(ref subpattern, _) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_pat(subpattern)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-03-06 06:54:44 -06:00
|
|
|
PatKind::Binding(_, ref pth1, ref optional_subpattern) => {
|
2016-03-06 06:54:44 -06:00
|
|
|
visitor.visit_name(pth1.span, pth1.node);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_pat, optional_subpattern);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-02-14 06:25:12 -06:00
|
|
|
PatKind::Lit(ref expression) => visitor.visit_expr(expression),
|
|
|
|
PatKind::Range(ref lower_bound, ref upper_bound) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(lower_bound);
|
|
|
|
visitor.visit_expr(upper_bound)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-02-14 06:25:12 -06:00
|
|
|
PatKind::Wild => (),
|
2016-09-19 19:14:46 -05:00
|
|
|
PatKind::Slice(ref prepatterns, ref slice_pattern, ref postpatterns) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_pat, prepatterns);
|
|
|
|
walk_list!(visitor, visit_pat, slice_pattern);
|
|
|
|
walk_list!(visitor, visit_pat, postpatterns);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-27 14:23:31 -05:00
|
|
|
pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(foreign_item.id);
|
2016-04-02 15:24:02 -05:00
|
|
|
visitor.visit_vis(&foreign_item.vis);
|
2015-09-19 20:50:30 -05:00
|
|
|
visitor.visit_name(foreign_item.span, foreign_item.name);
|
2015-07-31 02:04:06 -05:00
|
|
|
|
|
|
|
match foreign_item.node {
|
|
|
|
ForeignItemFn(ref function_declaration, ref generics) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_fn_decl(visitor, function_declaration);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_generics(generics)
|
|
|
|
}
|
2015-09-28 16:23:54 -05:00
|
|
|
ForeignItemStatic(ref typ, _) => visitor.visit_ty(typ),
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_attribute, &foreign_item.attrs);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
2015-09-27 14:23:31 -05:00
|
|
|
pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v TyParamBound) {
|
2015-07-31 02:04:06 -05:00
|
|
|
match *bound {
|
|
|
|
TraitTyParamBound(ref typ, ref modifier) => {
|
|
|
|
visitor.visit_poly_trait_ref(typ, modifier);
|
|
|
|
}
|
|
|
|
RegionTyParamBound(ref lifetime) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_lifetime(lifetime);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) {
|
2015-09-28 16:23:54 -05:00
|
|
|
for param in &generics.ty_params {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(param.id);
|
2015-09-20 08:47:24 -05:00
|
|
|
visitor.visit_name(param.span, param.name);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_ty_param_bound, ¶m.bounds);
|
|
|
|
walk_list!(visitor, visit_ty, ¶m.default);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_lifetime_def, &generics.lifetimes);
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(generics.where_clause.id);
|
2016-04-21 04:10:10 -05:00
|
|
|
walk_list!(visitor, visit_where_predicate, &generics.where_clause.predicates);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_where_predicate<'v, V: Visitor<'v>>(
|
|
|
|
visitor: &mut V,
|
|
|
|
predicate: &'v WherePredicate)
|
|
|
|
{
|
|
|
|
match predicate {
|
|
|
|
&WherePredicate::BoundPredicate(WhereBoundPredicate{ref bounded_ty,
|
|
|
|
ref bounds,
|
|
|
|
ref bound_lifetimes,
|
|
|
|
..}) => {
|
|
|
|
visitor.visit_ty(bounded_ty);
|
|
|
|
walk_list!(visitor, visit_ty_param_bound, bounds);
|
|
|
|
walk_list!(visitor, visit_lifetime_def, bound_lifetimes);
|
|
|
|
}
|
|
|
|
&WherePredicate::RegionPredicate(WhereRegionPredicate{ref lifetime,
|
|
|
|
ref bounds,
|
|
|
|
..}) => {
|
|
|
|
visitor.visit_lifetime(lifetime);
|
|
|
|
walk_list!(visitor, visit_lifetime, bounds);
|
|
|
|
}
|
|
|
|
&WherePredicate::EqPredicate(WhereEqPredicate{id,
|
|
|
|
ref path,
|
|
|
|
ref ty,
|
|
|
|
..}) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(id);
|
2016-04-21 04:10:10 -05:00
|
|
|
visitor.visit_path(path, id);
|
|
|
|
visitor.visit_ty(ty);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FunctionRetTy) {
|
|
|
|
if let Return(ref output_ty) = *ret_ty {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_ty(output_ty)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) {
|
|
|
|
for argument in &function_declaration.inputs {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(argument.id);
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_pat(&argument.pat);
|
|
|
|
visitor.visit_ty(&argument.ty)
|
|
|
|
}
|
|
|
|
walk_fn_ret_ty(visitor, &function_declaration.output)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_fn_decl_nopat<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) {
|
|
|
|
for argument in &function_declaration.inputs {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(argument.id);
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_ty(&argument.ty)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
walk_fn_ret_ty(visitor, &function_declaration.output)
|
|
|
|
}
|
|
|
|
|
2015-09-27 14:23:31 -05:00
|
|
|
pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'v>) {
|
2015-07-31 02:04:06 -05:00
|
|
|
match function_kind {
|
2016-08-26 11:23:42 -05:00
|
|
|
FnKind::ItemFn(_, generics, ..) => {
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_generics(generics);
|
|
|
|
}
|
2016-08-26 11:23:42 -05:00
|
|
|
FnKind::Method(_, sig, ..) => {
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_generics(&sig.generics);
|
|
|
|
}
|
2016-01-25 07:11:51 -06:00
|
|
|
FnKind::Closure(_) => {}
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2015-09-03 05:35:41 -05:00
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
|
2015-09-03 05:35:41 -05:00
|
|
|
pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
|
|
|
|
function_kind: FnKind<'v>,
|
|
|
|
function_declaration: &'v FnDecl,
|
2016-10-25 18:27:14 -05:00
|
|
|
function_body: &'v Expr,
|
2016-07-28 04:58:45 -05:00
|
|
|
_span: Span,
|
|
|
|
id: NodeId) {
|
|
|
|
visitor.visit_id(id);
|
2015-09-03 05:35:41 -05:00
|
|
|
walk_fn_decl(visitor, function_declaration);
|
|
|
|
walk_fn_kind(visitor, function_kind);
|
2016-10-25 18:27:14 -05:00
|
|
|
visitor.visit_expr(function_body)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) {
|
2015-09-19 20:50:30 -05:00
|
|
|
visitor.visit_name(trait_item.span, trait_item.name);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_attribute, &trait_item.attrs);
|
2015-07-31 02:04:06 -05:00
|
|
|
match trait_item.node {
|
|
|
|
ConstTraitItem(ref ty, ref default) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(trait_item.id);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_ty(ty);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_expr, default);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
MethodTraitItem(ref sig, None) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(trait_item.id);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_generics(&sig.generics);
|
|
|
|
walk_fn_decl(visitor, &sig.decl);
|
|
|
|
}
|
|
|
|
MethodTraitItem(ref sig, Some(ref body)) => {
|
2016-01-25 07:11:51 -06:00
|
|
|
visitor.visit_fn(FnKind::Method(trait_item.name,
|
|
|
|
sig,
|
|
|
|
None,
|
|
|
|
&trait_item.attrs),
|
2015-09-27 14:23:31 -05:00
|
|
|
&sig.decl,
|
|
|
|
body,
|
|
|
|
trait_item.span,
|
|
|
|
trait_item.id);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
TypeTraitItem(ref bounds, ref default) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(trait_item.id);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_ty_param_bound, bounds);
|
|
|
|
walk_list!(visitor, visit_ty, default);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) {
|
2016-11-14 10:00:02 -06:00
|
|
|
// NB: Deliberately force a compilation error if/when new fields are added.
|
|
|
|
let ImplItem { id: _, name, ref vis, ref defaultness, ref attrs, ref node, span } = *impl_item;
|
|
|
|
|
|
|
|
visitor.visit_name(span, name);
|
|
|
|
visitor.visit_vis(vis);
|
|
|
|
visitor.visit_defaultness(defaultness);
|
|
|
|
walk_list!(visitor, visit_attribute, attrs);
|
|
|
|
match *node {
|
2015-11-12 08:57:51 -06:00
|
|
|
ImplItemKind::Const(ref ty, ref expr) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(impl_item.id);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_ty(ty);
|
|
|
|
visitor.visit_expr(expr);
|
|
|
|
}
|
2015-11-12 08:57:51 -06:00
|
|
|
ImplItemKind::Method(ref sig, ref body) => {
|
2016-01-25 07:11:51 -06:00
|
|
|
visitor.visit_fn(FnKind::Method(impl_item.name,
|
|
|
|
sig,
|
2016-03-25 01:08:11 -05:00
|
|
|
Some(&impl_item.vis),
|
2016-01-25 07:11:51 -06:00
|
|
|
&impl_item.attrs),
|
2015-09-27 14:23:31 -05:00
|
|
|
&sig.decl,
|
|
|
|
body,
|
|
|
|
impl_item.span,
|
|
|
|
impl_item.id);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2015-11-12 08:57:51 -06:00
|
|
|
ImplItemKind::Type(ref ty) => {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(impl_item.id);
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_ty(ty);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-10 08:47:00 -06:00
|
|
|
pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'v ImplItemRef) {
|
2016-11-14 10:00:02 -06:00
|
|
|
// NB: Deliberately force a compilation error if/when new fields are added.
|
|
|
|
let ImplItemRef { id, name, ref kind, span, ref vis, ref defaultness } = *impl_item_ref;
|
|
|
|
visitor.visit_nested_impl_item(id);
|
|
|
|
visitor.visit_name(span, name);
|
|
|
|
visitor.visit_associated_item_kind(kind);
|
|
|
|
visitor.visit_vis(vis);
|
|
|
|
visitor.visit_defaultness(defaultness);
|
2016-11-10 08:47:00 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-07 19:20:57 -05:00
|
|
|
pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, struct_definition: &'v VariantData) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(struct_definition.id());
|
2015-10-08 15:45:46 -05:00
|
|
|
walk_list!(visitor, visit_struct_field, struct_definition.fields());
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
2015-09-27 14:23:31 -05:00
|
|
|
pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v StructField) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(struct_field.id);
|
2016-04-02 15:24:02 -05:00
|
|
|
visitor.visit_vis(&struct_field.vis);
|
2016-02-27 02:34:29 -06:00
|
|
|
visitor.visit_name(struct_field.span, struct_field.name);
|
|
|
|
visitor.visit_ty(&struct_field.ty);
|
|
|
|
walk_list!(visitor, visit_attribute, &struct_field.attrs);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(block.id);
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_stmt, &block.stmts);
|
|
|
|
walk_list!(visitor, visit_expr, &block.expr);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) {
|
|
|
|
match statement.node {
|
2016-07-28 04:58:45 -05:00
|
|
|
StmtDecl(ref declaration, id) => {
|
|
|
|
visitor.visit_id(id);
|
|
|
|
visitor.visit_decl(declaration)
|
|
|
|
}
|
|
|
|
StmtExpr(ref expression, id) |
|
|
|
|
StmtSemi(ref expression, id) => {
|
|
|
|
visitor.visit_id(id);
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(expression)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_decl<'v, V: Visitor<'v>>(visitor: &mut V, declaration: &'v Decl) {
|
|
|
|
match declaration.node {
|
2015-09-28 16:23:54 -05:00
|
|
|
DeclLocal(ref local) => visitor.visit_local(local),
|
2015-11-17 16:32:12 -06:00
|
|
|
DeclItem(item) => visitor.visit_nested_item(item),
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(expression.id);
|
2015-07-31 02:04:06 -05:00
|
|
|
match expression.node {
|
2015-09-24 10:00:08 -05:00
|
|
|
ExprBox(ref subexpression) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(subexpression)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-09-19 19:14:46 -05:00
|
|
|
ExprArray(ref subexpressions) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_expr, subexpressions);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
ExprRepeat(ref element, ref count) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(element);
|
|
|
|
visitor.visit_expr(count)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
ExprStruct(ref path, ref fields, ref optional_base) => {
|
|
|
|
visitor.visit_path(path, expression.id);
|
|
|
|
for field in fields {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_name(field.name.span, field.name.node);
|
|
|
|
visitor.visit_expr(&field.expr)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_expr, optional_base);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
ExprTup(ref subexpressions) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_expr, subexpressions);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
ExprCall(ref callee_expression, ref arguments) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_expr, arguments);
|
|
|
|
visitor.visit_expr(callee_expression)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2015-09-28 16:23:54 -05:00
|
|
|
ExprMethodCall(ref name, ref types, ref arguments) => {
|
|
|
|
visitor.visit_name(name.span, name.node);
|
|
|
|
walk_list!(visitor, visit_expr, arguments);
|
|
|
|
walk_list!(visitor, visit_ty, types);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
ExprBinary(_, ref left_expression, ref right_expression) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(left_expression);
|
|
|
|
visitor.visit_expr(right_expression)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
ExprAddrOf(_, ref subexpression) | ExprUnary(_, ref subexpression) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(subexpression)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
ExprLit(_) => {}
|
2015-12-02 20:37:48 -06:00
|
|
|
ExprCast(ref subexpression, ref typ) | ExprType(ref subexpression, ref typ) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(subexpression);
|
|
|
|
visitor.visit_ty(typ)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
ExprIf(ref head_expression, ref if_block, ref optional_else) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(head_expression);
|
|
|
|
visitor.visit_block(if_block);
|
|
|
|
walk_list!(visitor, visit_expr, optional_else);
|
|
|
|
}
|
2016-05-02 11:22:03 -05:00
|
|
|
ExprWhile(ref subexpression, ref block, ref opt_sp_name) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(subexpression);
|
|
|
|
visitor.visit_block(block);
|
2016-05-02 11:22:03 -05:00
|
|
|
walk_opt_sp_name(visitor, opt_sp_name);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
Implement the `loop_break_value` feature.
This implements RFC 1624, tracking issue #37339.
- `FnCtxt` (in typeck) gets a stack of `LoopCtxt`s, which store the
currently deduced type of that loop, the desired type, and a list of
break expressions currently seen. `loop` loops get a fresh type
variable as their initial type (this logic is stolen from that for
arrays). `while` loops get `()`.
- `break {expr}` looks up the broken loop, and unifies the type of
`expr` with the type of the loop.
- `break` with no expr unifies the loop's type with `()`.
- When building MIR, `loop` loops no longer construct a `()` value at
termination of the loop; rather, the `break` expression assigns the
result of the loop. `while` loops are unchanged.
- `break` respects contexts in which expressions may not end with braced
blocks. That is, `while break { break-value } { while-body }` is
illegal; this preserves backwards compatibility.
- The RFC did not make it clear, but I chose to make `break ()` inside
of a `while` loop illegal, just in case we wanted to do anything with
that design space in the future.
This is my first time dealing with this part of rustc so I'm sure
there's plenty of problems to pick on here ^_^
2016-10-29 17:15:06 -05:00
|
|
|
ExprLoop(ref block, ref opt_sp_name, _) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_block(block);
|
2016-05-02 11:22:03 -05:00
|
|
|
walk_opt_sp_name(visitor, opt_sp_name);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
ExprMatch(ref subexpression, ref arms, _) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(subexpression);
|
|
|
|
walk_list!(visitor, visit_arm, arms);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-04-20 13:44:07 -05:00
|
|
|
ExprClosure(_, ref function_declaration, ref body, _fn_decl_span) => {
|
2016-06-17 23:01:57 -05:00
|
|
|
visitor.visit_fn(FnKind::Closure(&expression.attrs),
|
2015-09-28 16:23:54 -05:00
|
|
|
function_declaration,
|
|
|
|
body,
|
2015-07-31 02:04:06 -05:00
|
|
|
expression.span,
|
|
|
|
expression.id)
|
|
|
|
}
|
2015-09-28 16:23:54 -05:00
|
|
|
ExprBlock(ref block) => visitor.visit_block(block),
|
2015-07-31 02:04:06 -05:00
|
|
|
ExprAssign(ref left_hand_expression, ref right_hand_expression) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(right_hand_expression);
|
|
|
|
visitor.visit_expr(left_hand_expression)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
ExprAssignOp(_, ref left_expression, ref right_expression) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(right_expression);
|
|
|
|
visitor.visit_expr(left_expression)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2015-09-28 16:23:54 -05:00
|
|
|
ExprField(ref subexpression, ref name) => {
|
|
|
|
visitor.visit_expr(subexpression);
|
|
|
|
visitor.visit_name(name.span, name.node);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
ExprTupField(ref subexpression, _) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(subexpression);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
ExprIndex(ref main_expression, ref index_expression) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
visitor.visit_expr(main_expression);
|
|
|
|
visitor.visit_expr(index_expression)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
ExprPath(ref maybe_qself, ref path) => {
|
2015-09-29 03:33:25 -05:00
|
|
|
if let Some(ref qself) = *maybe_qself {
|
2015-07-31 02:04:06 -05:00
|
|
|
visitor.visit_ty(&qself.ty);
|
|
|
|
}
|
|
|
|
visitor.visit_path(path, expression.id)
|
|
|
|
}
|
Implement the `loop_break_value` feature.
This implements RFC 1624, tracking issue #37339.
- `FnCtxt` (in typeck) gets a stack of `LoopCtxt`s, which store the
currently deduced type of that loop, the desired type, and a list of
break expressions currently seen. `loop` loops get a fresh type
variable as their initial type (this logic is stolen from that for
arrays). `while` loops get `()`.
- `break {expr}` looks up the broken loop, and unifies the type of
`expr` with the type of the loop.
- `break` with no expr unifies the loop's type with `()`.
- When building MIR, `loop` loops no longer construct a `()` value at
termination of the loop; rather, the `break` expression assigns the
result of the loop. `while` loops are unchanged.
- `break` respects contexts in which expressions may not end with braced
blocks. That is, `while break { break-value } { while-body }` is
illegal; this preserves backwards compatibility.
- The RFC did not make it clear, but I chose to make `break ()` inside
of a `while` loop illegal, just in case we wanted to do anything with
that design space in the future.
This is my first time dealing with this part of rustc so I'm sure
there's plenty of problems to pick on here ^_^
2016-10-29 17:15:06 -05:00
|
|
|
ExprBreak(ref opt_sp_name, ref opt_expr) => {
|
|
|
|
walk_opt_sp_name(visitor, opt_sp_name);
|
|
|
|
walk_list!(visitor, visit_expr, opt_expr);
|
|
|
|
}
|
|
|
|
ExprAgain(ref opt_sp_name) => {
|
2016-05-02 11:22:03 -05:00
|
|
|
walk_opt_sp_name(visitor, opt_sp_name);
|
2015-09-28 16:23:54 -05:00
|
|
|
}
|
2015-07-31 02:04:06 -05:00
|
|
|
ExprRet(ref optional_expression) => {
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_expr, optional_expression);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-03-09 14:17:02 -06:00
|
|
|
ExprInlineAsm(_, ref outputs, ref inputs) => {
|
|
|
|
for output in outputs {
|
|
|
|
visitor.visit_expr(output)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-03-09 14:17:02 -06:00
|
|
|
for input in inputs {
|
|
|
|
visitor.visit_expr(input)
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
visitor.visit_expr_post(expression)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) {
|
2015-09-28 16:23:54 -05:00
|
|
|
walk_list!(visitor, visit_pat, &arm.pats);
|
|
|
|
walk_list!(visitor, visit_expr, &arm.guard);
|
|
|
|
visitor.visit_expr(&arm.body);
|
|
|
|
walk_list!(visitor, visit_attribute, &arm.attrs);
|
2015-07-31 02:04:06 -05:00
|
|
|
}
|
2016-03-29 01:32:58 -05:00
|
|
|
|
2016-04-02 15:24:02 -05:00
|
|
|
pub fn walk_vis<'v, V: Visitor<'v>>(visitor: &mut V, vis: &'v Visibility) {
|
|
|
|
if let Visibility::Restricted { ref path, id } = *vis {
|
2016-07-28 04:58:45 -05:00
|
|
|
visitor.visit_id(id);
|
2016-04-02 15:24:02 -05:00
|
|
|
visitor.visit_path(path, id)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-14 10:00:02 -06:00
|
|
|
pub fn walk_associated_item_kind<'v, V: Visitor<'v>>(_: &mut V, _: &'v AssociatedItemKind) {
|
|
|
|
// No visitable content here: this fn exists so you can call it if
|
|
|
|
// the right thing to do, should content be added in the future,
|
|
|
|
// would be to walk it.
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn walk_defaultness<'v, V: Visitor<'v>>(_: &mut V, _: &'v Defaultness) {
|
|
|
|
// No visitable content here: this fn exists so you can call it if
|
|
|
|
// the right thing to do, should content be added in the future,
|
|
|
|
// would be to walk it.
|
|
|
|
}
|
|
|
|
|
2016-07-26 09:58:35 -05:00
|
|
|
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq)]
|
2016-03-29 04:12:01 -05:00
|
|
|
pub struct IdRange {
|
|
|
|
pub min: NodeId,
|
|
|
|
pub max: NodeId,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IdRange {
|
|
|
|
pub fn max() -> IdRange {
|
|
|
|
IdRange {
|
2016-08-31 06:00:29 -05:00
|
|
|
min: NodeId::from_u32(u32::MAX),
|
|
|
|
max: NodeId::from_u32(u32::MIN),
|
2016-03-29 04:12:01 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn empty(&self) -> bool {
|
|
|
|
self.min >= self.max
|
|
|
|
}
|
|
|
|
|
2016-07-28 04:58:45 -05:00
|
|
|
pub fn contains(&self, id: NodeId) -> bool {
|
|
|
|
id >= self.min && id < self.max
|
|
|
|
}
|
|
|
|
|
2016-03-29 04:12:01 -05:00
|
|
|
pub fn add(&mut self, id: NodeId) {
|
|
|
|
self.min = cmp::min(self.min, id);
|
2016-08-31 06:00:29 -05:00
|
|
|
self.max = cmp::max(self.max, NodeId::from_u32(id.as_u32() + 1));
|
2016-03-29 04:12:01 -05:00
|
|
|
}
|
2016-07-26 09:58:35 -05:00
|
|
|
|
2016-03-29 04:12:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub struct IdRangeComputingVisitor {
|
|
|
|
pub result: IdRange,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IdRangeComputingVisitor {
|
|
|
|
pub fn new() -> IdRangeComputingVisitor {
|
|
|
|
IdRangeComputingVisitor { result: IdRange::max() }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn result(&self) -> IdRange {
|
|
|
|
self.result
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-28 04:58:45 -05:00
|
|
|
impl<'v> Visitor<'v> for IdRangeComputingVisitor {
|
2016-03-29 04:12:01 -05:00
|
|
|
fn visit_id(&mut self, id: NodeId) {
|
|
|
|
self.result.add(id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-29 01:32:58 -05:00
|
|
|
/// Computes the id range for a single fn body, ignoring nested items.
|
|
|
|
pub fn compute_id_range_for_fn_body(fk: FnKind,
|
|
|
|
decl: &FnDecl,
|
2016-10-25 18:27:14 -05:00
|
|
|
body: &Expr,
|
2016-03-29 01:32:58 -05:00
|
|
|
sp: Span,
|
|
|
|
id: NodeId)
|
2016-03-29 04:12:01 -05:00
|
|
|
-> IdRange {
|
2016-07-28 04:58:45 -05:00
|
|
|
let mut visitor = IdRangeComputingVisitor::new();
|
|
|
|
visitor.visit_fn(fk, decl, body, sp, id);
|
|
|
|
visitor.result()
|
2016-03-29 01:32:58 -05:00
|
|
|
}
|