@@ -44,8 +44,19 @@ macro_rules! unsafe_fn {
4444 let ( tuple_tree, fun) = ( $crate:: unsafe_fn_internal_build_tuple_tree!{ $( $arg) ,+ } , $fn) ;
4545
4646 if false {
47+ // Detect code where `unsafe_fn!` is not needed at all. Maybe the function used
48+ // to be `unsafe`, but not anymore.
49+ //
4750 // Ensure that $fn is not safe, but `unsafe`. Using
4851 // https://doc.rust-lang.org/reference/types/function-item.html#r-type.fn-item.coercion
52+ //
53+ // We can't just use
54+ // ```
55+ // let _: unsafe fn(_, _,... ) -> _ = fun;
56+ // ```
57+ // (with the appropriate number of _ for arguments), because that would coerce a
58+ // safe function into unsafe, and we would lose the ability to verify that it's
59+ // indeed unsafe!
4960 let _ = if false {
5061 $crate:: expecting_unsafe_fn_path!( $( $arg ) ,+ )
5162 } else {
@@ -181,28 +192,51 @@ macro_rules! unsafe_method {
181192 // See unsafe_fn for why here we enclose in (...) and not in {...}.
182193 (
183194 if false {
184- // "Make" an owned_receiver, an instance/owned value of the same
185- // type as $self. (Of course, the instance is invalid - this is for compile-time
186- // checks only, hence `if false {...}`.)
195+ // "Make" an owned_receiver, an instance/owned value of the same type as $self. (Of
196+ // course, the instance is invalid - this is for compile-time checks only, hence `if
197+ // false {...}`.)
187198 //
188- // Then we simulate invocation of the given method inside `unsafe {...}`` , BUT
189- // without evaluating the given $self expression inside that same `unsafe
190- // {...}`` block, so that we isolate/catch any `unsafe` ` code in $self.
199+ // Then we simulate invocation of the given method inside `unsafe {...}`, BUT
200+ // without evaluating the given $self expression inside that same `unsafe {...}`
201+ // block, so that we isolate/catch any `unsafe` code in $self.
191202 //
192- // We **cannot** just move/take/assign $self by value, in case it's a non-Copy
193- // ** static** variable. See also comments in
203+ // We **cannot** just move/take/assign $self by value, in case it's a non-` Copy`
204+ // ` static` variable (or a deref of a non-`Copy` raw pointer) . See also comments in
194205 // unsafe_method_internal_build_accessors_check_args_call.
195206 let mref = {
196207 let rref = & ( $self ) ;
197208 $crate:: backend:: shared_to_mut( rref )
198209 } ;
199- #[ allow( unused_mut) ]
210+ #[ allow( unused_mut) ] // in case the method takes &mut self.
200211 #[ allow( invalid_value) ] // for &str and other types where zeroed() issues invalid_value warning.
201212 let mut owned_receiver = :: core:: mem:: replace( mref, unsafe { :: core:: mem:: zeroed( ) } ) ;
213+
214+ #[ cfg( feature="assert_unsafe_methods" ) ]
215+ if false {
216+ type OwnedReceiver = impl Sized ;
217+ //let _ = move || -> OwnedReceiver { owned_receiver };
218+ let owned_receiver: OwnedReceiver = owned_receiver;
219+
220+ // Detect code where `unsafe_method!` is not needed at all. Maybe the method used
221+ // to be `unsafe`, but not anymore.
222+ //
223+ // See unsafe_fn for why we can't just use simple coercion like:
224+ // ```
225+ // let _: unsafe fn(_, _,... ) -> _ = OwnedReceiver::$method;
226+ // ```
227+
228+ let _ = OwnedReceiver :: $method;
229+ /*let _ = if false {
230+ $crate::expecting_unsafe_fn_path!( first_goes_receiver $(, $arg )* )
231+ } else {
232+ OwnedReceiver::$method
233+ };*/
234+ :: core:: unreachable!( ) ;
235+ } ;
236+ // @TODO double check and remove:
237+ //
202238 // Detect code where `unsafe_method!` is not needed at all. Maybe the method used
203239 // to be `unsafe`, but not anymore.
204- //
205- // @TODO This is the only place where we "need" #[deny(unused_unsafe)]
206240 #[ deny( unused_unsafe) ]
207241 let _ = unsafe { owned_receiver. $method( $( $arg ) ,* ) } ;
208242 :: core:: unreachable!( )
0 commit comments