Skip to content

Commit ae272ad

Browse files
committed
Normalized TypeIds in type info reflection dump outputs, added assert tests for dynamic trait type info
1 parent 1681c98 commit ae272ad

File tree

4 files changed

+342
-92
lines changed

4 files changed

+342
-92
lines changed

library/coretests/tests/mem/type_info.rs

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,252 @@ fn test_references() {
125125
_ => unreachable!(),
126126
}
127127
}
128+
129+
#[test]
130+
fn test_dynamic_traits() {
131+
use std::collections::HashSet;
132+
use std::mem::type_info::Trait;
133+
trait A<T> {}
134+
trait B<T>: A<T> {}
135+
trait C<T>: B<T> {}
136+
trait D<T, U>: A<T> + B<T> + C<U> {}
137+
138+
trait E<const CONST_NUM: i32> {
139+
type Foo;
140+
}
141+
142+
trait AnotherTrait {}
143+
144+
trait BarTrait<'a, 'b, const N: usize>: AnotherTrait {}
145+
146+
trait FooTrait<'a, 'b, const N: usize>: BarTrait<'a, 'b, N> + for<'x> BarTrait<'x, 'x, 0> {}
147+
148+
trait ProjectorSuperSuperTrait<'a>: AnotherTrait {
149+
type Item;
150+
type AnotherItem;
151+
}
152+
trait ProjectorSuperTrait<'a, 'b>:
153+
AnotherTrait + ProjectorSuperSuperTrait<'a, Item = &'a i32, AnotherItem = &'a i32>
154+
{
155+
type Item;
156+
type AnotherItem;
157+
}
158+
trait ProjectorTrait<'a, 'b>:
159+
ProjectorSuperTrait<'a, 'b, Item = &'a u32, AnotherItem = &'b u32>
160+
{
161+
}
162+
163+
fn preds_of<T: ?Sized + 'static>() -> &'static [Trait] {
164+
match const { Type::of::<T>() }.kind {
165+
TypeKind::DynTrait(d) => d.predicates,
166+
_ => unreachable!(),
167+
}
168+
}
169+
170+
fn pred<'a>(preds: &'a [Trait], want: TypeId) -> &'a Trait {
171+
preds
172+
.iter()
173+
.find(|p| p.ty == want)
174+
.unwrap_or_else(|| panic!("missing predicate for {want:?}"))
175+
}
176+
177+
fn assert_typeid_set_eq(actual: &[TypeId], expected: &[TypeId]) {
178+
let actual_set: HashSet<TypeId> = actual.iter().copied().collect();
179+
let expected_set: HashSet<TypeId> = expected.iter().copied().collect();
180+
assert_eq!(actual.len(), actual_set.len(), "duplicates present: {actual:?}");
181+
assert_eq!(
182+
actual_set, expected_set,
183+
"unexpected ids.\nactual: {actual:?}\nexpected: {expected:?}"
184+
);
185+
}
186+
187+
fn assert_predicates_exact(preds: &[Trait], expected_pred_ids: &[TypeId]) {
188+
let actual_pred_ids: Vec<TypeId> = preds.iter().map(|p| p.ty).collect();
189+
assert_typeid_set_eq(&actual_pred_ids, expected_pred_ids);
190+
}
191+
192+
// dyn Send
193+
{
194+
let preds = preds_of::<dyn Send>();
195+
assert_predicates_exact(preds, &[TypeId::of::<dyn Send>()]);
196+
197+
let p = pred(preds, TypeId::of::<dyn Send>());
198+
assert!(p.is_auto);
199+
assert!(p.super_traits.is_empty());
200+
}
201+
202+
// dyn A<i32>
203+
{
204+
let preds = preds_of::<dyn A<i32>>();
205+
assert_predicates_exact(preds, &[TypeId::of::<dyn A<i32>>()]);
206+
207+
let p = pred(preds, TypeId::of::<dyn A<i32>>());
208+
assert!(!p.is_auto);
209+
assert!(p.super_traits.is_empty());
210+
}
211+
212+
// dyn B<i32> : A<i32>
213+
{
214+
let preds = preds_of::<dyn B<i32>>();
215+
assert_predicates_exact(preds, &[TypeId::of::<dyn B<i32>>()]);
216+
217+
let p = pred(preds, TypeId::of::<dyn B<i32>>());
218+
assert!(!p.is_auto);
219+
assert_typeid_set_eq(p.super_traits, &[TypeId::of::<dyn A<i32>>()]);
220+
}
221+
222+
// dyn C<i32> + Send : (C<i32> : B<i32> : A<i32>) + Send
223+
{
224+
let preds = preds_of::<dyn C<i32> + Send>();
225+
assert_predicates_exact(preds, &[TypeId::of::<dyn C<i32>>(), TypeId::of::<dyn Send>()]);
226+
227+
let c = pred(preds, TypeId::of::<dyn C<i32>>());
228+
assert!(!c.is_auto);
229+
assert_typeid_set_eq(
230+
c.super_traits,
231+
&[TypeId::of::<dyn B<i32>>(), TypeId::of::<dyn A<i32>>()],
232+
);
233+
234+
let send = pred(preds, TypeId::of::<dyn Send>());
235+
assert!(send.is_auto);
236+
assert!(send.super_traits.is_empty());
237+
}
238+
239+
// dyn D<i32, bool> : A<i32> + B<i32> + C<bool> (and transitive super traits)
240+
{
241+
let preds = preds_of::<dyn D<i32, bool>>();
242+
assert_predicates_exact(preds, &[TypeId::of::<dyn D<i32, bool>>()]);
243+
244+
let d = pred(preds, TypeId::of::<dyn D<i32, bool>>());
245+
assert!(!d.is_auto);
246+
assert_typeid_set_eq(
247+
d.super_traits,
248+
&[
249+
TypeId::of::<dyn B<i32>>(),
250+
TypeId::of::<dyn A<i32>>(),
251+
TypeId::of::<dyn C<bool>>(),
252+
TypeId::of::<dyn B<bool>>(),
253+
TypeId::of::<dyn A<bool>>(),
254+
],
255+
);
256+
}
257+
258+
// dyn E<5, Foo = i32>
259+
{
260+
let preds = preds_of::<dyn E<5, Foo = i32>>();
261+
assert_predicates_exact(preds, &[TypeId::of::<dyn E<5, Foo = i32>>()]);
262+
263+
let e = pred(preds, TypeId::of::<dyn E<5, Foo = i32>>());
264+
assert!(!e.is_auto);
265+
assert!(e.super_traits.is_empty());
266+
}
267+
268+
// dyn for<'a> FooTrait<'a, 'a, 7>
269+
{
270+
let preds = preds_of::<dyn for<'a> FooTrait<'a, 'a, 7>>();
271+
assert_predicates_exact(preds, &[TypeId::of::<dyn for<'a> FooTrait<'a, 'a, 7>>()]);
272+
273+
let foo = pred(preds, TypeId::of::<dyn for<'a> FooTrait<'a, 'a, 7>>());
274+
assert!(!foo.is_auto);
275+
assert_typeid_set_eq(
276+
foo.super_traits,
277+
&[
278+
TypeId::of::<dyn for<'a> BarTrait<'a, 'a, 7>>(),
279+
TypeId::of::<dyn for<'x> BarTrait<'x, 'x, 0>>(),
280+
TypeId::of::<dyn AnotherTrait>(),
281+
],
282+
);
283+
}
284+
285+
// dyn FooTrait<'static, 'static, 7>
286+
{
287+
let preds = preds_of::<dyn FooTrait<'static, 'static, 7>>();
288+
assert_predicates_exact(preds, &[TypeId::of::<dyn FooTrait<'static, 'static, 7>>()]);
289+
290+
let foo = pred(preds, TypeId::of::<dyn FooTrait<'static, 'static, 7>>());
291+
assert!(!foo.is_auto);
292+
assert_typeid_set_eq(
293+
foo.super_traits,
294+
&[
295+
TypeId::of::<dyn BarTrait<'static, 'static, 7>>(),
296+
TypeId::of::<dyn for<'x> BarTrait<'x, 'x, 0>>(),
297+
TypeId::of::<dyn AnotherTrait>(),
298+
],
299+
);
300+
}
301+
302+
// dyn for<'a, 'b> FooTrait<'a, 'b, 7>
303+
{
304+
let preds = preds_of::<dyn for<'a, 'b> FooTrait<'a, 'b, 7>>();
305+
assert_predicates_exact(preds, &[TypeId::of::<dyn for<'a, 'b> FooTrait<'a, 'b, 7>>()]);
306+
307+
let foo = pred(preds, TypeId::of::<dyn for<'a, 'b> FooTrait<'a, 'b, 7>>());
308+
assert!(!foo.is_auto);
309+
assert_typeid_set_eq(
310+
foo.super_traits,
311+
&[
312+
TypeId::of::<dyn for<'a, 'b> BarTrait<'a, 'b, 7>>(),
313+
TypeId::of::<dyn for<'x> BarTrait<'x, 'x, 0>>(),
314+
TypeId::of::<dyn AnotherTrait>(),
315+
],
316+
);
317+
}
318+
319+
// dyn for<'a, 'b> ProjectorTrait<'a, 'b>
320+
{
321+
let preds = preds_of::<dyn for<'a, 'b> ProjectorTrait<'a, 'b>>();
322+
assert_predicates_exact(preds, &[TypeId::of::<dyn for<'a, 'b> ProjectorTrait<'a, 'b>>()]);
323+
324+
let proj = pred(preds, TypeId::of::<dyn for<'a, 'b> ProjectorTrait<'a, 'b>>());
325+
assert!(!proj.is_auto);
326+
assert_typeid_set_eq(
327+
proj.super_traits,
328+
&[
329+
TypeId::of::<
330+
dyn for<'a, 'b> ProjectorSuperTrait<
331+
'a,
332+
'b,
333+
Item = &'a u32,
334+
AnotherItem = &'b u32,
335+
>,
336+
>(),
337+
TypeId::of::<
338+
dyn for<'a> ProjectorSuperSuperTrait<'a, Item = &'a i32, AnotherItem = &'a i32>,
339+
>(),
340+
TypeId::of::<dyn AnotherTrait>(),
341+
],
342+
);
343+
}
344+
345+
// dyn for<'a> FooTrait<'a, 'a, 7> + Send + Sync
346+
{
347+
let preds = preds_of::<dyn for<'a> FooTrait<'a, 'a, 7> + Send + Sync>();
348+
assert_predicates_exact(
349+
preds,
350+
&[
351+
TypeId::of::<dyn for<'a> FooTrait<'a, 'a, 7>>(),
352+
TypeId::of::<dyn Send>(),
353+
TypeId::of::<dyn Sync>(),
354+
],
355+
);
356+
357+
let foo = pred(preds, TypeId::of::<dyn for<'a> FooTrait<'a, 'a, 7>>());
358+
assert!(!foo.is_auto);
359+
assert_typeid_set_eq(
360+
foo.super_traits,
361+
&[
362+
TypeId::of::<dyn for<'a> BarTrait<'a, 'a, 7>>(),
363+
TypeId::of::<dyn for<'x> BarTrait<'x, 'x, 0>>(),
364+
TypeId::of::<dyn AnotherTrait>(),
365+
],
366+
);
367+
368+
let send = pred(preds, TypeId::of::<dyn Send>());
369+
assert!(send.is_auto);
370+
assert!(send.super_traits.is_empty());
371+
372+
let sync = pred(preds, TypeId::of::<dyn Sync>());
373+
assert!(sync.is_auto);
374+
assert!(sync.super_traits.is_empty());
375+
}
376+
}

0 commit comments

Comments
 (0)