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);

View File

@ -1,3 +1,4 @@
#![cfg_attr(feature = "nightly", feature(never_type))]
#![cfg_attr(feature = "nightly", feature(rustc_attrs))]
#![cfg_attr(feature = "nightly", allow(internal_features))]
@ -5,6 +6,8 @@
#[macro_use]
extern crate rustc_macros;
pub mod visit;
/// The movability of a coroutine / closure literal:
/// whether a coroutine contains self-references, causing it to be `!Unpin`.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]

View File

@ -0,0 +1,82 @@
use core::ops::ControlFlow;
/// 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 from_branch(b: ControlFlow<Self::Residual>) -> Self;
fn branch(self) -> ControlFlow<Self::Residual>;
}
impl VisitorResult for () {
#[cfg(feature = "nightly")]
type Residual = !;
#[cfg(not(feature = "nightly"))]
type Residual = core::ops::Infallible;
fn output() -> Self {}
fn from_residual(_: Self::Residual) -> Self {}
fn from_branch(_: ControlFlow<Self::Residual>) -> Self {}
fn branch(self) -> ControlFlow<Self::Residual> {
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 from_branch(b: Self) -> Self {
b
}
fn branch(self) -> Self {
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);
}
}
};
}
#[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,)* )?));
}
}
}
#[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! walk_visitable_list {
($visitor: expr, $list: expr $(, $($extra_args: expr),* )?) => {
for elem in $list {
$crate::try_visit!(elem.visit_with($visitor $(, $($extra_args,)* )?));
}
}
}

View File

@ -8,8 +8,7 @@
use itertools::{Either, Itertools};
use rustc_ast::ptr::P;
use rustc_ast::visit::{AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor};
use rustc_ast::walk_list;
use rustc_ast::visit::{walk_list, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor};
use rustc_ast::*;
use rustc_ast_pretty::pprust::{self, State};
use rustc_data_structures::fx::FxIndexMap;

View File

@ -2,7 +2,8 @@ use crate::deriving::generic::ty::*;
use crate::deriving::generic::*;
use crate::errors;
use rustc_ast as ast;
use rustc_ast::{attr, walk_list, EnumDef, VariantData};
use rustc_ast::visit::walk_list;
use rustc_ast::{attr, EnumDef, VariantData};
use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt};
use rustc_span::symbol::Ident;
use rustc_span::symbol::{kw, sym};

View File

@ -14,8 +14,7 @@ use rustc_ast::mut_visit::*;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter};
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::visit::{self, AssocCtxt, Visitor, VisitorResult};
use rustc_ast::{try_visit, walk_list};
use rustc_ast::visit::{self, try_visit, walk_list, AssocCtxt, Visitor, VisitorResult};
use rustc_ast::{AssocItemKind, AstNodeWrapper, AttrArgs, AttrStyle, AttrVec, ExprKind};
use rustc_ast::{ForeignItemKind, HasAttrs, HasNodeId};
use rustc_ast::{Inline, ItemKind, MacStmtStyle, MetaItemKind, ModKind};

View File

@ -65,8 +65,7 @@
//! example coroutine inference, and possibly also HIR borrowck.
use crate::hir::*;
use rustc_ast::visit::VisitorResult;
use rustc_ast::{try_visit, visit_opt, walk_list};
use rustc_ast::visit::{try_visit, visit_opt, walk_list, VisitorResult};
use rustc_ast::{Attribute, Label};
use rustc_span::def_id::LocalDefId;
use rustc_span::symbol::{Ident, Symbol};

View File

@ -6,7 +6,7 @@
//!
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/borrow_check.html
use rustc_ast::walk_list;
use rustc_ast::visit::walk_list;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;

View File

@ -6,7 +6,7 @@
//! the types in HIR to identify late-bound lifetimes and assign their Debruijn indices. This file
//! is also responsible for assigning their semantics to implicit lifetimes in trait objects.
use rustc_ast::walk_list;
use rustc_ast::visit::walk_list;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::{codes::*, struct_span_code_err};
use rustc_hir as hir;

View File

@ -17,8 +17,8 @@
use crate::context::{EarlyContext, LintContext, LintStore};
use crate::passes::{EarlyLintPass, EarlyLintPassObject};
use rustc_ast::ptr::P;
use rustc_ast::visit::{self as ast_visit, Visitor};
use rustc_ast::{self as ast, walk_list, HasAttrs};
use rustc_ast::visit::{self as ast_visit, walk_list, Visitor};
use rustc_ast::{self as ast, HasAttrs};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_feature::Features;
use rustc_middle::ty::RegisteredTools;

View File

@ -3,8 +3,7 @@ use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
use crate::query::LocalCrate;
use crate::ty::TyCtxt;
use rustc_ast as ast;
use rustc_ast::visit::VisitorResult;
use rustc_ast::walk_list;
use rustc_ast::visit::{walk_list, VisitorResult};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::svh::Svh;

View File

@ -13,7 +13,7 @@ use crate::{Module, ModuleOrUniformRoot, NameBinding, ParentScope, PathResult};
use crate::{ResolutionError, Resolver, Segment, UseError};
use rustc_ast::ptr::P;
use rustc_ast::visit::{AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor};
use rustc_ast::visit::{walk_list, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor};
use rustc_ast::*;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_errors::{