Move TypeVisitableExt from ir module
This commit is contained in:
parent
b409329c62
commit
e8d152d2f4
@ -39,24 +39,22 @@
|
||||
//! - u.visit_with(visitor)
|
||||
//! ```
|
||||
use crate::ty::{self, flags::FlagComputation, Binder, Ty, TyCtxt, TypeFlags};
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::sso::SsoHashSet;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
pub trait TypeVisitable<'tcx> = ir::TypeVisitable<'tcx> + ir::TypeVisitableExt<'tcx>;
|
||||
pub trait TypeVisitable<'tcx> = ir::TypeVisitable<'tcx> + TypeVisitableExt<'tcx>;
|
||||
pub trait TypeSuperVisitable<'tcx> = ir::TypeSuperVisitable<'tcx>;
|
||||
pub trait TypeVisitor<'tcx> = ir::TypeVisitor<'tcx>;
|
||||
|
||||
pub mod ir {
|
||||
use crate::ty::{self, Binder, Ty, TypeFlags};
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use crate::ty::{self, Binder, Ty};
|
||||
|
||||
use std::fmt;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
use super::{FoundFlags, HasEscapingVarsVisitor, HasTypeFlagsVisitor};
|
||||
|
||||
/// This trait is implemented for every type that can be visited,
|
||||
/// providing the skeleton of the traversal.
|
||||
///
|
||||
@ -76,7 +74,51 @@ pub mod ir {
|
||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy>;
|
||||
}
|
||||
|
||||
pub trait TypeVisitableExt<'tcx>: TypeVisitable<'tcx> {
|
||||
pub trait TypeSuperVisitable<'tcx>: TypeVisitable<'tcx> {
|
||||
/// Provides a default visit for a type of interest. This should only be
|
||||
/// called within `TypeVisitor` methods, when a non-custom traversal is
|
||||
/// desired for the value of the type of interest passed to that method.
|
||||
/// For example, in `MyVisitor::visit_ty(ty)`, it is valid to call
|
||||
/// `ty.super_visit_with(self)`, but any other visiting should be done
|
||||
/// with `xyz.visit_with(self)`.
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(
|
||||
&self,
|
||||
visitor: &mut V,
|
||||
) -> ControlFlow<V::BreakTy>;
|
||||
}
|
||||
|
||||
/// This trait is implemented for every visiting traversal. There is a visit
|
||||
/// method defined for every type of interest. Each such method has a default
|
||||
/// that recurses into the type's fields in a non-custom fashion.
|
||||
pub trait TypeVisitor<'tcx>: Sized {
|
||||
type BreakTy = !;
|
||||
|
||||
fn visit_binder<T: TypeVisitable<'tcx>>(
|
||||
&mut self,
|
||||
t: &Binder<'tcx, T>,
|
||||
) -> ControlFlow<Self::BreakTy> {
|
||||
t.super_visit_with(self)
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
t.super_visit_with(self)
|
||||
}
|
||||
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
r.super_visit_with(self)
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
c.super_visit_with(self)
|
||||
}
|
||||
|
||||
fn visit_predicate(&mut self, p: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
p.super_visit_with(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TypeVisitableExt<'tcx>: ir::TypeVisitable<'tcx> {
|
||||
/// Returns `true` if `self` has any late-bound regions that are either
|
||||
/// bound by `binder` or bound by some binder outside of `binder`.
|
||||
/// If `binder` is `ty::INNERMOST`, this indicates whether
|
||||
@ -102,8 +144,8 @@ pub mod ir {
|
||||
}
|
||||
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
let res = self.visit_with(&mut HasTypeFlagsVisitor { flags }).break_value()
|
||||
== Some(FoundFlags);
|
||||
let res =
|
||||
self.visit_with(&mut HasTypeFlagsVisitor { flags }).break_value() == Some(FoundFlags);
|
||||
trace!(?self, ?flags, ?res, "has_type_flags");
|
||||
res
|
||||
}
|
||||
@ -121,8 +163,7 @@ pub mod ir {
|
||||
}
|
||||
fn error_reported(&self) -> Result<(), ErrorGuaranteed> {
|
||||
if self.references_error() {
|
||||
if let Some(reported) = ty::tls::with(|tcx| tcx.sess.is_compilation_going_to_fail())
|
||||
{
|
||||
if let Some(reported) = ty::tls::with(|tcx| tcx.sess.is_compilation_going_to_fail()) {
|
||||
Err(reported)
|
||||
} else {
|
||||
bug!("expect tcx.sess.is_compilation_going_to_fail return `Some`");
|
||||
@ -199,51 +240,7 @@ pub mod ir {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitableExt<'tcx> for T {}
|
||||
|
||||
pub trait TypeSuperVisitable<'tcx>: TypeVisitable<'tcx> {
|
||||
/// Provides a default visit for a type of interest. This should only be
|
||||
/// called within `TypeVisitor` methods, when a non-custom traversal is
|
||||
/// desired for the value of the type of interest passed to that method.
|
||||
/// For example, in `MyVisitor::visit_ty(ty)`, it is valid to call
|
||||
/// `ty.super_visit_with(self)`, but any other visiting should be done
|
||||
/// with `xyz.visit_with(self)`.
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(
|
||||
&self,
|
||||
visitor: &mut V,
|
||||
) -> ControlFlow<V::BreakTy>;
|
||||
}
|
||||
|
||||
/// This trait is implemented for every visiting traversal. There is a visit
|
||||
/// method defined for every type of interest. Each such method has a default
|
||||
/// that recurses into the type's fields in a non-custom fashion.
|
||||
pub trait TypeVisitor<'tcx>: Sized {
|
||||
type BreakTy = !;
|
||||
|
||||
fn visit_binder<T: TypeVisitable<'tcx>>(
|
||||
&mut self,
|
||||
t: &Binder<'tcx, T>,
|
||||
) -> ControlFlow<Self::BreakTy> {
|
||||
t.super_visit_with(self)
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
t.super_visit_with(self)
|
||||
}
|
||||
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
r.super_visit_with(self)
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
c.super_visit_with(self)
|
||||
}
|
||||
|
||||
fn visit_predicate(&mut self, p: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
p.super_visit_with(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'tcx, T: ir::TypeVisitable<'tcx>> TypeVisitableExt<'tcx> for T {}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Region folder
|
||||
|
Loading…
x
Reference in New Issue
Block a user