From 2725fb2b2208a2359cdf0254bdb94dffa2a64869 Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sat, 29 Mar 2025 12:13:34 -0700 Subject: [PATCH] Address issue with adding strings in `TypePath` derive --- crates/bevy_reflect/derive/src/string_expr.rs | 2 +- crates/bevy_reflect/src/lib.rs | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/crates/bevy_reflect/derive/src/string_expr.rs b/crates/bevy_reflect/derive/src/string_expr.rs index cc48a90b91735..dc878f39a9fd4 100644 --- a/crates/bevy_reflect/derive/src/string_expr.rs +++ b/crates/bevy_reflect/derive/src/string_expr.rs @@ -80,7 +80,7 @@ impl StringExpr { let owned = self.into_owned(); let borrowed = other.into_borrowed(); Self::Owned(quote! { - #owned + #borrowed + ::core::ops::Add::<&str>::add(#owned, #borrowed) }) } } diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index 64d07513ea09d..31540a54d2e9b 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -988,6 +988,41 @@ mod tests { assert_eq!(values, vec![1]); } + /// This test ensures that we are able to reflect generic types with one or more type parameters. + /// + /// When there is an `Add` implementation for `String`, the compiler isn't able to infer the correct + /// type to deref to. + /// If we don't append the strings in the `TypePath` derive correctly (i.e. explicitly specifying the type), + /// we'll get a compilation error saying that "`&String` cannot be added to `String`". + /// + /// So this test just ensures that we do do that correctly. + /// + /// This problem is a known issue and is unexpectedly expected behavior: + /// - + /// - + /// - + #[test] + fn should_reflect_generic() { + struct FakeString {} + + // This implementation confuses the compiler when trying to add a `&String` to a `String` + impl core::ops::Add for String { + type Output = Self; + fn add(self, _rhs: FakeString) -> Self::Output { + unreachable!() + } + } + + #[derive(Reflect)] + struct Foo(A); + + #[derive(Reflect)] + struct Bar(A, B); + + #[derive(Reflect)] + struct Baz(A, B, C); + } + #[test] fn should_reflect_clone() { // Struct