@@ -63,30 +63,53 @@ declare_clippy_lint! {
6363 /// arguments but are not marked `unsafe`.
6464 ///
6565 /// ### Why is this bad?
66- /// The function should probably be marked `unsafe`, since
67- /// for an arbitrary raw pointer, there is no way of telling for sure if it is
68- /// valid.
66+ /// The function should almost definitely be marked `unsafe`, since for an
67+ /// arbitrary raw pointer, there is no way of telling for sure if it is valid.
68+ ///
69+ /// In general, this lint should **never be disabled** unless it is definitely a
70+ /// false positive (please submit an issue if so) since it breaks Rust's
71+ /// soundness guarantees, directly exposing API users to potentially dangerous
72+ /// program behavior. This is also true for internal APIs, as it is easy to leak
73+ /// unsoundness.
74+ ///
75+ /// ### Context
76+ /// In Rust, an `unsafe {...}` block is used to indicate that the code in that
77+ /// section has been verified in some way that the compiler can not. For a
78+ /// function that accepts a raw pointer then accesses the pointer's data, this is
79+ /// generally impossible as the incoming pointer could point anywhere, valid or
80+ /// not. So, the signature should be marked `unsafe fn`: this indicates that the
81+ /// function's caller must provide some verification that the arguments it sends
82+ /// are valid (and then call the function within an `unsafe` block).
6983 ///
7084 /// ### Known problems
7185 /// * It does not check functions recursively so if the pointer is passed to a
7286 /// private non-`unsafe` function which does the dereferencing, the lint won't
73- /// trigger.
87+ /// trigger (false negative) .
7488 /// * It only checks for arguments whose type are raw pointers, not raw pointers
7589 /// got from an argument in some other way (`fn foo(bar: &[*const u8])` or
76- /// `some_argument.get_raw_ptr()`).
90+ /// `some_argument.get_raw_ptr()`) (false negative) .
7791 ///
7892 /// ### Example
7993 /// ```rust,ignore
8094 /// pub fn foo(x: *const u8) {
8195 /// println!("{}", unsafe { *x });
8296 /// }
97+ ///
98+ /// // this call "looks" safe but will segfault or worse!
99+ /// // foo(invalid_ptr);
83100 /// ```
84101 ///
85102 /// Use instead:
86103 /// ```rust,ignore
87104 /// pub unsafe fn foo(x: *const u8) {
88105 /// println!("{}", unsafe { *x });
89106 /// }
107+ ///
108+ /// // this would cause a compiler error for calling without `unsafe`
109+ /// // foo(invalid_ptr);
110+ ///
111+ /// // sound call if the caller knows the pointer is valid
112+ /// unsafe { foo(valid_ptr); }
90113 /// ```
91114 #[ clippy:: version = "pre 1.29.0" ]
92115 pub NOT_UNSAFE_PTR_ARG_DEREF ,
0 commit comments