Skip to content

Commit 3d3fcee

Browse files
authored
Allow panic with args to be called in a const context (rust-lang#1918)
1 parent 52c4380 commit 3d3fcee

File tree

7 files changed

+62
-24
lines changed

7 files changed

+62
-24
lines changed

library/std/src/lib.rs

+6-16
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ macro_rules! assert {
5454
// strategy, which is tracked in
5555
// https://github.com/model-checking/kani/issues/692
5656
if false {
57-
::std::panic!($($arg)+);
57+
core::assert!(true, $($arg)+);
5858
}
5959
}};
6060
}
@@ -158,7 +158,7 @@ macro_rules! unreachable {
158158
// handle.
159159
($fmt:expr, $($arg:tt)*) => {{
160160
if false {
161-
let _ = format_args!($fmt, $($arg)+);
161+
core::assert!(true, $fmt, $($arg)+);
162162
}
163163
kani::panic(concat!("internal error: entered unreachable code: ",
164164
stringify!($fmt, $($arg)*)))}};
@@ -186,22 +186,12 @@ macro_rules! panic {
186186
($msg:expr $(,)?) => ({
187187
kani::panic(stringify!($msg));
188188
});
189-
// The first argument is the message and the rest contains tokens to be included in the msg.
189+
// All other cases, e.g.:
190190
// `panic!("Error: {}", code);`
191-
//
192-
// Note: This macro may match things that wouldn't be accepted by the panic!() macro. we have
193-
// decided to over-approximate the matching so we can deal with things like macro inside a macro
194-
// E.g.:
195-
// ```
196-
// panic!(concat!("Message {}", " split in two"), argument);
197-
// ```
198-
// The std implementation of `panic!()` macro is implemented in the compiler and it seems to
199-
// be able to do things that we cannot do here.
200-
// https://github.com/rust-lang/rust/blob/dc2d232c7485c60dd856f8b9aee83426492d4661/compiler/rustc_expand/src/base.rs#L1197
201-
($msg:expr, $($arg:tt)+) => {{
191+
($($arg:tt)+) => {{
202192
if false {
203-
let _ = format_args!($msg, $($arg)+);
193+
core::assert!(true, $($arg)+);
204194
}
205-
kani::panic(stringify!($msg, $($arg)+));
195+
kani::panic(stringify!($($arg)+));
206196
}};
207197
}
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
error: 1 positional argument in format string, but no arguments were given
2+
error: aborting due to previous error
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
// compile-flags: --edition 2021
4+
5+
//! This test checks that Kani processes arguments of panic macros and produces
6+
//! a compile error for invalid arguments (e.g. missing argument)
7+
8+
const fn my_const_fn(msg: &str) -> ! {
9+
core::panic!("{}")
10+
}
11+
12+
#[kani::proof]
13+
fn check_panic_arg_error() {
14+
my_const_fn("failed");
15+
}
+4-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
Failed Checks: concat!("Panic: {} code: ", 10), msg
1+
Failed Checks: concat! ("Panic: {} code: ", 10), msg
22
Failed Checks: msg
33
Failed Checks: explicit panic
44
Failed Checks: Panic message
55
Failed Checks: "Panic message with arg {}", "str"
66
Failed Checks: "{}", msg
77

8-
Failed Checks: concat!("ArrayVec::", "try_insert",\
9-
": index {} is out of bounds in vector of length {}"),\
10-
5, 3
8+
Failed Checks: concat!\
9+
("ArrayVec::", "try_insert",\
10+
": index {} is out of bounds in vector of length {}"), 5, 3
+4-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
Failed Checks: concat!("Panic: {} code: ", 10), msg
1+
Failed Checks: concat! ("Panic: {} code: ", 10), msg
22
Failed Checks: msg
33
Failed Checks: explicit panic
44
Failed Checks: Panic message
55
Failed Checks: "Panic message with arg {}", "str"
66
Failed Checks: "{}", msg
77

8-
Failed Checks: concat!("ArrayVec::", "try_insert",\
9-
": index {} is out of bounds in vector of length {}"),\
10-
5, 3
8+
Failed Checks: concat!\
9+
("ArrayVec::", "try_insert",\
10+
": index {} is out of bounds in vector of length {}"), 5, 3

tests/kani/Panic/compile_panic.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
// kani-check-fail
4+
5+
//! This test checks that Kani fails in compilation due to a panic evaluated at
6+
//! compile time
7+
8+
const fn my_const_fn(x: i32) -> i32 {
9+
if x > 0 { x - 1 } else { panic!("x is negative") }
10+
}
11+
12+
#[kani::proof]
13+
pub fn check_something() {
14+
const _X: i32 = my_const_fn(-3);
15+
}

tests/kani/Panic/const_args.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
//! This test checks that `panic!` with args can be used in a const fn
5+
6+
const fn my_const_fn(msg: &str) -> ! {
7+
panic!("{}", msg)
8+
}
9+
10+
#[kani::proof]
11+
pub fn check_something() {
12+
let x: u8 = if kani::any() { 3 } else { 95 };
13+
if x > 100 {
14+
my_const_fn("x is greater than 100");
15+
}
16+
}

0 commit comments

Comments
 (0)