@@ -304,7 +304,14 @@ fn derive_hashed_label(
304
304
305
305
let ident = input. ident ;
306
306
let ( impl_generics, ty_generics, where_clause) = input. generics . split_for_impl ( ) ;
307
- let where_clause = with_static_bound ( where_clause) ;
307
+ let mut where_clause = with_static_bound ( where_clause) ;
308
+ where_clause. predicates . push (
309
+ syn:: parse2 ( quote ! {
310
+ Self : :: std:: clone:: Clone + :: std:: cmp:: Eq + :: std:: hash:: Hash + :: std:: fmt:: Debug
311
+ + :: std:: marker:: Send + :: std:: marker:: Sync + ' static
312
+ } )
313
+ . unwrap ( ) ,
314
+ ) ;
308
315
309
316
let compute_hash_path = {
310
317
let mut path = manifest. get_path ( "bevy_utils" ) ;
@@ -331,15 +338,27 @@ fn derive_hashed_label(
331
338
path. segments . push ( format_ident ! ( "LabelDowncast" ) . into ( ) ) ;
332
339
path
333
340
} ;
341
+ let downcast_debug_path = {
342
+ let mut path = manifest. get_path ( "bevy_ecs" ) ;
343
+ path. segments . push ( format_ident ! ( "schedule" ) . into ( ) ) ;
344
+ path. segments . push ( format_ident ! ( "DowncastDebug" ) . into ( ) ) ;
345
+ path
346
+ } ;
334
347
335
348
quote ! {
336
- static #interner_ident : #interner_type_path <#ident #ty_generics> = #interner_type_path:: new( ) ;
349
+ // NOTE: We need to box the interned objects in order to deal with generics.
350
+ // Unfortunately, we cannot associate data with generic impls, so they all must be
351
+ // stored together.
352
+ // FIXME: Make this concrete for types without generics.
353
+ static #interner_ident
354
+ : #interner_type_path <:: std:: boxed:: Box :: <dyn #downcast_debug_path + :: std:: marker:: Send + :: std:: marker:: Sync >>
355
+ = #interner_type_path:: new( ) ;
337
356
338
357
impl #impl_generics #trait_path for #ident #ty_generics #where_clause {
339
358
#[ inline]
340
359
fn data( & self ) -> u64 {
341
360
let hash = #compute_hash_path( self ) ;
342
- #interner_ident . intern( hash, || :: std:: clone:: Clone :: clone( self ) ) ;
361
+ #interner_ident . intern( hash, || :: std:: boxed :: Box :: new ( :: std :: clone:: Clone :: clone( self ) ) ) ;
343
362
hash
344
363
}
345
364
fn fmt( hash: u64 , f: & mut :: std:: fmt:: Formatter ) -> :: std:: fmt:: Result {
@@ -353,8 +372,12 @@ fn derive_hashed_label(
353
372
type Output = #guard_type_path <' static , Self >;
354
373
fn downcast_from( label: #id_path) -> Option <Self :: Output > {
355
374
let hash = <#id_path as #trait_path>:: data( & label) ;
356
- #interner_ident . get( hash)
375
+ <#guard_type_path<_>>:: try_map(
376
+ #interner_ident . get( hash) ?,
377
+ |val| <dyn #downcast_debug_path>:: downcast_ref:: <Self >( & * * val) ,
378
+ ) . ok( )
357
379
}
358
380
}
359
- } . into ( )
381
+ }
382
+ . into ( )
360
383
}
0 commit comments