]> git.lizzy.rs Git - rust.git/blobdiff - src/tools/clippy/clippy_lints/src/functions/mod.rs
Merge commit '4f3ab69ea0a0908260944443c739426cc384ae1a' into clippyup
[rust.git] / src / tools / clippy / clippy_lints / src / functions / mod.rs
index 91e6ffe6447909d610bd14774b269c301c1eb0cf..9dbce3f889bef117ddfcbba93d9de08a85bd60bf 100644 (file)
     /// arguments but are not marked `unsafe`.
     ///
     /// ### Why is this bad?
-    /// The function should probably be marked `unsafe`, since
-    /// for an arbitrary raw pointer, there is no way of telling for sure if it is
-    /// valid.
+    /// The function should almost definitely be marked `unsafe`, since for an
+    /// arbitrary raw pointer, there is no way of telling for sure if it is valid.
+    ///
+    /// In general, this lint should **never be disabled** unless it is definitely a
+    /// false positive (please submit an issue if so) since it breaks Rust's
+    /// soundness guarantees, directly exposing API users to potentially dangerous
+    /// program behavior. This is also true for internal APIs, as it is easy to leak
+    /// unsoundness.
+    ///
+    /// ### Context
+    /// In Rust, an `unsafe {...}` block is used to indicate that the code in that
+    /// section has been verified in some way that the compiler can not. For a
+    /// function that accepts a raw pointer then accesses the pointer's data, this is
+    /// generally impossible as the incoming pointer could point anywhere, valid or
+    /// not. So, the signature should be marked `unsafe fn`: this indicates that the
+    /// function's caller must provide some verification that the arguments it sends
+    /// are valid (and then call the function within an `unsafe` block).
     ///
     /// ### Known problems
     /// * It does not check functions recursively so if the pointer is passed to a
     /// private non-`unsafe` function which does the dereferencing, the lint won't
-    /// trigger.
+    /// trigger (false negative).
     /// * It only checks for arguments whose type are raw pointers, not raw pointers
     /// got from an argument in some other way (`fn foo(bar: &[*const u8])` or
-    /// `some_argument.get_raw_ptr()`).
+    /// `some_argument.get_raw_ptr()`) (false negative).
     ///
     /// ### Example
     /// ```rust,ignore
     /// pub fn foo(x: *const u8) {
     ///     println!("{}", unsafe { *x });
     /// }
+    ///
+    /// // this call "looks" safe but will segfault or worse!
+    /// // foo(invalid_ptr);
     /// ```
     ///
     /// Use instead:
     /// pub unsafe fn foo(x: *const u8) {
     ///     println!("{}", unsafe { *x });
     /// }
+    ///
+    /// // this would cause a compiler error for calling without `unsafe`
+    /// // foo(invalid_ptr);
+    ///
+    /// // sound call if the caller knows the pointer is valid
+    /// unsafe { foo(valid_ptr); }
     /// ```
     #[clippy::version = "pre 1.29.0"]
     pub NOT_UNSAFE_PTR_ARG_DEREF,