Skip to content

Commit 171a899

Browse files
unsafe_method_* - WIP
1 parent 631c069 commit 171a899

File tree

2 files changed

+83
-31
lines changed

2 files changed

+83
-31
lines changed

README.md

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@ const B: bool = unsafe_fn!(unsafe_fn_one_arg, true);
2525
const U8: u8 = unsafe_fn!(unsafe_fn_two_args, true, 0);
2626
```
2727

28-
# unsafe_method
29-
The receiver type `S` is intentionally **not** [core::marker::Copy].
28+
# unsafe_method_ref
3029
```rust
3130
# use prudent::unsafe_method_ref;
32-
struct S {}
31+
let _ = unsafe_method_ref!(1u8, unchecked_add, 0);
32+
33+
struct S {} // intentionally NOT Copy
3334
impl S {
3435
fn unsafe_method_no_args(&self) {}
3536
fn unsafe_method_one_arg(&self, _: bool) {}
@@ -40,8 +41,22 @@ let s = S {};
4041
unsafe_method_ref!(s, unsafe_method_no_args);
4142
unsafe_method_ref!(s, unsafe_method_one_arg, true);
4243
unsafe_method_ref!(s, unsafe_method_two_args, true, false);
44+
```
4345

44-
let _ = unsafe_method_ref!(1u8, unchecked_add, 0);
46+
# unsafe_method_mut
47+
```rust
48+
# use prudent::unsafe_method_mut;
49+
struct S {}
50+
impl S {
51+
fn unsafe_method_no_args(&mut self) {}
52+
fn unsafe_method_one_arg(&mut self, _: bool) {}
53+
fn unsafe_method_two_args(&mut self, _: bool, _: bool) {}
54+
}
55+
56+
let mut s = S {};
57+
unsafe_method_mut!(s, unsafe_method_no_args);
58+
unsafe_method_mut!(s, unsafe_method_one_arg, true);
59+
unsafe_method_mut!(s, unsafe_method_two_args, true, false);
4560
```
4661

4762
```rust

src/lib.rs

Lines changed: 64 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ macro_rules! unsafe_fn {
2222
// 1. the result can be used as a value in an outer expression,and
2323
// 2. local variables don't conflict with the outer scope
2424
{
25-
let (tuple, fun) = ($crate::unsafe_fn!{~ $($arg),+ }, $fn);
26-
$crate::unsafe_fn! {~~~
25+
let (tuple, fun) = ($crate::unsafe_fn_internal!{ $($arg),+ }, $fn);
26+
27+
$crate::unsafe_fn_internal! {~
2728
fun,
2829
tuple,
2930
( $( $arg ),* ),
@@ -40,25 +41,28 @@ macro_rules! unsafe_fn {
4041
}
4142
}
4243
};
44+
}
4345

44-
// Construct the tuple:
45-
(~ $first:expr, $($rest:expr),+ ) => {
46+
#[macro_export]
47+
macro_rules! unsafe_fn_internal {
48+
// Construct the tuple. Recursive:
49+
( $first:expr, $($rest:expr),+ ) => {
4650
(
47-
$first, $crate::unsafe_fn!{ ~ $($rest),+ }
51+
$first, $crate::unsafe_fn_internal!{ $($rest),+ }
4852
)
4953
};
50-
(~ $last:expr) => {
54+
( $last:expr) => {
5155
($last,)
5256
};
5357

54-
// Access tuple parts and call the function:
55-
(~~~ $fn:expr, $tuple:ident,
58+
// Access tuple parts and get ready to call the function:
59+
(~ $fn:expr, $tuple:ident,
5660
( $_first_arg:expr, $($other_arg:expr),+ ),
5761
$( ( $($accessor_part:tt),+
5862
)
5963
),*
6064
) => {
61-
$crate::unsafe_fn!{ ~~~
65+
$crate::unsafe_fn_internal!{ ~
6266
$fn, $tuple, ( $($other_arg),+ ),
6367
// Insert a new accessor to front (left): 0.
6468
(0),
@@ -68,7 +72,7 @@ macro_rules! unsafe_fn {
6872
}
6973
};
7074
// All accessors are ready, so call the function:
71-
(~~~ $fn:expr, $tuple:ident,
75+
(~ $fn:expr, $tuple:ident,
7276
( $_last_or_only_arg:expr ),
7377
$( ( $($accessor_part:tt),+
7478
)
@@ -77,14 +81,14 @@ macro_rules! unsafe_fn {
7781
#[allow(unsafe_code)]
7882
unsafe {
7983
$fn( $(
80-
$crate::unsafe_fn!{ ~~~~~ $tuple, $($accessor_part),+ }
84+
$crate::unsafe_fn_internal!{ ~~~ $tuple, $($accessor_part),+ }
8185
),*
8286
)
8387
}
8488
};
8589

8690
// Expand an accessor group/list to access a field in the tuple:
87-
(~~~~~ $tuple:ident, $($accessor_part:tt),* ) => {
91+
(~~~ $tuple:ident, $($accessor_part:tt),* ) => {
8892
$tuple $(. $accessor_part )*
8993
};
9094
}
@@ -135,10 +139,10 @@ macro_rules! unsafe_method_ref {
135139
{
136140
use $crate::AsRefOrMut as _;
137141
let (tuple, receiver) = (
138-
$crate::unsafe_fn!{~ $($arg),+ },
142+
$crate::unsafe_fn_internal!{ $($arg),+ },
139143
( $self ).prudent_normalize_value_self_as_ref()
140144
);
141-
$crate::unsafe_method_ref! {~~~
145+
$crate::unsafe_method_ref_internal! {
142146
receiver,
143147
$fn,
144148
tuple,
@@ -158,15 +162,18 @@ macro_rules! unsafe_method_ref {
158162
}
159163
}
160164
};
165+
}
161166

162-
// Access tuple parts and call the function:
163-
(~~~ $self:expr, $fn:ident, $tuple:ident,
167+
#[macro_export]
168+
macro_rules! unsafe_method_ref_internal {
169+
// Access tuple parts and get ready to call the method:
170+
( $self:expr, $fn:ident, $tuple:ident,
164171
( $_first_arg:expr, $($other_arg:expr),+ ),
165172
$( ( $($accessor_part:tt),+
166173
)
167174
),*
168175
) => {
169-
$crate::unsafe_method_ref!{ ~~~
176+
$crate::unsafe_method_ref_internal!{
170177
$self, $fn, $tuple, ( $($other_arg),+ ),
171178
// Insert a new accessor to front (left): 0.
172179
(0),
@@ -177,21 +184,53 @@ macro_rules! unsafe_method_ref {
177184
};
178185
// All accessors are ready. $self was already evaluated (outside of unsafe {...}). So call the
179186
// function:
180-
(~~~ $self:expr, $fn:ident, $tuple:ident,
181-
( $_last_or_only_arg:expr ),
182-
$( ( $($accessor_part:tt),+
183-
)
184-
),*
187+
( $self:expr, $fn:ident, $tuple:ident,
188+
( $_last_or_only_arg:expr ),
189+
$( ( $($accessor_part:tt),+
190+
)
191+
),*
185192
) => {
193+
#[allow(unsafe_code)]
186194
unsafe {
187195
$self. $fn( $(
188-
$crate::unsafe_fn!{ ~~~~~ $tuple, $($accessor_part),+ }
196+
$crate::unsafe_fn_internal!{ ~~~ $tuple, $($accessor_part),+ }
189197
),*
190198
)
191199
}
192200
};
193201
}
194202

203+
/// Like [unsafe_method_ref], but for methods whose receiver is a mutable reference: `&mut self`.
204+
#[macro_export]
205+
macro_rules! unsafe_method_mut {
206+
($self:expr, $fn:ident $(, $arg:expr)+ ) => {
207+
{
208+
use $crate::AsRefOrMut as _;
209+
let (tuple, receiver) = (
210+
$crate::unsafe_fn_internal!{ $($arg),+ },
211+
( $self ).prudent_normalize_value_self_as_mut()
212+
);
213+
$crate::unsafe_method_ref_internal! {
214+
receiver,
215+
$fn,
216+
tuple,
217+
( $( $arg ),* ),
218+
(0)
219+
}
220+
}
221+
};
222+
223+
($self:expr, $fn:ident ) => {
224+
{
225+
use $crate::AsRefOrMut as _;
226+
let receiver = ( $self ).prudent_normalize_value_self_as_mut();
227+
#[allow(unsafe_code)]
228+
unsafe {
229+
receiver. $fn()
230+
}
231+
}
232+
};
233+
}
195234
//-------------
196235

197236
// @TODO
@@ -287,13 +326,11 @@ https://doc.rust-lang.org/std/clone/trait.UseCloned.html
287326
macro_rules! unsafe_use {
288327
($ptr:expr) => {{
289328
let ptr = $ptr;
290-
let _: *const _ = ptr; // Partial type check that $ptr yields a const pointer
291-
unsafe { *ptr }
329+
unsafe { ( *ptr ).use }
292330
}};
293331
($ptr:expr, $ptr_type:ty) => {{
294332
let ptr = $ptr as $ptr_type;
295-
let _: *const _ = ptr; // Partial type check that $ptr yields a const pointer
296-
unsafe { *ptr }
333+
unsafe { ( *ptr ).use }
297334
}};
298335
}*/
299336

0 commit comments

Comments
 (0)