Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert the rest of the visitors to use VisitorResult #121576

Merged
merged 4 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3970,6 +3970,7 @@ version = "0.0.0"
dependencies = [
"itertools 0.11.0",
"rustc_ast",
"rustc_ast_ir",
"rustc_attr",
"rustc_data_structures",
"rustc_errors",
Expand Down Expand Up @@ -4038,6 +4039,7 @@ dependencies = [
name = "rustc_infer"
version = "0.0.0"
dependencies = [
"rustc_ast_ir",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
Expand Down Expand Up @@ -4632,6 +4634,7 @@ dependencies = [
"bitflags 2.4.2",
"itertools 0.11.0",
"rustc_ast",
"rustc_ast_ir",
"rustc_attr",
"rustc_data_structures",
"rustc_errors",
Expand Down Expand Up @@ -4670,6 +4673,7 @@ name = "rustc_transmute"
version = "0.0.0"
dependencies = [
"itertools 0.11.0",
"rustc_ast_ir",
"rustc_data_structures",
"rustc_hir",
"rustc_infer",
Expand All @@ -4685,6 +4689,7 @@ name = "rustc_ty_utils"
version = "0.0.0"
dependencies = [
"itertools 0.11.0",
"rustc_ast_ir",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
Expand Down
68 changes: 3 additions & 65 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_ast_ir/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#![cfg_attr(feature = "nightly", feature(never_type))]
#![cfg_attr(feature = "nightly", feature(rustc_attrs))]
#![cfg_attr(feature = "nightly", allow(internal_features))]

#[cfg(feature = "nightly")]
#[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)]
Expand Down
82 changes: 82 additions & 0 deletions compiler/rustc_ast_ir/src/visit.rs
Original file line number Diff line number Diff line change
@@ -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,)* )?));
}
}
}
3 changes: 1 addition & 2 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_builtin_macros/src/deriving/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_const_eval/src/interpret/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ where
}

impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UsedParamsNeedInstantiationVisitor<'tcx> {
type BreakTy = FoundParam;
type Result = ControlFlow<FoundParam>;

fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
if !ty.has_param() {
return ControlFlow::Continue(());
}
Expand Down Expand Up @@ -64,7 +64,7 @@ where
}
}

fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_const(&mut self, c: ty::Const<'tcx>) -> Self::Result {
match c.kind() {
ty::ConstKind::Param(..) => ControlFlow::Break(FoundParam),
_ => c.super_visit_with(self),
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_const_eval/src/transform/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt};
use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitor};

use std::mem;
use std::ops::{ControlFlow, Deref};
use std::ops::Deref;

use super::ops::{self, NonConstOp, Status};
use super::qualifs::{self, HasMutInterior, NeedsDrop, NeedsNonConstDrop};
Expand Down Expand Up @@ -164,9 +164,9 @@ struct LocalReturnTyVisitor<'ck, 'mir, 'tcx> {
}

impl<'ck, 'mir, 'tcx> TypeVisitor<TyCtxt<'tcx>> for LocalReturnTyVisitor<'ck, 'mir, 'tcx> {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_ty(&mut self, t: Ty<'tcx>) {
match t.kind() {
ty::FnPtr(_) => ControlFlow::Continue(()),
ty::FnPtr(_) => {}
ty::Ref(_, _, hir::Mutability::Mut) => {
self.checker.check_op(ops::ty::MutRef(self.kind));
t.super_visit_with(self)
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1474,15 +1474,14 @@ fn opaque_type_cycle_error(
closures: Vec<DefId>,
}
impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
fn visit_ty(&mut self, t: Ty<'tcx>) {
match *t.kind() {
ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => {
self.opaques.push(def);
ControlFlow::Continue(())
}
ty::Closure(def_id, ..) | ty::Coroutine(def_id, ..) => {
self.closures.push(def_id);
t.super_visit_with(self)
t.super_visit_with(self);
}
_ => t.super_visit_with(self),
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use rustc_trait_selection::regions::InferCtxtRegionExt;
use rustc_trait_selection::traits::{
elaborate, normalize_param_env_or_error, outlives_bounds::InferCtxtExt, ObligationCtxt,
};
use std::ops::ControlFlow;

/// Check that an implementation does not refine an RPITIT from a trait method signature.
pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
Expand Down Expand Up @@ -211,9 +210,7 @@ struct ImplTraitInTraitCollector<'tcx> {
}

impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'tcx> {
type BreakTy = !;

fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow<Self::BreakTy> {
fn visit_ty(&mut self, ty: Ty<'tcx>) {
if let ty::Alias(ty::Projection, proj) = *ty.kind()
&& self.tcx.is_impl_trait_in_trait(proj.def_id)
{
Expand All @@ -223,12 +220,11 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'tcx> {
.explicit_item_bounds(proj.def_id)
.iter_instantiated_copied(self.tcx, proj.args)
{
pred.visit_with(self)?;
pred.visit_with(self);
}
}
ControlFlow::Continue(())
} else {
ty.super_visit_with(self)
ty.super_visit_with(self);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading
Loading