Use a default implementation for set_if_neq (#7660)
				
					
				
			# Objective While porting my crate `bevy_trait_query` to bevy 0.10, I ran into an issue with the `DetectChangesMut` trait. Due to the way that the `set_if_neq` method (added in #6853) is implemented, you are forced to write a nonsense implementation of it for dynamically sized types. This edge case shows up when implementing trait queries, since `DetectChangesMut` is implemented for `Mut<dyn Trait>`. ## Solution Simplify the generics for `set_if_neq` and add the `where Self::Target: Sized` trait bound to it. Add a default implementation so implementers don't need to implement a method with nonsensical trait bounds.
This commit is contained in:
		
							parent
							
								
									4f57f380c7
								
							
						
					
					
						commit
						670c4c1852
					
				@ -125,10 +125,17 @@ pub trait DetectChangesMut: DetectChanges {
 | 
				
			|||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// This is useful to ensure change detection is only triggered when the underlying value
 | 
					    /// This is useful to ensure change detection is only triggered when the underlying value
 | 
				
			||||||
    /// changes, instead of every time [`DerefMut`] is used.
 | 
					    /// changes, instead of every time [`DerefMut`] is used.
 | 
				
			||||||
    fn set_if_neq<Target>(&mut self, value: Target)
 | 
					    #[inline]
 | 
				
			||||||
 | 
					    fn set_if_neq(&mut self, value: Self::Inner)
 | 
				
			||||||
    where
 | 
					    where
 | 
				
			||||||
        Self: Deref<Target = Target> + DerefMut<Target = Target>,
 | 
					        Self::Inner: Sized + PartialEq,
 | 
				
			||||||
        Target: PartialEq;
 | 
					    {
 | 
				
			||||||
 | 
					        let old = self.bypass_change_detection();
 | 
				
			||||||
 | 
					        if *old != value {
 | 
				
			||||||
 | 
					            *old = value;
 | 
				
			||||||
 | 
					            self.set_changed();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
macro_rules! change_detection_impl {
 | 
					macro_rules! change_detection_impl {
 | 
				
			||||||
@ -195,19 +202,6 @@ macro_rules! change_detection_mut_impl {
 | 
				
			|||||||
            fn bypass_change_detection(&mut self) -> &mut Self::Inner {
 | 
					            fn bypass_change_detection(&mut self) -> &mut Self::Inner {
 | 
				
			||||||
                self.value
 | 
					                self.value
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					 | 
				
			||||||
            #[inline]
 | 
					 | 
				
			||||||
            fn set_if_neq<Target>(&mut self, value: Target)
 | 
					 | 
				
			||||||
            where
 | 
					 | 
				
			||||||
                Self: Deref<Target = Target> + DerefMut<Target = Target>,
 | 
					 | 
				
			||||||
                Target: PartialEq,
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                // This dereference is immutable, so does not trigger change detection
 | 
					 | 
				
			||||||
                if *<Self as Deref>::deref(self) != value {
 | 
					 | 
				
			||||||
                    // `DerefMut` usage triggers change detection
 | 
					 | 
				
			||||||
                    *<Self as DerefMut>::deref_mut(self) = value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        impl<$($generics),* : ?Sized $(+ $traits)?> DerefMut for $name<$($generics),*> {
 | 
					        impl<$($generics),* : ?Sized $(+ $traits)?> DerefMut for $name<$($generics),*> {
 | 
				
			||||||
@ -685,19 +679,6 @@ impl<'a> DetectChangesMut for MutUntyped<'a> {
 | 
				
			|||||||
    fn bypass_change_detection(&mut self) -> &mut Self::Inner {
 | 
					    fn bypass_change_detection(&mut self) -> &mut Self::Inner {
 | 
				
			||||||
        &mut self.value
 | 
					        &mut self.value
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[inline]
 | 
					 | 
				
			||||||
    fn set_if_neq<Target>(&mut self, value: Target)
 | 
					 | 
				
			||||||
    where
 | 
					 | 
				
			||||||
        Self: Deref<Target = Target> + DerefMut<Target = Target>,
 | 
					 | 
				
			||||||
        Target: PartialEq,
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // This dereference is immutable, so does not trigger change detection
 | 
					 | 
				
			||||||
        if *<Self as Deref>::deref(self) != value {
 | 
					 | 
				
			||||||
            // `DerefMut` usage triggers change detection
 | 
					 | 
				
			||||||
            *<Self as DerefMut>::deref_mut(self) = value;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl std::fmt::Debug for MutUntyped<'_> {
 | 
					impl std::fmt::Debug for MutUntyped<'_> {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user