xref: /relibc/core_io/patches/27ede55414e01f13c6869a8763da207e544cc6ad.patch (revision 2da6c7634d974687d6d431d9f70d5a37658e0b09)
1diff --git a/buffered.rs b/buffered.rs
2index 7001d8e..8e5daa4 100644
3--- a/buffered.rs
4+++ b/buffered.rs
5@@ -10,13 +10,13 @@
6
7 //! Buffering wrappers for I/O traits
8
9+use core::prelude::v1::*;
10 use io::prelude::*;
11
12-use cmp;
13-use error;
14-use fmt;
15+use core::cmp;
16+use core::fmt;
17 use io::{self, Initializer, DEFAULT_BUF_SIZE, Error, ErrorKind, SeekFrom};
18-use memchr;
19+use io::memchr;
20
21 /// The `BufReader` struct adds buffering to any reader.
22 ///
23@@ -46,7 +46,6 @@ use memchr;
24 /// # Ok(())
25 /// # }
26 /// ```
27-#[stable(feature = "rust1", since = "1.0.0")]
28 pub struct BufReader<R> {
29     inner: R,
30     buf: Box<[u8]>,
31@@ -69,7 +68,6 @@ impl<R: Read> BufReader<R> {
32     /// # Ok(())
33     /// # }
34     /// ```
35-    #[stable(feature = "rust1", since = "1.0.0")]
36     pub fn new(inner: R) -> BufReader<R> {
37         BufReader::with_capacity(DEFAULT_BUF_SIZE, inner)
38     }
39@@ -90,7 +88,6 @@ impl<R: Read> BufReader<R> {
40     /// # Ok(())
41     /// # }
42     /// ```
43-    #[stable(feature = "rust1", since = "1.0.0")]
44     pub fn with_capacity(cap: usize, inner: R) -> BufReader<R> {
45         unsafe {
46             let mut buffer = Vec::with_capacity(cap);
47@@ -123,7 +120,6 @@ impl<R: Read> BufReader<R> {
48     /// # Ok(())
49     /// # }
50     /// ```
51-    #[stable(feature = "rust1", since = "1.0.0")]
52     pub fn get_ref(&self) -> &R { &self.inner }
53
54     /// Gets a mutable reference to the underlying reader.
55@@ -144,7 +140,6 @@ impl<R: Read> BufReader<R> {
56     /// # Ok(())
57     /// # }
58     /// ```
59-    #[stable(feature = "rust1", since = "1.0.0")]
60     pub fn get_mut(&mut self) -> &mut R { &mut self.inner }
61
62     /// Returns `true` if there are no bytes in the internal buffer.
63@@ -167,7 +162,6 @@ impl<R: Read> BufReader<R> {
64     /// # Ok(())
65     /// # }
66     /// ```
67-    #[unstable(feature = "bufreader_is_empty", issue = "45323", reason = "recently added")]
68     pub fn is_empty(&self) -> bool {
69         self.pos == self.cap
70     }
71@@ -190,11 +184,9 @@ impl<R: Read> BufReader<R> {
72     /// # Ok(())
73     /// # }
74     /// ```
75-    #[stable(feature = "rust1", since = "1.0.0")]
76     pub fn into_inner(self) -> R { self.inner }
77 }
78
79-#[stable(feature = "rust1", since = "1.0.0")]
80 impl<R: Read> Read for BufReader<R> {
81     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
82         // If we don't have any buffered data and we're doing a massive read
83@@ -217,7 +209,6 @@ impl<R: Read> Read for BufReader<R> {
84     }
85 }
86
87-#[stable(feature = "rust1", since = "1.0.0")]
88 impl<R: Read> BufRead for BufReader<R> {
89     fn fill_buf(&mut self) -> io::Result<&[u8]> {
90         // If we've reached the end of our internal buffer then we need to fetch
91@@ -237,7 +228,6 @@ impl<R: Read> BufRead for BufReader<R> {
92     }
93 }
94
95-#[stable(feature = "rust1", since = "1.0.0")]
96 impl<R> fmt::Debug for BufReader<R> where R: fmt::Debug {
97     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
98         fmt.debug_struct("BufReader")
99@@ -247,7 +237,6 @@ impl<R> fmt::Debug for BufReader<R> where R: fmt::Debug {
100     }
101 }
102
103-#[stable(feature = "rust1", since = "1.0.0")]
104 impl<R: Seek> Seek for BufReader<R> {
105     /// Seek to an offset, in bytes, in the underlying reader.
106     ///
107@@ -345,7 +334,6 @@ impl<R: Seek> Seek for BufReader<R> {
108 /// [`Tcpstream::write`]: ../../std/net/struct.TcpStream.html#method.write
109 /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
110 /// [`flush`]: #method.flush
111-#[stable(feature = "rust1", since = "1.0.0")]
112 pub struct BufWriter<W: Write> {
113     inner: Option<W>,
114     buf: Vec<u8>,
115@@ -380,7 +368,6 @@ pub struct BufWriter<W: Write> {
116 /// };
117 /// ```
118 #[derive(Debug)]
119-#[stable(feature = "rust1", since = "1.0.0")]
120 pub struct IntoInnerError<W>(W, Error);
121
122 impl<W: Write> BufWriter<W> {
123@@ -394,7 +381,6 @@ impl<W: Write> BufWriter<W> {
124     ///
125     /// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
126     /// ```
127-    #[stable(feature = "rust1", since = "1.0.0")]
128     pub fn new(inner: W) -> BufWriter<W> {
129         BufWriter::with_capacity(DEFAULT_BUF_SIZE, inner)
130     }
131@@ -412,7 +398,6 @@ impl<W: Write> BufWriter<W> {
132     /// let stream = TcpStream::connect("127.0.0.1:34254").unwrap();
133     /// let mut buffer = BufWriter::with_capacity(100, stream);
134     /// ```
135-    #[stable(feature = "rust1", since = "1.0.0")]
136     pub fn with_capacity(cap: usize, inner: W) -> BufWriter<W> {
137         BufWriter {
138             inner: Some(inner),
139@@ -461,7 +446,6 @@ impl<W: Write> BufWriter<W> {
140     /// // we can use reference just like buffer
141     /// let reference = buffer.get_ref();
142     /// ```
143-    #[stable(feature = "rust1", since = "1.0.0")]
144     pub fn get_ref(&self) -> &W { self.inner.as_ref().unwrap() }
145
146     /// Gets a mutable reference to the underlying writer.
147@@ -479,7 +463,6 @@ impl<W: Write> BufWriter<W> {
148     /// // we can use reference just like buffer
149     /// let reference = buffer.get_mut();
150     /// ```
151-    #[stable(feature = "rust1", since = "1.0.0")]
152     pub fn get_mut(&mut self) -> &mut W { self.inner.as_mut().unwrap() }
153
154     /// Unwraps this `BufWriter`, returning the underlying writer.
155@@ -501,7 +484,6 @@ impl<W: Write> BufWriter<W> {
156     /// // unwrap the TcpStream and flush the buffer
157     /// let stream = buffer.into_inner().unwrap();
158     /// ```
159-    #[stable(feature = "rust1", since = "1.0.0")]
160     pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
161         match self.flush_buf() {
162             Err(e) => Err(IntoInnerError(self, e)),
163@@ -510,7 +492,6 @@ impl<W: Write> BufWriter<W> {
164     }
165 }
166
167-#[stable(feature = "rust1", since = "1.0.0")]
168 impl<W: Write> Write for BufWriter<W> {
169     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
170         if self.buf.len() + buf.len() > self.buf.capacity() {
171@@ -530,7 +511,6 @@ impl<W: Write> Write for BufWriter<W> {
172     }
173 }
174
175-#[stable(feature = "rust1", since = "1.0.0")]
176 impl<W: Write> fmt::Debug for BufWriter<W> where W: fmt::Debug {
177     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
178         fmt.debug_struct("BufWriter")
179@@ -540,7 +520,6 @@ impl<W: Write> fmt::Debug for BufWriter<W> where W: fmt::Debug {
180     }
181 }
182
183-#[stable(feature = "rust1", since = "1.0.0")]
184 impl<W: Write + Seek> Seek for BufWriter<W> {
185     /// Seek to the offset, in bytes, in the underlying writer.
186     ///
187@@ -550,7 +529,6 @@ impl<W: Write + Seek> Seek for BufWriter<W> {
188     }
189 }
190
191-#[stable(feature = "rust1", since = "1.0.0")]
192 impl<W: Write> Drop for BufWriter<W> {
193     fn drop(&mut self) {
194         if self.inner.is_some() && !self.panicked {
195@@ -589,7 +567,6 @@ impl<W> IntoInnerError<W> {
196     ///     }
197     /// };
198     /// ```
199-    #[stable(feature = "rust1", since = "1.0.0")]
200     pub fn error(&self) -> &Error { &self.1 }
201
202     /// Returns the buffered writer instance which generated the error.
203@@ -622,23 +599,13 @@ impl<W> IntoInnerError<W> {
204     ///     }
205     /// };
206     /// ```
207-    #[stable(feature = "rust1", since = "1.0.0")]
208     pub fn into_inner(self) -> W { self.0 }
209 }
210
211-#[stable(feature = "rust1", since = "1.0.0")]
212 impl<W> From<IntoInnerError<W>> for Error {
213     fn from(iie: IntoInnerError<W>) -> Error { iie.1 }
214 }
215
216-#[stable(feature = "rust1", since = "1.0.0")]
217-impl<W: Send + fmt::Debug> error::Error for IntoInnerError<W> {
218-    fn description(&self) -> &str {
219-        error::Error::description(self.error())
220-    }
221-}
222-
223-#[stable(feature = "rust1", since = "1.0.0")]
224 impl<W> fmt::Display for IntoInnerError<W> {
225     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
226         self.error().fmt(f)
227@@ -696,7 +663,6 @@ impl<W> fmt::Display for IntoInnerError<W> {
228 /// # Ok(())
229 /// # }
230 /// ```
231-#[stable(feature = "rust1", since = "1.0.0")]
232 pub struct LineWriter<W: Write> {
233     inner: BufWriter<W>,
234     need_flush: bool,
235@@ -717,7 +683,6 @@ impl<W: Write> LineWriter<W> {
236     /// # Ok(())
237     /// # }
238     /// ```
239-    #[stable(feature = "rust1", since = "1.0.0")]
240     pub fn new(inner: W) -> LineWriter<W> {
241         // Lines typically aren't that long, don't use a giant buffer
242         LineWriter::with_capacity(1024, inner)
243@@ -738,7 +703,6 @@ impl<W: Write> LineWriter<W> {
244     /// # Ok(())
245     /// # }
246     /// ```
247-    #[stable(feature = "rust1", since = "1.0.0")]
248     pub fn with_capacity(cap: usize, inner: W) -> LineWriter<W> {
249         LineWriter {
250             inner: BufWriter::with_capacity(cap, inner),
251@@ -762,7 +726,6 @@ impl<W: Write> LineWriter<W> {
252     /// # Ok(())
253     /// # }
254     /// ```
255-    #[stable(feature = "rust1", since = "1.0.0")]
256     pub fn get_ref(&self) -> &W { self.inner.get_ref() }
257
258     /// Gets a mutable reference to the underlying writer.
259@@ -785,7 +748,6 @@ impl<W: Write> LineWriter<W> {
260     /// # Ok(())
261     /// # }
262     /// ```
263-    #[stable(feature = "rust1", since = "1.0.0")]
264     pub fn get_mut(&mut self) -> &mut W { self.inner.get_mut() }
265
266     /// Unwraps this `LineWriter`, returning the underlying writer.
267@@ -811,7 +773,6 @@ impl<W: Write> LineWriter<W> {
268     /// # Ok(())
269     /// # }
270     /// ```
271-    #[stable(feature = "rust1", since = "1.0.0")]
272     pub fn into_inner(self) -> Result<W, IntoInnerError<LineWriter<W>>> {
273         self.inner.into_inner().map_err(|IntoInnerError(buf, e)| {
274             IntoInnerError(LineWriter {
275@@ -822,7 +783,6 @@ impl<W: Write> LineWriter<W> {
276     }
277 }
278
279-#[stable(feature = "rust1", since = "1.0.0")]
280 impl<W: Write> Write for LineWriter<W> {
281     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
282         if self.need_flush {
283@@ -867,7 +827,6 @@ impl<W: Write> Write for LineWriter<W> {
284     }
285 }
286
287-#[stable(feature = "rust1", since = "1.0.0")]
288 impl<W: Write> fmt::Debug for LineWriter<W> where W: fmt::Debug {
289     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
290         fmt.debug_struct("LineWriter")
291diff --git a/cursor.rs b/cursor.rs
292index c844770..dcc64c6 100644
293--- a/cursor.rs
294+++ b/cursor.rs
295@@ -8,10 +8,11 @@
296 // option. This file may not be copied, modified, or distributed
297 // except according to those terms.
298
299+use core::prelude::v1::*;
300 use io::prelude::*;
301
302-use core::convert::TryInto;
303-use cmp;
304+#[cfg(feature = "collections")] use core::convert::TryInto;
305+use core::cmp;
306 use io::{self, Initializer, SeekFrom, Error, ErrorKind};
307
308 /// A `Cursor` wraps another type and provides it with a
309@@ -79,7 +80,6 @@ use io::{self, Initializer, SeekFrom, Error, ErrorKind};
310 ///     assert_eq!(&buff.get_ref()[5..15], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
311 /// }
312 /// ```
313-#[stable(feature = "rust1", since = "1.0.0")]
314 #[derive(Clone, Debug)]
315 pub struct Cursor<T> {
316     inner: T,
317@@ -102,7 +102,6 @@ impl<T> Cursor<T> {
318     /// # fn force_inference(_: &Cursor<Vec<u8>>) {}
319     /// # force_inference(&buff);
320     /// ```
321-    #[stable(feature = "rust1", since = "1.0.0")]
322     pub fn new(inner: T) -> Cursor<T> {
323         Cursor { pos: 0, inner: inner }
324     }
325@@ -120,7 +119,6 @@ impl<T> Cursor<T> {
326     ///
327     /// let vec = buff.into_inner();
328     /// ```
329-    #[stable(feature = "rust1", since = "1.0.0")]
330     pub fn into_inner(self) -> T { self.inner }
331
332     /// Gets a reference to the underlying value in this cursor.
333@@ -136,7 +134,6 @@ impl<T> Cursor<T> {
334     ///
335     /// let reference = buff.get_ref();
336     /// ```
337-    #[stable(feature = "rust1", since = "1.0.0")]
338     pub fn get_ref(&self) -> &T { &self.inner }
339
340     /// Gets a mutable reference to the underlying value in this cursor.
341@@ -155,7 +152,6 @@ impl<T> Cursor<T> {
342     ///
343     /// let reference = buff.get_mut();
344     /// ```
345-    #[stable(feature = "rust1", since = "1.0.0")]
346     pub fn get_mut(&mut self) -> &mut T { &mut self.inner }
347
348     /// Returns the current position of this cursor.
349@@ -177,7 +173,6 @@ impl<T> Cursor<T> {
350     /// buff.seek(SeekFrom::Current(-1)).unwrap();
351     /// assert_eq!(buff.position(), 1);
352     /// ```
353-    #[stable(feature = "rust1", since = "1.0.0")]
354     pub fn position(&self) -> u64 { self.pos }
355
356     /// Sets the position of this cursor.
357@@ -197,11 +192,9 @@ impl<T> Cursor<T> {
358     /// buff.set_position(4);
359     /// assert_eq!(buff.position(), 4);
360     /// ```
361-    #[stable(feature = "rust1", since = "1.0.0")]
362     pub fn set_position(&mut self, pos: u64) { self.pos = pos; }
363 }
364
365-#[stable(feature = "rust1", since = "1.0.0")]
366 impl<T> io::Seek for Cursor<T> where T: AsRef<[u8]> {
367     fn seek(&mut self, style: SeekFrom) -> io::Result<u64> {
368         let (base_pos, offset) = match style {
369@@ -222,17 +215,16 @@ impl<T> io::Seek for Cursor<T> where T: AsRef<[u8]> {
370     }
371 }
372
373-#[stable(feature = "rust1", since = "1.0.0")]
374 impl<T> Read for Cursor<T> where T: AsRef<[u8]> {
375     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
376-        let n = Read::read(&mut self.fill_buf()?, buf)?;
377+        let n = Read::read(&mut self.get_buf()?, buf)?;
378         self.pos += n as u64;
379         Ok(n)
380     }
381
382     fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
383         let n = buf.len();
384-        Read::read_exact(&mut self.fill_buf()?, buf)?;
385+        Read::read_exact(&mut self.get_buf()?, buf)?;
386         self.pos += n as u64;
387         Ok(())
388     }
389@@ -243,12 +235,16 @@ impl<T> Read for Cursor<T> where T: AsRef<[u8]> {
390     }
391 }
392
393-#[stable(feature = "rust1", since = "1.0.0")]
394-impl<T> BufRead for Cursor<T> where T: AsRef<[u8]> {
395-    fn fill_buf(&mut self) -> io::Result<&[u8]> {
396+impl<T> Cursor<T> where T: AsRef<[u8]> {
397+    fn get_buf(&mut self) -> io::Result<&[u8]> {
398         let amt = cmp::min(self.pos, self.inner.as_ref().len() as u64);
399         Ok(&self.inner.as_ref()[(amt as usize)..])
400     }
401+}
402+
403+#[cfg(feature="collections")]
404+impl<T> BufRead for Cursor<T> where T: AsRef<[u8]> {
405+    fn fill_buf(&mut self) -> io::Result<&[u8]> { self.get_buf() }
406     fn consume(&mut self, amt: usize) { self.pos += amt as u64; }
407 }
408
409@@ -261,6 +257,7 @@ fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<us
410 }
411
412 // Resizing write implementation
413+#[cfg(feature="collections")]
414 fn vec_write(pos_mut: &mut u64, vec: &mut Vec<u8>, buf: &[u8]) -> io::Result<usize> {
415     let pos: usize = (*pos_mut).try_into().map_err(|_| {
416         Error::new(ErrorKind::InvalidInput,
417@@ -287,7 +284,6 @@ fn vec_write(pos_mut: &mut u64, vec: &mut Vec<u8>, buf: &[u8]) -> io::Result<usi
418     Ok(buf.len())
419 }
420
421-#[stable(feature = "rust1", since = "1.0.0")]
422 impl<'a> Write for Cursor<&'a mut [u8]> {
423     #[inline]
424     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
425@@ -296,7 +292,7 @@ impl<'a> Write for Cursor<&'a mut [u8]> {
426     fn flush(&mut self) -> io::Result<()> { Ok(()) }
427 }
428
429-#[unstable(feature = "cursor_mut_vec", issue = "30132")]
430+#[cfg(feature="collections")]
431 impl<'a> Write for Cursor<&'a mut Vec<u8>> {
432     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
433         vec_write(&mut self.pos, self.inner, buf)
434@@ -304,7 +300,7 @@ impl<'a> Write for Cursor<&'a mut Vec<u8>> {
435     fn flush(&mut self) -> io::Result<()> { Ok(()) }
436 }
437
438-#[stable(feature = "rust1", since = "1.0.0")]
439+#[cfg(feature = "collections")]
440 impl Write for Cursor<Vec<u8>> {
441     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
442         vec_write(&mut self.pos, &mut self.inner, buf)
443@@ -312,8 +308,8 @@ impl Write for Cursor<Vec<u8>> {
444     fn flush(&mut self) -> io::Result<()> { Ok(()) }
445 }
446
447-#[stable(feature = "cursor_box_slice", since = "1.5.0")]
448-impl Write for Cursor<Box<[u8]>> {
449+#[cfg(feature = "alloc")]
450+impl Write for Cursor<::alloc::boxed::Box<[u8]>> {
451     #[inline]
452     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
453         slice_write(&mut self.pos, &mut self.inner, buf)
454diff --git a/error.rs b/error.rs
455index bb9383d..01ddea6 100644
456--- a/error.rs
457+++ b/error.rs
458@@ -8,11 +8,16 @@
459 // option. This file may not be copied, modified, or distributed
460 // except according to those terms.
461
462-use error;
463-use fmt;
464-use result;
465-use sys;
466-use convert::From;
467+#[cfg(feature="alloc")] use alloc::boxed::Box;
468+#[cfg(not(feature="alloc"))] use ::FakeBox as Box;
469+use core::convert::Into;
470+use core::fmt;
471+use core::marker::{Send, Sync};
472+use core::option::Option::{self, Some, None};
473+use core::result;
474+#[cfg(feature="collections")] use collections::string::String;
475+#[cfg(not(feature="collections"))] use ::ErrorString as String;
476+use core::convert::From;
477
478 /// A specialized [`Result`](../result/enum.Result.html) type for I/O
479 /// operations.
480@@ -48,7 +53,6 @@ use convert::From;
481 ///     Ok(buffer)
482 /// }
483 /// ```
484-#[stable(feature = "rust1", since = "1.0.0")]
485 pub type Result<T> = result::Result<T, Error>;
486
487 /// The error type for I/O operations of the [`Read`], [`Write`], [`Seek`], and
488@@ -63,7 +67,6 @@ pub type Result<T> = result::Result<T, Error>;
489 /// [`Seek`]: ../io/trait.Seek.html
490 /// [`ErrorKind`]: enum.ErrorKind.html
491 #[derive(Debug)]
492-#[stable(feature = "rust1", since = "1.0.0")]
493 pub struct Error {
494     repr: Repr,
495 }
496@@ -71,13 +74,16 @@ pub struct Error {
497 enum Repr {
498     Os(i32),
499     Simple(ErrorKind),
500+    #[cfg(feature="alloc")]
501     Custom(Box<Custom>),
502+    #[cfg(not(feature="alloc"))]
503+    Custom(Custom),
504 }
505
506 #[derive(Debug)]
507 struct Custom {
508     kind: ErrorKind,
509-    error: Box<error::Error+Send+Sync>,
510+    error: String,
511 }
512
513 /// A list specifying general categories of I/O error.
514@@ -89,47 +95,34 @@ struct Custom {
515 ///
516 /// [`io::Error`]: struct.Error.html
517 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
518-#[stable(feature = "rust1", since = "1.0.0")]
519 #[allow(deprecated)]
520 pub enum ErrorKind {
521     /// An entity was not found, often a file.
522-    #[stable(feature = "rust1", since = "1.0.0")]
523     NotFound,
524     /// The operation lacked the necessary privileges to complete.
525-    #[stable(feature = "rust1", since = "1.0.0")]
526     PermissionDenied,
527     /// The connection was refused by the remote server.
528-    #[stable(feature = "rust1", since = "1.0.0")]
529     ConnectionRefused,
530     /// The connection was reset by the remote server.
531-    #[stable(feature = "rust1", since = "1.0.0")]
532     ConnectionReset,
533     /// The connection was aborted (terminated) by the remote server.
534-    #[stable(feature = "rust1", since = "1.0.0")]
535     ConnectionAborted,
536     /// The network operation failed because it was not connected yet.
537-    #[stable(feature = "rust1", since = "1.0.0")]
538     NotConnected,
539     /// A socket address could not be bound because the address is already in
540     /// use elsewhere.
541-    #[stable(feature = "rust1", since = "1.0.0")]
542     AddrInUse,
543     /// A nonexistent interface was requested or the requested address was not
544     /// local.
545-    #[stable(feature = "rust1", since = "1.0.0")]
546     AddrNotAvailable,
547     /// The operation failed because a pipe was closed.
548-    #[stable(feature = "rust1", since = "1.0.0")]
549     BrokenPipe,
550     /// An entity already exists, often a file.
551-    #[stable(feature = "rust1", since = "1.0.0")]
552     AlreadyExists,
553     /// The operation needs to block to complete, but the blocking operation was
554     /// requested to not occur.
555-    #[stable(feature = "rust1", since = "1.0.0")]
556     WouldBlock,
557     /// A parameter was incorrect.
558-    #[stable(feature = "rust1", since = "1.0.0")]
559     InvalidInput,
560     /// Data not valid for the operation were encountered.
561     ///
562@@ -141,10 +134,8 @@ pub enum ErrorKind {
563     /// `InvalidData` if the file's contents are not valid UTF-8.
564     ///
565     /// [`InvalidInput`]: #variant.InvalidInput
566-    #[stable(feature = "io_invalid_data", since = "1.2.0")]
567     InvalidData,
568     /// The I/O operation's timeout expired, causing it to be canceled.
569-    #[stable(feature = "rust1", since = "1.0.0")]
570     TimedOut,
571     /// An error returned when an operation could not be completed because a
572     /// call to [`write`] returned [`Ok(0)`].
573@@ -155,15 +146,12 @@ pub enum ErrorKind {
574     ///
575     /// [`write`]: ../../std/io/trait.Write.html#tymethod.write
576     /// [`Ok(0)`]: ../../std/io/type.Result.html
577-    #[stable(feature = "rust1", since = "1.0.0")]
578     WriteZero,
579     /// This operation was interrupted.
580     ///
581     /// Interrupted operations can typically be retried.
582-    #[stable(feature = "rust1", since = "1.0.0")]
583     Interrupted,
584     /// Any I/O error not part of this list.
585-    #[stable(feature = "rust1", since = "1.0.0")]
586     Other,
587
588     /// An error returned when an operation could not be completed because an
589@@ -172,15 +160,10 @@ pub enum ErrorKind {
590     /// This typically means that an operation could only succeed if it read a
591     /// particular number of bytes but only a smaller number of bytes could be
592     /// read.
593-    #[stable(feature = "read_exact", since = "1.6.0")]
594     UnexpectedEof,
595
596     /// A marker variant that tells the compiler that users of this enum cannot
597     /// match it exhaustively.
598-    #[unstable(feature = "io_error_internals",
599-               reason = "better expressed through extensible enums that this \
600-                         enum cannot be exhaustively matched against",
601-               issue = "0")]
602     #[doc(hidden)]
603     __Nonexhaustive,
604 }
605@@ -213,7 +196,6 @@ impl ErrorKind {
606
607 /// Intended for use for errors not exposed to the user, where allocating onto
608 /// the heap (for normal construction via Error::new) is too costly.
609-#[stable(feature = "io_error_from_errorkind", since = "1.14.0")]
610 impl From<ErrorKind> for Error {
611     #[inline]
612     fn from(kind: ErrorKind) -> Error {
613@@ -242,14 +224,13 @@ impl Error {
614     /// // errors can also be created from other errors
615     /// let custom_error2 = Error::new(ErrorKind::Interrupted, custom_error);
616     /// ```
617-    #[stable(feature = "rust1", since = "1.0.0")]
618     pub fn new<E>(kind: ErrorKind, error: E) -> Error
619-        where E: Into<Box<error::Error+Send+Sync>>
620+        where E: Into<String>
621     {
622         Self::_new(kind, error.into())
623     }
624
625-    fn _new(kind: ErrorKind, error: Box<error::Error+Send+Sync>) -> Error {
626+    fn _new(kind: ErrorKind, error: String) -> Error {
627         Error {
628             repr: Repr::Custom(Box::new(Custom {
629                 kind,
630@@ -258,24 +239,6 @@ impl Error {
631         }
632     }
633
634-    /// Returns an error representing the last OS error which occurred.
635-    ///
636-    /// This function reads the value of `errno` for the target platform (e.g.
637-    /// `GetLastError` on Windows) and will return a corresponding instance of
638-    /// `Error` for the error code.
639-    ///
640-    /// # Examples
641-    ///
642-    /// ```
643-    /// use std::io::Error;
644-    ///
645-    /// println!("last OS error: {:?}", Error::last_os_error());
646-    /// ```
647-    #[stable(feature = "rust1", since = "1.0.0")]
648-    pub fn last_os_error() -> Error {
649-        Error::from_raw_os_error(sys::os::errno() as i32)
650-    }
651-
652     /// Creates a new instance of an `Error` from a particular OS error code.
653     ///
654     /// # Examples
655@@ -301,7 +264,6 @@ impl Error {
656     /// assert_eq!(error.kind(), io::ErrorKind::AddrInUse);
657     /// # }
658     /// ```
659-    #[stable(feature = "rust1", since = "1.0.0")]
660     pub fn from_raw_os_error(code: i32) -> Error {
661         Error { repr: Repr::Os(code) }
662     }
663@@ -332,7 +294,6 @@ impl Error {
664     ///     print_os_error(&Error::new(ErrorKind::Other, "oh no!"));
665     /// }
666     /// ```
667-    #[stable(feature = "rust1", since = "1.0.0")]
668     pub fn raw_os_error(&self) -> Option<i32> {
669         match self.repr {
670             Repr::Os(i) => Some(i),
671@@ -366,12 +327,11 @@ impl Error {
672     ///     print_error(&Error::new(ErrorKind::Other, "oh no!"));
673     /// }
674     /// ```
675-    #[stable(feature = "io_error_inner", since = "1.3.0")]
676-    pub fn get_ref(&self) -> Option<&(error::Error+Send+Sync+'static)> {
677+    pub fn get_ref(&self) -> Option<&String> {
678         match self.repr {
679             Repr::Os(..) => None,
680             Repr::Simple(..) => None,
681-            Repr::Custom(ref c) => Some(&*c.error),
682+            Repr::Custom(ref c) => Some(&c.error),
683         }
684     }
685
686@@ -437,12 +397,11 @@ impl Error {
687     ///     print_error(&change_error(Error::new(ErrorKind::Other, MyError::new())));
688     /// }
689     /// ```
690-    #[stable(feature = "io_error_inner", since = "1.3.0")]
691-    pub fn get_mut(&mut self) -> Option<&mut (error::Error+Send+Sync+'static)> {
692+    pub fn get_mut(&mut self) -> Option<&mut String> {
693         match self.repr {
694             Repr::Os(..) => None,
695             Repr::Simple(..) => None,
696-            Repr::Custom(ref mut c) => Some(&mut *c.error),
697+            Repr::Custom(ref mut c) => Some(&mut c.error),
698         }
699     }
700
701@@ -471,8 +430,7 @@ impl Error {
702     ///     print_error(Error::new(ErrorKind::Other, "oh no!"));
703     /// }
704     /// ```
705-    #[stable(feature = "io_error_inner", since = "1.3.0")]
706-    pub fn into_inner(self) -> Option<Box<error::Error+Send+Sync>> {
707+    pub fn into_inner(self) -> Option<String> {
708         match self.repr {
709             Repr::Os(..) => None,
710             Repr::Simple(..) => None,
711@@ -498,10 +456,9 @@ impl Error {
712     ///     print_error(Error::new(ErrorKind::AddrInUse, "oh no!"));
713     /// }
714     /// ```
715-    #[stable(feature = "rust1", since = "1.0.0")]
716     pub fn kind(&self) -> ErrorKind {
717         match self.repr {
718-            Repr::Os(code) => sys::decode_error_kind(code),
719+            Repr::Os(_code) => ErrorKind::Other,
720             Repr::Custom(ref c) => c.kind,
721             Repr::Simple(kind) => kind,
722         }
723@@ -512,21 +469,18 @@ impl fmt::Debug for Repr {
724     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
725         match *self {
726             Repr::Os(ref code) =>
727-                fmt.debug_struct("Os").field("code", code)
728-                   .field("message", &sys::os::error_string(*code)).finish(),
729+                fmt.debug_struct("Os").field("code", code).finish(),
730             Repr::Custom(ref c) => fmt.debug_tuple("Custom").field(c).finish(),
731             Repr::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
732         }
733     }
734 }
735
736-#[stable(feature = "rust1", since = "1.0.0")]
737 impl fmt::Display for Error {
738     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
739         match self.repr {
740             Repr::Os(code) => {
741-                let detail = sys::os::error_string(code);
742-                write!(fmt, "{} (os error {})", detail, code)
743+                write!(fmt, "os error {}", code)
744             }
745             Repr::Custom(ref c) => c.error.fmt(fmt),
746             Repr::Simple(kind) => write!(fmt, "{}", kind.as_str()),
747@@ -534,24 +488,6 @@ impl fmt::Display for Error {
748     }
749 }
750
751-#[stable(feature = "rust1", since = "1.0.0")]
752-impl error::Error for Error {
753-    fn description(&self) -> &str {
754-        match self.repr {
755-            Repr::Os(..) | Repr::Simple(..) => self.kind().as_str(),
756-            Repr::Custom(ref c) => c.error.description(),
757-        }
758-    }
759-
760-    fn cause(&self) -> Option<&error::Error> {
761-        match self.repr {
762-            Repr::Os(..) => None,
763-            Repr::Simple(..) => None,
764-            Repr::Custom(ref c) => c.error.cause(),
765-        }
766-    }
767-}
768-
769 fn _assert_error_is_sync_send() {
770     fn _is_sync_send<T: Sync+Send>() {}
771     _is_sync_send::<Error>();
772diff --git a/impls.rs b/impls.rs
773index fe1179a..452b8b7 100644
774--- a/impls.rs
775+++ b/impls.rs
776@@ -8,15 +8,18 @@
777 // option. This file may not be copied, modified, or distributed
778 // except according to those terms.
779
780-use cmp;
781-use io::{self, SeekFrom, Read, Initializer, Write, Seek, BufRead, Error, ErrorKind};
782-use fmt;
783-use mem;
784+#[cfg(feature="alloc")] use alloc::boxed::Box;
785+use core::cmp;
786+use io::{self, SeekFrom, Read, Initializer, Write, Seek, Error, ErrorKind};
787+#[cfg(feature="collections")] use io::BufRead;
788+use core::fmt;
789+use core::mem;
790+#[cfg(feature="collections")] use collections::string::String;
791+#[cfg(feature="collections")] use collections::vec::Vec;
792
793 // =============================================================================
794 // Forwarding implementations
795
796-#[stable(feature = "rust1", since = "1.0.0")]
797 impl<'a, R: Read + ?Sized> Read for &'a mut R {
798     #[inline]
799     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
800@@ -28,11 +31,13 @@ impl<'a, R: Read + ?Sized> Read for &'a mut R {
801         (**self).initializer()
802     }
803
804+    #[cfg(feature="collections")]
805     #[inline]
806     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
807         (**self).read_to_end(buf)
808     }
809
810+    #[cfg(feature="collections")]
811     #[inline]
812     fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
813         (**self).read_to_string(buf)
814@@ -43,7 +48,6 @@ impl<'a, R: Read + ?Sized> Read for &'a mut R {
815         (**self).read_exact(buf)
816     }
817 }
818-#[stable(feature = "rust1", since = "1.0.0")]
819 impl<'a, W: Write + ?Sized> Write for &'a mut W {
820     #[inline]
821     fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) }
822@@ -61,12 +65,11 @@ impl<'a, W: Write + ?Sized> Write for &'a mut W {
823         (**self).write_fmt(fmt)
824     }
825 }
826-#[stable(feature = "rust1", since = "1.0.0")]
827 impl<'a, S: Seek + ?Sized> Seek for &'a mut S {
828     #[inline]
829     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) }
830 }
831-#[stable(feature = "rust1", since = "1.0.0")]
832+#[cfg(feature="collections")]
833 impl<'a, B: BufRead + ?Sized> BufRead for &'a mut B {
834     #[inline]
835     fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() }
836@@ -85,7 +88,7 @@ impl<'a, B: BufRead + ?Sized> BufRead for &'a mut B {
837     }
838 }
839
840-#[stable(feature = "rust1", since = "1.0.0")]
841+#[cfg(feature="alloc")]
842 impl<R: Read + ?Sized> Read for Box<R> {
843     #[inline]
844     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
845@@ -97,11 +100,13 @@ impl<R: Read + ?Sized> Read for Box<R> {
846         (**self).initializer()
847     }
848
849+    #[cfg(feature="collections")]
850     #[inline]
851     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
852         (**self).read_to_end(buf)
853     }
854
855+    #[cfg(feature="collections")]
856     #[inline]
857     fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
858         (**self).read_to_string(buf)
859@@ -112,7 +117,7 @@ impl<R: Read + ?Sized> Read for Box<R> {
860         (**self).read_exact(buf)
861     }
862 }
863-#[stable(feature = "rust1", since = "1.0.0")]
864+#[cfg(feature="alloc")]
865 impl<W: Write + ?Sized> Write for Box<W> {
866     #[inline]
867     fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) }
868@@ -130,12 +135,12 @@ impl<W: Write + ?Sized> Write for Box<W> {
869         (**self).write_fmt(fmt)
870     }
871 }
872-#[stable(feature = "rust1", since = "1.0.0")]
873+#[cfg(feature="alloc")]
874 impl<S: Seek + ?Sized> Seek for Box<S> {
875     #[inline]
876     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) }
877 }
878-#[stable(feature = "rust1", since = "1.0.0")]
879+#[cfg(feature="collections")]
880 impl<B: BufRead + ?Sized> BufRead for Box<B> {
881     #[inline]
882     fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() }
883@@ -161,7 +166,6 @@ impl<B: BufRead + ?Sized> BufRead for Box<B> {
884 ///
885 /// Note that reading updates the slice to point to the yet unread part.
886 /// The slice will be empty when EOF is reached.
887-#[stable(feature = "rust1", since = "1.0.0")]
888 impl<'a> Read for &'a [u8] {
889     #[inline]
890     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
891@@ -207,6 +211,7 @@ impl<'a> Read for &'a [u8] {
892         Ok(())
893     }
894
895+    #[cfg(feature="collections")]
896     #[inline]
897     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
898         buf.extend_from_slice(*self);
899@@ -216,7 +221,7 @@ impl<'a> Read for &'a [u8] {
900     }
901 }
902
903-#[stable(feature = "rust1", since = "1.0.0")]
904+#[cfg(feature="collections")]
905 impl<'a> BufRead for &'a [u8] {
906     #[inline]
907     fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(*self) }
908@@ -230,7 +235,6 @@ impl<'a> BufRead for &'a [u8] {
909 ///
910 /// Note that writing updates the slice to point to the yet unwritten part.
911 /// The slice will be empty when it has been completely overwritten.
912-#[stable(feature = "rust1", since = "1.0.0")]
913 impl<'a> Write for &'a mut [u8] {
914     #[inline]
915     fn write(&mut self, data: &[u8]) -> io::Result<usize> {
916@@ -256,7 +260,7 @@ impl<'a> Write for &'a mut [u8] {
917
918 /// Write is implemented for `Vec<u8>` by appending to the vector.
919 /// The vector will grow as needed.
920-#[stable(feature = "rust1", since = "1.0.0")]
921+#[cfg(feature="collections")]
922 impl Write for Vec<u8> {
923     #[inline]
924     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
925diff --git a/mod.rs b/mod.rs
926index 33d11eb..569daa2 100644
927--- a/mod.rs
928+++ b/mod.rs
929@@ -268,50 +268,38 @@
930 //! [`Result`]: ../result/enum.Result.html
931 //! [`.unwrap()`]: ../result/enum.Result.html#method.unwrap
932
933-#![stable(feature = "rust1", since = "1.0.0")]
934-
935-use cmp;
936+use core::cmp;
937 use core::str as core_str;
938-use error as std_error;
939-use fmt;
940-use result;
941-use str;
942-use memchr;
943-use ptr;
944-
945-#[stable(feature = "rust1", since = "1.0.0")]
946-pub use self::buffered::{BufReader, BufWriter, LineWriter};
947-#[stable(feature = "rust1", since = "1.0.0")]
948-pub use self::buffered::IntoInnerError;
949-#[stable(feature = "rust1", since = "1.0.0")]
950+use core::fmt;
951+use core::result;
952+#[cfg(feature="collections")] use collections::string::String;
953+use core::str;
954+#[cfg(feature="collections")] use collections::vec::Vec;
955+#[cfg(not(core_memchr))]
956+mod memchr;
957+#[cfg(all(feature="collections",core_memchr))]
958+use core::slice::memchr;
959+use core::ptr;
960+
961+#[cfg(feature="collections")] pub use self::buffered::{BufReader, BufWriter, LineWriter};
962+#[cfg(feature="collections")] pub use self::buffered::IntoInnerError;
963 pub use self::cursor::Cursor;
964-#[stable(feature = "rust1", since = "1.0.0")]
965 pub use self::error::{Result, Error, ErrorKind};
966-#[stable(feature = "rust1", since = "1.0.0")]
967 pub use self::util::{copy, sink, Sink, empty, Empty, repeat, Repeat};
968-#[stable(feature = "rust1", since = "1.0.0")]
969-pub use self::stdio::{stdin, stdout, stderr, Stdin, Stdout, Stderr};
970-#[stable(feature = "rust1", since = "1.0.0")]
971-pub use self::stdio::{StdoutLock, StderrLock, StdinLock};
972-#[unstable(feature = "print_internals", issue = "0")]
973-pub use self::stdio::{_print, _eprint};
974-#[unstable(feature = "libstd_io_internals", issue = "42788")]
975-#[doc(no_inline, hidden)]
976-pub use self::stdio::{set_panic, set_print};
977
978 pub mod prelude;
979-mod buffered;
980+#[cfg(feature="collections")] mod buffered;
981 mod cursor;
982 mod error;
983 mod impls;
984-mod lazy;
985 mod util;
986-mod stdio;
987
988-const DEFAULT_BUF_SIZE: usize = ::sys_common::io::DEFAULT_BUF_SIZE;
989+const DEFAULT_BUF_SIZE: usize = 8 * 1024;
990
991+#[cfg(feature="collections")]
992 struct Guard<'a> { buf: &'a mut Vec<u8>, len: usize }
993
994+#[cfg(feature="collections")]
995 impl<'a> Drop for Guard<'a> {
996     fn drop(&mut self) {
997         unsafe { self.buf.set_len(self.len); }
998@@ -336,6 +324,7 @@ impl<'a> Drop for Guard<'a> {
999 // 2. We're passing a raw buffer to the function `f`, and it is expected that
1000 //    the function only *appends* bytes to the buffer. We'll get undefined
1001 //    behavior if existing bytes are overwritten to have non-UTF-8 data.
1002+#[cfg(feature="collections")]
1003 fn append_to_string<F>(buf: &mut String, f: F) -> Result<usize>
1004     where F: FnOnce(&mut Vec<u8>) -> Result<usize>
1005 {
1006@@ -363,6 +352,7 @@ fn append_to_string<F>(buf: &mut String, f: F) -> Result<usize>
1007 //
1008 // Because we're extending the buffer with uninitialized data for trusted
1009 // readers, we need to make sure to truncate that if any of this panics.
1010+#[cfg(feature="collections")]
1011 fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> {
1012     let start_len = buf.len();
1013     let mut g = Guard { len: buf.len(), buf: buf };
1014@@ -466,7 +456,6 @@ fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize>
1015 /// [`BufReader`]: struct.BufReader.html
1016 /// [`&str`]: ../../std/primitive.str.html
1017 /// [slice]: ../../std/primitive.slice.html
1018-#[stable(feature = "rust1", since = "1.0.0")]
1019 #[doc(spotlight)]
1020 pub trait Read {
1021     /// Pull some bytes from this source into the specified buffer, returning
1022@@ -523,7 +512,6 @@ pub trait Read {
1023     /// # Ok(())
1024     /// # }
1025     /// ```
1026-    #[stable(feature = "rust1", since = "1.0.0")]
1027     fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
1028
1029     /// Determines if this `Read`er can work with buffers of uninitialized
1030@@ -548,7 +536,6 @@ pub trait Read {
1031     ///
1032     /// [`Initializer::nop()`]: ../../std/io/struct.Initializer.html#method.nop
1033     /// [`Initializer`]: ../../std/io/struct.Initializer.html
1034-    #[unstable(feature = "read_initializer", issue = "42788")]
1035     #[inline]
1036     unsafe fn initializer(&self) -> Initializer {
1037         Initializer::zeroing()
1038@@ -596,7 +583,7 @@ pub trait Read {
1039     /// # Ok(())
1040     /// # }
1041     /// ```
1042-    #[stable(feature = "rust1", since = "1.0.0")]
1043+    #[cfg(feature="collections")]
1044     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
1045         read_to_end(self, buf)
1046     }
1047@@ -634,7 +621,7 @@ pub trait Read {
1048     /// # Ok(())
1049     /// # }
1050     /// ```
1051-    #[stable(feature = "rust1", since = "1.0.0")]
1052+    #[cfg(feature="collections")]
1053     fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
1054         // Note that we do *not* call `.read_to_end()` here. We are passing
1055         // `&mut Vec<u8>` (the raw contents of `buf`) into the `read_to_end`
1056@@ -697,7 +684,6 @@ pub trait Read {
1057     /// # Ok(())
1058     /// # }
1059     /// ```
1060-    #[stable(feature = "read_exact", since = "1.6.0")]
1061     fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<()> {
1062         while !buf.is_empty() {
1063             match self.read(buf) {
1064@@ -749,7 +735,6 @@ pub trait Read {
1065     /// # Ok(())
1066     /// # }
1067     /// ```
1068-    #[stable(feature = "rust1", since = "1.0.0")]
1069     fn by_ref(&mut self) -> &mut Self where Self: Sized { self }
1070
1071     /// Transforms this `Read` instance to an [`Iterator`] over its bytes.
1072@@ -786,7 +771,6 @@ pub trait Read {
1073     /// # Ok(())
1074     /// # }
1075     /// ```
1076-    #[stable(feature = "rust1", since = "1.0.0")]
1077     fn bytes(self) -> Bytes<Self> where Self: Sized {
1078         Bytes { inner: self }
1079     }
1080@@ -827,10 +811,6 @@ pub trait Read {
1081     /// # Ok(())
1082     /// # }
1083     /// ```
1084-    #[unstable(feature = "io", reason = "the semantics of a partial read/write \
1085-                                         of where errors happen is currently \
1086-                                         unclear and may change",
1087-               issue = "27802")]
1088     fn chars(self) -> Chars<Self> where Self: Sized {
1089         Chars { inner: self }
1090     }
1091@@ -865,7 +845,6 @@ pub trait Read {
1092     /// # Ok(())
1093     /// # }
1094     /// ```
1095-    #[stable(feature = "rust1", since = "1.0.0")]
1096     fn chain<R: Read>(self, next: R) -> Chain<Self, R> where Self: Sized {
1097         Chain { first: self, second: next, done_first: false }
1098     }
1099@@ -901,20 +880,17 @@ pub trait Read {
1100     /// # Ok(())
1101     /// # }
1102     /// ```
1103-    #[stable(feature = "rust1", since = "1.0.0")]
1104     fn take(self, limit: u64) -> Take<Self> where Self: Sized {
1105         Take { inner: self, limit: limit }
1106     }
1107 }
1108
1109 /// A type used to conditionally initialize buffers passed to `Read` methods.
1110-#[unstable(feature = "read_initializer", issue = "42788")]
1111 #[derive(Debug)]
1112 pub struct Initializer(bool);
1113
1114 impl Initializer {
1115     /// Returns a new `Initializer` which will zero out buffers.
1116-    #[unstable(feature = "read_initializer", issue = "42788")]
1117     #[inline]
1118     pub fn zeroing() -> Initializer {
1119         Initializer(true)
1120@@ -928,21 +904,18 @@ impl Initializer {
1121     /// read from buffers passed to `Read` methods, and that the return value of
1122     /// the method accurately reflects the number of bytes that have been
1123     /// written to the head of the buffer.
1124-    #[unstable(feature = "read_initializer", issue = "42788")]
1125     #[inline]
1126     pub unsafe fn nop() -> Initializer {
1127         Initializer(false)
1128     }
1129
1130     /// Indicates if a buffer should be initialized.
1131-    #[unstable(feature = "read_initializer", issue = "42788")]
1132     #[inline]
1133     pub fn should_initialize(&self) -> bool {
1134         self.0
1135     }
1136
1137     /// Initializes a buffer if necessary.
1138-    #[unstable(feature = "read_initializer", issue = "42788")]
1139     #[inline]
1140     pub fn initialize(&self, buf: &mut [u8]) {
1141         if self.should_initialize() {
1142@@ -985,7 +958,6 @@ impl Initializer {
1143 /// # Ok(())
1144 /// # }
1145 /// ```
1146-#[stable(feature = "rust1", since = "1.0.0")]
1147 #[doc(spotlight)]
1148 pub trait Write {
1149     /// Write a buffer into this object, returning how many bytes were written.
1150@@ -1034,7 +1006,6 @@ pub trait Write {
1151     /// # Ok(())
1152     /// # }
1153     /// ```
1154-    #[stable(feature = "rust1", since = "1.0.0")]
1155     fn write(&mut self, buf: &[u8]) -> Result<usize>;
1156
1157     /// Flush this output stream, ensuring that all intermediately buffered
1158@@ -1060,7 +1031,6 @@ pub trait Write {
1159     /// # Ok(())
1160     /// # }
1161     /// ```
1162-    #[stable(feature = "rust1", since = "1.0.0")]
1163     fn flush(&mut self) -> Result<()>;
1164
1165     /// Attempts to write an entire buffer into this write.
1166@@ -1093,7 +1063,6 @@ pub trait Write {
1167     /// # Ok(())
1168     /// # }
1169     /// ```
1170-    #[stable(feature = "rust1", since = "1.0.0")]
1171     fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
1172         while !buf.is_empty() {
1173             match self.write(buf) {
1174@@ -1145,7 +1114,6 @@ pub trait Write {
1175     /// # Ok(())
1176     /// # }
1177     /// ```
1178-    #[stable(feature = "rust1", since = "1.0.0")]
1179     fn write_fmt(&mut self, fmt: fmt::Arguments) -> Result<()> {
1180         // Create a shim which translates a Write to a fmt::Write and saves
1181         // off I/O errors. instead of discarding them
1182@@ -1201,7 +1169,6 @@ pub trait Write {
1183     /// # Ok(())
1184     /// # }
1185     /// ```
1186-    #[stable(feature = "rust1", since = "1.0.0")]
1187     fn by_ref(&mut self) -> &mut Self where Self: Sized { self }
1188 }
1189
1190@@ -1231,7 +1198,6 @@ pub trait Write {
1191 /// # Ok(())
1192 /// # }
1193 /// ```
1194-#[stable(feature = "rust1", since = "1.0.0")]
1195 pub trait Seek {
1196     /// Seek to an offset, in bytes, in a stream.
1197     ///
1198@@ -1247,7 +1213,6 @@ pub trait Seek {
1199     /// Seeking to a negative offset is considered an error.
1200     ///
1201     /// [`SeekFrom::Start`]: enum.SeekFrom.html#variant.Start
1202-    #[stable(feature = "rust1", since = "1.0.0")]
1203     fn seek(&mut self, pos: SeekFrom) -> Result<u64>;
1204 }
1205
1206@@ -1257,29 +1222,26 @@ pub trait Seek {
1207 ///
1208 /// [`Seek`]: trait.Seek.html
1209 #[derive(Copy, PartialEq, Eq, Clone, Debug)]
1210-#[stable(feature = "rust1", since = "1.0.0")]
1211 pub enum SeekFrom {
1212     /// Set the offset to the provided number of bytes.
1213-    #[stable(feature = "rust1", since = "1.0.0")]
1214-    Start(#[stable(feature = "rust1", since = "1.0.0")] u64),
1215+    Start(u64),
1216
1217     /// Set the offset to the size of this object plus the specified number of
1218     /// bytes.
1219     ///
1220     /// It is possible to seek beyond the end of an object, but it's an error to
1221     /// seek before byte 0.
1222-    #[stable(feature = "rust1", since = "1.0.0")]
1223-    End(#[stable(feature = "rust1", since = "1.0.0")] i64),
1224+    End(i64),
1225
1226     /// Set the offset to the current position plus the specified number of
1227     /// bytes.
1228     ///
1229     /// It is possible to seek beyond the end of an object, but it's an error to
1230     /// seek before byte 0.
1231-    #[stable(feature = "rust1", since = "1.0.0")]
1232-    Current(#[stable(feature = "rust1", since = "1.0.0")] i64),
1233+    Current(i64),
1234 }
1235
1236+#[cfg(feature="collections")]
1237 fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
1238                                    -> Result<usize> {
1239     let mut read = 0;
1240@@ -1359,7 +1321,7 @@ fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
1241 /// # }
1242 /// ```
1243 ///
1244-#[stable(feature = "rust1", since = "1.0.0")]
1245+#[cfg(feature="collections")]
1246 pub trait BufRead: Read {
1247     /// Fills the internal buffer of this object, returning the buffer contents.
1248     ///
1249@@ -1404,7 +1366,6 @@ pub trait BufRead: Read {
1250     /// // ensure the bytes we worked with aren't returned again later
1251     /// stdin.consume(length);
1252     /// ```
1253-    #[stable(feature = "rust1", since = "1.0.0")]
1254     fn fill_buf(&mut self) -> Result<&[u8]>;
1255
1256     /// Tells this buffer that `amt` bytes have been consumed from the buffer,
1257@@ -1426,7 +1387,6 @@ pub trait BufRead: Read {
1258     /// that method's example includes an example of `consume()`.
1259     ///
1260     /// [`fill_buf`]: #tymethod.fill_buf
1261-    #[stable(feature = "rust1", since = "1.0.0")]
1262     fn consume(&mut self, amt: usize);
1263
1264     /// Read all bytes into `buf` until the delimiter `byte` or EOF is reached.
1265@@ -1484,7 +1444,6 @@ pub trait BufRead: Read {
1266     /// assert_eq!(num_bytes, 0);
1267     /// assert_eq!(buf, b"");
1268     /// ```
1269-    #[stable(feature = "rust1", since = "1.0.0")]
1270     fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> {
1271         read_until(self, byte, buf)
1272     }
1273@@ -1541,7 +1500,6 @@ pub trait BufRead: Read {
1274     /// assert_eq!(num_bytes, 0);
1275     /// assert_eq!(buf, "");
1276     /// ```
1277-    #[stable(feature = "rust1", since = "1.0.0")]
1278     fn read_line(&mut self, buf: &mut String) -> Result<usize> {
1279         // Note that we are not calling the `.read_until` method here, but
1280         // rather our hardcoded implementation. For more details as to why, see
1281@@ -1582,7 +1540,6 @@ pub trait BufRead: Read {
1282     /// assert_eq!(split_iter.next(), Some(b"dolor".to_vec()));
1283     /// assert_eq!(split_iter.next(), None);
1284     /// ```
1285-    #[stable(feature = "rust1", since = "1.0.0")]
1286     fn split(self, byte: u8) -> Split<Self> where Self: Sized {
1287         Split { buf: self, delim: byte }
1288     }
1289@@ -1621,7 +1578,6 @@ pub trait BufRead: Read {
1290     /// Each line of the iterator has the same error semantics as [`BufRead::read_line`].
1291     ///
1292     /// [`BufRead::read_line`]: trait.BufRead.html#method.read_line
1293-    #[stable(feature = "rust1", since = "1.0.0")]
1294     fn lines(self) -> Lines<Self> where Self: Sized {
1295         Lines { buf: self }
1296     }
1297@@ -1633,7 +1589,6 @@ pub trait BufRead: Read {
1298 /// Please see the documentation of [`chain`] for more details.
1299 ///
1300 /// [`chain`]: trait.Read.html#method.chain
1301-#[stable(feature = "rust1", since = "1.0.0")]
1302 pub struct Chain<T, U> {
1303     first: T,
1304     second: U,
1305@@ -1659,7 +1614,6 @@ impl<T, U> Chain<T, U> {
1306     /// # Ok(())
1307     /// # }
1308     /// ```
1309-    #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
1310     pub fn into_inner(self) -> (T, U) {
1311         (self.first, self.second)
1312     }
1313@@ -1682,7 +1636,6 @@ impl<T, U> Chain<T, U> {
1314     /// # Ok(())
1315     /// # }
1316     /// ```
1317-    #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
1318     pub fn get_ref(&self) -> (&T, &U) {
1319         (&self.first, &self.second)
1320     }
1321@@ -1709,13 +1662,11 @@ impl<T, U> Chain<T, U> {
1322     /// # Ok(())
1323     /// # }
1324     /// ```
1325-    #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
1326     pub fn get_mut(&mut self) -> (&mut T, &mut U) {
1327         (&mut self.first, &mut self.second)
1328     }
1329 }
1330
1331-#[stable(feature = "std_debug", since = "1.16.0")]
1332 impl<T: fmt::Debug, U: fmt::Debug> fmt::Debug for Chain<T, U> {
1333     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1334         f.debug_struct("Chain")
1335@@ -1725,7 +1676,6 @@ impl<T: fmt::Debug, U: fmt::Debug> fmt::Debug for Chain<T, U> {
1336     }
1337 }
1338
1339-#[stable(feature = "rust1", since = "1.0.0")]
1340 impl<T: Read, U: Read> Read for Chain<T, U> {
1341     fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
1342         if !self.done_first {
1343@@ -1747,7 +1697,7 @@ impl<T: Read, U: Read> Read for Chain<T, U> {
1344     }
1345 }
1346
1347-#[stable(feature = "chain_bufread", since = "1.9.0")]
1348+#[cfg(feature="collections")]
1349 impl<T: BufRead, U: BufRead> BufRead for Chain<T, U> {
1350     fn fill_buf(&mut self) -> Result<&[u8]> {
1351         if !self.done_first {
1352@@ -1774,7 +1724,6 @@ impl<T: BufRead, U: BufRead> BufRead for Chain<T, U> {
1353 /// Please see the documentation of [`take`] for more details.
1354 ///
1355 /// [`take`]: trait.Read.html#method.take
1356-#[stable(feature = "rust1", since = "1.0.0")]
1357 #[derive(Debug)]
1358 pub struct Take<T> {
1359     inner: T,
1360@@ -1809,7 +1758,6 @@ impl<T> Take<T> {
1361     /// # Ok(())
1362     /// # }
1363     /// ```
1364-    #[stable(feature = "rust1", since = "1.0.0")]
1365     pub fn limit(&self) -> u64 { self.limit }
1366
1367     /// Sets the number of bytes that can be read before this instance will
1368@@ -1836,7 +1784,6 @@ impl<T> Take<T> {
1369     /// # Ok(())
1370     /// # }
1371     /// ```
1372-    #[unstable(feature = "take_set_limit", issue = "42781")]
1373     pub fn set_limit(&mut self, limit: u64) {
1374         self.limit = limit;
1375     }
1376@@ -1861,7 +1808,6 @@ impl<T> Take<T> {
1377     /// # Ok(())
1378     /// # }
1379     /// ```
1380-    #[stable(feature = "io_take_into_inner", since = "1.15.0")]
1381     pub fn into_inner(self) -> T {
1382         self.inner
1383     }
1384@@ -1886,7 +1832,6 @@ impl<T> Take<T> {
1385     /// # Ok(())
1386     /// # }
1387     /// ```
1388-    #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
1389     pub fn get_ref(&self) -> &T {
1390         &self.inner
1391     }
1392@@ -1915,13 +1860,11 @@ impl<T> Take<T> {
1393     /// # Ok(())
1394     /// # }
1395     /// ```
1396-    #[stable(feature = "more_io_inner_methods", since = "1.20.0")]
1397     pub fn get_mut(&mut self) -> &mut T {
1398         &mut self.inner
1399     }
1400 }
1401
1402-#[stable(feature = "rust1", since = "1.0.0")]
1403 impl<T: Read> Read for Take<T> {
1404     fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
1405         // Don't call into inner reader at all at EOF because it may still block
1406@@ -1940,7 +1883,7 @@ impl<T: Read> Read for Take<T> {
1407     }
1408 }
1409
1410-#[stable(feature = "rust1", since = "1.0.0")]
1411+#[cfg(feature="collections")]
1412 impl<T: BufRead> BufRead for Take<T> {
1413     fn fill_buf(&mut self) -> Result<&[u8]> {
1414         // Don't call into inner reader at all at EOF because it may still block
1415@@ -1979,13 +1922,11 @@ fn read_one_byte(reader: &mut Read) -> Option<Result<u8>> {
1416 /// Please see the documentation of [`bytes`] for more details.
1417 ///
1418 /// [`bytes`]: trait.Read.html#method.bytes
1419-#[stable(feature = "rust1", since = "1.0.0")]
1420 #[derive(Debug)]
1421 pub struct Bytes<R> {
1422     inner: R,
1423 }
1424
1425-#[stable(feature = "rust1", since = "1.0.0")]
1426 impl<R: Read> Iterator for Bytes<R> {
1427     type Item = Result<u8>;
1428
1429@@ -2000,8 +1941,6 @@ impl<R: Read> Iterator for Bytes<R> {
1430 /// Please see the documentation of `chars()` for more details.
1431 ///
1432 /// [chars]: trait.Read.html#method.chars
1433-#[unstable(feature = "io", reason = "awaiting stability of Read::chars",
1434-           issue = "27802")]
1435 #[derive(Debug)]
1436 pub struct Chars<R> {
1437     inner: R,
1438@@ -2010,8 +1949,6 @@ pub struct Chars<R> {
1439 /// An enumeration of possible errors that can be generated from the `Chars`
1440 /// adapter.
1441 #[derive(Debug)]
1442-#[unstable(feature = "io", reason = "awaiting stability of Read::chars",
1443-           issue = "27802")]
1444 pub enum CharsError {
1445     /// Variant representing that the underlying stream was read successfully
1446     /// but it did not contain valid utf8 data.
1447@@ -2021,8 +1958,6 @@ pub enum CharsError {
1448     Other(Error),
1449 }
1450
1451-#[unstable(feature = "io", reason = "awaiting stability of Read::chars",
1452-           issue = "27802")]
1453 impl<R: Read> Iterator for Chars<R> {
1454     type Item = result::Result<char, CharsError>;
1455
1456@@ -2053,25 +1988,6 @@ impl<R: Read> Iterator for Chars<R> {
1457     }
1458 }
1459
1460-#[unstable(feature = "io", reason = "awaiting stability of Read::chars",
1461-           issue = "27802")]
1462-impl std_error::Error for CharsError {
1463-    fn description(&self) -> &str {
1464-        match *self {
1465-            CharsError::NotUtf8 => "invalid utf8 encoding",
1466-            CharsError::Other(ref e) => std_error::Error::description(e),
1467-        }
1468-    }
1469-    fn cause(&self) -> Option<&std_error::Error> {
1470-        match *self {
1471-            CharsError::NotUtf8 => None,
1472-            CharsError::Other(ref e) => e.cause(),
1473-        }
1474-    }
1475-}
1476-
1477-#[unstable(feature = "io", reason = "awaiting stability of Read::chars",
1478-           issue = "27802")]
1479 impl fmt::Display for CharsError {
1480     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1481         match *self {
1482@@ -2090,14 +2006,14 @@ impl fmt::Display for CharsError {
1483 /// `BufRead`. Please see the documentation of `split()` for more details.
1484 ///
1485 /// [split]: trait.BufRead.html#method.split
1486-#[stable(feature = "rust1", since = "1.0.0")]
1487+#[cfg(feature="collections")]
1488 #[derive(Debug)]
1489 pub struct Split<B> {
1490     buf: B,
1491     delim: u8,
1492 }
1493
1494-#[stable(feature = "rust1", since = "1.0.0")]
1495+#[cfg(feature="collections")]
1496 impl<B: BufRead> Iterator for Split<B> {
1497     type Item = Result<Vec<u8>>;
1498
1499@@ -2122,13 +2038,13 @@ impl<B: BufRead> Iterator for Split<B> {
1500 /// `BufRead`. Please see the documentation of `lines()` for more details.
1501 ///
1502 /// [lines]: trait.BufRead.html#method.lines
1503-#[stable(feature = "rust1", since = "1.0.0")]
1504+#[cfg(feature="collections")]
1505 #[derive(Debug)]
1506 pub struct Lines<B> {
1507     buf: B,
1508 }
1509
1510-#[stable(feature = "rust1", since = "1.0.0")]
1511+#[cfg(feature="collections")]
1512 impl<B: BufRead> Iterator for Lines<B> {
1513     type Item = Result<String>;
1514
1515diff --git a/prelude.rs b/prelude.rs
1516index 8772d0f..49d66c9 100644
1517--- a/prelude.rs
1518+++ b/prelude.rs
1519@@ -18,7 +18,8 @@
1520 //! use std::io::prelude::*;
1521 //! ```
1522
1523-#![stable(feature = "rust1", since = "1.0.0")]
1524+pub use super::{Read, Write, Seek};
1525+#[cfg(feature="collections")] pub use super::BufRead;
1526
1527-#[stable(feature = "rust1", since = "1.0.0")]
1528-pub use super::{Read, Write, BufRead, Seek};
1529+#[cfg(feature="collections")] pub use alloc::boxed::Box;
1530+#[cfg(feature="collections")] pub use collections::vec::Vec;
1531diff --git a/util.rs b/util.rs
1532index 45d281e..0efc3b1 100644
1533--- a/util.rs
1534+++ b/util.rs
1535@@ -10,9 +10,10 @@
1536
1537 #![allow(missing_copy_implementations)]
1538
1539-use fmt;
1540-use io::{self, Read, Initializer, Write, ErrorKind, BufRead};
1541-use mem;
1542+use core::fmt;
1543+use io::{self, Read, Initializer, Write, ErrorKind};
1544+use core::mem;
1545+#[cfg(feature="collections")] use io::BufRead;
1546
1547 /// Copies the entire contents of a reader into a writer.
1548 ///
1549@@ -45,7 +46,6 @@ use mem;
1550 /// # }
1551 /// # foo().unwrap();
1552 /// ```
1553-#[stable(feature = "rust1", since = "1.0.0")]
1554 pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> io::Result<u64>
1555     where R: Read, W: Write
1556 {
1557@@ -74,7 +74,6 @@ pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> io::Result<
1558 /// the documentation of [`empty()`][`empty`] for more details.
1559 ///
1560 /// [`empty`]: fn.empty.html
1561-#[stable(feature = "rust1", since = "1.0.0")]
1562 pub struct Empty { _priv: () }
1563
1564 /// Constructs a new handle to an empty reader.
1565@@ -94,10 +93,8 @@ pub struct Empty { _priv: () }
1566 /// io::empty().read_to_string(&mut buffer).unwrap();
1567 /// assert!(buffer.is_empty());
1568 /// ```
1569-#[stable(feature = "rust1", since = "1.0.0")]
1570 pub fn empty() -> Empty { Empty { _priv: () } }
1571
1572-#[stable(feature = "rust1", since = "1.0.0")]
1573 impl Read for Empty {
1574     #[inline]
1575     fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { Ok(0) }
1576@@ -107,7 +104,8 @@ impl Read for Empty {
1577         Initializer::nop()
1578     }
1579 }
1580-#[stable(feature = "rust1", since = "1.0.0")]
1581+
1582+#[cfg(feature="collections")]
1583 impl BufRead for Empty {
1584     #[inline]
1585     fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(&[]) }
1586@@ -115,7 +113,6 @@ impl BufRead for Empty {
1587     fn consume(&mut self, _n: usize) {}
1588 }
1589
1590-#[stable(feature = "std_debug", since = "1.16.0")]
1591 impl fmt::Debug for Empty {
1592     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1593         f.pad("Empty { .. }")
1594@@ -128,7 +125,6 @@ impl fmt::Debug for Empty {
1595 /// see the documentation of `repeat()` for more details.
1596 ///
1597 /// [repeat]: fn.repeat.html
1598-#[stable(feature = "rust1", since = "1.0.0")]
1599 pub struct Repeat { byte: u8 }
1600
1601 /// Creates an instance of a reader that infinitely repeats one byte.
1602@@ -145,10 +141,8 @@ pub struct Repeat { byte: u8 }
1603 /// io::repeat(0b101).read_exact(&mut buffer).unwrap();
1604 /// assert_eq!(buffer, [0b101, 0b101, 0b101]);
1605 /// ```
1606-#[stable(feature = "rust1", since = "1.0.0")]
1607 pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } }
1608
1609-#[stable(feature = "rust1", since = "1.0.0")]
1610 impl Read for Repeat {
1611     #[inline]
1612     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
1613@@ -164,7 +158,6 @@ impl Read for Repeat {
1614     }
1615 }
1616
1617-#[stable(feature = "std_debug", since = "1.16.0")]
1618 impl fmt::Debug for Repeat {
1619     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1620         f.pad("Repeat { .. }")
1621@@ -177,7 +170,6 @@ impl fmt::Debug for Repeat {
1622 /// see the documentation of `sink()` for more details.
1623 ///
1624 /// [sink]: fn.sink.html
1625-#[stable(feature = "rust1", since = "1.0.0")]
1626 pub struct Sink { _priv: () }
1627
1628 /// Creates an instance of a writer which will successfully consume all data.
1629@@ -194,10 +186,8 @@ pub struct Sink { _priv: () }
1630 /// let num_bytes = io::sink().write(&buffer).unwrap();
1631 /// assert_eq!(num_bytes, 5);
1632 /// ```
1633-#[stable(feature = "rust1", since = "1.0.0")]
1634 pub fn sink() -> Sink { Sink { _priv: () } }
1635
1636-#[stable(feature = "rust1", since = "1.0.0")]
1637 impl Write for Sink {
1638     #[inline]
1639     fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) }
1640@@ -205,7 +195,6 @@ impl Write for Sink {
1641     fn flush(&mut self) -> io::Result<()> { Ok(()) }
1642 }
1643
1644-#[stable(feature = "std_debug", since = "1.16.0")]
1645 impl fmt::Debug for Sink {
1646     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1647         f.pad("Sink { .. }")
1648