Skip to content

Commit 7920a8f

Browse files
unsafe_fn/unsafe_method: back to tuple_tree (WIP)
1 parent 49bbb61 commit 7920a8f

File tree

1 file changed

+102
-8
lines changed

1 file changed

+102
-8
lines changed

src/lib.rs

Lines changed: 102 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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]
9898
macro_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)]
146177
pub 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)]
151245
pub 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

Comments
 (0)