From 2627eedde97e3e94e786faf8dfe612d65d8a6fa6 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 8 Aug 2020 21:05:50 -0400 Subject: Avoid deleting temporary files on error Previously if the compiler error'd, fatally, then temporary directories which should be preserved by -Csave-temps would be deleted due to fatal compiler errors being implemented as panics. --- src/librustc_data_structures/Cargo.toml | 1 + src/librustc_data_structures/lib.rs | 1 + src/librustc_data_structures/temp_dir.rs | 34 ++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 src/librustc_data_structures/temp_dir.rs (limited to 'src/librustc_data_structures') diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index 811d1e49626..65812cc4e68 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -30,6 +30,7 @@ bitflags = "1.2.1" measureme = "0.7.1" libc = "0.2" stacker = "0.1.9" +tempfile = "3.0.5" [dependencies.parking_lot] version = "0.10" diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 0b2e7cda1b4..3884fc05105 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -95,6 +95,7 @@ pub mod vec_linked_list; pub mod work_queue; pub use atomic_ref::AtomicRef; pub mod frozen; +pub mod temp_dir; pub struct OnDrop(pub F); diff --git a/src/librustc_data_structures/temp_dir.rs b/src/librustc_data_structures/temp_dir.rs new file mode 100644 index 00000000000..0d9b3e3ca25 --- /dev/null +++ b/src/librustc_data_structures/temp_dir.rs @@ -0,0 +1,34 @@ +use std::mem::ManuallyDrop; +use std::path::Path; +use tempfile::TempDir; + +/// This is used to avoid TempDir being dropped on error paths unintentionally. +#[derive(Debug)] +pub struct MaybeTempDir { + dir: ManuallyDrop, + // Whether the TempDir should be deleted on drop. + keep: bool, +} + +impl Drop for MaybeTempDir { + fn drop(&mut self) { + // Safety: We are in the destructor, and no further access will + // occur. + let dir = unsafe { ManuallyDrop::take(&mut self.dir) }; + if self.keep { + dir.into_path(); + } + } +} + +impl AsRef for MaybeTempDir { + fn as_ref(&self) -> &Path { + self.dir.path() + } +} + +impl MaybeTempDir { + pub fn new(dir: TempDir, keep_on_drop: bool) -> MaybeTempDir { + MaybeTempDir { dir: ManuallyDrop::new(dir), keep: keep_on_drop } + } +} -- cgit 1.4.1-3-g733a5