@@ -83,7 +83,7 @@ extern crate alloc;
8383/// [true]
8484/// }
8585///
86- /// let _b = unsafe_fn!( return_array)[0];
86+ /// let _ = unsafe_fn!( return_array)[0];
8787/// ```
8888/// ```
8989/// # use prudent::unsafe_fn;
@@ -96,9 +96,7 @@ extern crate alloc;
9696/// ```
9797#[ macro_export]
9898macro_rules! unsafe_fn {
99- ( $fn: expr $( , $arg: expr) * ) => {
100- // Enclosed in (...) and NOT in {...}. Why? Because the later does NOT work if the result is
101- // an array/slice and then it's indexed with array access suffix [usize_idx].
99+ /*( $fn:expr $(, $arg:expr)* ) => {
102100 (
103101 if false {
104102 #[deny(unused_unsafe)]
@@ -115,6 +113,39 @@ macro_rules! unsafe_fn {
115113 }
116114 }
117115 )
116+ };*/
117+ ( $fn: expr $( , $arg: expr) + ) => {
118+ // Enclosed in (...) and NOT in {...}. Why? Because the later does NOT work if the result is
119+ // an array/slice and then it's indexed with array access suffix [usize_idx].
120+ (
121+ // Enclosed in a block, so that
122+ // 1. the result can be used as a value in an outer expression, and
123+ // 2. local variables don't conflict with the outer scope
124+ {
125+ #[ deny( unused_unsafe) ]
126+ let ( tuple_tree, fun) = ( $crate:: unsafe_fn_internal_build_tuple_tree!{ $( $arg) ,+ } , $fn) ;
127+
128+ $crate:: unsafe_fn_internal_build_accessors_and_call! {
129+ fun,
130+ tuple_tree,
131+ ( $( $arg ) ,* ) ,
132+ ( 0 )
133+ }
134+ }
135+ )
136+ } ;
137+ ( $fn: expr) => {
138+ (
139+ {
140+ #[ deny( unused_unsafe) ]
141+ let fun = $fn;
142+ #[ allow( unsafe_code) ]
143+ #[ deny( unused_unsafe) ]
144+ unsafe {
145+ fun( )
146+ }
147+ }
148+ )
118149 } ;
119150}
120151
@@ -145,8 +176,71 @@ pub const _: () = {};
145176#[ cfg( doctest) ]
146177pub const _: ( ) = { } ;
147178
179+ #[ doc( hidden) ]
180+ #[ macro_export]
181+ macro_rules! unsafe_fn_internal_build_tuple_tree {
182+ // Construct the tuple_tree. Recursive:
183+ ( $first: expr, $( $rest: expr) ,+ ) => {
184+ (
185+ $first, $crate:: unsafe_fn_internal_build_tuple_tree!{ $( $rest) ,+ }
186+ )
187+ } ;
188+ ( $last: expr) => {
189+ ( $last, )
190+ } ;
191+ }
192+
193+ #[ doc( hidden) ]
194+ #[ macro_export]
195+ macro_rules! unsafe_fn_internal_build_accessors_and_call {
196+ // Access tuple_tree parts and get ready to call the function:
197+ ( $fn: expr, $tuple_tree: ident,
198+ ( $_first_arg: expr, $( $other_arg: expr) ,+ ) ,
199+ $( ( $( $accessor_part: tt) ,+
200+ )
201+ ) ,*
202+ ) => {
203+ $crate:: unsafe_fn_internal_build_accessors_and_call!{
204+ $fn, $tuple_tree, ( $( $other_arg) ,+ ) ,
205+ // Insert a new accessor to front (left): 0.
206+ ( 0 ) ,
207+ $( // Prepend 1 to each supplied/existing accessor
208+ ( 1 , $( $accessor_part) ,+ )
209+ ) ,*
210+ }
211+ } ;
212+ // All accessors are ready, so call the function:
213+ ( $fn: expr, $tuple_tree: ident,
214+ ( $_last_or_only_arg: expr ) ,
215+ $( ( $( $accessor_part: tt) ,+
216+ )
217+ ) ,*
218+ ) => {
219+ #[ allow( unsafe_code) ]
220+ #[ deny( unused_unsafe) ]
221+ unsafe {
222+ $fn( $(
223+ $crate:: unsafe_fn_internal_access_tuple_tree_field!{ $tuple_tree, $( $accessor_part) ,+ }
224+ ) ,*
225+ )
226+ }
227+ } ;
228+ }
229+
230+ #[ doc( hidden) ]
231+ #[ macro_export]
232+ /// INTERNAL. Do NOT use directly - subject to change.
233+ ///
234+ /// Expand an accessor group/list to access a field in the tuple_tree.
235+ macro_rules! unsafe_fn_internal_access_tuple_tree_field {
236+ ( $tuple_tree: ident, $( $accessor_part: tt) ,* ) => {
237+ $tuple_tree $( . $accessor_part ) *
238+ } ;
239+ }
240+ //-------------
241+
148242/// NOT a part of public API. Pretend to get a mutable reference from a shared reference. For
149- /// internal/generated compile-time checks only.
243+ /// internal/generated ** compile-time** checks only.
150244#[ doc( hidden) ]
151245pub const fn shared_to_mut < T > ( _: & T ) -> & mut T {
152246 unreachable ! ( )
@@ -175,7 +269,7 @@ macro_rules! unsafe_method {
175269 $( ~allow_unsafe $( { $allow_unsafe_empty_indicator: tt } ) ? ) ?
176270 $self: expr, $fn: ident $( , $arg: expr ) *
177271 ) => {
178- :: prudent :: unsafe_method_internal!(
272+ $crate :: unsafe_method_internal!(
179273 $( ~allow_unsafe $( { $allow_unsafe_empty_indicator } ) ? ) ?
180274 $self, $fn $( , $arg ) *
181275 )
@@ -184,7 +278,7 @@ macro_rules! unsafe_method {
184278 $( ~expect_unsafe $( { $expect_unsafe_empty_indicator: tt } ) ? ) ?
185279 $self: expr, $fn: ident $( , $arg: expr ) *
186280 ) => {
187- :: prudent :: unsafe_method_internal!(
281+ $crate :: unsafe_method_internal!(
188282 $( ~expect_unsafe $( { $expect_unsafe_empty_indicator } ) ? ) ?
189283 $self, $fn $( , $arg ) *
190284 )
@@ -231,7 +325,7 @@ macro_rules! unsafe_method_internal {
231325 rref
232326 } ;
233327 //
234- let mref = :: prudent :: shared_to_mut( rref) ;
328+ let mref = $crate :: shared_to_mut( rref) ;
235329 let mut owned_receiver = :: core:: mem:: replace( mref, unsafe { :: core:: mem:: zeroed( ) } ) ;
236330 // @TODO
237331 //
0 commit comments