run-make-support: add drop bomb module

This commit is contained in:
许杰友 Jieyou Xu (Joe) 2024-06-09 14:13:01 +00:00
parent 7255c2825d
commit a3feeb3afe
3 changed files with 66 additions and 0 deletions

View File

@ -0,0 +1,50 @@
//! This module implements "drop bombs" intended for use by command wrappers to ensure that the
//! constructed commands are *eventually* executed. This is exactly like `rustc_errors::Diag` where
//! we force every `Diag` to be consumed or we emit a bug, but we panic instead.
//!
//! This is adapted from <https://docs.rs/drop_bomb/latest/drop_bomb/> and simplified for our
//! purposes.
use std::ffi::{OsStr, OsString};
use std::panic;
#[cfg(test)]
mod tests;
#[derive(Debug)]
pub(crate) struct DropBomb {
command: OsString,
defused: bool,
armed_line: u32,
}
impl DropBomb {
/// Arm a [`DropBomb`]. If the value is dropped without being [`defused`][Self::defused], then
/// it will panic. It is expected that the command wrapper uses `#[track_caller]` to help
/// propagate the caller info from rmake.rs.
#[track_caller]
pub(crate) fn arm<S: AsRef<OsStr>>(command: S) -> DropBomb {
DropBomb {
command: command.as_ref().into(),
defused: false,
armed_line: panic::Location::caller().line(),
}
}
/// Defuse the [`DropBomb`]. This will prevent the drop bomb from panicking when dropped.
pub(crate) fn defuse(&mut self) {
self.defused = true;
}
}
impl Drop for DropBomb {
fn drop(&mut self) {
if !self.defused && !std::thread::panicking() {
panic!(
"command constructed but not executed at line {}: `{}`",
self.armed_line,
self.command.to_string_lossy()
)
}
}
}

View File

@ -0,0 +1,15 @@
use super::DropBomb;
#[test]
#[should_panic]
fn test_arm() {
let bomb = DropBomb::arm("hi :3");
drop(bomb); // <- armed bomb should explode when not defused
}
#[test]
fn test_defuse() {
let mut bomb = DropBomb::arm("hi :3");
bomb.defuse();
drop(bomb); // <- defused bomb should not explode
}

View File

@ -7,6 +7,7 @@ pub mod cc;
pub mod clang;
mod command;
pub mod diff;
mod drop_bomb;
pub mod llvm_readobj;
pub mod run;
pub mod rustc;