From 77ecd8802fd8e4b324ca9a4840369a5eb0912ff6 Mon Sep 17 00:00:00 2001
From: Mads Marquart <mads@marquart.dk>
Date: Sun, 29 Aug 2021 21:21:06 +0200
Subject: [PATCH 1/6] Move examples to top level directory

---
 objc_foundation/examples/example.rs => examples/foundation.rs     | 0
 .../custom_class.rs => examples/foundation_custom_class.rs        | 0
 objc/examples/example.rs => examples/objc.rs                      | 0
 3 files changed, 0 insertions(+), 0 deletions(-)
 rename objc_foundation/examples/example.rs => examples/foundation.rs (100%)
 rename objc_foundation/examples/custom_class.rs => examples/foundation_custom_class.rs (100%)
 rename objc/examples/example.rs => examples/objc.rs (100%)

diff --git a/objc_foundation/examples/example.rs b/examples/foundation.rs
similarity index 100%
rename from objc_foundation/examples/example.rs
rename to examples/foundation.rs
diff --git a/objc_foundation/examples/custom_class.rs b/examples/foundation_custom_class.rs
similarity index 100%
rename from objc_foundation/examples/custom_class.rs
rename to examples/foundation_custom_class.rs
diff --git a/objc/examples/example.rs b/examples/objc.rs
similarity index 100%
rename from objc/examples/example.rs
rename to examples/objc.rs

From 5e4fd93ebf68d2b079055e5db34079cb0b11bd1f Mon Sep 17 00:00:00 2001
From: Mads Marquart <mads@marquart.dk>
Date: Sun, 29 Aug 2021 21:40:40 +0200
Subject: [PATCH 2/6] Update crates to edition 2018

---
 objc_exception/Cargo.toml         |  1 +
 objc_exception/src/lib.rs         | 10 +++++-----
 objc_foundation/Cargo.toml        |  1 +
 objc_foundation/src/array.rs      |  4 ++--
 objc_foundation/src/data.rs       |  4 ++--
 objc_foundation/src/dictionary.rs |  4 ++--
 objc_foundation/src/enumerator.rs |  4 ++--
 objc_foundation/src/object.rs     |  4 ++--
 objc_foundation/src/string.rs     |  2 +-
 objc_foundation/src/value.rs      |  4 ++--
 objc_id/Cargo.toml                |  1 +
 11 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/objc_exception/Cargo.toml b/objc_exception/Cargo.toml
index 7bb99c7cf..ea842f180 100644
--- a/objc_exception/Cargo.toml
+++ b/objc_exception/Cargo.toml
@@ -2,6 +2,7 @@
 name = "objc_exception"
 version = "0.1.2"
 authors = ["Steven Sheldon"]
+edition = "2018"
 
 description = "Rust interface for Objective-C's throw and try/catch statements."
 keywords = ["objective-c", "osx", "ios"]
