1
Fork 0

Move visitor utils to rustc_ast_ir

This commit is contained in:
Jason Newcomb 2024-02-24 15:22:42 -05:00
parent c7beecf3e3
commit 5abfb3775d
12 changed files with 99 additions and 79 deletions

View file

@ -15,11 +15,12 @@
use crate::ast::*;
use core::ops::ControlFlow;
use rustc_span::symbol::Ident;
use rustc_span::Span;
pub use rustc_ast_ir::visit::VisitorResult;
pub use rustc_ast_ir::{try_visit, visit_opt, walk_list, walk_visitable_list};
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum AssocCtxt {
Trait,
@ -101,51 +102,6 @@ pub enum LifetimeCtxt {
GenericArg,
}
/// Similar to the `Try` trait, but also implemented for `()`.
pub trait VisitorResult {
type Residual;
fn output() -> Self;
fn from_residual(residual: Self::Residual) -> Self;
fn branch(self) -> ControlFlow<Self::Residual>;
}
impl VisitorResult for () {
type Residual = !;
fn output() -> Self {}
fn from_residual(_: !) -> Self {}
fn branch(self) -> ControlFlow<!> {
ControlFlow::Continue(())
}
}
impl<T> VisitorResult for ControlFlow<T> {
type Residual = T;
fn output() -> Self {
ControlFlow::Continue(())
}
fn from_residual(residual: Self::Residual) -> Self {
ControlFlow::Break(residual)
}
fn branch(self) -> ControlFlow<T> {
self
}
}
#[macro_export]
macro_rules! try_visit {
($e:expr) => {
match $crate::visit::VisitorResult::branch($e) {
core::ops::ControlFlow::Continue(()) => (),
#[allow(unreachable_code)]
core::ops::ControlFlow::Break(r) => {
return $crate::visit::VisitorResult::from_residual(r);
}
}
};
}
/// 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;
@ -316,24 +272,6 @@ pub trait Visitor<'ast>: Sized {
}
}
#[macro_export]
macro_rules! walk_list {
($visitor: expr, $method: ident, $list: expr $(, $($extra_args: expr),* )?) => {
for elem in $list {
$crate::try_visit!($visitor.$method(elem $(, $($extra_args,)* )?));
}
}
}
#[macro_export]
macro_rules! visit_opt {
($visitor: expr, $method: ident, $opt: expr $(, $($extra_args: expr),* )?) => {
if let Some(x) = $opt {
$crate::try_visit!($visitor.$method(x $(, $($extra_args,)* )?));
}
}
}
pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) -> V::Result {
walk_list!(visitor, visit_item, &krate.items);
walk_list!(visitor, visit_attribute, &krate.attrs);