Skip to content

Commit a520893

Browse files
Docs + tests
1 parent d1d5608 commit a520893

File tree

1 file changed

+17
-59
lines changed

1 file changed

+17
-59
lines changed

README.md

Lines changed: 17 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ results](https://github.com/peter-lyons-kehl/prudent/actions/workflows/main.yml/
99
- clear
1010
- obvious (easy to search for and review).
1111

12+
# const-friendly
13+
Results of `prudent`'s macro invocations are `const` if the original invocation would be `const`
14+
also.
15+
1216
# API and examples
1317
All the following examples are also run as
1418
[doctests](https://doc.rust-lang.org/rustdoc/write-documentation/documentation-tests.html).
@@ -20,61 +24,17 @@ const unsafe fn unsafe_fn_no_args() {}
2024
const unsafe fn unsafe_fn_one_arg(b: bool) -> bool { b }
2125
const unsafe fn unsafe_fn_two_args(_: bool, u: u8) -> u8 { u }
2226

23-
unsafe_fn!(unsafe_fn_no_args);
24-
unsafe_fn!(unsafe_fn_one_arg, true);
25-
unsafe_fn!(unsafe_fn_two_args, true, 0);
26-
```
27-
28-
# unsafe_method_***
29-
30-
Unfortunately, Rust macros can't have access to the type system. So they can't differentiate whether
31-
a method's receiver is a shared reference `&self`, a mutable reference `&mut self` or a value
32-
`self`.
33-
34-
We need to use three different macros:
35-
- `unsafe_method_ref`,
36-
- `unsafe_method_mut` and
37-
- `unsafe_method_val`.
38-
39-
# unsafe_method_ref and unsafe_method_mut in const
40-
41-
As of late 2025, `const` traits are not stabilized in Rust. So, currently `unsafe_method_ref` and
42-
`unsafe_method_mut` can't be used in `const` context. Please give thumbs up to
43-
`feature(const_trait_impl)`
44-
[rust-lang/rust#143874](https://github.com/rust-lang/rust/issues/143874).
45-
46-
<!--UNSURE: `unsafe_method_ref` and `unsafe_method_mut` in `const` **will** be supported by `prudent` on`nightly` Rust toolchain in late 2025.-->
47-
There are two workarounds. Both require you to pass in the receiver expression **typed exactly** as
48-
the receiver of the method. So, you can **not** hand a receiver expression with type `T` if the
49-
method's receiver is defined as `&T` or `&mut T`.
50-
51-
## More ergonomic alternative
52-
53-
1. This re-uses `unsafe_method_val`.
54-
2. You _could_ use `unsafe_method_val` directly. But, if you'd like to be able to search/easily
55-
notice these `const` use cases, (re)import `unsafe_method_val` under a different name, like
56-
`unsafe_method_for`.
57-
3. However, suggest **not** to (re)import `unsafe_method_val` as `unsafe_method_const` or any other
58-
name implying `const`, because this macro on its own **cannot** give a `const` guarantee.
59-
60-
```text,ignore
61-
//use prudent::unsafe_method as unsafe_method_for;
62-
63-
// @TODO accept path
64-
//
65-
//const ONE: u8 = unsafe_method_for!(1, u8::unchecked_add, );
66-
```
67-
68-
## Less ergonomic
69-
```rust
70-
# use prudent::unsafe_fn;
71-
const _ONE: u8 = unsafe_fn!(u8::unchecked_add, 1, 0);
27+
const _: () = unsafe_fn!(unsafe_fn_no_args);
28+
const _: bool = unsafe_fn!(unsafe_fn_one_arg, true);
29+
const _: u8 = unsafe_fn!(unsafe_fn_two_args, true, 0);
7230
```
7331

74-
# unsafe_method_ref
32+
# unsafe_method
33+
## unsafe_method > self: shared reference
7534
```rust
7635
# use prudent::unsafe_method;
77-
let _ = unsafe_method!(1u8, unchecked_add, 0);
36+
// Works for Copy types
37+
const _: u8 = unsafe_method!(1u8, unchecked_add, 0);
7838

7939
struct SNonCopy {}
8040
impl SNonCopy {
@@ -84,12 +44,13 @@ impl SNonCopy {
8444
}
8545

8646
let s = SNonCopy {};
47+
// Works for non-Copy types
8748
unsafe_method!(s, unsafe_method_no_args);
8849
unsafe_method!(s, unsafe_method_one_arg, true);
8950
unsafe_method!(s, unsafe_method_two_args, true, false);
9051
```
9152

92-
# unsafe_method_mut
53+
## unsafe_method > self: mutable reference
9354
```rust
9455
# use prudent::unsafe_method;
9556
struct SNonCopy {}
@@ -105,7 +66,7 @@ unsafe_method!(s, unsafe_method_one_arg, true);
10566
unsafe_method!(s, unsafe_method_two_args, true, false);
10667
```
10768

108-
# unsafe_method_val
69+
## unsafe_method > self: by value
10970
```rust
11071
# use prudent::unsafe_method;
11172
{
@@ -116,12 +77,9 @@ unsafe_method!(s, unsafe_method_two_args, true, false);
11677
fn unsafe_method_two_args(self, _: bool, _: bool) {}
11778
}
11879

119-
let sNonCopy = SNonCopy {};
120-
unsafe_method!(sNonCopy, unsafe_method_no_args);
121-
let sNonCopy = SNonCopy {};
122-
unsafe_method!(sNonCopy, unsafe_method_one_arg, true);
123-
let sNonCopy = SNonCopy {};
124-
unsafe_method!(sNonCopy, unsafe_method_two_args, true, false);
80+
unsafe_method!(SNonCopy {}, unsafe_method_no_args);
81+
unsafe_method!(SNonCopy {}, unsafe_method_one_arg, true);
82+
unsafe_method!(SNonCopy {}, unsafe_method_two_args, true, false);
12583
}
12684
{
12785
#[derive(Clone, Copy)]

0 commit comments

Comments
 (0)