@@ -2777,17 +2777,10 @@ pub struct Bytes<R> {
27772777impl < R : Read > Iterator for Bytes < R > {
27782778 type Item = Result < u8 > ;
27792779
2780- #[ inline]
2780+ // Not `#[inline]`. This function gets inlined even without it, but having
2781+ // the inline annotation can result in worse code generation. See #116785.
27812782 fn next ( & mut self ) -> Option < Result < u8 > > {
2782- let mut byte = 0 ;
2783- loop {
2784- return match self . inner . read ( slice:: from_mut ( & mut byte) ) {
2785- Ok ( 0 ) => None ,
2786- Ok ( ..) => Some ( Ok ( byte) ) ,
2787- Err ( ref e) if e. is_interrupted ( ) => continue ,
2788- Err ( e) => Some ( Err ( e) ) ,
2789- } ;
2790- }
2783+ SpecReadByte :: spec_read_byte ( & mut self . inner )
27912784 }
27922785
27932786 #[ inline]
@@ -2796,6 +2789,43 @@ impl<R: Read> Iterator for Bytes<R> {
27962789 }
27972790}
27982791
2792+ /// For the specialization of `Bytes::next`.
2793+ trait SpecReadByte {
2794+ fn spec_read_byte ( & mut self ) -> Option < Result < u8 > > ;
2795+ }
2796+
2797+ impl < R > SpecReadByte for R
2798+ where
2799+ Self : Read ,
2800+ {
2801+ #[ inline]
2802+ default fn spec_read_byte ( & mut self ) -> Option < Result < u8 > > {
2803+ inlined_slow_read_byte ( self )
2804+ }
2805+ }
2806+
2807+ /// Read a single byte in a slow, generic way. This is used by the default
2808+ /// `spec_read_byte`.
2809+ #[ inline]
2810+ fn inlined_slow_read_byte < R : Read > ( reader : & mut R ) -> Option < Result < u8 > > {
2811+ let mut byte = 0 ;
2812+ loop {
2813+ return match reader. read ( slice:: from_mut ( & mut byte) ) {
2814+ Ok ( 0 ) => None ,
2815+ Ok ( ..) => Some ( Ok ( byte) ) ,
2816+ Err ( ref e) if e. is_interrupted ( ) => continue ,
2817+ Err ( e) => Some ( Err ( e) ) ,
2818+ } ;
2819+ }
2820+ }
2821+
2822+ // Used by `BufReader::spec_read_byte`, for which the `inline(ever)` is
2823+ // important.
2824+ #[ inline( never) ]
2825+ fn uninlined_slow_read_byte < R : Read > ( reader : & mut R ) -> Option < Result < u8 > > {
2826+ inlined_slow_read_byte ( reader)
2827+ }
2828+
27992829trait SizeHint {
28002830 fn lower_bound ( & self ) -> usize ;
28012831
0 commit comments