@@ -106,53 +106,55 @@ pub fn from_reflect_with_fallback<T: Reflect + TypePath>(
106
106
world : & mut World ,
107
107
registry : & TypeRegistry ,
108
108
) -> 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.
123
119
// 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" )
128
125
}
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",
153
147
) ;
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 ( )
158
160
}
0 commit comments