Skip to content

Commit bf9a12c

Browse files
internal_coverage_positive = rustdoc automation of 2x load of coverage_positive/
1 parent 1168931 commit bf9a12c

File tree

10 files changed

+92
-34
lines changed

10 files changed

+92
-34
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
/violations_coverage/in_crate/Cargo.lock
44
/violations_coverage/verify_error_messages/target
55
/violations_coverage/verify_error_messages/Cargo.lock
6+
/coverage_*/target
7+
/coverage_*/Cargo.lock

README.md

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ _not_ at runtime/dynamic, but it's done at compile time.) You do it only once pe
2121
- If you want to apply lints to the macro-generated code (which is highly recommended), your crate
2222
needs to contain/have access to (a copy of) `prudent`'s file [src/linted.rs](src/linted.rs), which
2323
you "load" with `::prudent::load!(...)`.
24-
- If you don't need lints, just `::prudent::load()`.
24+
- If you don't need lints, just `::prudent::load!()`.
2525

2626
Both ways of `::prudent::load!(...)` create a module, called `prudent` by default. If your crate
2727
already uses `prudent` identifier, you can choose a different identifier for `prudent`'s top-level
@@ -131,13 +131,14 @@ fn main() {}
131131
mod module {
132132
use crate::prudent::unsafe_method;
133133
// Works for Copy types
134-
const _: u8 = unsafe_method!(1u8 =>@ unchecked_add => 0);
135-
//const _: u8 = unsafe_method!(({#[forbid(unused)] let v = 1u8; v}), unchecked_add, 0);
136-
//const _: u8 = unsafe_method!(#[allow_unsafe] 1u8, unchecked_add, 0);
137-
//const _: u8 = unsafe_method!(#[expect_unsafex] 1u8, unchecked_add, 0);
138-
139-
//const _: u8 = unsafe_method!(({#forbid(unused) let v = 1u8; v}), unchecked_add, 0);
140-
const _: u8 = unsafe_method!(~allow_unsafe 1u8 =>@ unchecked_add => 0);
134+
const _: u8 = unsafe_method!( 1u8 =>@ unchecked_add => 0);
135+
const _: u8 = unsafe_method!(~allow_unsafe 1u8 =>@ unchecked_add => 0);
136+
const _: u8 = unsafe_method!(~allow_unsafe unsafe { 1u8.unchecked_add(2) } =>@ unchecked_add => 0);
137+
const _: u8 = unsafe_method!(~expect_unsafe unsafe { 1u8.unchecked_add(2) } =>@ unchecked_add => 0);
138+
// @TODO compile_fail:
139+
//
140+
// const _: u8 = unsafe_method!( unsafe { 1u8.unchecked_add(2) } =>@ unchecked_add => 0);
141+
//
141142
//const _: u8 = unsafe_method!(~expect_unsafe 1u8, unchecked_add, 0);
142143
}
143144
fn main() {}
@@ -619,12 +620,20 @@ That IS OK with macros by example (defined with `macro_rules!`), and OK with any
619620
procedural macros. However, if you pass in an expression that invokes a procedural macro that has
620621
side effects or state, it's your problem. Such a macro contradicts Rust guidelines.
621622

623+
## unsafe_fn limit max 12 arguments
624+
625+
`unsafe_fn` validates that the function to be called is indeed `unsafe`. It does _not_ use lints to
626+
validate it, but it uses its own compile time checks instead. Those checks only work with functions
627+
up to a certain number of arguments. Increasing the limit makes implementation longer (see
628+
`prudent::unlinted::expecting_unsafe_fn`). For now, the limit is 12. To keep the overall API simple
629+
enough, those checks can't be turned off.
630+
622631
# Updates
623632

