@@ -136,7 +136,21 @@ mod write_string {
136136 fn sink_buffered_windowed ( ) {
137137 let data = INPUT ;
138138 let size = data. len ( ) ;
139- let mut writer = BufWriter :: new ( WriteStats :: new ( io:: sink ( ) ) ) ;
139+
140+ // We store the inner writer in a separate variable so its
141+ // destructor is called correctly. We then wrap a mutable
142+ // reference to it in a buffered writer. The destructor of the
143+ // buffered writer is suppressed, because it tries to flush the
144+ // inner writer. (It doesn't do anything else, so it's fine to
145+ // skip it.) This would cause a non-unwinding panic if the inner
146+ // writer hasn't implemented `write` yet. The standard library
147+ // implementation of `BufWriter` does try to keep track of a
148+ // panic by the inner writer, but it's not perfect. We access
149+ // the inner writer later with `.get_ref()`. If there is a panic
150+ // in that situation, the buffered writer cannot observe and
151+ // track it.
152+ let mut inner_writer = WriteStats :: new ( io:: sink ( ) ) ;
153+ let mut writer = std:: mem:: ManuallyDrop :: new ( BufWriter :: new ( & mut inner_writer) ) ;
140154
141155 for chunk in data. chunks ( CHUNK_SIZE ) {
142156 let written = writer. write ( chunk) ;
@@ -286,7 +300,21 @@ mod write_byte_literal {
286300 fn sink_buffered_windowed ( ) {
287301 let data = INPUT ;
288302 let size = data. len ( ) ;
289- let mut writer = BufWriter :: new ( WriteStats :: new ( io:: sink ( ) ) ) ;
303+
304+ // We store the inner writer in a separate variable so its
305+ // destructor is called correctly. We then wrap a mutable
306+ // reference to it in a buffered writer. The destructor of the
307+ // buffered writer is suppressed, because it tries to flush the
308+ // inner writer. (It doesn't do anything else, so it's fine to
309+ // skip it.) This would cause a non-unwinding panic if the inner
310+ // writer hasn't implemented `write` yet. The standard library
311+ // implementation of `BufWriter` does try to keep track of a
312+ // panic by the inner writer, but it's not perfect. We access
313+ // the inner writer later with `.get_ref()`. If there is a panic
314+ // in that situation, the buffered writer cannot observe and
315+ // track it.
316+ let mut inner_writer = WriteStats :: new ( io:: sink ( ) ) ;
317+ let mut writer = std:: mem:: ManuallyDrop :: new ( BufWriter :: new ( & mut inner_writer) ) ;
290318
291319 for chunk in data. chunks ( CHUNK_SIZE ) {
292320 let written = writer. write ( chunk) ;
0 commit comments