@@ -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.\n actual: {actual:?}\n expected: {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