From 92624e5ea29eb0566c5a45207591fa315f45baeb Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Thu, 26 May 2022 08:08:16 -0700 Subject: [PATCH] Make `GraphicsContext::window_mut()` an `unsafe fn`. As documented in the new safety comment, providing `&mut` access to an inner component about which there are consistency invariants is unsafe, because `&mut` is sufficient for a caller to completely replace the value (using assignment or `std::mem::swap()`). Luckily, when `softbuffer` is used with `winit`, no `&mut` access is needed. However, other windowing libraries such as `glfw` and `sdl2` do have `&mut` methods, so this method can't simply be removed. This is a breaking change since it makes a previously safe function unsafe, and should not be published without a major version bump (i.e. to `0.2.0` or higher). --- src/lib.rs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d1799242..06a071b5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -62,15 +62,28 @@ impl GraphicsContext { }) } - /// Gets shared access to the underlying window + /// Gets shared access to the underlying window. #[inline] pub fn window(&self) -> &W { &self.window } - /// Gets mut/exclusive access to the underlying window + /// Gets mut/exclusive access to the underlying window. + /// + /// This method is `unsafe` because it could be used to replace the window with another one, + /// thus dropping the original window and violating the property that this [`GraphicsContext`] + /// will always be destroyed before the window it writes into. This method should only be used + /// when the window type in use requires mutable access to perform some action on an existing + /// window. + /// + /// # Safety + /// + /// - After the returned mutable reference is dropped, the window must still be the same window + /// which this [`GraphicsContext`] was created for; and within that window, the + /// platform-specific configuration for 2D drawing must not have been modified. (For example, + /// on macOS the view hierarchy of the window must not have been modified.) #[inline] - pub fn window_mut(&mut self) -> &mut W { + pub unsafe fn window_mut(&mut self) -> &mut W { &mut self.window }