Skip to content
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
55 changes: 32 additions & 23 deletions compiler/rustc_type_ir/src/generic_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,35 @@ use crate::Interner;
/// This trait is implemented for every type that can be visited,
/// providing the skeleton of the traversal.
///
/// To implement this conveniently, use the derive macro located in
/// `rustc_macros`.
pub trait GenericTypeVisitable<V> {
/// ## Safety
///
/// A manual implementation **must visit** every field.
///
/// Therefore, it is advised to instead derive this using the derive
/// macro located in `rustc_macros`.
pub unsafe trait GenericTypeVisitable<V> {
Comment thread
JonathanBrouwer marked this conversation as resolved.
fn generic_visit_with(&self, visitor: &mut V);
}

///////////////////////////////////////////////////////////////////////////
// Traversal implementations.

impl<V, T: ?Sized + GenericTypeVisitable<V>> GenericTypeVisitable<V> for &T {
unsafe impl<V, T: ?Sized + GenericTypeVisitable<V>> GenericTypeVisitable<V> for &T {
fn generic_visit_with(&self, visitor: &mut V) {
T::generic_visit_with(*self, visitor)
}
}

impl<V, T: GenericTypeVisitable<V>, U: GenericTypeVisitable<V>> GenericTypeVisitable<V> for (T, U) {
unsafe impl<V, T: GenericTypeVisitable<V>, U: GenericTypeVisitable<V>> GenericTypeVisitable<V>
for (T, U)
{
fn generic_visit_with(&self, visitor: &mut V) {
self.0.generic_visit_with(visitor);
self.1.generic_visit_with(visitor);
}
}

impl<V, A: GenericTypeVisitable<V>, B: GenericTypeVisitable<V>, C: GenericTypeVisitable<V>>
unsafe impl<V, A: GenericTypeVisitable<V>, B: GenericTypeVisitable<V>, C: GenericTypeVisitable<V>>
GenericTypeVisitable<V> for (A, B, C)
{
fn generic_visit_with(&self, visitor: &mut V) {
Expand All @@ -52,7 +58,7 @@ impl<V, A: GenericTypeVisitable<V>, B: GenericTypeVisitable<V>, C: GenericTypeVi
}
}

impl<V, T: GenericTypeVisitable<V>> GenericTypeVisitable<V> for Option<T> {
unsafe impl<V, T: GenericTypeVisitable<V>> GenericTypeVisitable<V> for Option<T> {
fn generic_visit_with(&self, visitor: &mut V) {
match self {
Some(v) => v.generic_visit_with(visitor),
Expand All @@ -61,7 +67,7 @@ impl<V, T: GenericTypeVisitable<V>> GenericTypeVisitable<V> for Option<T> {
}
}

impl<V, T: GenericTypeVisitable<V>, E: GenericTypeVisitable<V>> GenericTypeVisitable<V>
unsafe impl<V, T: GenericTypeVisitable<V>, E: GenericTypeVisitable<V>> GenericTypeVisitable<V>
for Result<T, E>
{
fn generic_visit_with(&self, visitor: &mut V) {
Expand All @@ -72,54 +78,56 @@ impl<V, T: GenericTypeVisitable<V>, E: GenericTypeVisitable<V>> GenericTypeVisit
}
}

impl<V, T: ?Sized + GenericTypeVisitable<V>> GenericTypeVisitable<V> for Arc<T> {
unsafe impl<V, T: ?Sized + GenericTypeVisitable<V>> GenericTypeVisitable<V> for Arc<T> {
fn generic_visit_with(&self, visitor: &mut V) {
(**self).generic_visit_with(visitor)
}
}

impl<V, T: ?Sized + GenericTypeVisitable<V>> GenericTypeVisitable<V> for Box<T> {
unsafe impl<V, T: ?Sized + GenericTypeVisitable<V>> GenericTypeVisitable<V> for Box<T> {
fn generic_visit_with(&self, visitor: &mut V) {
(**self).generic_visit_with(visitor)
}
}

impl<V, T: GenericTypeVisitable<V>> GenericTypeVisitable<V> for Vec<T> {
unsafe impl<V, T: GenericTypeVisitable<V>> GenericTypeVisitable<V> for Vec<T> {
fn generic_visit_with(&self, visitor: &mut V) {
self.iter().for_each(|it| it.generic_visit_with(visitor));
}
}

impl<V, T: GenericTypeVisitable<V>> GenericTypeVisitable<V> for ThinVec<T> {
unsafe impl<V, T: GenericTypeVisitable<V>> GenericTypeVisitable<V> for ThinVec<T> {
fn generic_visit_with(&self, visitor: &mut V) {
self.iter().for_each(|it| it.generic_visit_with(visitor));
}
}

impl<V, T: GenericTypeVisitable<V>, const N: usize> GenericTypeVisitable<V> for SmallVec<[T; N]> {
unsafe impl<V, T: GenericTypeVisitable<V>, const N: usize> GenericTypeVisitable<V>
for SmallVec<[T; N]>
{
fn generic_visit_with(&self, visitor: &mut V) {
self.iter().for_each(|it| it.generic_visit_with(visitor));
}
}

impl<V, T: GenericTypeVisitable<V>> GenericTypeVisitable<V> for [T] {
unsafe impl<V, T: GenericTypeVisitable<V>> GenericTypeVisitable<V> for [T] {
fn generic_visit_with(&self, visitor: &mut V) {
self.iter().for_each(|it| it.generic_visit_with(visitor));
}
}

impl<V, T: GenericTypeVisitable<V>, Ix: Idx> GenericTypeVisitable<V> for IndexVec<Ix, T> {
unsafe impl<V, T: GenericTypeVisitable<V>, Ix: Idx> GenericTypeVisitable<V> for IndexVec<Ix, T> {
fn generic_visit_with(&self, visitor: &mut V) {
self.iter().for_each(|it| it.generic_visit_with(visitor));
}
}

impl<S, V> GenericTypeVisitable<V> for std::hash::BuildHasherDefault<S> {
unsafe impl<S, V> GenericTypeVisitable<V> for std::hash::BuildHasherDefault<S> {
fn generic_visit_with(&self, _visitor: &mut V) {}
}

#[expect(rustc::default_hash_types, rustc::potential_query_instability)]
impl<
unsafe impl<
Visitor,
Key: GenericTypeVisitable<Visitor>,
Value: GenericTypeVisitable<Visitor>,
Expand All @@ -133,7 +141,7 @@ impl<
}

#[expect(rustc::default_hash_types, rustc::potential_query_instability)]
impl<V, T: GenericTypeVisitable<V>, S: GenericTypeVisitable<V>> GenericTypeVisitable<V>
unsafe impl<V, T: GenericTypeVisitable<V>, S: GenericTypeVisitable<V>> GenericTypeVisitable<V>
for std::collections::HashSet<T, S>
{
fn generic_visit_with(&self, visitor: &mut V) {
Expand All @@ -142,7 +150,7 @@ impl<V, T: GenericTypeVisitable<V>, S: GenericTypeVisitable<V>> GenericTypeVisit
}
}

impl<
unsafe impl<
Visitor,
Key: GenericTypeVisitable<Visitor>,
Value: GenericTypeVisitable<Visitor>,
Expand All @@ -155,7 +163,7 @@ impl<
}
}

impl<V, T: GenericTypeVisitable<V>, S: GenericTypeVisitable<V>> GenericTypeVisitable<V>
unsafe impl<V, T: GenericTypeVisitable<V>, S: GenericTypeVisitable<V>> GenericTypeVisitable<V>
for indexmap::IndexSet<T, S>
{
fn generic_visit_with(&self, visitor: &mut V) {
Expand All @@ -167,7 +175,7 @@ impl<V, T: GenericTypeVisitable<V>, S: GenericTypeVisitable<V>> GenericTypeVisit
macro_rules! trivial_impls {
( $($ty:ty),* $(,)? ) => {
$(
impl<V>
unsafe impl<V>
GenericTypeVisitable<V> for $ty
{
fn generic_visit_with(&self, _visitor: &mut V) {}
Expand All @@ -176,7 +184,7 @@ macro_rules! trivial_impls {
};
}

impl<T: ?Sized, V> GenericTypeVisitable<V> for std::marker::PhantomData<T> {
unsafe impl<T: ?Sized, V> GenericTypeVisitable<V> for std::marker::PhantomData<T> {
fn generic_visit_with(&self, _visitor: &mut V) {}
}

Expand Down Expand Up @@ -215,6 +223,7 @@ trivial_impls!(
rustc_abi::ExternAbi,
);

impl<I: Interner, V> GenericTypeVisitable<V> for crate::FnSigKind<I> {
// SAFETY: `FnSigKind` is a packed representation, therefore visiting its fields doesn't make sense
unsafe impl<I: Interner, V> GenericTypeVisitable<V> for crate::FnSigKind<I> {
fn generic_visit_with(&self, _visitor: &mut V) {}
}
2 changes: 0 additions & 2 deletions compiler/rustc_type_ir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ mod const_kind;
mod flags;
mod fold;
mod generic_arg;
#[cfg(not(feature = "nightly"))]
mod generic_visit;
mod infer_ctxt;
mod interner;
Expand Down Expand Up @@ -97,7 +96,6 @@ pub use const_kind::*;
pub use flags::*;
pub use fold::*;
pub use generic_arg::*;
#[cfg(not(feature = "nightly"))]
pub use generic_visit::*;
pub use infer_ctxt::*;
pub use interner::*;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_type_ir/src/region_constraint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ pub enum RegionConstraint<I: Interner, S = ()> {
/// and there may wind up being assumptions we can use to prove this when we're in a smaller universe.
PlaceholderTyOutlives(I::Ty, Region<I>, S),

And(Box<[RegionConstraint<I, S>]>),
Or(Box<[RegionConstraint<I, S>]>),
And(#[generic_type_visitable(bounds())] Box<[RegionConstraint<I, S>]>),
Or(#[generic_type_visitable(bounds())] Box<[RegionConstraint<I, S>]>),
}

/// A solver region constraint together with the span that caused each leaf constraint.
Expand Down
Loading
Loading