Skip to content

Commit 8cd7a2a

Browse files
committed
Add tests for the new assert_hierarchy lint
UI test coverage includes: - literals - `const` generics - wrapper macros - local `const`-only helpers - non-`const` helpers - `match` expressions - comments around macro commas - outer local bindings - local bindings inside the asserted condition - `const_assert!` sites that can be changed to `static_assert!` Signed-off-by: Mohamad Alsadhan <mo@sdhn.cc>
1 parent b157b15 commit 8cd7a2a

File tree

2 files changed

+274
-0
lines changed

2 files changed

+274
-0
lines changed

tests/ui/assert_hierarchy.rs

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
#![deny(klint::assert_hierarchy)]
2+
3+
unsafe extern "C" {
4+
#[klint::diagnostic_item = "build_error"]
5+
safe fn rust_build_error();
6+
}
7+
8+
#[klint::diagnostic_item = "build_assert"]
9+
macro_rules! build_assert {
10+
($expr:expr $(,)?) => {
11+
if !$expr {
12+
rust_build_error();
13+
}
14+
};
15+
($expr:expr, $msg:expr $(,)?) => {
16+
if !$expr {
17+
let _ = $msg;
18+
rust_build_error();
19+
}
20+
};
21+
}
22+
23+
macro_rules! forward_build_assert {
24+
($expr:expr $(,)?) => {
25+
build_assert!($expr)
26+
};
27+
}
28+
29+
macro_rules! forward_const_check {
30+
($expr:expr $(,)?) => {
31+
build_assert!($expr);
32+
let _x = 0usize;
33+
};
34+
}
35+
36+
macro_rules! const_assert {
37+
($expr:expr $(,)?) => {
38+
const {
39+
assert!($expr);
40+
}
41+
};
42+
}
43+
44+
macro_rules! impl_runtime_check {
45+
() => {
46+
fn macro_generated_runtime(n: usize) {
47+
build_assert!(n < LIMIT);
48+
}
49+
};
50+
}
51+
52+
const OFFSET: usize = 1;
53+
const LIMIT: usize = 4;
54+
55+
fn literal_const_only() {
56+
build_assert!(1 < LIMIT);
57+
}
58+
59+
fn const_generic_only<const N: usize>() {
60+
build_assert!(OFFSET < N, "offset must stay in bounds");
61+
}
62+
63+
fn wrapper_const_only() {
64+
forward_build_assert!(OFFSET < LIMIT);
65+
}
66+
67+
// Macro-generated assertions still lint based on the expanded condition.
68+
fn wrapper_const_generic<const N: usize>() {
69+
forward_const_check!(N > 0);
70+
}
71+
72+
const fn const_helper<const N: usize>() -> usize {
73+
N - 1
74+
}
75+
76+
fn const_fn_helper_only<const N: usize>() {
77+
build_assert!(const_helper::<N>() < N);
78+
}
79+
80+
fn helper<const N: usize>() -> usize {
81+
N - 1
82+
}
83+
84+
fn non_const_fn_helper<const N: usize>() {
85+
build_assert!(helper::<N>() < N);
86+
}
87+
88+
fn const_match_only() {
89+
build_assert!(match LIMIT {
90+
4 => true,
91+
_ => false,
92+
});
93+
}
94+
95+
fn const_comment_comma() {
96+
build_assert!(1 /* , */ < LIMIT);
97+
}
98+
99+
fn const_comment_comma_msg() {
100+
build_assert!(1 /* , */ < LIMIT, "still const");
101+
}
102+
103+
fn local_binding_from_outer_scope() {
104+
let offset = OFFSET;
105+
build_assert!(offset < LIMIT);
106+
}
107+
108+
fn local_binding_inside_condition() {
109+
build_assert!({
110+
let offset = OFFSET;
111+
offset < LIMIT
112+
});
113+
}
114+
115+
fn const_assert_static_only() {
116+
const_assert!(1 < LIMIT);
117+
}
118+
119+
fn const_assert_generic<const N: usize>() {
120+
const_assert!(OFFSET < N);
121+
}
122+
123+
#[inline(always)]
124+
fn runtime_dependent(offset: usize, n: usize) {
125+
build_assert!(offset < n);
126+
}
127+
128+
fn runtime_through_helper(offset: usize) {
129+
runtime_dependent(offset, LIMIT);
130+
}
131+
132+
impl_runtime_check!();
133+
134+
fn main() {
135+
literal_const_only();
136+
const_generic_only::<LIMIT>();
137+
wrapper_const_only();
138+
wrapper_const_generic::<LIMIT>();
139+
const_fn_helper_only::<LIMIT>();
140+
non_const_fn_helper::<LIMIT>();
141+
const_match_only();
142+
const_comment_comma();
143+
const_comment_comma_msg();
144+
local_binding_from_outer_scope();
145+
local_binding_inside_condition();
146+
const_assert_static_only();
147+
const_assert_generic::<LIMIT>();
148+
runtime_dependent(OFFSET, LIMIT);
149+
runtime_through_helper(OFFSET);
150+
macro_generated_runtime(OFFSET);
151+
}

