Skip to content

Commit ff15fed

Browse files
Add support for edition 2018 crates using assert! (Fixes #3717) (#4096)
We export `core::assert` as `__kani__workaround_core_assert!` to every crate which uses `assert`. Because kani uses edition 2021, crates which are built edition 2018 now use the 2021 `assert`. The behaviour of `assert` changed between both editions (see https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html). This commit adds an extra clause to handle the case, if the first message parameter isn't of string type and adds a format string accordingly This resolves #3717 . By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses. --------- Co-authored-by: Zyad Hassan <zyadh@amazon.com> Co-authored-by: Zyad Hassan <88045115+zhassan-aws@users.noreply.github.com>
1 parent dc83be9 commit ff15fed

File tree

4 files changed

+45
-5
lines changed

4 files changed

+45
-5
lines changed

library/std/src/lib.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,15 @@ macro_rules! assert {
4343
// The double negation is to resolve https://github.com/model-checking/kani/issues/2108
4444
kani::assert(!!$cond, concat!("assertion failed: ", stringify!($cond)));
4545
};
46-
($cond:expr, $($arg:tt)+) => {{
47-
kani::assert(!!$cond, concat!(stringify!($($arg)+)));
46+
// Before edition 2021, the `assert!` macro could take a single argument
47+
// that wasn't a string literal. This is not supported in edition 2021 and above.
48+
// Because we reexport the 2021 edition macro, we need to support this
49+
// case. For this, if there is a single argument we do the following:
50+
// If it is a literal: Just pass it through and stringify it.
51+
// If it isn't a literal: We add a default format
52+
// specifier to the macro (see https://github.com/model-checking/kani/issues/1375).
53+
($cond:expr, $first:literal $(,)?) => {{
54+
kani::assert(!!$cond, stringify!($first));
4855
// Process the arguments of the assert inside an unreachable block. This
4956
// is to make sure errors in the arguments (e.g. an unknown variable or
5057
// an argument that does not implement the Display or Debug traits) are
@@ -56,6 +63,20 @@ macro_rules! assert {
5663
// effects). This is fine until we add support for the "unwind" panic
5764
// strategy, which is tracked in
5865
// https://github.com/model-checking/kani/issues/692
66+
if false {
67+
kani::__kani__workaround_core_assert!(true, "{}", $first);
68+
}
69+
}};
70+
($cond:expr, $first:expr $(,)?) => {{
71+
kani::assert(!!$cond, stringify!($first));
72+
// See comment above
73+
if false {
74+
kani::__kani__workaround_core_assert!(true, "{}", $first);
75+
}
76+
}};
77+
($cond:expr, $($arg:tt)+) => {{
78+
kani::assert(!!$cond, concat!(stringify!($($arg)+)));
79+
// See comment above
5980
if false {
6081
kani::__kani__workaround_core_assert!(true, $($arg)+);
6182
}

tests/coverage/abort/expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@
1717
17| 0| ```process::exit'''(1);\
1818
18| 1| } \
1919
19| | }\
20-
20| 0| ```assert!'''(false, ```"This is unreachable"''');\
20+
20| 0| ```assert!'''(false, "This is unreachable");\
2121
21| | }\

tests/coverage/debug-assert/expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
9| | #[kani::proof]\
1010
10| 1| fn main() {\
1111
11| 1| for i in 0..4 {\
12-
12| 1| debug_assert!(i > 0, ```"This should fail and stop the execution"''');\
13-
13| 0| ```assert!(i == 0''', ```"This should be unreachable"''');\
12+
12| 1| debug_assert!(i > 0, "This should fail and stop the execution");\
13+
13| 0| ```assert!(i == 0''', "This should be unreachable");\
1414
14| | }\
1515
15| | }\

tests/kani/Assert/assert2018.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
//
4+
// compile-flags: --edition 2018
5+
// Check that an assert that uses a pre-Rust-2018 style, where a string is
6+
// directly used without a format string literal is accepted by Kani
7+
// This was previously failing:
8+
// https://github.com/model-checking/kani/issues/3717
9+
10+
#[kani::proof]
11+
fn check_assert_2018() {
12+
let s = String::new();
13+
// This is deprecated in Rust 2018 and is a hard error starting Rust 2021.
14+
// One should instead use:
15+
// ```
16+
// assert!(true, "{}", s);
17+
// ```
18+
assert!(true, s);
19+
}

0 commit comments

Comments
 (0)