Allow AST and HIR visitors to return ControlFlow
This commit is contained in:
parent
1f8e824f11
commit
864cee3ea3
6 changed files with 958 additions and 768 deletions
|
@ -12,10 +12,12 @@
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustdoc_internals)]
|
||||||
#![feature(associated_type_bounds)]
|
#![feature(associated_type_bounds)]
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![feature(if_let_guard)]
|
#![feature(if_let_guard)]
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
#![cfg_attr(bootstrap, feature(min_specialization))]
|
#![cfg_attr(bootstrap, feature(min_specialization))]
|
||||||
|
#![feature(never_type)]
|
||||||
#![feature(negative_impls)]
|
#![feature(negative_impls)]
|
||||||
#![feature(stmt_expr_attributes)]
|
#![feature(stmt_expr_attributes)]
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -96,7 +96,7 @@ impl Annotatable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) {
|
pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) -> V::Result {
|
||||||
match self {
|
match self {
|
||||||
Annotatable::Item(item) => visitor.visit_item(item),
|
Annotatable::Item(item) => visitor.visit_item(item),
|
||||||
Annotatable::TraitItem(item) => visitor.visit_assoc_item(item, AssocCtxt::Trait),
|
Annotatable::TraitItem(item) => visitor.visit_assoc_item(item, AssocCtxt::Trait),
|
||||||
|
|
|
@ -14,7 +14,8 @@ use rustc_ast::mut_visit::*;
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
use rustc_ast::token::{self, Delimiter};
|
use rustc_ast::token::{self, Delimiter};
|
||||||
use rustc_ast::tokenstream::TokenStream;
|
use rustc_ast::tokenstream::TokenStream;
|
||||||
use rustc_ast::visit::{self, AssocCtxt, Visitor};
|
use rustc_ast::visit::{self, AssocCtxt, Visitor, VisitorResult};
|
||||||
|
use rustc_ast::{try_visit, walk_list};
|
||||||
use rustc_ast::{AssocItemKind, AstNodeWrapper, AttrArgs, AttrStyle, AttrVec, ExprKind};
|
use rustc_ast::{AssocItemKind, AstNodeWrapper, AttrArgs, AttrStyle, AttrVec, ExprKind};
|
||||||
use rustc_ast::{ForeignItemKind, HasAttrs, HasNodeId};
|
use rustc_ast::{ForeignItemKind, HasAttrs, HasNodeId};
|
||||||
use rustc_ast::{Inline, ItemKind, MacStmtStyle, MetaItemKind, ModKind};
|
use rustc_ast::{Inline, ItemKind, MacStmtStyle, MetaItemKind, ModKind};
|
||||||
|
@ -143,16 +144,15 @@ macro_rules! ast_fragments {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) {
|
pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) -> V::Result {
|
||||||
match self {
|
match self {
|
||||||
AstFragment::OptExpr(Some(expr)) => visitor.visit_expr(expr),
|
AstFragment::OptExpr(Some(expr)) => try_visit!(visitor.visit_expr(expr)),
|
||||||
AstFragment::OptExpr(None) => {}
|
AstFragment::OptExpr(None) => {}
|
||||||
AstFragment::MethodReceiverExpr(expr) => visitor.visit_method_receiver_expr(expr),
|
AstFragment::MethodReceiverExpr(expr) => try_visit!(visitor.visit_method_receiver_expr(expr)),
|
||||||
$($(AstFragment::$Kind(ast) => visitor.$visit_ast(ast),)?)*
|
$($(AstFragment::$Kind(ast) => try_visit!(visitor.$visit_ast(ast)),)?)*
|
||||||
$($(AstFragment::$Kind(ast) => for ast_elt in &ast[..] {
|
$($(AstFragment::$Kind(ast) => walk_list!(visitor, $visit_ast_elt, &ast[..], $($args)*),)?)*
|
||||||
visitor.$visit_ast_elt(ast_elt, $($args)*);
|
|
||||||
})?)*
|
|
||||||
}
|
}
|
||||||
|
V::Result::output()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,6 +3,8 @@ use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
|
||||||
use crate::query::LocalCrate;
|
use crate::query::LocalCrate;
|
||||||
use crate::ty::TyCtxt;
|
use crate::ty::TyCtxt;
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
|
use rustc_ast::visit::VisitorResult;
|
||||||
|
use rustc_ast::walk_list;
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
use rustc_data_structures::svh::Svh;
|
use rustc_data_structures::svh::Svh;
|
||||||
|
@ -431,23 +433,28 @@ impl<'hir> Map<'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Walks the contents of the local crate. See also `visit_all_item_likes_in_crate`.
|
/// Walks the contents of the local crate. See also `visit_all_item_likes_in_crate`.
|
||||||
pub fn walk_toplevel_module(self, visitor: &mut impl Visitor<'hir>) {
|
pub fn walk_toplevel_module<V>(self, visitor: &mut V) -> V::Result
|
||||||
|
where
|
||||||
|
V: Visitor<'hir>,
|
||||||
|
{
|
||||||
let (top_mod, span, hir_id) = self.get_module(LocalModDefId::CRATE_DEF_ID);
|
let (top_mod, span, hir_id) = self.get_module(LocalModDefId::CRATE_DEF_ID);
|
||||||
visitor.visit_mod(top_mod, span, hir_id);
|
visitor.visit_mod(top_mod, span, hir_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Walks the attributes in a crate.
|
/// Walks the attributes in a crate.
|
||||||
pub fn walk_attributes(self, visitor: &mut impl Visitor<'hir>) {
|
pub fn walk_attributes<V>(self, visitor: &mut V) -> V::Result
|
||||||
|
where
|
||||||
|
V: Visitor<'hir>,
|
||||||
|
{
|
||||||
let krate = self.krate();
|
let krate = self.krate();
|
||||||
for info in krate.owners.iter() {
|
for info in krate.owners.iter() {
|
||||||
if let MaybeOwner::Owner(info) = info {
|
if let MaybeOwner::Owner(info) = info {
|
||||||
for attrs in info.attrs.map.values() {
|
for attrs in info.attrs.map.values() {
|
||||||
for a in *attrs {
|
walk_list!(visitor, visit_attribute, *attrs);
|
||||||
visitor.visit_attribute(a)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
V::Result::output()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Visits all item-likes in the crate in some deterministic (but unspecified) order. If you
|
/// Visits all item-likes in the crate in some deterministic (but unspecified) order. If you
|
||||||
|
@ -460,52 +467,38 @@ impl<'hir> Map<'hir> {
|
||||||
/// provided by `tcx.hir_crate_items(())`.
|
/// provided by `tcx.hir_crate_items(())`.
|
||||||
///
|
///
|
||||||
/// Please see the notes in `intravisit.rs` for more information.
|
/// Please see the notes in `intravisit.rs` for more information.
|
||||||
pub fn visit_all_item_likes_in_crate<V>(self, visitor: &mut V)
|
pub fn visit_all_item_likes_in_crate<V>(self, visitor: &mut V) -> V::Result
|
||||||
where
|
where
|
||||||
V: Visitor<'hir>,
|
V: Visitor<'hir>,
|
||||||
{
|
{
|
||||||
let krate = self.tcx.hir_crate_items(());
|
let krate = self.tcx.hir_crate_items(());
|
||||||
|
walk_list!(visitor, visit_item, krate.items().map(|id| self.item(id)));
|
||||||
for id in krate.items() {
|
walk_list!(visitor, visit_trait_item, krate.trait_items().map(|id| self.trait_item(id)));
|
||||||
visitor.visit_item(self.item(id));
|
walk_list!(visitor, visit_impl_item, krate.impl_items().map(|id| self.impl_item(id)));
|
||||||
}
|
walk_list!(
|
||||||
|
visitor,
|
||||||
for id in krate.trait_items() {
|
visit_foreign_item,
|
||||||
visitor.visit_trait_item(self.trait_item(id));
|
krate.foreign_items().map(|id| self.foreign_item(id))
|
||||||
}
|
);
|
||||||
|
V::Result::output()
|
||||||
for id in krate.impl_items() {
|
|
||||||
visitor.visit_impl_item(self.impl_item(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
for id in krate.foreign_items() {
|
|
||||||
visitor.visit_foreign_item(self.foreign_item(id));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This method is the equivalent of `visit_all_item_likes_in_crate` but restricted to
|
/// This method is the equivalent of `visit_all_item_likes_in_crate` but restricted to
|
||||||
/// item-likes in a single module.
|
/// item-likes in a single module.
|
||||||
pub fn visit_item_likes_in_module<V>(self, module: LocalModDefId, visitor: &mut V)
|
pub fn visit_item_likes_in_module<V>(self, module: LocalModDefId, visitor: &mut V) -> V::Result
|
||||||
where
|
where
|
||||||
V: Visitor<'hir>,
|
V: Visitor<'hir>,
|
||||||
{
|
{
|
||||||
let module = self.tcx.hir_module_items(module);
|
let module = self.tcx.hir_module_items(module);
|
||||||
|
walk_list!(visitor, visit_item, module.items().map(|id| self.item(id)));
|
||||||
for id in module.items() {
|
walk_list!(visitor, visit_trait_item, module.trait_items().map(|id| self.trait_item(id)));
|
||||||
visitor.visit_item(self.item(id));
|
walk_list!(visitor, visit_impl_item, module.impl_items().map(|id| self.impl_item(id)));
|
||||||
}
|
walk_list!(
|
||||||
|
visitor,
|
||||||
for id in module.trait_items() {
|
visit_foreign_item,
|
||||||
visitor.visit_trait_item(self.trait_item(id));
|
module.foreign_items().map(|id| self.foreign_item(id))
|
||||||
}
|
);
|
||||||
|
V::Result::output()
|
||||||
for id in module.impl_items() {
|
|
||||||
visitor.visit_impl_item(self.impl_item(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
for id in module.foreign_items() {
|
|
||||||
visitor.visit_foreign_item(self.foreign_item(id));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn for_each_module(self, mut f: impl FnMut(LocalModDefId)) {
|
pub fn for_each_module(self, mut f: impl FnMut(LocalModDefId)) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue