Skip to content

Commit 124b1d3

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 c9e8521 commit 124b1d3

2 files changed

Lines changed: 298 additions & 0 deletions

File tree

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: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
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 `static_assert!` form
35+
--> $DIR/assert_hierarchy.rs:64:5
36+
|
37+
64 | forward_build_assert!(OFFSET < LIMIT);
38+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
39+
|
40+
note: this asserted condition is closed over compile-time context, so `static_assert!` is the stronger form here
41+
--> $DIR/assert_hierarchy.rs:64:27
42+
|
43+
64 | forward_build_assert!(OFFSET < LIMIT);
44+
| ^^^^^^^^^^^^^^
45+
46+
error: this assertion can use the stronger `const_assert!` form
47+
--> $DIR/assert_hierarchy.rs:69:5
48+
|
49+
69 | forward_const_check!(N > 0);
50+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
51+
|
52+
note: this asserted condition is valid in a generic-aware const context, so `build_assert!` is unnecessary here
53+
--> $DIR/assert_hierarchy.rs:69:26
54+
|
55+
69 | forward_const_check!(N > 0);
56+
| ^^^^^
57+
58+
error: this assertion can use the stronger `const_assert!` form
59+
--> $DIR/assert_hierarchy.rs:77:5
60+
|
61+
77 | build_assert!(const_helper::<N>() < N);
62+
| ------------^^^^^^^^^^^^^^^^^^^^^^^^^^
63+
| |
64+
| help: replace the macro name: `const_assert`
65+
|
66+
note: this asserted condition is valid in a generic-aware const context, so `build_assert!` is unnecessary here
67+
--> $DIR/assert_hierarchy.rs:77:19
68+
|
69+
77 | build_assert!(const_helper::<N>() < N);
70+
| ^^^^^^^^^^^^^^^^^^^^^^^
71+
72+
error: this assertion can use the stronger `static_assert!` form
73+
--> $DIR/assert_hierarchy.rs:89:5
74+
|
75+
89 | build_assert!(match LIMIT {
76+
| ^-----------
77+
| |
78+
| _____help: replace the macro name: `static_assert`
79+
| |
80+
90 | | 4 => true,
81+
91 | | _ => false,
82+
92 | | });
83+
| |______^
84+
|
85+
note: this asserted condition is closed over compile-time context, so `static_assert!` is the stronger form here
86+
--> $DIR/assert_hierarchy.rs:89:19
87+
|
88+
89 | build_assert!(match LIMIT {
89+
| ___________________^
90+
90 | | 4 => true,
91+
91 | | _ => false,
92+
92 | | });
93+
| |_____^
94+
95+
error: this assertion can use the stronger `static_assert!` form
96+
--> $DIR/assert_hierarchy.rs:96:5
97+
|
98+
96 | build_assert!(1 /* , */ < LIMIT);
99+
| ------------^^^^^^^^^^^^^^^^^^^^
100+
| |
101+
| help: replace the macro name: `static_assert`
102+
|
103+
note: this asserted condition is closed over compile-time context, so `static_assert!` is the stronger form here
104+
--> $DIR/assert_hierarchy.rs:96:19
105+
|
106+
96 | build_assert!(1 /* , */ < LIMIT);
107+
| ^^^^^^^^^^^^^^^^^
108+
109+
error: this assertion can use the stronger `static_assert!` form
110+
--> $DIR/assert_hierarchy.rs:100:5
111+
|
112+
100 | build_assert!(1 /* , */ < LIMIT, "still const");
113+
| ------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
114+
| |
115+
| help: replace the macro name: `static_assert`
116+
|
117+
note: this asserted condition is closed over compile-time context, so `static_assert!` is the stronger form here
118+
--> $DIR/assert_hierarchy.rs:100:19
119+
|
120+
100 | build_assert!(1 /* , */ < LIMIT, "still const");
121+
| ^^^^^^^^^^^^^^^^^
122+
123+
error: this assertion can use the stronger `const_assert!` form
124+
--> $DIR/assert_hierarchy.rs:109:5
125+
|
126+
109 | build_assert!({
127+
| ^-----------
128+
| |
129+
| _____help: replace the macro name: `const_assert`
130+
| |
131+
110 | | let offset = OFFSET;
132+
111 | | offset < LIMIT
133+
112 | | });
134+
| |______^
135+
|
136+
note: this asserted condition is valid in a generic-aware const context, so `build_assert!` is unnecessary here
137+
--> $DIR/assert_hierarchy.rs:109:19
138+
|
139+
109 | build_assert!({
140+
| ___________________^
141+
110 | | let offset = OFFSET;
142+
111 | | offset < LIMIT
143+
112 | | });
144+
| |_____^
145+
146+
error: aborting due to 9 previous errors
147+

0 commit comments

Comments
 (0)