diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 6ccddb17ff22b..315ab8b97e9b6 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -35,6 +35,7 @@ nightly = [ "dep:rustc_span", "rustc_ast_ir/nightly", "rustc_index/nightly", + "rustc_type_ir_macros/nightly", "smallvec/may_dangle", "smallvec/union", ] diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index 94b950357e1e4..3c722b87f5aa7 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -4,7 +4,9 @@ use std::ops::{ControlFlow, Deref}; use derive_where::derive_where; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; -use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + CustomizableTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic, +}; use tracing::instrument; use crate::data_structures::SsoHashSet; @@ -24,6 +26,7 @@ use crate::{self as ty, DebruijnIndex, Interner}; /// `Decodable` and `Encodable` are implemented for `Binder` using the `impl_binder_encode_decode!` macro. #[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, T)] #[derive_where(Copy; I: Interner, T: Copy)] +#[derive(CustomizableTypeVisitable)] #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] pub struct Binder { value: T, @@ -360,6 +363,7 @@ impl TypeVisitor for ValidateBoundVars { #[derive_where(Clone, PartialEq, Ord, Hash, Debug; I: Interner, T)] #[derive_where(PartialOrd; I: Interner, T: Ord)] #[derive_where(Copy; I: Interner, T: Copy)] +#[derive(CustomizableTypeVisitable)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) @@ -943,7 +947,7 @@ impl<'a, I: Interner> ArgFolder<'a, I> { feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) )] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic)] pub enum BoundVarIndexKind { Bound(DebruijnIndex), Canonical, diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs index 7b4b953b2cf65..cef9cc64efecd 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -5,7 +5,9 @@ use arrayvec::ArrayVec; use derive_where::derive_where; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; -use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + CustomizableTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, +}; use crate::data_structures::HashMap; use crate::inherent::*; @@ -86,6 +88,7 @@ impl fmt::Display for Canonical { /// a copy of the canonical value in some other inference context, /// with fresh inference variables replacing the canonical values. #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] +#[derive(CustomizableTypeVisitable)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -219,7 +222,7 @@ impl CanonicalVarKind { feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) )] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] pub struct CanonicalVarValues { pub var_values: I::GenericArgs, } diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index 8393bbe5caf83..94ec201990626 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -5,12 +5,15 @@ use derive_where::derive_where; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; -use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + CustomizableTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, +}; use crate::{self as ty, BoundVarIndexKind, Interner}; /// Represents a constant in Rust. #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] +#[derive(CustomizableTypeVisitable)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) @@ -66,7 +69,7 @@ impl fmt::Debug for ConstKind { /// An unevaluated (potentially generic) constant used in the type-system. #[derive_where(Clone, Copy, Debug, Hash, PartialEq; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) diff --git a/compiler/rustc_type_ir/src/customizable_visit.rs b/compiler/rustc_type_ir/src/customizable_visit.rs new file mode 100644 index 0000000000000..422594b36403f --- /dev/null +++ b/compiler/rustc_type_ir/src/customizable_visit.rs @@ -0,0 +1,259 @@ +//! A visiting traversal mechanism for complex data structures that contain type +//! information. +//! +//! This is a read-only traversal of the data structure. +//! +//! This traversal has limited flexibility. Only a small number of "types of +//! interest" within the complex data structures can receive custom +//! visitation. These are the ones containing the most important type-related +//! information, such as `Ty`, `Predicate`, `Region`, and `Const`. +//! +//! There are three traits involved in each traversal. +//! - `CustomizableTypeVisitable`. This is implemented once for many types, including: +//! - Types of interest, for which the methods delegate to the visitor. +//! - All other types, including generic containers like `Vec` and `Option`. +//! It defines a "skeleton" of how they should be visited. +//! - `TypeSuperVisitable`. This is implemented only for recursive types of +//! interest, and defines the visiting "skeleton" for these types. (This +//! excludes `Region` because it is non-recursive, i.e. it never contains +//! other types of interest.) +//! - `CustomizableTypeVisitor`. This is implemented for each visitor. This defines how +//! types of interest are visited. +//! +//! This means each visit is a mixture of (a) generic visiting operations, and (b) +//! custom visit operations that are specific to the visitor. +//! - The `CustomizableTypeVisitable` impls handle most of the traversal, and call into +//! `CustomizableTypeVisitor` when they encounter a type of interest. +//! - A `CustomizableTypeVisitor` may call into another `CustomizableTypeVisitable` impl, because some of +//! the types of interest are recursive and can contain other types of interest. +//! - A `CustomizableTypeVisitor` may also call into a `TypeSuperVisitable` impl, because each +//! visitor might provide custom handling only for some types of interest, or +//! only for some variants of each type of interest, and then use default +//! traversal for the remaining cases. +//! +//! For example, if you have `struct S(Ty, U)` where `S: CustomizableTypeVisitable` and `U: +//! CustomizableTypeVisitable`, and an instance `s = S(ty, u)`, it would be visited like so: +//! ```text +//! s.customizable_visit_with(visitor) calls +//! - ty.customizable_visit_with(visitor) calls +//! - visitor.visit_ty(ty) may call +//! - ty.super_customizable_visit_with(visitor) +//! - u.customizable_visit_with(visitor) +//! ``` + +use std::sync::Arc; + +use rustc_index::{Idx, IndexVec}; +use smallvec::SmallVec; +use thin_vec::ThinVec; + +/// 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 CustomizableTypeVisitable { + /// The entry point for visiting. To visit a value `t` with a visitor `v` + /// call: `t.customizable_visit_with(v)`. + /// + /// For most types, this just traverses the value, calling `customizable_visit_with` on + /// each field/element. + /// + /// For types of interest (such as `Ty`), the implementation of this method + /// that calls a visitor method specifically for that type (such as + /// `V::visit_ty`). This is where control transfers from `CustomizableTypeVisitable` to + /// `CustomizableTypeVisitor`. + fn customizable_visit_with(&self, visitor: &mut V); +} + +/////////////////////////////////////////////////////////////////////////// +// Traversal implementations. + +impl> CustomizableTypeVisitable for &T { + fn customizable_visit_with(&self, visitor: &mut V) { + T::customizable_visit_with(*self, visitor) + } +} + +impl, U: CustomizableTypeVisitable> + CustomizableTypeVisitable for (T, U) +{ + fn customizable_visit_with(&self, visitor: &mut V) { + self.0.customizable_visit_with(visitor); + self.1.customizable_visit_with(visitor); + } +} + +impl< + V, + A: CustomizableTypeVisitable, + B: CustomizableTypeVisitable, + C: CustomizableTypeVisitable, +> CustomizableTypeVisitable for (A, B, C) +{ + fn customizable_visit_with(&self, visitor: &mut V) { + self.0.customizable_visit_with(visitor); + self.1.customizable_visit_with(visitor); + self.2.customizable_visit_with(visitor); + } +} + +impl> CustomizableTypeVisitable for Option { + fn customizable_visit_with(&self, visitor: &mut V) { + match self { + Some(v) => v.customizable_visit_with(visitor), + None => {} + } + } +} + +impl, E: CustomizableTypeVisitable> + CustomizableTypeVisitable for Result +{ + fn customizable_visit_with(&self, visitor: &mut V) { + match self { + Ok(v) => v.customizable_visit_with(visitor), + Err(e) => e.customizable_visit_with(visitor), + } + } +} + +impl> CustomizableTypeVisitable for Arc { + fn customizable_visit_with(&self, visitor: &mut V) { + (**self).customizable_visit_with(visitor) + } +} + +impl> CustomizableTypeVisitable for Box { + fn customizable_visit_with(&self, visitor: &mut V) { + (**self).customizable_visit_with(visitor) + } +} + +impl> CustomizableTypeVisitable for Vec { + fn customizable_visit_with(&self, visitor: &mut V) { + self.iter().for_each(|it| it.customizable_visit_with(visitor)); + } +} + +impl> CustomizableTypeVisitable for ThinVec { + fn customizable_visit_with(&self, visitor: &mut V) { + self.iter().for_each(|it| it.customizable_visit_with(visitor)); + } +} + +impl, const N: usize> CustomizableTypeVisitable + for SmallVec<[T; N]> +{ + fn customizable_visit_with(&self, visitor: &mut V) { + self.iter().for_each(|it| it.customizable_visit_with(visitor)); + } +} + +impl> CustomizableTypeVisitable for [T] { + fn customizable_visit_with(&self, visitor: &mut V) { + self.iter().for_each(|it| it.customizable_visit_with(visitor)); + } +} + +impl, Ix: Idx> CustomizableTypeVisitable for IndexVec { + fn customizable_visit_with(&self, visitor: &mut V) { + self.iter().for_each(|it| it.customizable_visit_with(visitor)); + } +} + +impl CustomizableTypeVisitable for std::hash::BuildHasherDefault { + fn customizable_visit_with(&self, _visitor: &mut V) {} +} + +#[expect(rustc::default_hash_types, rustc::potential_query_instability)] +impl< + Visitor, + Key: CustomizableTypeVisitable, + Value: CustomizableTypeVisitable, + S: CustomizableTypeVisitable, +> CustomizableTypeVisitable for std::collections::HashMap +{ + fn customizable_visit_with(&self, visitor: &mut Visitor) { + self.iter().for_each(|it| it.customizable_visit_with(visitor)); + self.hasher().customizable_visit_with(visitor); + } +} + +#[expect(rustc::default_hash_types, rustc::potential_query_instability)] +impl, S: CustomizableTypeVisitable> + CustomizableTypeVisitable for std::collections::HashSet +{ + fn customizable_visit_with(&self, visitor: &mut V) { + self.iter().for_each(|it| it.customizable_visit_with(visitor)); + self.hasher().customizable_visit_with(visitor); + } +} + +impl< + Visitor, + Key: CustomizableTypeVisitable, + Value: CustomizableTypeVisitable, + S: CustomizableTypeVisitable, +> CustomizableTypeVisitable for indexmap::IndexMap +{ + fn customizable_visit_with(&self, visitor: &mut Visitor) { + self.iter().for_each(|it| it.customizable_visit_with(visitor)); + self.hasher().customizable_visit_with(visitor); + } +} + +impl, S: CustomizableTypeVisitable> + CustomizableTypeVisitable for indexmap::IndexSet +{ + fn customizable_visit_with(&self, visitor: &mut V) { + self.iter().for_each(|it| it.customizable_visit_with(visitor)); + self.hasher().customizable_visit_with(visitor); + } +} + +macro_rules! trivial_impls { + ( $($ty:ty),* $(,)? ) => { + $( + impl + CustomizableTypeVisitable for $ty + { + fn customizable_visit_with(&self, _visitor: &mut V) {} + } + )* + }; +} + +trivial_impls!( + (), + rustc_ast_ir::Mutability, + bool, + i8, + i16, + i32, + i64, + i128, + isize, + u8, + u16, + u32, + u64, + u128, + usize, + crate::PredicatePolarity, + crate::BoundConstness, + crate::AliasRelationDirection, + crate::DebruijnIndex, + crate::solve::Certainty, + crate::UniverseIndex, + crate::BoundVar, + crate::InferTy, + crate::IntTy, + crate::UintTy, + crate::FloatTy, + crate::InferConst, + crate::RegionVid, + rustc_hash::FxBuildHasher, + crate::TypeFlags, + crate::solve::GoalSource, +); diff --git a/compiler/rustc_type_ir/src/error.rs b/compiler/rustc_type_ir/src/error.rs index eb5b6b4a1b450..d0c2a5c0d8f5b 100644 --- a/compiler/rustc_type_ir/src/error.rs +++ b/compiler/rustc_type_ir/src/error.rs @@ -1,11 +1,13 @@ use derive_where::derive_where; -use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + CustomizableTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic, +}; use crate::solve::NoSolution; use crate::{self as ty, Interner}; #[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[derive(TypeFoldable_Generic, TypeVisitable_Generic)] +#[derive(TypeFoldable_Generic, TypeVisitable_Generic, CustomizableTypeVisitable)] pub struct ExpectedFound { pub expected: T, pub found: T, @@ -19,7 +21,7 @@ impl ExpectedFound { // Data structures used in type unification #[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable)] #[cfg_attr(feature = "nightly", rustc_pass_by_value)] pub enum TypeError { Mismatch, diff --git a/compiler/rustc_type_ir/src/generic_arg.rs b/compiler/rustc_type_ir/src/generic_arg.rs index d6e33f724d0b2..b7459a8c8c131 100644 --- a/compiler/rustc_type_ir/src/generic_arg.rs +++ b/compiler/rustc_type_ir/src/generic_arg.rs @@ -1,10 +1,12 @@ use derive_where::derive_where; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; +use rustc_type_ir_macros::CustomizableTypeVisitable; use crate::Interner; #[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)] +#[derive(CustomizableTypeVisitable)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -18,6 +20,7 @@ pub enum GenericArgKind { impl Eq for GenericArgKind {} #[derive_where(Clone, Copy, PartialEq, Debug; I: Interner)] +#[derive(CustomizableTypeVisitable)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 8065db1e05dd7..5ac845e6ba883 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -41,6 +41,8 @@ mod macros; mod binder; mod canonical; mod const_kind; +#[cfg(not(feature = "nightly"))] +mod customizable_visit; mod flags; mod fold; mod generic_arg; @@ -64,6 +66,8 @@ pub use Variance::*; pub use binder::*; pub use canonical::*; pub use const_kind::*; +#[cfg(not(feature = "nightly"))] +pub use customizable_visit::*; pub use flags::*; pub use fold::*; pub use generic_arg::*; @@ -75,6 +79,7 @@ pub use predicate::*; pub use predicate_kind::*; pub use region_kind::*; pub use rustc_ast_ir::{FloatTy, IntTy, Movability, Mutability, Pinnedness, UintTy}; +use rustc_type_ir_macros::CustomizableTypeVisitable; pub use ty_info::*; pub use ty_kind::*; pub use upcast::*; @@ -213,7 +218,7 @@ pub fn debug_bound_var( } } -#[derive(Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, CustomizableTypeVisitable)] #[cfg_attr(feature = "nightly", derive(Decodable, Encodable, HashStable_NoContext))] #[cfg_attr(feature = "nightly", rustc_pass_by_value)] pub enum Variance { diff --git a/compiler/rustc_type_ir/src/opaque_ty.rs b/compiler/rustc_type_ir/src/opaque_ty.rs index b6fb9f28930f2..b660ac3f0fec7 100644 --- a/compiler/rustc_type_ir/src/opaque_ty.rs +++ b/compiler/rustc_type_ir/src/opaque_ty.rs @@ -1,13 +1,15 @@ use derive_where::derive_where; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; -use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + CustomizableTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic, +}; use crate::inherent::*; use crate::{self as ty, Interner}; #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) diff --git a/compiler/rustc_type_ir/src/pattern.rs b/compiler/rustc_type_ir/src/pattern.rs index 1f8b7158cb111..2a3cdfe74f775 100644 --- a/compiler/rustc_type_ir/src/pattern.rs +++ b/compiler/rustc_type_ir/src/pattern.rs @@ -1,12 +1,14 @@ use derive_where::derive_where; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; -use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + CustomizableTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, +}; use crate::Interner; #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs index 3e32a77885468..ebb4a8ec0e769 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -6,7 +6,9 @@ use derive_where::derive_where; use rustc_macros::{ Decodable, Decodable_NoContext, Encodable, Encodable_NoContext, HashStable_NoContext, }; -use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + CustomizableTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, +}; use crate::inherent::*; use crate::lift::Lift; @@ -17,7 +19,7 @@ use crate::{self as ty, Interner}; /// `A: 'region` #[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, A)] #[derive_where(Copy; I: Interner, A: Copy)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -52,7 +54,7 @@ where /// Trait references also appear in object types like `Foo`, but in /// that case the `Self` parameter is absent from the generic parameters. #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -129,7 +131,7 @@ impl ty::Binder> { } #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -274,7 +276,7 @@ impl fmt::Display for PredicatePolarity { } #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -325,7 +327,7 @@ impl ty::Binder> { /// The generic parameters don't include the erased `Self`, only trait /// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above). #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -394,7 +396,7 @@ impl ty::Binder> { /// A `ProjectionPredicate` for an `ExistentialTraitRef`. #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -552,7 +554,7 @@ impl From for AliasTermKind { /// * For an inherent projection, this would be `Ty::N<...>`. /// * For an opaque type, there is no explicit syntax. #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -764,7 +766,7 @@ impl From> for AliasTerm { /// Form #2 eventually yields one of these `ProjectionPredicate` /// instances to normalize the LHS. #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -827,7 +829,7 @@ impl fmt::Debug for ProjectionPredicate { /// Used by the new solver to normalize an alias. This always expects the `term` to /// be an unconstrained inference variable which is used as the output. #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -864,7 +866,7 @@ impl fmt::Debug for NormalizesTo { } #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) @@ -910,7 +912,7 @@ impl ty::Binder> { /// whether the `a` type is the type that we should label as "expected" when /// presenting user diagnostics. #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -925,7 +927,7 @@ impl Eq for SubtypePredicate {} /// Encodes that we have to coerce *from* the `a` type to the `b` type. #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs index 785d41929cfce..b64f89d050cd2 100644 --- a/compiler/rustc_type_ir/src/predicate_kind.rs +++ b/compiler/rustc_type_ir/src/predicate_kind.rs @@ -3,14 +3,16 @@ use std::fmt; use derive_where::derive_where; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; -use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + CustomizableTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic, +}; use crate::{self as ty, Interner}; /// A clause is something that can appear in where bounds or be inferred /// by implied bounds. #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) @@ -58,7 +60,7 @@ pub enum ClauseKind { impl Eq for ClauseKind {} #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) diff --git a/compiler/rustc_type_ir/src/region_kind.rs b/compiler/rustc_type_ir/src/region_kind.rs index 1e8585cf52ce8..48e202bb69a4d 100644 --- a/compiler/rustc_type_ir/src/region_kind.rs +++ b/compiler/rustc_type_ir/src/region_kind.rs @@ -5,6 +5,7 @@ use derive_where::derive_where; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; +use rustc_type_ir_macros::CustomizableTypeVisitable; use self::RegionKind::*; use crate::{BoundVarIndexKind, Interner}; @@ -126,6 +127,7 @@ rustc_index::newtype_index! { /// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/ /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] +#[derive(CustomizableTypeVisitable)] #[cfg_attr(feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext))] pub enum RegionKind { /// A region parameter; for example `'a` in `impl<'a> Trait for &'a ()`. diff --git a/compiler/rustc_type_ir/src/solve/inspect.rs b/compiler/rustc_type_ir/src/solve/inspect.rs index 3af2f8dbaf27d..eb0aa606ba828 100644 --- a/compiler/rustc_type_ir/src/solve/inspect.rs +++ b/compiler/rustc_type_ir/src/solve/inspect.rs @@ -18,7 +18,9 @@ //! [canonicalized]: https://rustc-dev-guide.rust-lang.org/solve/canonicalization.html use derive_where::derive_where; -use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + CustomizableTypeVisitable, TypeFoldable_Generic, TypeVisitable_Generic, +}; use crate::solve::{CandidateSource, Certainty, Goal, GoalSource, QueryResult}; use crate::{Canonical, CanonicalVarValues, Interner}; @@ -31,7 +33,7 @@ use crate::{Canonical, CanonicalVarValues, Interner}; /// inference variables from a nested `InferCtxt`. #[derive_where(Clone, PartialEq, Hash, Debug; I: Interner, T)] #[derive_where(Copy; I: Interner, T: Copy)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic)] pub struct State { pub var_values: CanonicalVarValues, pub data: T, @@ -87,7 +89,7 @@ pub enum ProbeStep { /// the final result of the current goal - via [ProbeKind::Root] - we also /// store the [QueryResult]. #[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic)] pub enum ProbeKind { /// The root inference context while proving a goal. Root { result: QueryResult }, diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs index ede23d5998327..bda9c2fea5aaa 100644 --- a/compiler/rustc_type_ir/src/solve/mod.rs +++ b/compiler/rustc_type_ir/src/solve/mod.rs @@ -5,7 +5,9 @@ use std::hash::Hash; use derive_where::derive_where; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; -use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + CustomizableTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, +}; use crate::lang_items::SolverTraitLangItem; use crate::search_graph::PathKind; @@ -33,7 +35,7 @@ pub struct NoSolution; /// we're currently typechecking while the `predicate` is some trait bound. #[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, P)] #[derive_where(Copy; I: Interner, P: Copy)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -95,7 +97,7 @@ pub enum GoalSource { #[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, Goal)] #[derive_where(Copy; I: Interner, Goal: Copy)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -206,7 +208,7 @@ pub enum ParamEnvSource { } #[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic)] pub enum AliasBoundKind { /// Alias bound from the self type of a projection SelfBounds, @@ -235,7 +237,7 @@ pub enum BuiltinImplSource { } #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic)] #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] pub struct Response { pub certainty: Certainty, @@ -248,7 +250,7 @@ impl Eq for Response {} /// Additional constraints returned on success. #[derive_where(Clone, Hash, PartialEq, Debug, Default; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic)] #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] pub struct ExternalConstraintsData { pub region_constraints: Vec>, @@ -267,7 +269,7 @@ impl ExternalConstraintsData { } #[derive_where(Clone, Hash, PartialEq, Debug, Default; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic)] #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] pub struct NestedNormalizationGoals(pub Vec<(GoalSource, Goal)>); diff --git a/compiler/rustc_type_ir/src/ty_info.rs b/compiler/rustc_type_ir/src/ty_info.rs index a999566745070..3eb2082fb8f2b 100644 --- a/compiler/rustc_type_ir/src/ty_info.rs +++ b/compiler/rustc_type_ir/src/ty_info.rs @@ -6,6 +6,7 @@ use std::ops::Deref; use rustc_data_structures::fingerprint::Fingerprint; #[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_type_ir_macros::CustomizableTypeVisitable; use crate::{DebruijnIndex, TypeFlags}; @@ -16,7 +17,7 @@ use crate::{DebruijnIndex, TypeFlags}; /// StableHash::ZERO for the hash, in which case the hash gets computed each time. /// This is useful if you have values that you intern but never (can?) use for stable /// hashing. -#[derive(Copy, Clone)] +#[derive(Copy, Clone, CustomizableTypeVisitable)] pub struct WithCachedTypeInfo { pub internee: T, diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index bb80e2cf46d45..ab9fb617e3f03 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -8,7 +8,9 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext}; use rustc_type_ir::data_structures::{NoError, UnifyKey, UnifyValue}; -use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + CustomizableTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, +}; use self::TyKind::*; pub use self::closure::*; @@ -20,6 +22,7 @@ use crate::{self as ty, BoundVarIndexKind, FloatTy, IntTy, Interner, UintTy}; mod closure; #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[derive(CustomizableTypeVisitable)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) @@ -56,6 +59,7 @@ impl AliasTyKind { /// converted to this representation using `::lower_ty`. #[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")] #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] +#[derive(CustomizableTypeVisitable)] #[cfg_attr( feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) @@ -391,7 +395,7 @@ impl fmt::Debug for TyKind { /// * For an inherent projection, this would be `Ty::N<...>`. /// * For an opaque type, there is no explicit syntax. #[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] #[cfg_attr( feature = "nightly", derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext) @@ -713,7 +717,7 @@ impl fmt::Debug for InferTy { feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) )] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic)] pub struct TypeAndMut { pub ty: I::Ty, pub mutbl: Mutability, @@ -726,7 +730,7 @@ impl Eq for TypeAndMut {} feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) )] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] pub struct FnSig { pub inputs_and_output: I::Tys, pub c_variadic: bool, @@ -839,7 +843,7 @@ impl fmt::Debug for FnSig { // impls in this crate for `Binder`. #[derive_where(Clone, Copy, PartialEq, Hash; I: Interner)] #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] pub struct UnsafeBinderInner(ty::Binder); impl Eq for UnsafeBinderInner {} @@ -905,7 +909,7 @@ where feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) )] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] pub struct FnSigTys { pub inputs_and_output: I::Tys, } @@ -959,7 +963,7 @@ impl ty::Binder> { feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) )] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] pub struct FnHeader { pub c_variadic: bool, pub safety: I::Safety, @@ -973,7 +977,7 @@ impl Eq for FnHeader {} feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext) )] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] pub struct CoroutineWitnessTypes { pub types: I::Tys, pub assumptions: I::RegionAssumptions, diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs index 4d9fd6040d8bf..91d93eff11094 100644 --- a/compiler/rustc_type_ir/src/ty_kind/closure.rs +++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs @@ -1,7 +1,9 @@ use std::ops::ControlFlow; use derive_where::derive_where; -use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; +use rustc_type_ir_macros::{ + CustomizableTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, +}; use crate::data_structures::DelayedMap; use crate::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable, shift_region}; @@ -102,7 +104,7 @@ use crate::{self as ty, Interner}; /// * `GR`: The "return type", which is the type of value returned upon /// completion of the coroutine. #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] pub struct ClosureArgs { /// Lifetime and type parameters from the enclosing function, /// concatenated with a tuple containing the types of the upvars. @@ -206,7 +208,7 @@ impl ClosureArgs { } #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] pub struct CoroutineClosureArgs { pub args: I::GenericArgs, } @@ -354,7 +356,7 @@ impl TypeVisitor for HasRegionsBoundAt { } #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic)] pub struct CoroutineClosureSignature { pub tupled_inputs_ty: I::Ty, pub resume_ty: I::Ty, @@ -549,7 +551,7 @@ impl TypeFolder for FoldEscapingRegions { } #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic)] pub struct GenSig { pub resume_ty: I::Ty, pub yield_ty: I::Ty, @@ -559,7 +561,7 @@ pub struct GenSig { impl Eq for GenSig {} /// Similar to `ClosureArgs`; see the above documentation for more. #[derive_where(Clone, Copy, PartialEq, Hash, Debug; I: Interner)] -#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[derive(TypeVisitable_Generic, CustomizableTypeVisitable, TypeFoldable_Generic, Lift_Generic)] pub struct CoroutineArgs { pub args: I::GenericArgs, } diff --git a/compiler/rustc_type_ir_macros/Cargo.toml b/compiler/rustc_type_ir_macros/Cargo.toml index 14bffa403a867..910eef5e21f41 100644 --- a/compiler/rustc_type_ir_macros/Cargo.toml +++ b/compiler/rustc_type_ir_macros/Cargo.toml @@ -6,6 +6,9 @@ edition = "2024" [lib] proc-macro = true +[features] +nightly = [] + [dependencies] # tidy-alphabetical-start proc-macro2 = "1" diff --git a/compiler/rustc_type_ir_macros/src/lib.rs b/compiler/rustc_type_ir_macros/src/lib.rs index 37617b789dba7..2d777d0a5f1e1 100644 --- a/compiler/rustc_type_ir_macros/src/lib.rs +++ b/compiler/rustc_type_ir_macros/src/lib.rs @@ -12,6 +12,10 @@ decl_derive!( decl_derive!( [Lift_Generic] => lift_derive ); +#[cfg(not(feature = "nightly"))] +decl_derive!( + [CustomizableTypeVisitable] => customizable_type_visitable_derive +); fn has_ignore_attr(attrs: &[Attribute], name: &'static str, meta: &'static str) -> bool { let mut ignored = false; @@ -211,3 +215,39 @@ fn lift(mut ty: syn::Type) -> syn::Type { ty } + +#[cfg(not(feature = "nightly"))] +fn customizable_type_visitable_derive( + mut s: synstructure::Structure<'_>, +) -> proc_macro2::TokenStream { + if let syn::Data::Union(_) = s.ast().data { + panic!("cannot derive on union") + } + + s.add_impl_generic(parse_quote!(__V)); + s.add_bounds(synstructure::AddBounds::Fields); + let body_visit = s.each(|bind| { + quote! { + ::rustc_type_ir::CustomizableTypeVisitable::<__V>::customizable_visit_with(#bind, __visitor); + } + }); + s.bind_with(|_| synstructure::BindStyle::Move); + + s.bound_impl( + quote!(::rustc_type_ir::CustomizableTypeVisitable<__V>), + quote! { + fn customizable_visit_with( + &self, + __visitor: &mut __V + ) { + match *self { #body_visit } + } + }, + ) +} + +#[cfg(feature = "nightly")] +#[proc_macro_derive(CustomizableTypeVisitable)] +pub fn customizable_type_visitable_derive(_: proc_macro::TokenStream) -> proc_macro::TokenStream { + proc_macro::TokenStream::new() +}