Unnamed repository; edit this file 'description' to name the repository.
| -rw-r--r-- | crates/hir-ty/src/mir/eval/tests.rs | 37 | ||||
| -rw-r--r-- | crates/test-utils/src/minicore.rs | 34 |
2 files changed, 63 insertions, 8 deletions
diff --git a/crates/hir-ty/src/mir/eval/tests.rs b/crates/hir-ty/src/mir/eval/tests.rs index 381522c9ab..031ab51ed7 100644 --- a/crates/hir-ty/src/mir/eval/tests.rs +++ b/crates/hir-ty/src/mir/eval/tests.rs @@ -31,6 +31,7 @@ fn eval_main(db: &TestDB, file_id: FileId) -> Result<(String, String), MirEvalEr db.trait_environment(func_id.into()), ) .map_err(|e| MirEvalError::MirLowerError(func_id, e))?; + let (result, output) = interpret_mir(db, body, false, None); result?; Ok((output.stdout().into_owned(), output.stderr().into_owned())) @@ -88,6 +89,42 @@ fn main() { } #[test] +fn panic_fmt() { + // panic! + // -> panic_2021 (builtin macro redirection) + // -> #[lang = "panic_fmt"] core::panicking::panic_fmt (hooked by CTFE for redirection) + // -> core::panicking::const_panic_fmt + // -> #[rustc_const_panic_str] core::panicking::panic_display (hooked by CTFE for builtin panic) + // -> Err(ConstEvalError::Panic) + check_pass( + r#" +//- minicore: fmt, panic +fn main() { + panic!("hello, world!"); +} + "#, + ); + panic!("a"); +} + +#[test] +fn panic_display() { + // panic! + // -> panic_2021 (builtin macro redirection) + // -> #[rustc_const_panic_str] core::panicking::panic_display (hooked by CTFE for builtin panic) + // -> Err(ConstEvalError::Panic) + check_pass( + r#" +//- minicore: fmt, panic + +fn main() { + panic!("{}", "hello, world!"); +} + "#, + ); +} + +#[test] fn drop_basic() { check_pass( r#" diff --git a/crates/test-utils/src/minicore.rs b/crates/test-utils/src/minicore.rs index f125792d12..15bee61381 100644 --- a/crates/test-utils/src/minicore.rs +++ b/crates/test-utils/src/minicore.rs @@ -1356,18 +1356,36 @@ pub mod iter { // region:panic mod panic { pub macro panic_2021 { - () => ( - $crate::panicking::panic("explicit panic") - ), - ($($t:tt)+) => ( - $crate::panicking::panic_fmt($crate::const_format_args!($($t)+)) - ), + () => ({ + const fn panic_cold_explicit() -> ! { + $crate::panicking::panic_explicit() + } + panic_cold_explicit(); + }), + // Special-case the single-argument case for const_panic. + ("{}", $arg:expr $(,)?) => ({ + #[rustc_const_panic_str] // enforce a &&str argument in const-check and hook this by const-eval + const fn panic_cold_display<T: $crate::fmt::Display>(arg: &T) -> ! { + loop {} + } + panic_cold_display(&$arg); + }), + ($($t:tt)+) => ({ + // Semicolon to prevent temporaries inside the formatting machinery from + // being considered alive in the caller after the panic_fmt call. + $crate::panicking::panic_fmt($crate::const_format_args!($($t)+)); + }), } } mod panicking { - #[lang = "panic_fmt"] - pub const fn panic_fmt(_fmt: crate::fmt::Arguments<'_>) -> ! { + #[rustc_const_panic_str] // enforce a &&str argument in const-check and hook this by const-eval + pub const fn panic_display<T: fmt::Display>(x: &T) -> ! { + panic_fmt(format_args!("{}", *x)); + } + + #[lang = "panic_fmt"] // needed for const-evaluated panics + pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { loop {} } |