1use std::sync::Arc;
13
14use rustc_index::{Idx, IndexVec};
15use smallvec::SmallVec;
16use thin_vec::ThinVec;
17
18use crate::Interner;
19
20pub unsafe trait GenericTypeVisitable<V> {
30 fn generic_visit_with(&self, visitor: &mut V);
31}
32
33unsafe impl<V, T: ?Sized + GenericTypeVisitable<V>> GenericTypeVisitable<V> for &T {
37 fn generic_visit_with(&self, visitor: &mut V) {
38 T::generic_visit_with(*self, visitor)
39 }
40}
41
42unsafe impl<V, T: GenericTypeVisitable<V>, U: GenericTypeVisitable<V>> GenericTypeVisitable<V>
43 for (T, U)
44{
45 fn generic_visit_with(&self, visitor: &mut V) {
46 self.0.generic_visit_with(visitor);
47 self.1.generic_visit_with(visitor);
48 }
49}
50
51unsafe impl<V, A: GenericTypeVisitable<V>, B: GenericTypeVisitable<V>, C: GenericTypeVisitable<V>>
52 GenericTypeVisitable<V> for (A, B, C)
53{
54 fn generic_visit_with(&self, visitor: &mut V) {
55 self.0.generic_visit_with(visitor);
56 self.1.generic_visit_with(visitor);
57 self.2.generic_visit_with(visitor);
58 }
59}
60
61unsafe impl<V, T: GenericTypeVisitable<V>> GenericTypeVisitable<V> for Option<T> {
62 fn generic_visit_with(&self, visitor: &mut V) {
63 match self {
64 Some(v) => v.generic_visit_with(visitor),
65 None => {}
66 }
67 }
68}
69
70unsafe impl<V, T: GenericTypeVisitable<V>, E: GenericTypeVisitable<V>> GenericTypeVisitable<V>
71 for Result<T, E>
72{
73 fn generic_visit_with(&self, visitor: &mut V) {
74 match self {
75 Ok(v) => v.generic_visit_with(visitor),
76 Err(e) => e.generic_visit_with(visitor),
77 }
78 }
79}
80
81unsafe impl<V, T: ?Sized + GenericTypeVisitable<V>> GenericTypeVisitable<V> for Arc<T> {
82 fn generic_visit_with(&self, visitor: &mut V) {
83 (**self).generic_visit_with(visitor)
84 }
85}
86
87unsafe impl<V, T: ?Sized + GenericTypeVisitable<V>> GenericTypeVisitable<V> for Box<T> {
88 fn generic_visit_with(&self, visitor: &mut V) {
89 (**self).generic_visit_with(visitor)
90 }
91}
92
93unsafe impl<V, T: GenericTypeVisitable<V>> GenericTypeVisitable<V> for Vec<T> {
94 fn generic_visit_with(&self, visitor: &mut V) {
95 self.iter().for_each(|it| it.generic_visit_with(visitor));
96 }
97}
98
99unsafe impl<V, T: GenericTypeVisitable<V>> GenericTypeVisitable<V> for ThinVec<T> {
100 fn generic_visit_with(&self, visitor: &mut V) {
101 self.iter().for_each(|it| it.generic_visit_with(visitor));
102 }
103}
104
105unsafe impl<V, T: GenericTypeVisitable<V>, const N: usize> GenericTypeVisitable<V>
106 for SmallVec<[T; N]>
107{
108 fn generic_visit_with(&self, visitor: &mut V) {
109 self.iter().for_each(|it| it.generic_visit_with(visitor));
110 }
111}
112
113unsafe impl<V, T: GenericTypeVisitable<V>> GenericTypeVisitable<V> for [T] {
114 fn generic_visit_with(&self, visitor: &mut V) {
115 self.iter().for_each(|it| it.generic_visit_with(visitor));
116 }
117}
118
119unsafe impl<V, T: GenericTypeVisitable<V>, Ix: Idx> GenericTypeVisitable<V> for IndexVec<Ix, T> {
120 fn generic_visit_with(&self, visitor: &mut V) {
121 self.iter().for_each(|it| it.generic_visit_with(visitor));
122 }
123}
124
125unsafe impl<S, V> GenericTypeVisitable<V> for std::hash::BuildHasherDefault<S> {
126 fn generic_visit_with(&self, _visitor: &mut V) {}
127}
128
129#[expect(rustc::default_hash_types, rustc::potential_query_instability)]
130unsafe impl<
131 Visitor,
132 Key: GenericTypeVisitable<Visitor>,
133 Value: GenericTypeVisitable<Visitor>,
134 S: GenericTypeVisitable<Visitor>,
135> GenericTypeVisitable<Visitor> for std::collections::HashMap<Key, Value, S>
136{
137 fn generic_visit_with(&self, visitor: &mut Visitor) {
138 self.iter().for_each(|it| it.generic_visit_with(visitor));
139 self.hasher().generic_visit_with(visitor);
140 }
141}
142
143#[expect(rustc::default_hash_types, rustc::potential_query_instability)]
144unsafe impl<V, T: GenericTypeVisitable<V>, S: GenericTypeVisitable<V>> GenericTypeVisitable<V>
145 for std::collections::HashSet<T, S>
146{
147 fn generic_visit_with(&self, visitor: &mut V) {
148 self.iter().for_each(|it| it.generic_visit_with(visitor));
149 self.hasher().generic_visit_with(visitor);
150 }
151}
152
153unsafe impl<
154 Visitor,
155 Key: GenericTypeVisitable<Visitor>,
156 Value: GenericTypeVisitable<Visitor>,
157 S: GenericTypeVisitable<Visitor>,
158> GenericTypeVisitable<Visitor> for indexmap::IndexMap<Key, Value, S>
159{
160 fn generic_visit_with(&self, visitor: &mut Visitor) {
161 self.iter().for_each(|it| it.generic_visit_with(visitor));
162 self.hasher().generic_visit_with(visitor);
163 }
164}
165
166unsafe impl<V, T: GenericTypeVisitable<V>, S: GenericTypeVisitable<V>> GenericTypeVisitable<V>
167 for indexmap::IndexSet<T, S>
168{
169 fn generic_visit_with(&self, visitor: &mut V) {
170 self.iter().for_each(|it| it.generic_visit_with(visitor));
171 self.hasher().generic_visit_with(visitor);
172 }
173}
174
175macro_rules! trivial_impls {
176 ( $($ty:ty),* $(,)? ) => {
177 $(
178 unsafe impl<V>
179 GenericTypeVisitable<V> for $ty
180 {
181 fn generic_visit_with(&self, _visitor: &mut V) {}
182 }
183 )*
184 };
185}
186
187unsafe impl<T: ?Sized, V> GenericTypeVisitable<V> for std::marker::PhantomData<T> {
188 fn generic_visit_with(&self, _visitor: &mut V) {}
189}
190
191unsafe impl<V> GenericTypeVisitable<V> for rustc_abi::ExternAbi {
fn generic_visit_with(&self, _visitor: &mut V) {}
}trivial_impls!(
192 (),
193 rustc_ast_ir::Mutability,
194 bool,
195 i8,
196 i16,
197 i32,
198 i64,
199 i128,
200 isize,
201 u8,
202 u16,
203 u32,
204 u64,
205 u128,
206 usize,
207 crate::ClausePolarity,
208 crate::BoundConstness,
209 crate::DebruijnIndex,
210 crate::solve::Certainty,
211 crate::UniverseIndex,
212 crate::BoundVar,
213 crate::InferTy,
214 crate::IntTy,
215 crate::UintTy,
216 crate::FloatTy,
217 crate::InferConst,
218 crate::RegionVid,
219 rustc_hash::FxBuildHasher,
220 crate::TypeFlags,
221 crate::solve::GoalSource,
222 crate::solve::VisibleForLeakCheck,
223 rustc_abi::ExternAbi,
224);
225
226unsafe impl<I: Interner, V> GenericTypeVisitable<V> for crate::FnSigKind<I> {
228 fn generic_visit_with(&self, _visitor: &mut V) {}
229}