diff --git a/src/praetor/mod.rs b/src/praetor/mod.rs index 568884a..ebad441 100644 --- a/src/praetor/mod.rs +++ b/src/praetor/mod.rs @@ -935,6 +935,9 @@ mod job { // turn `this`, which was allocated at (2), into box. // miri complains this is a use-after-free, but it isn't? silly miri... + // Turns out this is actually correct on miri's end, but because + // we ensure that the scope lives as long as any jobs, this is + // actually fine, as far as I can tell. let this = unsafe { Box::from_raw(this.cast::>().cast_mut()) }; let f = this.into_inner(); @@ -948,9 +951,9 @@ mod job { } // (1) allocate box for job - Box::into_raw(Box::new(Job::new(harness::, unsafe { + Box::into_raw(Box::new(Job::new(harness::, { // (2) convert self into a pointer - NonNull::new_unchecked(Box::into_raw(self)).cast() + Box::into_non_null(self).cast() }))) } } @@ -1436,7 +1439,10 @@ impl<'scope> Scope<'scope> { R: Send, { run_in_worker(|worker| { - let this = Self::from_context(worker.context.clone()); + // SAFETY: we call complete() after creating this scope, which + // ensures that any jobs spawned from the scope exit before the + // scope closes. + let this = unsafe { Self::from_context(worker.context.clone()) }; this.complete(worker, || f(&this)) }) } @@ -1447,7 +1453,10 @@ impl<'scope> Scope<'scope> { R: Send, { context.run_in_worker(|worker| { - let this = Self::from_context(context.clone()); + // SAFETY: we call complete() after creating this scope, which + // ensures that any jobs spawned from the scope exit before the + // scope closes. + let this = unsafe { Self::from_context(context.clone()) }; this.complete(worker, || f(&this)) }) } @@ -1628,7 +1637,7 @@ impl<'scope> Scope<'scope> { ) } - fn from_context(ctx: Arc) -> Self { + unsafe fn from_context(ctx: Arc) -> Self { Self { context: ctx, job_counter: JobCounter::default(),