@@ -106,53 +106,55 @@ pub fn from_reflect_with_fallback<T: Reflect + TypePath>(
106106 world : & mut World ,
107107 registry : & TypeRegistry ,
108108) -> T {
109- fn different_type_error < T : TypePath > ( reflected : & str ) -> ! {
110- panic ! (
111- "The registration for the reflected `{}` trait for the type `{}` produced \
112- a value of a different type",
113- reflected,
114- T :: type_path( ) ,
115- ) ;
116- }
117-
118- // First, try `FromReflect`. This is handled differently from the others because
119- // it doesn't need a subsequent `apply` and may fail.
120- if let Some ( reflect_from_reflect) =
121- registry. get_type_data :: < ReflectFromReflect > ( TypeId :: of :: < T > ( ) )
122- {
109+ #[ inline( never) ]
110+ fn type_erased (
111+ reflected : & dyn PartialReflect ,
112+ world : & mut World ,
113+ registry : & TypeRegistry ,
114+ id : TypeId ,
115+ name : DebugName ,
116+ ) -> alloc:: boxed:: Box < dyn core:: any:: Any > {
117+ // First, try `FromReflect`. This is handled differently from the others because
118+ // it doesn't need a subsequent `apply` and may fail.
123119 // If it fails it's ok, we can continue checking `Default` and `FromWorld`.
124- if let Some ( value) = reflect_from_reflect. from_reflect ( reflected) {
125- return value
126- . take :: < T > ( )
127- . unwrap_or_else ( |_| different_type_error :: < T > ( "FromReflect" ) ) ;
120+ let ( value, source) = if let Some ( value) = registry
121+ . get_type_data :: < ReflectFromReflect > ( id)
122+ . and_then ( |reflect_from_reflect| reflect_from_reflect. from_reflect ( reflected) )
123+ {
124+ ( value, "FromReflect" )
128125 }
129- }
130-
131- // Create an instance of `T` using either the reflected `Default` or `FromWorld`.
132- let mut value = if let Some ( reflect_default) =
133- registry. get_type_data :: < ReflectDefault > ( TypeId :: of :: < T > ( ) )
134- {
135- reflect_default
136- . default ( )
137- . take :: < T > ( )
138- . unwrap_or_else ( |_| different_type_error :: < T > ( "Default" ) )
139- } else if let Some ( reflect_from_world) =
140- registry. get_type_data :: < ReflectFromWorld > ( TypeId :: of :: < T > ( ) )
141- {
142- reflect_from_world
143- . from_world ( world)
144- . take :: < T > ( )
145- . unwrap_or_else ( |_| different_type_error :: < T > ( "FromWorld" ) )
146- } else {
147- panic ! (
148- "Couldn't create an instance of `{}` using the reflected `FromReflect`, \
149- `Default` or `FromWorld` traits. Are you perhaps missing a `#[reflect(Default)]` \
150- or `#[reflect(FromWorld)]`?",
151- // FIXME: once we have unique reflect, use `TypePath`.
152- DebugName :: type_name:: <T >( ) ,
126+ // Create an instance of `T` using either the reflected `Default` or `FromWorld`.
127+ else if let Some ( reflect_default) = registry. get_type_data :: < ReflectDefault > ( id) {
128+ let mut value = reflect_default. default ( ) ;
129+ value. apply ( reflected) ;
130+ ( value, "Default" )
131+ } else if let Some ( reflect_from_world) = registry. get_type_data :: < ReflectFromWorld > ( id) {
132+ let mut value = reflect_from_world. from_world ( world) ;
133+ value. apply ( reflected) ;
134+ ( value, "FromWorld" )
135+ } else {
136+ panic ! (
137+ "Couldn't create an instance of `{name}` using the reflected `FromReflect`, \
138+ `Default` or `FromWorld` traits. Are you perhaps missing a `#[reflect(Default)]` \
139+ or `#[reflect(FromWorld)]`?",
140+ ) ;
141+ } ;
142+ assert_eq ! (
143+ value. as_any( ) . type_id( ) ,
144+ id,
145+ "The registration for the reflected `{source}` trait for the type `{name}` produced \
146+ a value of a different type",
153147 ) ;
154- } ;
155-
156- value. apply ( reflected) ;
157- value
148+ value
149+ }
150+ * type_erased (
151+ reflected,
152+ world,
153+ registry,
154+ TypeId :: of :: < T > ( ) ,
155+ // FIXME: once we have unique reflect, use `TypePath`.
156+ DebugName :: type_name :: < T > ( ) ,
157+ )
158+ . downcast :: < T > ( )
159+ . unwrap ( )
158160}
0 commit comments