Skip to content

Commit

Permalink
CommandExt::before_exec: deprecate safety in edition 2024
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Jun 8, 2024
1 parent 90d6255 commit 87bbe0b
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 2 deletions.
19 changes: 17 additions & 2 deletions library/std/src/os/unix/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,25 @@ pub trait CommandExt: Sealed {
/// Schedules a closure to be run just before the `exec` function is
/// invoked.
///
/// This method is stable and usable, but it should be unsafe. To fix
/// that, it got deprecated in favor of the unsafe [`pre_exec`].
/// `before_exec` used to be a safe method, but it needs to be unsafe since the closure may only
/// perform operations that are *async-signal-safe*. Hence it got deprecated in favor of the
/// unsafe [`pre_exec`]. Meanwhile, Rust gained the ability to make an existing safe method
/// fully unsafe in a new edition, which is how `before_exec` became `unsafe`It still also
/// remains deprecated; `pre_exec` should be used instead.
///
/// [`pre_exec`]: CommandExt::pre_exec
#[cfg(not(bootstrap))]
#[stable(feature = "process_exec", since = "1.15.0")]
#[deprecated(since = "1.37.0", note = "should be unsafe, use `pre_exec` instead")]
#[rustc_deprecated_safe_2024]
unsafe fn before_exec<F>(&mut self, f: F) -> &mut process::Command
where
F: FnMut() -> io::Result<()> + Send + Sync + 'static,
{
unsafe { self.pre_exec(f) }
}

#[cfg(bootstrap)]
#[stable(feature = "process_exec", since = "1.15.0")]
#[deprecated(since = "1.37.0", note = "should be unsafe, use `pre_exec` instead")]
fn before_exec<F>(&mut self, f: F) -> &mut process::Command
Expand Down
11 changes: 11 additions & 0 deletions tests/ui/rust-2024/unsafe-before_exec.e2024.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error[E0133]: call to unsafe function `before_exec` is unsafe and requires unsafe block
--> $DIR/unsafe-before_exec.rs:14:5
|
LL | cmd.before_exec(|| Ok(()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
= note: consult the function's documentation for information on how to avoid undefined behavior

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0133`.
17 changes: 17 additions & 0 deletions tests/ui/rust-2024/unsafe-before_exec.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//@ revisions: e2021 e2024
//@ only-unix
//@[e2021] edition: 2021
//@[e2021] check-pass
//@[e2024] edition: 2024
//@[e2024] compile-flags: -Zunstable-options

use std::process::Command;
use std::os::unix::process::CommandExt;

#[allow(deprecated)]
fn main() {
let mut cmd = Command::new("sleep");
cmd.before_exec(|| Ok(()));
//[e2024]~^ ERROR call to unsafe function `before_exec` is unsafe
drop(cmd); // we don't actually run the command.
}

0 comments on commit 87bbe0b

Please sign in to comment.