Skip to content

Commit 9f20e84

Browse files
authoredJul 26, 2022
Fix compilation of panic!() when the arg is another macro. (rust-lang#1407)
1 parent 9fcac41 commit 9f20e84

File tree

8 files changed

+52
-5
lines changed

8 files changed

+52
-5
lines changed
 

‎library/std/src/lib.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,9 @@ macro_rules! unreachable {
158158
);
159159
// The first argument is the format and the rest contains tokens to be included in the msg.
160160
// `unreachable!("Error: {}", code);`
161-
($fmt:literal, $($arg:tt)*) => (
161+
// We have the same issue as with panic!() described bellow where we over-approx what we can
162+
// handle.
163+
($fmt:expr, $($arg:tt)*) => (
162164
kani::panic(concat!("internal error: entered unreachable code: ",
163165
stringify!($fmt, $($arg)*))));
164166
}
@@ -185,9 +187,19 @@ macro_rules! panic {
185187
($msg:expr $(,)?) => ({
186188
kani::panic(stringify!($msg));
187189
});
188-
// The first argument is the format and the rest contains tokens to be included in the msg.
190+
// The first argument is the message and the rest contains tokens to be included in the msg.
189191
// `panic!("Error: {}", code);`
190-
($msg:literal, $($arg:tt)+) => ({
192+
//
193+
// Note: This macro may match things that wouldn't be accepted by the panic!() macro. we have
194+
// decided to over-approximate the matching so we can deal with things like macro inside a macro
195+
// E.g.:
196+
// ```
197+
// panic!(concat!("Message {}", " split in two"), argument);
198+
// ```
199+
// The std implementation of `panic!()` macro is implemented in the compiler and it seems to
200+
// be able to do things that we cannot do here.
201+
// https://github.com/rust-lang/rust/blob/dc2d232c7485c60dd856f8b9aee83426492d4661/compiler/rustc_expand/src/base.rs#L1197
202+
($msg:expr, $($arg:tt)+) => ({
191203
kani::panic(stringify!($msg, $($arg)+));
192204
});
193205
}
+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
Failed Checks: concat!("Panic: {} code: ", 10), msg
12
Failed Checks: msg
23
Failed Checks: explicit panic
34
Failed Checks: Panic message
45
Failed Checks: "Panic message with arg {}", "str"
56
Failed Checks: "{}", msg
7+
8+
Failed Checks: concat!("ArrayVec::", "try_insert",\
9+
": index {} is out of bounds in vector of length {}"),\
10+
5, 3

‎tests/expected/panic/panic-2018/messages.rs

+5
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,8 @@ include! {"../test.rs"}
1111
fn check_panic_2018() {
1212
check_panic();
1313
}
14+
15+
#[kani::proof]
16+
fn check_user_panic_macro() {
17+
panic_oob!("try_insert", 5, 3);
18+
}
+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
Failed Checks: concat!("Panic: {} code: ", 10), msg
12
Failed Checks: msg
23
Failed Checks: explicit panic
34
Failed Checks: Panic message
45
Failed Checks: "Panic message with arg {}", "str"
56
Failed Checks: "{}", msg
7+
8+
Failed Checks: concat!("ArrayVec::", "try_insert",\
9+
": index {} is out of bounds in vector of length {}"),\
10+
5, 3

‎tests/expected/panic/panic-2021/messages.rs

+5
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,8 @@ include! {"../test.rs"}
1111
fn check_panic_2021() {
1212
check_panic();
1313
}
14+
15+
#[kani::proof]
16+
fn check_user_panic_macro() {
17+
panic_oob!("try_insert", 5, 3);
18+
}

‎tests/expected/panic/test.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,20 @@ fn check_panic() {
88
1 => panic!("Panic message"),
99
2 => panic!("Panic message with arg {}", "str"),
1010
3 => panic!("{}", msg),
11-
_ => panic!(msg),
11+
4 => panic!(msg),
12+
_ => panic!(concat!("Panic: {} code: ", 10), msg),
1213
}
1314
}
15+
16+
macro_rules! panic_oob {
17+
($method_name:expr, $index:expr, $len:expr) => {
18+
panic!(
19+
concat!(
20+
"ArrayVec::",
21+
$method_name,
22+
": index {} is out of bounds in vector of length {}"
23+
),
24+
$index, $len
25+
)
26+
};
27+
}

‎tests/expected/unreachable/expected

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ Failed Checks: internal error: entered unreachable code:
33
Failed Checks: internal error: entered unreachable code: Error message
44
Failed Checks: internal error: entered unreachable code: "Unreachable message with arg {}", "str"
55
Failed Checks: internal error: entered unreachable code: "{}", msg
6-
6+
Failed Checks: internal error: entered unreachable code: concat!("My", " error", " message")

‎tests/expected/unreachable/unreach_msg.rs

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ fn check_unreachable() {
1010
1 => unreachable!("Error message"),
1111
2 => unreachable!("Unreachable message with arg {}", "str"),
1212
3 => unreachable!("{}", msg),
13+
4 => unreachable!(concat!("My", " error", " message")),
1314
_ => unreachable!(msg),
1415
}
1516
}

0 commit comments

Comments
 (0)
Please sign in to comment.