@@ -53,9 +53,14 @@ macro_rules! internal_prudent_unsafe_fn {
5353 // 1. the result can be used as a value in an outer expression, and
5454 // 2. local variables don't conflict with the outer scope
5555 {
56- // Ensure that $fn (the expression itself, one that yields a function to call) and
57- // any arguments (expressions that yield values passed to the function to call)
56+ // Ensure that
57+ // - $fn (the expression itself, one that yields the function to call) and
58+ // - any arguments (expressions that yield values passed to the function to call)
59+ //
5860 // don't include any unnecessary `unsafe{...}` block(s):
61+ //
62+ // @TODO remove this #[deny(unused_unsafe)] ??? $fn or any of $arg could be a rexult
63+ // of unsafe_method!(...) that itself MAY have "unused_unsafe" in $self!!!
5964 #[ deny( unused_unsafe) ]
6065 // Ensure that $fn (the expression itself) and any arguments (expressions) don't
6166 // include any unsafe code/calls/casts on their own without their own `unsafe{...}`
@@ -108,6 +113,8 @@ macro_rules! internal_prudent_unsafe_fn {
108113 ( {
109114 // Ensure that $fn (the expression itself, one that yields a function to call) doesn't
110115 // include an unnecessary `unsafe{...}` block:
116+ //
117+ // @TODO remove this #[deny(unused_unsafe)]
111118 #[ deny( unused_unsafe) ]
112119 // Ensure that $fn (the expression itself) doesn't include any unsafe code/calls/casts
113120 // on its own without its own `unsafe{...}` block(s):
@@ -122,11 +129,6 @@ macro_rules! internal_prudent_unsafe_fn {
122129 } ;
123130 :: core:: unreachable!( )
124131 }
125- // `#[deny(unused_unsafe)]` does NOT work here. Why? Because when we assigned `let fun =
126- // $fn` above, that then happily coerces/infers to an unsafe function, even though it's
127- // safe. That's why we have `expecting_unsafe_fn` module.
128- #[ deny( unused_unsafe) ]
129- #[ allow( unsafe_code) ]
130132 let result = unsafe {
131133 fun( )
132134 } ;
@@ -182,6 +184,7 @@ macro_rules! internal_prudent_unsafe_fn_internal_build_accessors_and_call {
182184 ) ,*
183185 ) => {
184186 #[ allow( unsafe_code) ]
187+ // @TODO remove this #[deny(unused_unsafe)]
185188 #[ deny( unused_unsafe) ]
186189 unsafe {
187190 $fn( $(
@@ -215,91 +218,52 @@ pub use internal_prudent_unsafe_fn_internal_access_tuple_tree_field;
215218/// - This treats `self` as if it were evaluated **outside** the `unsafe {...}` block.
216219/// - $fn can **NOT** be an expression or a qualified path (which doesn't work in standard methods
217220/// calls anyways), but only an identifier.
218- ///
219- /// Do NOT use parameters/input parts matched by
220- /// - `$expect_unsafe_empty_indicator` or
221- /// - `$allow_unsafe_empty_indicator`
222- ///
223- /// as they are internal.
224221#[ macro_export]
225222#[ doc( hidden) ]
226223macro_rules! internal_prudent_unsafe_method {
227224 (
228- $( ~allow_unsafe $( { $allow_unsafe_empty_indicator: tt } ) ? ) ?
229- $( ~expect_unsafe $( { $expect_unsafe_empty_indicator: tt } ) ? ) ?
230225 $self: expr =>@ $method: ident
231226 ) => {
232227 internal_prudent_unsafe_method!(
233- $( ~allow_unsafe $( { $allow_unsafe_empty_indicator } ) ? ) ?
234- $( ~expect_unsafe $( { $expect_unsafe_empty_indicator } ) ? ) ?
235228 $self =>@ $method =>
236229 )
237230 } ;
238231 (
239- $( ~allow_unsafe $( { $allow_unsafe_empty_indicator: tt } ) ? ) ?
240- $( ~expect_unsafe $( { $expect_unsafe_empty_indicator: tt } ) ? ) ?
241232 $self: expr =>@ $method: ident => $( $arg: expr ) ,*
242233 ) => {
243234 // See unsafe_fn for why here we enclose in (...) and not in {...}.
244235 (
245236 if false {
246- // no module needed in the following macro path, since allow_unsafe_expect_unsafe_is_correct has #[macro_export]
247- :: prudent:: max_one_active_of_allow_unsafe_expect_unsafe!{
248- $( ~allow_unsafe $( { $allow_unsafe_empty_indicator } ) ? ) ?
249- $( ~expect_unsafe $( { $expect_unsafe_empty_indicator } ) ? ) ?
250- }
251- if false {
252- // This block "makes" an owned_receiver, an instance/owned value of the same
253- // type as $self. (Of course, the instance is invalid - this is for compile-time
254- // checks only, hence `if false {...}`.)
255- //
256- // Then we simulate invocation of the given method inside `unsafe {...}``, BUT
257- // without evaluating the given $self expression inside that same `unsafe
258- // {...}`` block, so that we isolate/catch any `unsafe`` code in $self.
259- //
260- // We **cannot** just move/take/assign $self by value, in case it's a non-Copy
261- // **static** variable. See also comments in
262- // unsafe_method_internal_build_accessors_check_args_call.
263- let mref = {
264- #[ rustfmt:: skip]
265- #[ deny( unused_unsafe) ]
266- // @TODO simplify once https://github.com/rust-lang/rust/issues/15701
267- // (attributes on expressions)
268- #[ deny( unsafe_code) ]
269- #[ deny( unfulfilled_lint_expectations) ]
270- $(
271- $( { $allow_unsafe_empty_indicator } ) ?
272- #[ allow( unsafe_code) ]
273- ) ?
274- $(
275- $( { $expect_unsafe_empty_indicator } ) ?
276- #[ expect( unsafe_code) ]
277- ) ?
278- let rref = & ( $self ) ;
279- :: prudent:: backend:: shared_to_mut( rref )
280- } ;
281- #[ allow( unused_mut) ]
282- #[ allow( invalid_value) ] // for &str and other types where zeroed() issues invalid_value warning.
283- let mut owned_receiver = :: core:: mem:: replace( mref, unsafe { :: core:: mem:: zeroed( ) } ) ;
284- // Detect code where unsafe_method! is not needed at all. Maybe the method used
285- // to be `unsafe`, but not anymore.
286- #[ deny( unused_unsafe) ]
287- let _ = unsafe { owned_receiver. $method( $( $arg ) ,* ) } ;
288- //@TODO here call the method with tuple tree-stored evaluated args.
289- //
290- //THEN simplify internal_prudent_unsafe_method_internal_check_args_etc -> internal_prudent_unsafe_method_internal_build_accessors_check_args_call
291- } else {
292- // @TODO eliminate
293- $(
294- #[ deny( unused_unsafe) ]
295- let _ = $arg;
296- ) *
297- }
237+ // "Make" an owned_receiver, an instance/owned value of the same
238+ // type as $self. (Of course, the instance is invalid - this is for compile-time
239+ // checks only, hence `if false {...}`.)
240+ //
241+ // Then we simulate invocation of the given method inside `unsafe {...}``, BUT
242+ // without evaluating the given $self expression inside that same `unsafe
243+ // {...}`` block, so that we isolate/catch any `unsafe`` code in $self.
244+ //
245+ // We **cannot** just move/take/assign $self by value, in case it's a non-Copy
246+ // **static** variable. See also comments in
247+ // unsafe_method_internal_build_accessors_check_args_call.
248+ let mref = {
249+ let rref = & ( $self ) ;
250+ :: prudent:: backend:: shared_to_mut( rref )
251+ } ;
252+ #[ allow( unused_mut) ]
253+ #[ allow( invalid_value) ] // for &str and other types where zeroed() issues invalid_value warning.
254+ let mut owned_receiver = :: core:: mem:: replace( mref, unsafe { :: core:: mem:: zeroed( ) } ) ;
255+ // Detect code where `unsafe_method!` is not needed at all. Maybe the method used
256+ // to be `unsafe`, but not anymore.
257+ //
258+ // @TODO This is the only place where we "need" #[deny(unused_unsafe)]
259+ #[ deny( unused_unsafe) ]
260+ let _ = unsafe { owned_receiver. $method( $( $arg ) ,* ) } ;
261+ //@TODO here call the method with tuple tree-stored evaluated args.
262+ //
263+ //THEN simplify internal_prudent_unsafe_method_internal_check_args_etc -> internal_prudent_unsafe_method_internal_build_accessors_check_args_call
298264 :: core:: unreachable!( )
299265 } else {
300266 internal_prudent_unsafe_method_internal_check_args_etc!(
301- $( ~allow_unsafe $( { $allow_unsafe_empty_indicator } ) ? ) ?
302- $( ~expect_unsafe $( { $expect_unsafe_empty_indicator } ) ? ) ?
303267 $self, $method $( , $arg ) *
304268 )
305269 }
@@ -312,17 +276,12 @@ pub use internal_prudent_unsafe_method;
312276#[ macro_export]
313277macro_rules! internal_prudent_unsafe_method_internal_check_args_etc {
314278 (
315- $( ~expect_unsafe $( { $expect_unsafe_empty_indicator: tt } ) ? ) ?
316- $( ~allow_unsafe $( { $allow_unsafe_empty_indicator: tt } ) ? ) ?
317279 $self: expr, $fn: ident $( , $arg: expr ) +
318280 ) => { ( {
319- #[ deny( unused_unsafe) ]
320281 let tuple_tree =
321282 internal_prudent_unsafe_fn_internal_build_tuple_tree!{ $( $arg) ,+ } ;
322283
323284 internal_prudent_unsafe_method_internal_build_accessors_check_args_call! {
324- $( ~allow_unsafe $( { $allow_unsafe_empty_indicator } ) ? ) ?
325- $( ~expect_unsafe $( { $expect_unsafe_empty_indicator } ) ? ) ?
326285 $self,
327286 $fn,
328287 tuple_tree,
@@ -331,22 +290,9 @@ macro_rules! internal_prudent_unsafe_method_internal_check_args_etc {
331290 }
332291 } ) } ;
333292 (
334- $( ~expect_unsafe $( { $expect_unsafe_empty_indicator: tt } ) ? ) ?
335- $( ~allow_unsafe $( { $allow_unsafe_empty_indicator: tt } ) ? ) ?
336293 $self: expr, $fn: ident
337294 ) => { ( {
338295 #[ allow( unsafe_code) ]
339- // Notify if $self includes `unsafe {...}`, but no ~allow_unsafe or ~expect_unsafe:
340- #[ deny( unused_unsafe) ]
341- $(
342- $( { $allow_unsafe_empty_indicator } ) ?
343- #[ allow( unused_unsafe) ]
344- ) ?
345- $(
346- $( { $expect_unsafe_empty_indicator } ) ?
347- #[ expect( unused_unsafe) ]
348- ) ?
349- //#[deny(unused_unsafe)]
350296 let result = unsafe { $self. $fn ( ) } ;
351297 result
352298 } ) } ;
@@ -358,17 +304,13 @@ pub use internal_prudent_unsafe_method_internal_check_args_etc;
358304macro_rules! internal_prudent_unsafe_method_internal_build_accessors_check_args_call {
359305 // Access tuple_tree parts and get ready to call the method:
360306 (
361- $( ~expect_unsafe $( { $expect_unsafe_empty_indicator: tt } ) ? ) ?
362- $( ~allow_unsafe $( { $allow_unsafe_empty_indicator: tt } ) ? ) ?
363307 $self: expr, $fn: ident, $tuple_tree: ident,
364308 ( $_first_arg: expr, $( $other_arg: expr) ,+ ) ,
365309 $( ( $( $accessor_part: tt) ,+
366310 )
367311 ) ,*
368312 ) => {
369313 internal_prudent_unsafe_method_internal_build_accessors_check_args_call!{
370- $( ~allow_unsafe $( { $allow_unsafe_empty_indicator } ) ? ) ?
371- $( ~expect_unsafe $( { $expect_unsafe_empty_indicator } ) ? ) ?
372314 $self, $fn, $tuple_tree, ( $( $other_arg) ,+ ) ,
373315 // Insert a new accessor to the front (left): 0.
374316 ( 0 ) ,
@@ -379,30 +321,20 @@ macro_rules! internal_prudent_unsafe_method_internal_build_accessors_check_args_
379321 } ;
380322 // All accessors are ready. Call the function:
381323 (
382- $( ~expect_unsafe $( { $expect_unsafe_empty_indicator: tt } ) ? ) ?
383- $( ~allow_unsafe $( { $allow_unsafe_empty_indicator: tt } ) ? ) ?
384324 $self: expr, $fn: ident, $tuple_tree: ident,
385325 ( $_last_or_only_arg: expr ) ,
386326 $( ( $( $accessor_part: tt) ,+
387327 )
388328 ) ,*
389329 ) => { ( {
390330 #[ allow( unsafe_code) ]
391- #[ deny( unused_unsafe) ]
392- $(
393- $( { $allow_unsafe_empty_indicator } ) ?
394- #[ allow( unused_unsafe) ]
395- ) ?
396- $(
397- $( { $expect_unsafe_empty_indicator } ) ?
398- #[ expect( unused_unsafe) ]
399- ) ?
400331 let result = unsafe {
401332 // Unlike arguments, we can NOT store result of $self expression in a variable, because
402333 // - it would be moved, but a method with receiver by reference `&self` or `&mut self`
403334 // does NOT move the instance it's called on. Also,
404335 // - if Self were `Copy`, then `&self` or `&mut self` reference would not point to the
405336 // original instance! (Plus extra stack used, plus lifetimes issues.)
337+ // - it could be a non-Copy **static** variable, which cannot be moved.
406338 $self. $fn( $(
407339 internal_prudent_unsafe_fn_internal_access_tuple_tree_field!{ $tuple_tree, $( $accessor_part) ,+ }
408340 ) ,*
0 commit comments