From b1a264188a0ac8127b89fe3b0b37fefaf65fa4b3 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 8 Sep 2024 03:20:37 +0200 Subject: [PATCH] Add #![warn(clippy::undocumented_unsafe_blocks)] --- src/lib.rs | 3 +++ src/observer.rs | 10 +++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 4ef210f..85635a7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -100,6 +100,7 @@ #![cfg(target_vendor = "apple")] #![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg_hide), doc(cfg_hide(doc)))] #![deny(unsafe_op_in_unsafe_fn)] +#![warn(clippy::undocumented_unsafe_blocks)] mod observer; @@ -143,6 +144,7 @@ impl hash::Hash for Layer { // // TODO(madsmtm): Move this to `objc2-quartz-core`. unsafe impl Send for Layer {} +// SAFETY: Same as above. unsafe impl Sync for Layer {} // Layer methods may panic, but that won't leave the layer in an invalid state. @@ -325,6 +327,7 @@ impl Layer { let ns_view: &NSObject = unsafe { ns_view_ptr.cast().as_ref() }; // Force the view to become layer backed + // SAFETY: The signature of `NSView::setWantsLayer` is correctly specified, and let _: () = unsafe { msg_send![ns_view, setWantsLayer: true] }; // SAFETY: `-[NSView layer]` returns an optional `CALayer` diff --git a/src/observer.rs b/src/observer.rs index ff8bea6..59b9cef 100644 --- a/src/observer.rs +++ b/src/observer.rs @@ -59,6 +59,7 @@ impl Drop for ObserverLayer { // We use a weak variable here to avoid issues if the layer was removed from the super // layer, and then later de-allocated, without de-registering these observers. if let Some(root_layer) = self.ivars().load() { + // SAFETY: The observer is registered for these key paths in `new`. unsafe { root_layer.removeObserver_forKeyPath(self, ns_string!("contentsScale")); root_layer.removeObserver_forKeyPath(self, ns_string!("bounds")); @@ -76,6 +77,7 @@ impl ObserverLayer { /// Create a new custom layer that tracks parameters from the given super layer. pub fn new(root_layer: &CALayer) -> Retained { let this = Self::alloc().set_ivars(Weak::new(root_layer)); + // SAFETY: Initializing `CAMetalLayer` is safe. let this: Retained = unsafe { msg_send_id![super(this), init] }; // Add the layer as a sublayer of the root layer. @@ -143,6 +145,8 @@ impl ObserverLayer { ) { // An unrecognized context must belong to the super class. if context != ObserverLayer::context() { + // SAFETY: The signature is correct, and it's safe to forward to the superclass' method + // when we're overriding the method. return unsafe { msg_send![ super(self), @@ -156,8 +160,10 @@ impl ObserverLayer { let change = change.expect("requested a change dictionary in `addObserver`, but none was provided"); + // SAFETY: The static is declared with the correct type in `objc2`. + let key = unsafe { NSKeyValueChangeNewKey }; let new = change - .get(unsafe { NSKeyValueChangeNewKey }) + .get(key) .expect("requested change dictionary did not contain `NSKeyValueChangeNewKey`"); // NOTE: Setting these values usually causes a quarter second animation to occur, which is @@ -167,6 +173,7 @@ impl ObserverLayer { // ongoing, and as such we don't need to wrap this in a `CATransaction` ourselves. if key_path == Some(ns_string!("contentsScale")) { + // SAFETY: `contentsScale` is a CGFloat, and so the observed value is always a NSNumber. let new = unsafe { &*(new as *const AnyObject as *const NSNumber) }; let scale_factor = new.as_cgfloat(); @@ -174,6 +181,7 @@ impl ObserverLayer { // moved to a different monitor, or monitor settings changed). self.setContentsScale(scale_factor); } else if key_path == Some(ns_string!("bounds")) { + // SAFETY: `bounds` is a CGRect, and so the observed value is always a NSValue. let new = unsafe { &*(new as *const AnyObject as *const NSValue) }; let bounds = new.get_rect().expect("new bounds value was not CGRect");