tests/ui/assert_hierarchy.stderr

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
error: this assertion can use the stronger `static_assert!` form
2+
--> $DIR/assert_hierarchy.rs:56:5
3+
|
4+
56 | build_assert!(1 < LIMIT);
5+
| ------------^^^^^^^^^^^^
6+
| |
7+
| help: replace the macro name: `static_assert`
8+
|
9+
note: this asserted condition is closed over compile-time context, so `static_assert!` is the stronger form here
10+
--> $DIR/assert_hierarchy.rs:56:19
11+
|
12+
56 | build_assert!(1 < LIMIT);
13+
| ^^^^^^^^^
14+
note: the lint level is defined here
15+
--> $DIR/assert_hierarchy.rs:1:9
16+
|
17+
1 | #![deny(klint::assert_hierarchy)]
18+
| ^^^^^^^^^^^^^^^^^^^^^^^
19+
20+
error: this assertion can use the stronger `const_assert!` form
21+
--> $DIR/assert_hierarchy.rs:60:5
22+
|
23+
60 | build_assert!(OFFSET < N, "offset must stay in bounds");
24+
| ------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
25+
| |
26+
| help: replace the macro name: `const_assert`
27+
|
28+
note: this asserted condition is valid in a generic-aware const context, so `build_assert!` is unnecessary here
29+
--> $DIR/assert_hierarchy.rs:60:19
30+
|
31+
60 | build_assert!(OFFSET < N, "offset must stay in bounds");
32+
| ^^^^^^^^^^
33+
34+
error: this assertion can use the stronger `const_assert!` form
35+
--> $DIR/assert_hierarchy.rs:77:5
36+
|
37+
77 | build_assert!(const_helper::<N>() < N);
38+
| ------------^^^^^^^^^^^^^^^^^^^^^^^^^^
39+
| |
40+
| help: replace the macro name: `const_assert`
41+
|
42+
note: this asserted condition is valid in a generic-aware const context, so `build_assert!` is unnecessary here
43+
--> $DIR/assert_hierarchy.rs:77:19
44+
|
45+
77 | build_assert!(const_helper::<N>() < N);
46+
| ^^^^^^^^^^^^^^^^^^^^^^^
47+
48+
error: this assertion can use the stronger `static_assert!` form
49+
--> $DIR/assert_hierarchy.rs:89:5
50+
|
51+
89 | build_assert!(match LIMIT {
52+
| ^-----------
53+
| |
54+
| _____help: replace the macro name: `static_assert`
55+
| |
56+
90 | | 4 => true,
57+
91 | | _ => false,
58+
92 | | });
59+
| |______^
60+
|
61+
note: this asserted condition is closed over compile-time context, so `static_assert!` is the stronger form here
62+
--> $DIR/assert_hierarchy.rs:89:19
63+
|
64+
89 | build_assert!(match LIMIT {
65+
| ___________________^
66+
90 | | 4 => true,
67+
91 | | _ => false,
68+
92 | | });
69+
| |_____^
70+
71+
error: this assertion can use the stronger `static_assert!` form
72+
--> $DIR/assert_hierarchy.rs:96:5
73+
|
74+
96 | build_assert!(1 /* , */ < LIMIT);
75+
| ------------^^^^^^^^^^^^^^^^^^^^
76+
| |
77+
| help: replace the macro name: `static_assert`
78+
|
79+
note: this asserted condition is closed over compile-time context, so `static_assert!` is the stronger form here
80+
--> $DIR/assert_hierarchy.rs:96:19
81+
|
82+
96 | build_assert!(1 /* , */ < LIMIT);
83+
| ^^^^^^^^^^^^^^^^^
84+
85+
error: this assertion can use the stronger `static_assert!` form
86+
--> $DIR/assert_hierarchy.rs:100:5
87+
|
88+
100 | build_assert!(1 /* , */ < LIMIT, "still const");
89+
| ------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
90+
| |
91+
| help: replace the macro name: `static_assert`
92+
|
93+
note: this asserted condition is closed over compile-time context, so `static_assert!` is the stronger form here
94+
--> $DIR/assert_hierarchy.rs:100:19
95+
|
96+
100 | build_assert!(1 /* , */ < LIMIT, "still const");
97+
| ^^^^^^^^^^^^^^^^^
98+
99+
error: this assertion can use the stronger `const_assert!` form
100+
--> $DIR/assert_hierarchy.rs:109:5
101+
|
102+
109 | build_assert!({
103+
| ^-----------
104+
| |
105+
| _____help: replace the macro name: `const_assert`
106+
| |
107+
110 | | let offset = OFFSET;
108+
111 | | offset < LIMIT
109+
112 | | });
110+
| |______^
111+
|
112+
note: this asserted condition is valid in a generic-aware const context, so `build_assert!` is unnecessary here
113+
--> $DIR/assert_hierarchy.rs:109:19
114+
|
115+
109 | build_assert!({
116+
| ___________________^
117+
110 | | let offset = OFFSET;
118+
111 | | offset < LIMIT
119+
112 | | });
120+
| |_____^
121+
122+
error: aborting due to 7 previous errors
123+

0 commit comments

Comments
 (0)