diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index 67dfeb2bb10f7..ffc1c485aab88 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -55,7 +55,10 @@ pub mod __macro_exports { let mut new = [0; 16]; let mut i = 0; while i < new.len() { - new[i] = a.as_bytes()[i] ^ b.as_bytes()[i]; + // rotating ensures different uuids for A> and B> because: A ^ (B ^ C) = B ^ (A ^ C) + // notice that you have to rotate the second parameter: A.rr ^ (B.rr ^ C) = B.rr ^ (A.rr ^ C) + // Solution: A ^ (B ^ C.rr).rr != B ^ (A ^ C.rr).rr + new[i] = a.as_bytes()[i] ^ b.as_bytes()[i].rotate_right(1); i += 1; } diff --git a/crates/bevy_reflect/src/type_uuid.rs b/crates/bevy_reflect/src/type_uuid.rs index 9679f1836516c..906442713a78a 100644 --- a/crates/bevy_reflect/src/type_uuid.rs +++ b/crates/bevy_reflect/src/type_uuid.rs @@ -34,6 +34,7 @@ mod test { use super::*; use crate as bevy_reflect; use bevy_reflect_derive::TypeUuid; + use std::marker::PhantomData; #[derive(TypeUuid)] #[uuid = "af6466c2-a9f4-11eb-bcbc-0242ac130002"] @@ -73,4 +74,36 @@ mod test { assert_ne!(uuid_a, A::TYPE_UUID); assert_ne!(uuid_b, B::TYPE_UUID); } + + #[test] + fn test_inverted_generic_type_unique_uuid() { + #[derive(TypeUuid, Clone)] + #[uuid = "49951b1c-4811-45e7-acc6-3119249fbd8f"] + struct Inner; + + #[derive(TypeUuid, Clone)] + #[uuid = "23ebc0c3-ef69-4ea0-8c2a-dca1b4e27c0d"] + struct TestDeriveStructA + where + T: Clone, + { + _phantom: PhantomData, + } + + #[derive(TypeUuid, Clone)] + #[uuid = "a82f9936-70cb-482a-bd3d-cb99d87de55f"] + struct TestDeriveStructB + where + T: Clone, + { + _phantom: PhantomData, + } + + let uuid_ab = TestDeriveStructA::>::TYPE_UUID; + let uuid_ba = TestDeriveStructB::>::TYPE_UUID; + + assert_ne!(uuid_ab, uuid_ba); + assert_ne!(uuid_ab, TestDeriveStructA::::TYPE_UUID); + assert_ne!(uuid_ba, TestDeriveStructB::::TYPE_UUID); + } }