624633
Please subscribe for low frequency updates at
625634
[peter-lyons-kehl/prudent#1](https://github.com/peter-lyons-kehl/prudent/issues/1).
626635

627-
# Side fruit and related issues
636+
# Side fruit, related issues, credits
628637
Please contribute, or at least subscribe, and give thumbs up, to:
629638

630639
## Related issues
@@ -664,6 +673,11 @@ Sorted by importance (for `prudent`):
664673
- [dtolnay/trybuild#321](https://github.com/dtolnay/trybuild/pull/321) README: Avoid directory
665674
traversal
666675

676+
## Credits
677+
678+
Thanks to [Kevin Reid `kpreid`](https://github.com/kpreid) for a tip on [Preamble for doc
679+
tests...](https://users.rust-lang.org/t/preamble-for-doc-tests-doc-test-attr-or-another-way/136594/2).
680+
667681
<!-- 1. Link URLs to be used on GitHub.
668682
2. Relative links also work auto-magically on https://crates.io/crates/prudent.
669683
3. Keep them in the same order as used above.

coverage_positive/fn.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
use crate::prudent::unsafe_fn;
2+
3+
const unsafe fn unsafe_fn_no_args() {}
4+
const unsafe fn unsafe_fn_one_arg(b: bool) -> bool { b }
5+
const unsafe fn unsafe_fn_two_args(_: bool, u: u8) -> u8 { u }
6+
7+
const _: () = unsafe_fn!(unsafe_fn_no_args);
8+
const _: bool = unsafe_fn!(unsafe_fn_one_arg=> true);
9+
const _: u8 = unsafe_fn!(unsafe_fn_two_args=> true, 0);
10+
fn main() {}

coverage_positive/md-mut_ref.rs

Whitespace-only changes.

coverage_positive/md-shared_ref.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
use crate::prudent::unsafe_method;
2+
// Works for Copy types
3+
const _: u8 = unsafe_method!( 1u8 =>@ unchecked_add => 0);
4+
const _: u8 = unsafe_method!(~allow_unsafe 1u8 =>@ unchecked_add => 0);
5+
const _: u8 = unsafe_method!(~allow_unsafe unsafe { 1u8.unchecked_add(2) } =>@ unchecked_add => 0);
6+
const _: u8 = unsafe_method!(~expect_unsafe unsafe { 1u8.unchecked_add(2) } =>@ unchecked_add => 0);
7+
8+
fn main() {}
9+

coverage_positive/md-value.rs

Whitespace-only changes.

src/lib.rs

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,14 @@
2323
//! use crate::prudent::*;
2424
//! ```
2525
//!
26-
//! Pass a second parameter, after `->`, if you want the load in a module with name of your choice
26+
//! Pass a second parameter, after `=>`, if you want the loaded module to have name of your choice
2727
//! (other than `prudent`).
2828
#![allow(clippy::useless_attribute)]
2929
#![allow(clippy::needless_doctest_main)]
30+
//! # Examples (linted)
31+
#![doc = internal_coverage_positive!("any: \"linted.rs\"") ]
32+
//! # Examples (not linted)
33+
#![doc = internal_coverage_positive!("") ]
3034
#![doc = include_str!("../README.md")]
3135
#![cfg_attr(not(any(doc, test)), no_std)]
3236
#![forbid(unknown_lints)]
@@ -79,18 +83,38 @@
7983
// Workaround for https://github.com/rust-lang/rust/issues/148599
8084
#![doc(test(attr(allow(forbidden_lint_groups))))]
8185

82-
// Needed, so that macro_rules! in linted.rs can refer to this crate, regardless of whether those
83-
// macros from linted.rs are accessed as from ::prudent, or loaded with load!() as a module in
84-
// user crate's namespace.
85-
//
86-
//extern crate self as prudent;
87-
8886
#[cfg(doc)]
8987
extern crate alloc;
9088

91-
//#[cfg(not(doctest))]
92-
//#[cfg(doctest)]
93-
//compile_error!("NOT DOCTEST!");
89+
#[doc(hidden)]
90+
#[macro_export]
91+
macro_rules! internal_coverage_positive {
92+
(
93+
$load_params:literal
94+
) => {
95+
$crate::internal_coverage_positive!(
96+
$load_params,
97+
"unsafe_fn" -> "../coverage_positive/fn.rs",
98+
"unsafe_method > self: shared reference" -> "../coverage_positive/md-shared_ref.rs"
99+
)
100+
};
101+
(
102+
$load_params:literal,
103+
$( $description:literal -> $file:literal ),*
104+
) => {
105+
::core::concat!(
106+
$(
107+
$description,
108+
"\n```\n",
109+
"::prudent::load!(", $load_params, ");\n",
110+
::core::include_str!($file),
111+
// just in case the file doesn't end with a new line, inject it anyway:
112+
"\n```\n",
113+
)*
114+
"\n"
115+
)
116+
};
117+
}
94118

95119
pub mod unlinted;
96120

@@ -99,6 +123,7 @@ pub mod unlinted;
99123
mod linted_untested;
100124

101125
#[path = "linted_with_tests.rs"]
126+
#[doc(hidden)]
102127
pub mod linted;
103128

104129
/// No need to be public. The only functionality is macros, which are exported even if private.

src/linted.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ macro_rules! internal_prudent_unsafe_fn {
124124
// `#[deny(unused_unsafe)]` does NOT work here. Why? Because when we assigned `let fun =
125125
// $fn` above, that then happily coerces/infers to an unsafe function, even though it's
126126
// safe. That's why we have `expecting_unsafe_fn` module.
127+
#[deny(unused_unsafe)]
127128
#[allow(unsafe_code)]
128129
let result = unsafe {
129130
fun()
@@ -331,8 +332,6 @@ macro_rules! internal_prudent_unsafe_method_internal_check_args_etc {
331332
) => {({
332333
#[allow(unsafe_code)]
333334
// Notify if $self includes `unsafe {...}`, but no ~allow_unsafe or ~expect_unsafe:
334-
//
335-
//#[deny(unused_unsafe)]
336335
#[deny(unused_unsafe)]
337336
$(
338337
$( { $allow_unsafe_empty_indicator } )?
@@ -342,7 +341,7 @@ macro_rules! internal_prudent_unsafe_method_internal_check_args_etc {
342341
$( { $expect_unsafe_empty_indicator } )?
343342
#[expect(unused_unsafe)]
344343
)?
345-
#[deny(unused_unsafe)]
344+
//#[deny(unused_unsafe)]
346345
let result = unsafe { $self. $fn () };
347346
result
348347
})};

src/linted_loader.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,27 +29,27 @@ macro_rules! load {
2929
// Since `any` is **not** specified, this applies to `$[cfg(test)` only.
3030
( $prudent_linted_first:literal
3131
$( $prudent_linted_second:literal )?
32-
$( -> $module_name:ident )?
32+
$( => $module_name:ident )?
3333
) => {
3434
$crate::load!( ~
3535
(test) :
3636
$prudent_linted_first
3737
$( $prudent_linted_second )?
38-
$( -> $module_name )?
38+
$( => $module_name )?
3939
);
4040
};
4141
// `any`` means any build/`$cfg`/profile/target...
4242
( any :
4343
$prudent_linted_first:literal
4444
$( $prudent_linted_second:literal )?
45-
$( -> $module_name:ident )?
45+
$( => $module_name:ident )?
4646
) => {
4747
// @TODO test:
4848
$crate::load!( ~
4949
(test,not(test)) :
5050
$prudent_linted_first
5151
$( $prudent_linted_second )?
52-
$( -> $module_name )?
52+
$( => $module_name )?
5353
);
5454
};
5555
( ~
@@ -61,45 +61,45 @@ macro_rules! load {
6161
( $( $cfg_filter )* ) :
6262
$prudent_linted_first
6363
$( $prudent_linted_second )?
64-
-> prudent
64+
=> prudent
6565
);
6666
};
6767
( ~
6868
( $( $cfg_filter:tt )* ) :
6969
$prudent_linted_same:literal
70-
-> $module_name:ident
70+
=> $module_name:ident
7171
) => {
7272
$crate::load!( ~
7373
( $( $cfg_filter )* ) :
7474
$prudent_linted_same
7575
$prudent_linted_same
76-
-> $module_name
76+
=> $module_name
7777
);
7878
};
7979
( ~
8080
( $( $cfg_filter:tt )* ) :
8181
$prudent_linted_first:literal
8282
$prudent_linted_second:literal
83-
-> $module_name:ident
83+
=> $module_name:ident
8484
) => {
8585
#[cfg(not(windows))]
8686
$crate::load!( ~~
8787
( $( $cfg_filter )* ) :
8888
$prudent_linted_first
89-
-> $module_name
89+
=> $module_name
9090
);
9191

9292
#[cfg(windows)]
9393
$crate::load!( ~~
9494
( $( $cfg_filter )* ) :
9595
$prudent_linted_second
96-
-> $module_name
96+
=> $module_name
9797
);
9898
};
9999
( ~~
100100
( $( $cfg_filter:tt )* ) :
101101
$prudent_linted:literal
102-
-> $module_name:ident
102+
=> $module_name:ident
103103
) => {
104104
#[cfg(any( $( $cfg_filter )* ))]
105105
#[allow(unused)]

src/linted_with_tests.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,6 @@ pub use crate::linted_untested::internal_prudent_unsafe_fn_internal_access_tuple
179179
#[doc = include_str!("../violations_coverage/unsafe_method/fn_unused_unsafe/some_args.rs")]
180180
/// ```
181181
///
182-
/// TODO SHOULD FAIL, but it does NOT
183182
/// ```compile_fail
184183
#[doc = include_str!("../violations_coverage/unsafe_method/unused_expect_unsafe/zero_args.rs")]
185184
/// ```

0 commit comments

Comments
 (0)