Skip to content

Commit 7592cd6

Browse files
authored
Add yet another Buffer error message example. (#1375)
Add the error message described [here], and a workaround. [here]: #1290 (comment)
1 parent 4ad9705 commit 7592cd6

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

examples/buffer_errors.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
fn main() {
77
error_buffer_wrapper();
88
error_retry_closure();
9+
error_retry_closure_uninit();
910
error_retry_indirect_closure();
1011
error_empty_slice();
1112
error_array_by_value();
@@ -40,8 +41,8 @@ fn error_retry_closure() {
4041
use rustix::io;
4142
use rustix::io::retry_on_intr;
4243

43-
fn b<B: Buffer<u8>>(_: B) -> io::Result<()> {
44-
Ok(())
44+
fn b<B: Buffer<u8>>(b: B) -> io::Result<B::Output> {
45+
unsafe { Ok(b.assume_init(0)) }
4546
}
4647

4748
let mut event_buf = [0; 4];
@@ -58,6 +59,33 @@ fn error_retry_closure() {
5859
retry_on_intr(|| b(&mut *event_buf_slice)).unwrap();
5960
}
6061

62+
fn error_retry_closure_uninit() {
63+
use rustix::buffer::Buffer;
64+
use rustix::io;
65+
use std::mem::MaybeUninit;
66+
67+
fn b<B: Buffer<u8>>(b: B) -> io::Result<B::Output> {
68+
unsafe { Ok(b.assume_init(0)) }
69+
}
70+
71+
let mut event_buf = [MaybeUninit::<u8>::uninit(); 4];
72+
73+
// Ideally we'd write this, but it gets:
74+
// "captured variable cannot escape `FnMut` closure body".
75+
/*
76+
rustix::io::retry_on_intr(|| b(&mut event_buf)).unwrap();
77+
*/
78+
79+
// The fix: Don't use `retry_on_intr`, unfortunately.
80+
loop {
81+
match b(&mut event_buf) {
82+
Ok((_init, _unini)) => break,
83+
Err(io::Errno::INTR) => continue,
84+
Err(err) => Err(err).unwrap(),
85+
}
86+
}
87+
}
88+
6189
fn error_retry_indirect_closure() {
6290
use rustix::buffer::Buffer;
6391
use rustix::io;

src/buffer.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ use core::slice;
8787
/// try replacing `x` with `&mut *x`, or, if that doesn't work, try moving a
8888
/// `let` into the closure body. See `error_retry_closure` and
8989
/// `error_retry_indirect_closure` in examples/buffer_errors.rs.
90+
///
91+
/// If you see errors like
92+
/// "captured variable cannot escape `FnMut` closure body",
93+
/// use an explicit loop instead of `retry_on_intr`, assuming you're using
94+
/// that. See `error_retry_closure_uninit` in examples.rs.
9095
pub trait Buffer<T>: private::Sealed<T> {}
9196

9297
// Implement `Buffer` for all the types that implement `Sealed`.

0 commit comments

Comments
 (0)