| 87 | } |
| 88 | |
| 89 | fn error_retry_indirect_closure() { |
| 90 | use rustix::buffer::Buffer; |
| 91 | use rustix::io; |
| 92 | let flag = true; |
| 93 | |
| 94 | // This is reduced from the xattr crate, src/sys/linux_macos.rs line 119. |
| 95 | |
| 96 | // Ideally we'd write this, but it gets: |
| 97 | // "borrowed data escapes outside of closure". |
| 98 | /* |
| 99 | let func = if flag { |
| 100 | f |
| 101 | } else { |
| 102 | g |
| 103 | }; |
| 104 | let _vec = allocate_loop(|buf| func(buf)).unwrap(); |
| 105 | */ |
| 106 | |
| 107 | // The fix: Move `func` to inside the closure. |
| 108 | let _vec = allocate_loop(|buf| { |
| 109 | let func = if flag { f } else { g }; |
| 110 | func(buf) |
| 111 | }) |
| 112 | .unwrap(); |
| 113 | |
| 114 | fn allocate_loop<F: FnMut(&mut [u8]) -> io::Result<usize>>(mut f: F) -> io::Result<Vec<u8>> { |
| 115 | let mut vec: Vec<u8> = Vec::new(); |
| 116 | loop { |
| 117 | let ret = f(&mut [])?; |
| 118 | vec.resize(ret, 0); |
| 119 | |
| 120 | match f(&mut vec) { |
| 121 | Ok(size) => { |
| 122 | vec.truncate(size); |
| 123 | vec.shrink_to_fit(); |
| 124 | return Ok(vec); |
| 125 | } |
| 126 | Err(err) => return Err(err), |
| 127 | } |
| 128 | } |
| 129 | } |
| 130 | fn f<B: Buffer<u8>>(_: B) -> Result<usize, io::Errno> { |
| 131 | Ok(0) |
| 132 | } |
| 133 | fn g<B: Buffer<u8>>(_: B) -> Result<usize, io::Errno> { |
| 134 | Ok(0) |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | fn error_empty_slice() { |
| 139 | use rustix::buffer::Buffer; |