Rollup merge of #111875 - WaffleLapkin:defer_on_drop, r=Nilstrieb
Don't leak the function that is called on drop It probably wasn't causing problems anyway, but still, a `// this leaks, please don't pass anything that owns memory` is not sustainable. I could implement a version which does not require `Option`, but it would require `unsafe`, at which point it's probably not worth it.
This commit is contained in:
commit
a9743e108a
5 changed files with 21 additions and 15 deletions
|
@ -102,21 +102,27 @@ pub mod unord;
|
||||||
pub use ena::undo_log;
|
pub use ena::undo_log;
|
||||||
pub use ena::unify;
|
pub use ena::unify;
|
||||||
|
|
||||||
pub struct OnDrop<F: Fn()>(pub F);
|
/// Returns a structure that calls `f` when dropped.
|
||||||
|
pub fn defer<F: FnOnce()>(f: F) -> OnDrop<F> {
|
||||||
|
OnDrop(Some(f))
|
||||||
|
}
|
||||||
|
|
||||||
impl<F: Fn()> OnDrop<F> {
|
pub struct OnDrop<F: FnOnce()>(Option<F>);
|
||||||
/// Forgets the function which prevents it from running.
|
|
||||||
/// Ensure that the function owns no memory, otherwise it will be leaked.
|
impl<F: FnOnce()> OnDrop<F> {
|
||||||
|
/// Disables on-drop call.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn disable(self) {
|
pub fn disable(mut self) {
|
||||||
std::mem::forget(self);
|
self.0.take();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Fn()> Drop for OnDrop<F> {
|
impl<F: FnOnce()> Drop for OnDrop<F> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
(self.0)();
|
if let Some(f) = self.0.take() {
|
||||||
|
f();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
defer,
|
||||||
owned_slice::{slice_owned, try_slice_owned, OwnedSlice},
|
owned_slice::{slice_owned, try_slice_owned, OwnedSlice},
|
||||||
OnDrop,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -66,7 +66,7 @@ fn boxed() {
|
||||||
fn drop_drops() {
|
fn drop_drops() {
|
||||||
let flag = Arc::new(AtomicBool::new(false));
|
let flag = Arc::new(AtomicBool::new(false));
|
||||||
let flag_prime = Arc::clone(&flag);
|
let flag_prime = Arc::clone(&flag);
|
||||||
let d = OnDrop(move || flag_prime.store(true, atomic::Ordering::Relaxed));
|
let d = defer(move || flag_prime.store(true, atomic::Ordering::Relaxed));
|
||||||
|
|
||||||
let slice = slice_owned(d, |_| &[]);
|
let slice = slice_owned(d, |_| &[]);
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,9 @@ use crate::util;
|
||||||
use rustc_ast::token;
|
use rustc_ast::token;
|
||||||
use rustc_ast::{self as ast, LitKind, MetaItemKind};
|
use rustc_ast::{self as ast, LitKind, MetaItemKind};
|
||||||
use rustc_codegen_ssa::traits::CodegenBackend;
|
use rustc_codegen_ssa::traits::CodegenBackend;
|
||||||
|
use rustc_data_structures::defer;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_data_structures::OnDrop;
|
|
||||||
use rustc_errors::registry::Registry;
|
use rustc_errors::registry::Registry;
|
||||||
use rustc_errors::{ErrorGuaranteed, Handler};
|
use rustc_errors::{ErrorGuaranteed, Handler};
|
||||||
use rustc_lint::LintStore;
|
use rustc_lint::LintStore;
|
||||||
|
@ -325,7 +325,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
|
||||||
|
|
||||||
rustc_span::set_source_map(compiler.sess.parse_sess.clone_source_map(), move || {
|
rustc_span::set_source_map(compiler.sess.parse_sess.clone_source_map(), move || {
|
||||||
let r = {
|
let r = {
|
||||||
let _sess_abort_error = OnDrop(|| {
|
let _sess_abort_error = defer(|| {
|
||||||
compiler.sess.finish_diagnostics(registry);
|
compiler.sess.finish_diagnostics(registry);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ where
|
||||||
{
|
{
|
||||||
TLV.with(|tlv| {
|
TLV.with(|tlv| {
|
||||||
let old = tlv.replace(erase(context));
|
let old = tlv.replace(erase(context));
|
||||||
let _reset = rustc_data_structures::OnDrop(move || tlv.set(old));
|
let _reset = rustc_data_structures::defer(move || tlv.set(old));
|
||||||
f()
|
f()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ use {
|
||||||
rustc_data_structures::fx::FxHashSet,
|
rustc_data_structures::fx::FxHashSet,
|
||||||
rustc_data_structures::sync::Lock,
|
rustc_data_structures::sync::Lock,
|
||||||
rustc_data_structures::sync::Lrc,
|
rustc_data_structures::sync::Lrc,
|
||||||
rustc_data_structures::{jobserver, OnDrop},
|
rustc_data_structures::{defer, jobserver},
|
||||||
rustc_span::DUMMY_SP,
|
rustc_span::DUMMY_SP,
|
||||||
std::iter,
|
std::iter,
|
||||||
std::process,
|
std::process,
|
||||||
|
@ -530,7 +530,7 @@ fn remove_cycle<D: DepKind>(
|
||||||
/// all active queries for cycles before finally resuming all the waiters at once.
|
/// all active queries for cycles before finally resuming all the waiters at once.
|
||||||
#[cfg(parallel_compiler)]
|
#[cfg(parallel_compiler)]
|
||||||
pub fn deadlock<D: DepKind>(query_map: QueryMap<D>, registry: &rayon_core::Registry) {
|
pub fn deadlock<D: DepKind>(query_map: QueryMap<D>, registry: &rayon_core::Registry) {
|
||||||
let on_panic = OnDrop(|| {
|
let on_panic = defer(|| {
|
||||||
eprintln!("deadlock handler panicked, aborting process");
|
eprintln!("deadlock handler panicked, aborting process");
|
||||||
process::abort();
|
process::abort();
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue