run-make-support: add drop bomb module
This commit is contained in:
parent
7255c2825d
commit
a3feeb3afe
50
src/tools/run-make-support/src/drop_bomb/mod.rs
Normal file
50
src/tools/run-make-support/src/drop_bomb/mod.rs
Normal 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()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
src/tools/run-make-support/src/drop_bomb/tests.rs
Normal file
15
src/tools/run-make-support/src/drop_bomb/tests.rs
Normal 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
|
||||||
|
}
|
@ -7,6 +7,7 @@ pub mod cc;
|
|||||||
pub mod clang;
|
pub mod clang;
|
||||||
mod command;
|
mod command;
|
||||||
pub mod diff;
|
pub mod diff;
|
||||||
|
mod drop_bomb;
|
||||||
pub mod llvm_readobj;
|
pub mod llvm_readobj;
|
||||||
pub mod run;
|
pub mod run;
|
||||||
pub mod rustc;
|
pub mod rustc;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user