Change:
<!-- Thank you for creating a tracking issue! Tracking issues are for tracking a feature from implementation to stabilization. Make sure to include the relevant RFC for the feature if it has one. If the new feature is small, it may be fine to skip the RFC process. In that case, you can use use in your initial implementation PR. The reviewer will ask you to open a tracking issue if they agree your feature can be without an RFC. --Feature gate: This is a tracking issue for and its associated error type etc. This allows a to be disassembled, and the inner writer to be recovered - without attempting to write out any buffered data (instead it is returnedt to the caller), and therefore (unlike ) succeeding even if the underlying writer is returning errors. <!-- For most library features, it'd be useful to include a summarized version of the public API. (E.g. just the public function signatures without their doc comments or implementation.) --- [x] Implementation: [x] Gain experience with this API, to see if it's good [ ] Stabilization PR with Final commenting period (FCP)Should be called ? Is there a suitable simpler API for presenting this functionality? (I think not, see )
fcp merge Check out recap of this API in
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [x] [x] [x] [x] [x] [x] [x] Concerns: name () Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
Should be called instead? In all previous uses of "raw" in similar names, I believe a raw pointer is involved somewhere. But that isn't the case here. Also, it looks like the error might not actually be exported? At least, rustdoc doesn't think so:
I don't have an opinion about this. I just chose that name to distinguish it more from . I would be quite happy to change it to . I will check this. Thanks!
I'm with on this one, the in this fn name feels odd.
Indeed. I did some looking around and I think your feeling is Hence where I change this. That ought to go first. I'm not sure what the implications are for the stabilisation - does that mean it should wait some more? Thanks.
:bell: This is now entering its final comment period, as per the . :bell:
concern name Registering a concern so that this FCP doesn't complete until we finalize the name. I agree that makes sense here; this is a safe method returning safe objects, unlike which is unsafe and returns a raw pointer.
If the only thing that changes is the name, we don't need to delay stabilization (other than to wait for the PR changing the name). If something more substantive changes, we can consider if that impacts the evaluation we've done so far or not.
The 'raw' here refers to the fact that unlike .intoinner(), this function does not attempt to flush the data but just directly gives you the 'raw' parts of the buffer, without trying to process them. I can see how it can be confusing with our other uses of the word raw, but just calling it might not make clear what the difference with is. (Though on the other hand, one could argue that .intoinner has to consolidate the parts into a single 'inner' again before returning it, wheras .into_parts just returns the parts (the buffer and the underlying writer) directly.)
gives you just an inner writer; gives you all the parts. I don't have a particularly strong feeling about this but I think is somewhat better. So I'll go and deal with the review comment on the fixups MR .
Looks like WriterPanicked isn't publicly available: Did something go wrong there with the visibility?
Yes, something did go wrong - I don't think I understood how all the use/visibility/stability plumbing worked. I was trying to fix that in but there is still something wrong with that. I will fix it tomorrow when I have a clear head. My apologies.

Discussion:
/// # Examples /// /// ``` <del> /// #![feature(bufwriter_into_parts)] </del> /// use std::io::{BufWriter, Write}; /// /// let mut buffer = [0u8; 10];

/// assert_eq!(recovered_writer.len(), 0); /// assert_eq!(&buffered_data.unwrap(), b"ata"); /// ``` <del> #[unstable(feature = "bufwriter_into_parts", issue = "80690")] </del> <ins> #[stable(feature = "bufwriter_into_parts", since = "1.56.0")] </ins> pub fn into_parts(mut self) -> (W, Result<Vec<u8>, WriterPanicked>) { let buf = mem::take(&mut self.buf); let buf = if !self.panicked { Ok(buf) } else { Err(WriterPanicked { buf }) };

} } <del> #[unstable(feature = "bufwriter_into_parts", issue = "80690")] </del> <ins> #[stable(feature = "bufwriter_into_parts", since = "1.56.0")] </ins> /// Error returned for the buffered data from `BufWriter::into_parts`, when the underlying /// writer has previously panicked.  Contains the (possibly partly written) buffered data. /// /// # Example /// /// ``` <del> /// #![feature(bufwriter_into_parts)] </del> /// use std::io::{self, BufWriter, Write}; /// use std::panic::{catch_unwind, AssertUnwindSafe}; ///

impl WriterPanicked { /// Returns the perhaps-unwritten data.  Some of this data may have been written by the /// panicking call(s) to the underlying writer, so simply writing it again is not a good idea. <del> #[unstable(feature = "bufwriter_into_parts", issue = "80690")] </del> <ins> #[stable(feature = "bufwriter_into_parts", since = "1.56.0")] </ins> pub fn into_inner(self) -> Vec<u8> { self.buf }

"BufWriter inner writer panicked, what data remains unwritten is not known"; } <del> #[unstable(feature = "bufwriter_into_parts", issue = "80690")] </del> <ins> #[stable(feature = "bufwriter_into_parts", since = "1.56.0")] </ins> impl error::Error for WriterPanicked { #[allow(deprecated, deprecated_in_future)] fn description(&self) -> &str {

} } <del> #[unstable(feature = "bufwriter_into_parts", issue = "80690")] </del> <ins> #[stable(feature = "bufwriter_into_parts", since = "1.56.0")] </ins> impl fmt::Display for WriterPanicked { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", Self::DESCRIPTION) } } <del> #[unstable(feature = "bufwriter_into_parts", issue = "80690")] </del> <ins> #[stable(feature = "bufwriter_into_parts", since = "1.56.0")] </ins> impl fmt::Debug for WriterPanicked { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("WriterPanicked")

pub use bufreader::BufReader; pub use bufwriter::BufWriter; <del> #[unstable(feature = "bufwriter_into_parts", issue = "80690")] </del> <ins> #[stable(feature = "bufwriter_into_parts", since = "1.56.0")] </ins> pub use bufwriter::WriterPanicked; pub use linewriter::LineWriter; use linewritershim::LineWriterShim;

#[stable(feature = "rust1", since = "1.0.0")] pub use self::buffered::IntoInnerError; <del> #[unstable(feature = "bufwriter_into_parts", issue = "80690")] </del> <ins> #[stable(feature = "bufwriter_into_parts", since = "1.56.0")] </ins> pub use self::buffered::WriterPanicked; #[stable(feature = "rust1", since = "1.0.0")] pub use self::buffered::{BufReader, BufWriter, LineWriter};