diff --git a/objc_exception/src/lib.rs b/objc_exception/src/lib.rs
index b79f1367b..6b31de84a 100644
--- a/objc_exception/src/lib.rs
+++ b/objc_exception/src/lib.rs
@@ -10,7 +10,7 @@ extern "C" {}
 extern "C" {
     fn RustObjCExceptionThrow(exception: *mut c_void);
     fn RustObjCExceptionTryCatch(
-        try: extern "C" fn(*mut c_void),
+        r#try: extern "C" fn(*mut c_void),
         context: *mut c_void,
         error: *mut *mut c_void,
     ) -> c_int;
@@ -66,7 +66,7 @@ where
 ///
 /// Unsafe because this encourages unwinding through the closure from
 /// Objective-C, which is not safe.
-pub unsafe fn try<F, R>(closure: F) -> Result<R, *mut Exception>
+pub unsafe fn r#try<F, R>(closure: F) -> Result<R, *mut Exception>
 where
     F: FnOnce() -> R,
 {
@@ -83,14 +83,14 @@ where
 
 #[cfg(test)]
 mod tests {
-    use super::{throw, try};
+    use super::{r#try, throw};
     use std::ptr;
 
     #[test]
     fn test_try() {
         unsafe {
             let s = "Hello".to_string();
-            let result = try(move || {
+            let result = r#try(move || {
                 if s.len() > 0 {
                     throw(ptr::null_mut());
                 }
@@ -99,7 +99,7 @@ mod tests {
             assert!(result.unwrap_err() == ptr::null_mut());
 
             let mut s = "Hello".to_string();
-            let result = try(move || {
+            let result = r#try(move || {
                 s.push_str(", World!");
                 s
             });
diff --git a/objc_foundation/Cargo.toml b/objc_foundation/Cargo.toml
index 17c4a0ed4..02c4091c6 100644
--- a/objc_foundation/Cargo.toml
+++ b/objc_foundation/Cargo.toml
@@ -2,6 +2,7 @@
 name = "objc-foundation"
 version = "0.1.1"
 authors = ["Steven Sheldon"]
+edition = "2018"
 
 description = "Rust wrapper for Objective-C's Foundation framework."
 keywords = ["objective-c", "osx", "ios", "cocoa", "uikit"]
diff --git a/objc_foundation/src/array.rs b/objc_foundation/src/array.rs
index 527e8123a..6b031521b 100644
--- a/objc_foundation/src/array.rs
+++ b/objc_foundation/src/array.rs
@@ -6,7 +6,7 @@ use std::os::raw::c_void;
 use objc::runtime::{Class, Object};
 use objc_id::{Id, Owned, Ownership, ShareId, Shared};
 
-use {INSCopying, INSFastEnumeration, INSMutableCopying, INSObject, NSEnumerator};
+use super::{INSCopying, INSFastEnumeration, INSMutableCopying, INSObject, NSEnumerator};
 
 #[repr(isize)]
 #[derive(Clone, Copy)]
@@ -400,8 +400,8 @@ pub type NSMutableSharedArray<T> = NSMutableArray<T, Shared>;
 #[cfg(test)]
 mod tests {
     use super::{INSArray, INSMutableArray, NSArray, NSMutableArray};
+    use crate::{INSObject, INSString, NSObject, NSString};
     use objc_id::Id;
-    use {INSObject, INSString, NSObject, NSString};
 
     fn sample_array(len: usize) -> Id<NSArray<NSObject>> {
         let mut vec = Vec::with_capacity(len);
diff --git a/objc_foundation/src/data.rs b/objc_foundation/src/data.rs
index 178291e5d..1e386ad39 100644
--- a/objc_foundation/src/data.rs
+++ b/objc_foundation/src/data.rs
@@ -3,9 +3,9 @@ use std::ops::Range;
 use std::os::raw::c_void;
 use std::slice;
 
+use super::{INSCopying, INSMutableCopying, INSObject, NSRange};
 use block::{Block, ConcreteBlock};
 use objc_id::Id;
-use {INSCopying, INSMutableCopying, INSObject, NSRange};
 
 pub trait INSData: INSObject {
     fn len(&self) -> usize {
@@ -128,7 +128,7 @@ impl INSMutableCopying for NSMutableData {
 #[cfg(test)]
 mod tests {
     use super::{INSData, INSMutableData, NSData, NSMutableData};
-    use INSObject;
+    use crate::INSObject;
 
     #[test]
     fn test_bytes() {
diff --git a/objc_foundation/src/dictionary.rs b/objc_foundation/src/dictionary.rs
index 35260f9cf..3c29caff7 100644
--- a/objc_foundation/src/dictionary.rs
+++ b/objc_foundation/src/dictionary.rs
@@ -6,7 +6,7 @@ use std::ptr;
 use objc::runtime::Class;
 use objc_id::{Id, Owned, Ownership, ShareId};
 
-use {INSCopying, INSFastEnumeration, INSObject, NSArray, NSEnumerator, NSSharedArray};
+use super::{INSCopying, INSFastEnumeration, INSObject, NSArray, NSEnumerator, NSSharedArray};
 
 unsafe fn from_refs<D, T>(keys: &[&T], vals: &[&D::Value]) -> Id<D>
 where
@@ -164,8 +164,8 @@ where
 #[cfg(test)]
 mod tests {
     use super::{INSDictionary, NSDictionary};
+    use crate::{INSArray, INSObject, INSString, NSObject, NSString};
     use objc_id::Id;
-    use {INSArray, INSObject, INSString, NSObject, NSString};
 
     fn sample_dict(key: &str) -> Id<NSDictionary<NSString, NSObject>> {
         let string = NSString::from_str(key);
diff --git a/objc_foundation/src/enumerator.rs b/objc_foundation/src/enumerator.rs
index f3df042ba..121ac5481 100644
--- a/objc_foundation/src/enumerator.rs
+++ b/objc_foundation/src/enumerator.rs
@@ -7,7 +7,7 @@ use std::slice;
 use objc::runtime::Object;
 use objc_id::Id;
 
-use INSObject;
+use super::INSObject;
 
 pub struct NSEnumerator<'a, T>
 where
@@ -158,7 +158,7 @@ impl<'a, C: INSFastEnumeration> Iterator for NSFastEnumerator<'a, C> {
 #[cfg(test)]
 mod tests {
     use super::INSFastEnumeration;
-    use {INSArray, INSValue, NSArray, NSValue};
+    use crate::{INSArray, INSValue, NSArray, NSValue};
 
     #[test]
     fn test_enumerator() {
diff --git a/objc_foundation/src/object.rs b/objc_foundation/src/object.rs
index 77286ff50..b0b6b3e22 100644
--- a/objc_foundation/src/object.rs
+++ b/objc_foundation/src/object.rs
@@ -4,7 +4,7 @@ use objc::runtime::{Class, BOOL, NO};
 use objc::Message;
 use objc_id::{Id, ShareId};
 
-use NSString;
+use super::NSString;
 
 /*
 The Sized bound is unfortunate; ideally, objc objects would not be
@@ -54,7 +54,7 @@ object_struct!(NSObject);
 #[cfg(test)]
 mod tests {
     use super::{INSObject, NSObject};
-    use {INSString, NSString};
+    use crate::{INSString, NSString};
 
     #[test]
     fn test_is_equal() {
diff --git a/objc_foundation/src/string.rs b/objc_foundation/src/string.rs
index e7d9a9cff..3f9c21ed9 100644
--- a/objc_foundation/src/string.rs
+++ b/objc_foundation/src/string.rs
@@ -5,7 +5,7 @@ use std::str;
 
 use objc_id::{Id, ShareId};
 
-use INSObject;
+use super::INSObject;
 
 pub trait INSCopying: INSObject {
     type Output: INSObject;
diff --git a/objc_foundation/src/value.rs b/objc_foundation/src/value.rs
index f534d5674..16bf274a1 100644
--- a/objc_foundation/src/value.rs
+++ b/objc_foundation/src/value.rs
@@ -9,7 +9,7 @@ use objc::runtime::Class;
 use objc::{Encode, Encoding};
 use objc_id::Id;
 
-use {INSCopying, INSObject};
+use super::{INSCopying, INSObject};
 
 pub trait INSValue: INSObject {
     type Value: 'static + Copy + Encode;
@@ -79,8 +79,8 @@ where
 
 #[cfg(test)]
 mod tests {
+    use crate::{INSValue, NSValue};
     use objc::Encode;
-    use {INSValue, NSValue};
 
     #[test]
     fn test_value() {
diff --git a/objc_id/Cargo.toml b/objc_id/Cargo.toml
index 99598b913..71196c703 100644
--- a/objc_id/Cargo.toml
+++ b/objc_id/Cargo.toml
@@ -2,6 +2,7 @@
 name = "objc_id"
 version = "0.1.1"
 authors = ["Steven Sheldon"]
+edition = "2018"
 
 description = "Rust smart pointers for Objective-C reference counting."
 keywords = ["objective-c", "osx", "ios"]

From b2e8b53ed2e0a248a6463f158d80ebbfb1e07930 Mon Sep 17 00:00:00 2001
From: Mads Marquart <mads@marquart.dk>
Date: Sun, 29 Aug 2021 22:00:12 +0200
Subject: [PATCH 3/6] Remove most `extern crate` usage

---
 examples/foundation.rs                | 2 --
 examples/foundation_custom_class.rs   | 5 +----
 examples/objc.rs                      | 5 +----
 objc/src/declare.rs                   | 2 +-
 objc/src/lib.rs                       | 7 +------
 objc/src/macros.rs                    | 3 ---
 objc/src/message/mod.rs               | 2 +-
 objc/src/rc/mod.rs                    | 2 +-
 objc/tests-ios/prelude.rs             | 3 ---
 objc/tests/use_macros.rs              | 2 --
 objc_encode/examples/core_graphics.rs | 2 --
 objc_exception/build.rs               | 2 --
 objc_foundation/src/lib.rs            | 2 --
 objc_id/src/id.rs                     | 1 +
 objc_id/src/lib.rs                    | 6 +-----
 15 files changed, 8 insertions(+), 38 deletions(-)

diff --git a/examples/foundation.rs b/examples/foundation.rs
index 55c981e4a..310896608 100644
--- a/examples/foundation.rs
+++ b/examples/foundation.rs
@@ -1,5 +1,3 @@
-extern crate objc_foundation;
-
 use objc_foundation::{
     INSArray, INSCopying, INSDictionary, INSObject, INSString, NSArray, NSDictionary, NSObject,
     NSString,
diff --git a/examples/foundation_custom_class.rs b/examples/foundation_custom_class.rs
index 919b88cd1..22bef447b 100644
--- a/examples/foundation_custom_class.rs
+++ b/examples/foundation_custom_class.rs
@@ -1,10 +1,7 @@
-#[macro_use]
-extern crate objc;
-extern crate objc_foundation;
-
 use std::sync::{Once, ONCE_INIT};
 
 use objc::declare::ClassDecl;
+use objc::msg_send;
 use objc::runtime::{Class, Object, Sel};
 use objc::Message;
 use objc_foundation::{INSObject, NSObject};
diff --git a/examples/objc.rs b/examples/objc.rs
index a6f06b3d2..5026a77b6 100644
--- a/examples/objc.rs
+++ b/examples/objc.rs
@@ -1,9 +1,6 @@
-#[macro_use]
-extern crate objc;
-
 use objc::rc::StrongPtr;
 use objc::runtime::{Class, Object};
-use objc::Encode;
+use objc::{class, msg_send, Encode};
 
 fn main() {
     // Get a class
diff --git a/objc/src/declare.rs b/objc/src/declare.rs
index 3f39b251a..51e926df2 100644
--- a/objc/src/declare.rs
+++ b/objc/src/declare.rs
@@ -10,7 +10,7 @@ The following example demonstrates declaring a class named `MyNumber` that has
 one ivar, a `u32` named `_number` and a `number` method that returns it:
 
 ``` no_run
-# #[macro_use] extern crate objc;
+# use objc::class;
 # use objc::declare::ClassDecl;
 # use objc::runtime::{Class, Object, Sel};
 # fn main() {
diff --git a/objc/src/lib.rs b/objc/src/lib.rs
index 2f88a9796..d788f211c 100644
--- a/objc/src/lib.rs
+++ b/objc/src/lib.rs
@@ -6,7 +6,7 @@ Objective-C Runtime bindings and wrapper for Rust.
 Objective-C objects can be messaged using the [`msg_send!`](macro.msg_send!.html) macro:
 
 ``` no_run
-# #[macro_use] extern crate objc;
+# use objc::{class, msg_send};
 # use objc::runtime::{BOOL, Class, Object};
 # fn main() {
 # unsafe {
@@ -64,11 +64,6 @@ The bindings can be used on Linux or *BSD utilizing the
 #![crate_type = "lib"]
 #![warn(missing_docs)]
 
-extern crate malloc_buf;
-extern crate objc_encode;
-#[cfg(feature = "exception")]
-extern crate objc_exception;
-
 pub use objc_encode::{Encode, Encoding};
 
 pub use crate::encode::EncodeArguments;
diff --git a/objc/src/macros.rs b/objc/src/macros.rs
index 328f7a0c4..1bbb71486 100644
--- a/objc/src/macros.rs
+++ b/objc/src/macros.rs
@@ -6,7 +6,6 @@ To check for a class that may not exist, use `Class::get`.
 
 # Example
 ``` no_run
-# #[macro_use] extern crate objc;
 # fn main() {
 let cls = class!(NSObject);
 # }
@@ -31,7 +30,6 @@ Registers a selector, returning a `Sel`.
 
 # Example
 ```
-# #[macro_use] extern crate objc;
 # fn main() {
 let sel = sel!(description);
 let sel = sel!(setObject:forKey:);
@@ -64,7 +62,6 @@ Variadic arguments are not currently supported.
 
 # Example
 ``` no_run
-# #[macro_use] extern crate objc;
 # use objc::runtime::Object;
 # fn main() {
 # unsafe {
diff --git a/objc/src/message/mod.rs b/objc/src/message/mod.rs
index 301c16a71..c56017ef7 100644
--- a/objc/src/message/mod.rs
+++ b/objc/src/message/mod.rs
@@ -90,7 +90,7 @@ pub unsafe trait Message {
 
     # Example
     ``` no_run
-    # #[macro_use] extern crate objc;
+    # use objc::{class, msg_send};
     # use objc::runtime::{BOOL, Class, Object};
     # use objc::Message;
     # fn main() {
diff --git a/objc/src/rc/mod.rs b/objc/src/rc/mod.rs
index b609eb55a..a03647352 100644
--- a/objc/src/rc/mod.rs
+++ b/objc/src/rc/mod.rs
@@ -16,7 +16,7 @@ For more information on Objective-C's reference counting, see Apple's documentat
 # Example
 
 ``` no_run
-# #[macro_use] extern crate objc;
+# use objc::{class, msg_send};
 # use objc::rc::{autoreleasepool, StrongPtr};
 # fn main() {
 // StrongPtr will release the object when dropped
diff --git a/objc/tests-ios/prelude.rs b/objc/tests-ios/prelude.rs
index 2eabd4c83..8ec4c55ad 100644
--- a/objc/tests-ios/prelude.rs
+++ b/objc/tests-ios/prelude.rs
@@ -1,6 +1,3 @@
-#[macro_use]
-extern crate objc;
-
 use objc::rc::*;
 use objc::runtime::*;
 pub use objc::*;
diff --git a/objc/tests/use_macros.rs b/objc/tests/use_macros.rs
index b078503f0..8039c0ca6 100644
--- a/objc/tests/use_macros.rs
+++ b/objc/tests/use_macros.rs
@@ -1,7 +1,5 @@
 #![cfg(any(target_os = "macos", target_os = "ios"))]
 
-extern crate objc;
-
 use objc::runtime::Object;
 use objc::{class, msg_send, sel};
 
diff --git a/objc_encode/examples/core_graphics.rs b/objc_encode/examples/core_graphics.rs
index 4c0b7f75b..ed2f7c85a 100644
--- a/objc_encode/examples/core_graphics.rs
+++ b/objc_encode/examples/core_graphics.rs
@@ -1,5 +1,3 @@
-extern crate objc_encode;
-
 use objc_encode::{Encode, Encoding};
 
 #[cfg(target_pointer_width = "32")]
diff --git a/objc_exception/build.rs b/objc_exception/build.rs
index ba728b6e1..a17b0cc09 100644
--- a/objc_exception/build.rs
+++ b/objc_exception/build.rs
@@ -1,5 +1,3 @@
-extern crate cc;
-
 fn main() {
     cc::Build::new()
         .file("extern/exception.m")
diff --git a/objc_foundation/src/lib.rs b/objc_foundation/src/lib.rs
index 16f49cf87..6e1a6fa9c 100644
--- a/objc_foundation/src/lib.rs
+++ b/objc_foundation/src/lib.rs
@@ -3,8 +3,6 @@
 
 #[macro_use]
 extern crate objc;
-extern crate block;
-extern crate objc_id;
 
 pub use self::array::{
     INSArray, INSMutableArray, NSArray, NSComparisonResult, NSMutableArray, NSMutableSharedArray,
diff --git a/objc_id/src/id.rs b/objc_id/src/id.rs
index 2bb7a1aae..af4548597 100644
--- a/objc_id/src/id.rs
+++ b/objc_id/src/id.rs
@@ -202,6 +202,7 @@ unsafe impl<T> Send for WeakId<T> where T: Sync {}
 mod tests {
     use super::{Id, ShareId, WeakId};
     use objc::runtime::Object;
+    use objc::{class, msg_send};
 
     fn retain_count(obj: &Object) -> usize {
         unsafe { msg_send![obj, retainCount] }
diff --git a/objc_id/src/lib.rs b/objc_id/src/lib.rs
index d61d4fe0c..2a82acf9a 100644
--- a/objc_id/src/lib.rs
+++ b/objc_id/src/lib.rs
@@ -12,8 +12,7 @@ which can be cloned to allow multiple references.
 Weak references may be created using the [`WeakId`](struct.WeakId.html) struct.
 
 ```
-# #[macro_use] extern crate objc;
-# extern crate objc_id;
+# use objc::msg_send;
 use objc::runtime::{Class, Object};
 use objc_id::{Id, WeakId};
 
@@ -39,9 +38,6 @@ assert!(weak.load().is_none());
 ```
 */
 
-#[macro_use]
-extern crate objc;
-
 pub use id::{Id, Owned, Ownership, ShareId, Shared, WeakId};
 
 mod id;

From 7cc4d8db748028e26e15b9c08e8a68741dd728a8 Mon Sep 17 00:00:00 2001
From: Mads Marquart <mads@marquart.dk>
Date: Sun, 29 Aug 2021 22:01:56 +0200
Subject: [PATCH 4/6] Fix warnings (and upcoming edition idioms)

---
 objc/src/declare.rs          |  2 +-
 objc/src/message/mod.rs      |  8 ++++----
 objc/src/message/verify.rs   |  4 ++--
 objc/src/rc/strong.rs        |  2 +-
 objc/src/runtime.rs          |  9 +++++----
 objc/src/test_utils.rs       |  1 +
 objc_encode/src/encoding.rs  |  4 ++--
 objc_encode/src/parse.rs     |  4 ++--
 objc_foundation/src/value.rs | 11 +++++------
 objc_id/src/id.rs            |  4 ++--
 10 files changed, 25 insertions(+), 24 deletions(-)

diff --git a/objc/src/declare.rs b/objc/src/declare.rs
index 51e926df2..28221c75e 100644
--- a/objc/src/declare.rs
+++ b/objc/src/declare.rs
@@ -91,7 +91,7 @@ fn count_args(sel: Sel) -> usize {
     sel.name().chars().filter(|&c| c == ':').count()
 }
 
-fn method_type_encoding(ret: &Encoding, args: &[Encoding]) -> CString {
+fn method_type_encoding(ret: &Encoding<'_>, args: &[Encoding<'_>]) -> CString {
     // First two arguments are always self and the selector
     let mut types = format!("{}{}{}", ret, <*mut Object>::ENCODING, Sel::ENCODING);
     for enc in args {
diff --git a/objc/src/message/mod.rs b/objc/src/message/mod.rs
index c56017ef7..07a7e4d92 100644
--- a/objc/src/message/mod.rs
+++ b/objc/src/message/mod.rs
@@ -70,6 +70,7 @@ pub unsafe trait Message {
         send_message(self, sel, args)
     }
 
+    #[allow(missing_docs)]
     #[cfg(feature = "verify_message")]
     unsafe fn send_message<A, R>(&self, sel: Sel, args: A) -> Result<R, MessageError>
     where
@@ -195,7 +196,7 @@ Currently, an error may be returned in two cases:
 pub struct MessageError(String);
 
 impl fmt::Display for MessageError {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Display::fmt(&self.0, f)
     }
 }
@@ -207,7 +208,7 @@ impl Error for MessageError {
 }
 
 impl<'a> From<VerificationError<'a>> for MessageError {
-    fn from(err: VerificationError) -> MessageError {
+    fn from(err: VerificationError<'_>) -> MessageError {
         MessageError(err.to_string())
     }
 }
@@ -284,8 +285,7 @@ where
 
 #[cfg(test)]
 mod tests {
-    use super::Message;
-    use crate::runtime::Object;
+    use super::*;
     use crate::test_utils;
 
     #[test]
diff --git a/objc/src/message/verify.rs b/objc/src/message/verify.rs
index 06a5a6b37..7b401cabc 100644
--- a/objc/src/message/verify.rs
+++ b/objc/src/message/verify.rs
@@ -12,7 +12,7 @@ pub enum VerificationError<'a> {
 }
 
 impl<'a> fmt::Display for VerificationError<'a> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
             VerificationError::NilReceiver(sel) => {
                 write!(f, "Messsaging {:?} to nil", sel)
@@ -55,7 +55,7 @@ impl<'a> fmt::Display for VerificationError<'a> {
     }
 }
 
-pub fn verify_message_signature<A, R>(cls: &Class, sel: Sel) -> Result<(), VerificationError>
+pub fn verify_message_signature<A, R>(cls: &Class, sel: Sel) -> Result<(), VerificationError<'_>>
 where
     A: EncodeArguments,
     R: Encode,
diff --git a/objc/src/rc/strong.rs b/objc/src/rc/strong.rs
index 4536586ca..da3abd74a 100644
--- a/objc/src/rc/strong.rs
+++ b/objc/src/rc/strong.rs
@@ -65,7 +65,7 @@ impl Deref for StrongPtr {
 }
 
 impl fmt::Pointer for StrongPtr {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Pointer::fmt(&self.0, f)
     }
 }
diff --git a/objc/src/runtime.rs b/objc/src/runtime.rs
index 0c4eaa0d5..f763767cb 100644
--- a/objc/src/runtime.rs
+++ b/objc/src/runtime.rs
@@ -74,6 +74,7 @@ pub struct Object {
 /// A pointer to the start of a method implementation.
 pub type Imp = unsafe extern "C" fn();
 
+#[allow(missing_docs)]
 #[link(name = "objc", kind = "dylib")]
 extern "C" {
     pub fn sel_registerName(name: *const c_char) -> Sel;
@@ -210,7 +211,7 @@ impl Clone for Sel {
 }
 
 impl fmt::Debug for Sel {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(f, "{}", self.name())
     }
 }
@@ -405,7 +406,7 @@ impl PartialEq for Class {
 impl Eq for Class {}
 
 impl fmt::Debug for Class {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(f, "{}", self.name())
     }
 }
@@ -464,7 +465,7 @@ impl PartialEq for Protocol {
 impl Eq for Protocol {}
 
 impl fmt::Debug for Protocol {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(f, "{}", self.name())
     }
 }
@@ -538,7 +539,7 @@ impl Object {
 }
 
 impl fmt::Debug for Object {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(f, "<{:?}: {:p}>", self.class(), self)
     }
 }
diff --git a/objc/src/test_utils.rs b/objc/src/test_utils.rs
index 737965075..128954935 100644
--- a/objc/src/test_utils.rs
+++ b/objc/src/test_utils.rs
@@ -40,6 +40,7 @@ impl Drop for CustomObject {
 }
 
 #[derive(Eq, PartialEq)]
+#[repr(C)]
 pub struct CustomStruct {
     pub a: u64,
     pub b: u64,
diff --git a/objc_encode/src/encoding.rs b/objc_encode/src/encoding.rs
index 4932a54fe..868c5d4cc 100644
--- a/objc_encode/src/encoding.rs
+++ b/objc_encode/src/encoding.rs
@@ -36,7 +36,7 @@ pub enum Encoding<'a> {
 }
 
 impl fmt::Display for Encoding<'_> {
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
         use Encoding::*;
         let code = match *self {
             Char => "c",
@@ -94,7 +94,7 @@ impl PartialEq<str> for Encoding<'_> {
 }
 
 impl PartialEq<Encoding<'_>> for str {
-    fn eq(&self, other: &Encoding) -> bool {
+    fn eq(&self, other: &Encoding<'_>) -> bool {
         parse::eq_enc(self, other)
     }
 }
diff --git a/objc_encode/src/parse.rs b/objc_encode/src/parse.rs
index e935043c4..3082e5895 100644
--- a/objc_encode/src/parse.rs
+++ b/objc_encode/src/parse.rs
@@ -12,7 +12,7 @@ const QUALIFIERS: &'static [char] = &[
     'V', // oneway
 ];
 
-fn rm_enc_prefix<'a>(s: &'a str, enc: &Encoding) -> Option<&'a str> {
+fn rm_enc_prefix<'a>(s: &'a str, enc: &Encoding<'_>) -> Option<&'a str> {
     use Encoding::*;
     let code = match *enc {
         Char => "c",
@@ -96,7 +96,7 @@ fn rm_prefix<'a>(s: &'a str, other: &str) -> Option<&'a str> {
     }
 }
 
-pub fn eq_enc(s: &str, enc: &Encoding) -> bool {
+pub fn eq_enc(s: &str, enc: &Encoding<'_>) -> bool {
     // strip qualifiers
     let s = s.trim_start_matches(QUALIFIERS);
 
diff --git a/objc_foundation/src/value.rs b/objc_foundation/src/value.rs
index 16bf274a1..2f888d31f 100644
--- a/objc_foundation/src/value.rs
+++ b/objc_foundation/src/value.rs
@@ -1,7 +1,7 @@
 use std::any::Any;
 use std::ffi::{CStr, CString};
 use std::marker::PhantomData;
-use std::mem;
+use std::mem::MaybeUninit;
 use std::os::raw::{c_char, c_void};
 use std::str;
 
@@ -16,12 +16,11 @@ pub trait INSValue: INSObject {
 
     fn value(&self) -> Self::Value {
         assert!(Self::Value::encode() == self.encoding());
+        let mut value = MaybeUninit::<Self::Value>::uninit();
+        let ptr = value.as_mut_ptr() as *mut c_void;
         unsafe {
-            let mut value = mem::uninitialized::<Self::Value>();
-            let value_ptr: *mut Self::Value = &mut value;
-            let bytes = value_ptr as *mut c_void;
-            let _: () = msg_send![self, getValue: bytes];
-            value
+            let _: () = msg_send![self, getValue: ptr];
+            value.assume_init()
         }
     }
 
diff --git a/objc_id/src/id.rs b/objc_id/src/id.rs
index af4548597..c547324d8 100644
--- a/objc_id/src/id.rs
+++ b/objc_id/src/id.rs
@@ -149,13 +149,13 @@ impl<T, O> fmt::Debug for Id<T, O>
 where
     T: fmt::Debug,
 {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         self.deref().fmt(f)
     }
 }
 
 impl<T, O> fmt::Pointer for Id<T, O> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Pointer::fmt(&self.ptr, f)
     }
 }

From e42c7061812040b3f7168ccd8c941f519570e791 Mon Sep 17 00:00:00 2001
From: Mads Marquart <mads@marquart.dk>
Date: Sun, 29 Aug 2021 22:06:58 +0200
Subject: [PATCH 5/6] Apply automatic clippy fixes

---
 objc/src/declare.rs               | 4 ++--
 objc/src/message/apple/mod.rs     | 2 +-
 objc/src/rc/mod.rs                | 5 ++++-
 objc/src/runtime.rs               | 2 +-
 objc/src/test_utils.rs            | 2 +-
 objc_encode/src/parse.rs          | 2 +-
 objc_exception/src/lib.rs         | 2 +-
 objc_foundation/src/array.rs      | 2 +-
 objc_foundation/src/enumerator.rs | 4 ++--
 objc_id/src/id.rs                 | 2 +-
 10 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/objc/src/declare.rs b/objc/src/declare.rs
index 28221c75e..047e567a2 100644
--- a/objc/src/declare.rs
+++ b/objc/src/declare.rs
@@ -123,7 +123,7 @@ impl ClassDecl {
         if cls.is_null() {
             None
         } else {
-            Some(ClassDecl { cls: cls })
+            Some(ClassDecl { cls })
         }
     }
 
@@ -262,7 +262,7 @@ impl ProtocolDecl {
         if proto.is_null() {
             None
         } else {
-            Some(ProtocolDecl { proto: proto })
+            Some(ProtocolDecl { proto })
         }
     }
 
diff --git a/objc/src/message/apple/mod.rs b/objc/src/message/apple/mod.rs
index 3c9a9f71f..6ed5140be 100644
--- a/objc/src/message/apple/mod.rs
+++ b/objc/src/message/apple/mod.rs
@@ -42,7 +42,7 @@ where
 {
     let sup = Super {
         receiver: obj as *mut T as *mut Object,
-        superclass: superclass,
+        superclass,
     };
     let receiver = &sup as *const Super as *mut Object;
     let msg_send_fn = msg_send_super_fn::<R>();
diff --git a/objc/src/rc/mod.rs b/objc/src/rc/mod.rs
index a03647352..4bb40b565 100644
--- a/objc/src/rc/mod.rs
+++ b/objc/src/rc/mod.rs
@@ -91,8 +91,11 @@ mod tests {
         let weak = obj.weak();
 
         let weak2 = weak.clone();
-        let strong = weak2.load();
+
+        let strong = weak.load();
+        let strong2 = weak2.load();
         assert!(*strong == *obj);
+        assert!(*strong2 == *obj);
     }
 
     #[test]
diff --git a/objc/src/runtime.rs b/objc/src/runtime.rs
index f763767cb..deed6f65c 100644
--- a/objc/src/runtime.rs
+++ b/objc/src/runtime.rs
@@ -180,7 +180,7 @@ impl Sel {
     /// This is almost never what you want; use `Sel::register()` instead.
     #[inline]
     pub unsafe fn from_ptr(ptr: *const c_void) -> Sel {
-        Sel { ptr: ptr }
+        Sel { ptr }
     }
 
     /// Returns a pointer to the raw selector.
diff --git a/objc/src/test_utils.rs b/objc/src/test_utils.rs
index 128954935..2e2277b15 100644
--- a/objc/src/test_utils.rs
+++ b/objc/src/test_utils.rs
@@ -13,7 +13,7 @@ pub struct CustomObject {
 impl CustomObject {
     fn new(class: &Class) -> Self {
         let obj = unsafe { runtime::class_createInstance(class, 0) };
-        CustomObject { obj: obj }
+        CustomObject { obj }
     }
 }
 
diff --git a/objc_encode/src/parse.rs b/objc_encode/src/parse.rs
index 3082e5895..04239a658 100644
--- a/objc_encode/src/parse.rs
+++ b/objc_encode/src/parse.rs
@@ -2,7 +2,7 @@
 
 use crate::Encoding;
 
-const QUALIFIERS: &'static [char] = &[
+const QUALIFIERS: &[char] = &[
     'r', // const
     'n', // in
     'N', // inout
diff --git a/objc_exception/src/lib.rs b/objc_exception/src/lib.rs
index 6b31de84a..ac30cba29 100644
--- a/objc_exception/src/lib.rs
+++ b/objc_exception/src/lib.rs
@@ -91,7 +91,7 @@ mod tests {
         unsafe {
             let s = "Hello".to_string();
             let result = r#try(move || {
-                if s.len() > 0 {
+                if !s.is_empty() {
                     throw(ptr::null_mut());
                 }
                 s.len()
diff --git a/objc_foundation/src/array.rs b/objc_foundation/src/array.rs
index 6b031521b..b05ec7a66 100644
--- a/objc_foundation/src/array.rs
+++ b/objc_foundation/src/array.rs
@@ -453,7 +453,7 @@ mod tests {
         assert!(middle_objs[1] == array.object_at(2));
 
         let empty_objs = array.objects_in_range(1..1);
-        assert!(empty_objs.len() == 0);
+        assert!(empty_objs.is_empty());
 
         let all_objs = array.objects_in_range(0..4);
         assert!(all_objs.len() == 4);
diff --git a/objc_foundation/src/enumerator.rs b/objc_foundation/src/enumerator.rs
index 121ac5481..69d900722 100644
--- a/objc_foundation/src/enumerator.rs
+++ b/objc_foundation/src/enumerator.rs
@@ -98,7 +98,7 @@ pub struct NSFastEnumerator<'a, C: 'a + INSFastEnumeration> {
 impl<'a, C: INSFastEnumeration> NSFastEnumerator<'a, C> {
     fn new(object: &C) -> NSFastEnumerator<C> {
         NSFastEnumerator {
-            object: object,
+            object,
 
             ptr: ptr::null(),
             end: ptr::null(),
@@ -129,7 +129,7 @@ impl<'a, C: INSFastEnumeration> NSFastEnumerator<'a, C> {
             }
 
             self.ptr = buf.as_ptr();
-            self.end = unsafe { self.ptr.offset(buf.len() as isize) };
+            self.end = unsafe { self.ptr.add(buf.len()) };
             true
         } else {
             self.ptr = ptr::null();
diff --git a/objc_id/src/id.rs b/objc_id/src/id.rs
index c547324d8..41dd8e51f 100644
--- a/objc_id/src/id.rs
+++ b/objc_id/src/id.rs
@@ -46,7 +46,7 @@ where
 {
     unsafe fn new(ptr: StrongPtr) -> Id<T, O> {
         Id {
-            ptr: ptr,
+            ptr,
             item: PhantomData,
             own: PhantomData,
         }

From 30d83ea40d09cec51082fd73898f3d2715da5168 Mon Sep 17 00:00:00 2001
From: Mads Marquart <mads@marquart.dk>
Date: Sun, 29 Aug 2021 22:33:46 +0200
Subject: [PATCH 6/6] Fix remaining clippy lints

---
 objc/src/declare.rs               | 14 +++++++++----
 objc/src/exception.rs             | 13 ++++++++++++
 objc/src/lib.rs                   |  1 +
 objc/src/rc/strong.rs             | 10 +++++++--
 objc/src/rc/weak.rs               |  5 ++++-
 objc/src/runtime.rs               | 22 ++++++++++++++------
 objc_encode/src/parse.rs          | 34 ++++++++++++-------------------
 objc_exception/src/lib.rs         |  9 ++++++--
 objc_foundation/src/data.rs       |  4 ++++
 objc_foundation/src/enumerator.rs |  6 ++++++
 objc_foundation/src/string.rs     |  4 ++++
 objc_id/src/id.rs                 | 18 ++++++++--------
 12 files changed, 96 insertions(+), 44 deletions(-)

diff --git a/objc/src/declare.rs b/objc/src/declare.rs
index 047e567a2..6e395d8bc 100644
--- a/objc/src/declare.rs
+++ b/objc/src/declare.rs
@@ -159,8 +159,11 @@ impl ClassDecl {
     /// Adds a method with the given name and implementation to self.
     /// Panics if the method wasn't sucessfully added
     /// or if the selector and function take different numbers of arguments.
-    /// Unsafe because the caller must ensure that the types match those that
-    /// are expected when the method is invoked from Objective-C.
+    ///
+    /// # Safety
+    ///
+    /// The caller must ensure that the types match those that are expected
+    /// when the method is invoked from Objective-C.
     pub unsafe fn add_method<F>(&mut self, sel: Sel, func: F)
     where
         F: MethodImplementation<Callee = Object>,
@@ -182,8 +185,11 @@ impl ClassDecl {
     /// Adds a class method with the given name and implementation to self.
     /// Panics if the method wasn't sucessfully added
     /// or if the selector and function take different numbers of arguments.
-    /// Unsafe because the caller must ensure that the types match those that
-    /// are expected when the method is invoked from Objective-C.
+    ///
+    /// # Safety
+    ///
+    /// The caller must ensure that the types match those that are expected
+    /// when the method is invoked from Objective-C.
     pub unsafe fn add_class_method<F>(&mut self, sel: Sel, func: F)
     where
         F: MethodImplementation<Callee = Class>,
diff --git a/objc/src/exception.rs b/objc/src/exception.rs
index 3e16c92cf..f5dab0992 100644
--- a/objc/src/exception.rs
+++ b/objc/src/exception.rs
@@ -3,6 +3,19 @@ use objc_exception;
 use crate::rc::StrongPtr;
 use crate::runtime::Object;
 
+// Comment copied from `objc_exception`
+
+/// Tries to execute the given closure and catches an Objective-C exception
+/// if one is thrown.
+///
+/// Returns a `Result` that is either `Ok` if the closure succeeded without an
+/// exception being thrown, or an `Err` with a pointer to an exception if one
+/// was thrown. The exception is retained and so must be released.
+///
+/// # Safety
+///
+/// This encourages unwinding through the closure from Objective-C, which is
+/// not safe.
 pub unsafe fn catch_exception<F, R>(closure: F) -> Result<R, StrongPtr>
 where
     F: FnOnce() -> R,
diff --git a/objc/src/lib.rs b/objc/src/lib.rs
index d788f211c..40d9e56a7 100644
--- a/objc/src/lib.rs
+++ b/objc/src/lib.rs
@@ -63,6 +63,7 @@ The bindings can be used on Linux or *BSD utilizing the
 #![crate_name = "objc"]
 #![crate_type = "lib"]
 #![warn(missing_docs)]
+#![allow(clippy::missing_safety_doc)]
 
 pub use objc_encode::{Encode, Encoding};
 
diff --git a/objc/src/rc/strong.rs b/objc/src/rc/strong.rs
index da3abd74a..971692d63 100644
--- a/objc/src/rc/strong.rs
+++ b/objc/src/rc/strong.rs
@@ -12,14 +12,20 @@ impl StrongPtr {
     /// Constructs a `StrongPtr` to a newly created object that already has a
     /// +1 retain count. This will not retain the object.
     /// When dropped, the object will be released.
-    /// Unsafe because the caller must ensure the given object pointer is valid.
+    ///
+    /// # Safety
+    ///
+    /// The caller must ensure the given object pointer is valid.
     pub unsafe fn new(ptr: *mut Object) -> Self {
         StrongPtr(ptr)
     }
 
     /// Retains the given object and constructs a `StrongPtr` to it.
     /// When dropped, the object will be released.
-    /// Unsafe because the caller must ensure the given object pointer is valid.
+    ///
+    /// # Safety
+    ///
+    /// The caller must ensure the given object pointer is valid.
     pub unsafe fn retain(ptr: *mut Object) -> Self {
         StrongPtr(runtime::objc_retain(ptr))
     }
diff --git a/objc/src/rc/weak.rs b/objc/src/rc/weak.rs
index 4a748f9f4..975fb94bc 100644
--- a/objc/src/rc/weak.rs
+++ b/objc/src/rc/weak.rs
@@ -14,7 +14,10 @@ pub struct WeakPtr(Box<UnsafeCell<*mut Object>>);
 
 impl WeakPtr {
     /// Constructs a `WeakPtr` to the given object.
-    /// Unsafe because the caller must ensure the given object pointer is valid.
+    ///
+    /// # Safety
+    ///
+    /// The caller must ensure the given object pointer is valid.
     pub unsafe fn new(obj: *mut Object) -> Self {
         let ptr = Box::new(UnsafeCell::new(ptr::null_mut()));
         runtime::objc_initWeak(ptr.get(), obj);
diff --git a/objc/src/runtime.rs b/objc/src/runtime.rs
index deed6f65c..f1a0732ff 100644
--- a/objc/src/runtime.rs
+++ b/objc/src/runtime.rs
@@ -177,6 +177,10 @@ impl Sel {
 
     /// Wraps a raw pointer to a selector into a `Sel` object.
     ///
+    /// # Safety
+    ///
+    /// The pointer must a valid, registered selector.
+    ///
     /// This is almost never what you want; use `Sel::register()` instead.
     #[inline]
     pub unsafe fn from_ptr(ptr: *const c_void) -> Sel {
@@ -478,8 +482,10 @@ impl Object {
 
     /// Returns a reference to the ivar of self with the given name.
     /// Panics if self has no ivar with the given name.
-    /// Unsafe because the caller must ensure that the ivar is actually
-    /// of type `T`.
+    ///
+    /// # Safety
+    ///
+    /// The caller must ensure that the ivar is actually of type `T`.
     pub unsafe fn get_ivar<T>(&self, name: &str) -> &T
     where
         T: Encode,
@@ -503,8 +509,10 @@ impl Object {
 
     /// Returns a mutable reference to the ivar of self with the given name.
     /// Panics if self has no ivar with the given name.
-    /// Unsafe because the caller must ensure that the ivar is actually
-    /// of type `T`.
+    ///
+    /// # Safety
+    ///
+    /// The caller must ensure that the ivar is actually of type `T`.
     pub unsafe fn get_mut_ivar<T>(&mut self, name: &str) -> &mut T
     where
         T: Encode,
@@ -528,8 +536,10 @@ impl Object {
 
     /// Sets the value of the ivar of self with the given name.
     /// Panics if self has no ivar with the given name.
-    /// Unsafe because the caller must ensure that the ivar is actually
-    /// of type `T`.
+    ///
+    /// # Safety
+    ///
+    /// The caller must ensure that the ivar is actually of type `T`.
     pub unsafe fn set_ivar<T>(&mut self, name: &str, value: T)
     where
         T: Encode,
diff --git a/objc_encode/src/parse.rs b/objc_encode/src/parse.rs
index 04239a658..a0dfaca7c 100644
--- a/objc_encode/src/parse.rs
+++ b/objc_encode/src/parse.rs
@@ -36,43 +36,43 @@ fn rm_enc_prefix<'a>(s: &'a str, enc: &Encoding<'_>) -> Option<&'a str> {
         Sel => ":",
         Unknown => "?",
         BitField(b) => {
-            let s = rm_prefix(s, "b")?;
+            let s = s.strip_prefix('b')?;
             return rm_int_prefix(s, b);
         }
         Pointer(t) => {
-            let s = rm_prefix(s, "^")?;
+            let s = s.strip_prefix('^')?;
             return rm_enc_prefix(s, t);
         }
         Array(len, item) => {
             let mut s = s;
-            s = rm_prefix(s, "[")?;
+            s = s.strip_prefix('[')?;
             s = rm_int_prefix(s, len)?;
             s = rm_enc_prefix(s, item)?;
-            return rm_prefix(s, "]");
+            return s.strip_prefix(']');
         }
         Struct(name, fields) => {
             let mut s = s;
-            s = rm_prefix(s, "{")?;
-            s = rm_prefix(s, name)?;
-            s = rm_prefix(s, "=")?;
+            s = s.strip_prefix('{')?;
+            s = s.strip_prefix(name)?;
+            s = s.strip_prefix('=')?;
             for field in fields {
                 s = rm_enc_prefix(s, field)?;
             }
-            return rm_prefix(s, "}");
+            return s.strip_prefix('}');
         }
         Union(name, members) => {
             let mut s = s;
-            s = rm_prefix(s, "(")?;
-            s = rm_prefix(s, name)?;
-            s = rm_prefix(s, "=")?;
+            s = s.strip_prefix('(')?;
+            s = s.strip_prefix(name)?;
+            s = s.strip_prefix('=')?;
             for member in members {
                 s = rm_enc_prefix(s, member)?;
             }
-            return rm_prefix(s, ")");
+            return s.strip_prefix(')');
         }
     };
 
-    rm_prefix(s, code)
+    s.strip_prefix(code)
 }
 
 fn chomp_int(s: &str) -> Option<(u32, &str)> {
@@ -88,14 +88,6 @@ fn rm_int_prefix(s: &str, other: u32) -> Option<&str> {
     chomp_int(s).and_then(|(n, t)| if other == n { Some(t) } else { None })
 }
 
-fn rm_prefix<'a>(s: &'a str, other: &str) -> Option<&'a str> {
-    if s.starts_with(other) {
-        Some(&s[other.len()..])
-    } else {
-        None
-    }
-}
-
 pub fn eq_enc(s: &str, enc: &Encoding<'_>) -> bool {
     // strip qualifiers
     let s = s.trim_start_matches(QUALIFIERS);
diff --git a/objc_exception/src/lib.rs b/objc_exception/src/lib.rs
index ac30cba29..5b591257e 100644
--- a/objc_exception/src/lib.rs
+++ b/objc_exception/src/lib.rs
@@ -22,7 +22,10 @@ pub enum Exception {}
 /// Throws an Objective-C exception.
 /// The argument must be a pointer to an Objective-C object.
 ///
-/// Unsafe because this unwinds from Objective-C.
+/// # Safety
+///
+/// This unwinds from Objective-C, and the exception must be caught using an
+/// Objective-C exception handler.
 pub unsafe fn throw(exception: *mut Exception) -> ! {
     RustObjCExceptionThrow(exception as *mut _);
     unreachable!();
@@ -64,7 +67,9 @@ where
 /// exception being thrown, or an `Err` with a pointer to an exception if one
 /// was thrown. The exception is retained and so must be released.
 ///
-/// Unsafe because this encourages unwinding through the closure from
+/// # Safety
+///
+/// This encourages unwinding through the closure from
 /// Objective-C, which is not safe.
 pub unsafe fn r#try<F, R>(closure: F) -> Result<R, *mut Exception>
 where
diff --git a/objc_foundation/src/data.rs b/objc_foundation/src/data.rs
index 1e386ad39..717ec728b 100644
--- a/objc_foundation/src/data.rs
+++ b/objc_foundation/src/data.rs
@@ -12,6 +12,10 @@ pub trait INSData: INSObject {
         unsafe { msg_send![self, length] }
     }
 
+    fn is_empty(&self) -> bool {
+        self.len() == 0
+    }
+
     fn bytes(&self) -> &[u8] {
         let ptr: *const c_void = unsafe { msg_send![self, bytes] };
         // The bytes pointer may be null for length zero
diff --git a/objc_foundation/src/enumerator.rs b/objc_foundation/src/enumerator.rs
index 69d900722..c0860f642 100644
--- a/objc_foundation/src/enumerator.rs
+++ b/objc_foundation/src/enumerator.rs
@@ -21,6 +21,12 @@ impl<'a, T> NSEnumerator<'a, T>
 where
     T: INSObject,
 {
+    /// TODO
+    ///
+    /// # Safety
+    ///
+    /// The object pointer must be a valid `NSEnumerator` with `Owned`
+    /// ownership.
     pub unsafe fn from_ptr(ptr: *mut Object) -> NSEnumerator<'a, T> {
         NSEnumerator {
             id: Id::from_ptr(ptr),
diff --git a/objc_foundation/src/string.rs b/objc_foundation/src/string.rs
index 3f9c21ed9..34f38a810 100644
--- a/objc_foundation/src/string.rs
+++ b/objc_foundation/src/string.rs
@@ -36,6 +36,10 @@ pub trait INSString: INSObject {
         unsafe { msg_send![self, lengthOfBytesUsingEncoding: UTF8_ENCODING] }
     }
 
+    fn is_empty(&self) -> bool {
+        self.len() == 0
+    }
+
     fn as_str(&self) -> &str {
         let bytes = unsafe {
             let bytes: *const c_char = msg_send![self, UTF8String];
diff --git a/objc_id/src/id.rs b/objc_id/src/id.rs
index 41dd8e51f..b5ed2829e 100644
--- a/objc_id/src/id.rs
+++ b/objc_id/src/id.rs
@@ -54,8 +54,11 @@ where
 
     /// Constructs an `Id` from a pointer to an unretained object and
     /// retains it. Panics if the pointer is null.
-    /// Unsafe because the pointer must be to a valid object and
-    /// the caller must ensure the ownership is correct.
+    ///
+    /// # Safety
+    ///
+    /// The pointer must be to a valid object and the caller must ensure the
+    /// ownership is correct.
     pub unsafe fn from_ptr(ptr: *mut T) -> Id<T, O> {
         assert!(
             !ptr.is_null(),
@@ -67,8 +70,11 @@ where
     /// Constructs an `Id` from a pointer to a retained object; this won't
     /// retain the pointer, so the caller must ensure the object has a +1
     /// retain count. Panics if the pointer is null.
-    /// Unsafe because the pointer must be to a valid object and
-    /// the caller must ensure the ownership is correct.
+    ///
+    /// # Safety
+    ///
+    /// The pointer must be to a valid object and the caller must ensure the
+    /// ownership is correct.
     pub unsafe fn from_retained_ptr(ptr: *mut T) -> Id<T, O> {
         assert!(
             !ptr.is_null(),
@@ -125,10 +131,6 @@ where
     fn eq(&self, other: &Id<T, O>) -> bool {
         self.deref() == other.deref()
     }
-
-    fn ne(&self, other: &Id<T, O>) -> bool {
-        self.deref() != other.deref()
-    }
 }
 
 impl<T, O> Eq for Id<T, O> where T: Eq {}