@@ -63,30 +63,54 @@ 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
66+ /// The function should almost definitely be marked `unsafe`, since
6767 /// for an arbitrary raw pointer, there is no way of telling for sure if it is
6868 /// valid.
6969 ///
70+ /// In general, this lint should **never be disabled** unless it is definitely a
71+ /// false positive (please submit an issue if so) since it breaks Rust's
72+ /// soundness guarantees, directly exposing API users to potentially dangerous
73+ /// program behavior. This is also true for internal APIs, as it is easy to leak
74+ /// unsoundness.
75+ ///
76+ /// ### Context
77+ /// In general, an `unsafe {...}` block is used to indicate that the code in that
78+ /// section has been verified in some way that the compiler can not. For a
79+ /// function that accepts a raw pointer then accesses the pointer's data, this is
80+ /// generally impossible as the incoming pointer could point anywhere, valid or
81+ /// not. So, the signature should be marked `unsafe fn`: this indicates that the
82+ /// function's caller must provide some verification that the arguments it sends
83+ /// are valid (and then call the function within an `unsafe` block).
84+ ///
7085 /// ### Known problems
7186 /// * It does not check functions recursively so if the pointer is passed to a
7287 /// private non-`unsafe` function which does the dereferencing, the lint won't
73- /// trigger.
88+ /// trigger (false negative) .
7489 /// * It only checks for arguments whose type are raw pointers, not raw pointers
7590 /// got from an argument in some other way (`fn foo(bar: &[*const u8])` or
76- /// `some_argument.get_raw_ptr()`).
91+ /// `some_argument.get_raw_ptr()`) (false negative) .
7792 ///
7893 /// ### Example
7994 /// ```rust,ignore
8095 /// pub fn foo(x: *const u8) {
8196 /// println!("{}", unsafe { *x });
8297 /// }
98+ ///
99+ /// // this call "looks" safe but will segfault or worse!
100+ /// // foo(invalid_ptr);
83101 /// ```
84102 ///
85103 /// Use instead:
86104 /// ```rust,ignore
87105 /// pub unsafe fn foo(x: *const u8) {
88106 /// println!("{}", unsafe { *x });
89107 /// }
108+ ///
109+ /// // this call would cause a compiler error
110+ /// // foo(invalid_ptr);
111+ ///
112+ /// // sound call if the caller knows the pointer is valid
113+ /// unsafe { foo(valid_ptr); }
90114 /// ```
91115 #[ clippy:: version = "pre 1.29.0" ]
92116 pub NOT_UNSAFE_PTR_ARG_DEREF ,
0 commit comments