@@ -28,6 +28,22 @@ impl<I> Fuse<I> {
2828#[ stable( feature = "fused" ,  since = "1.26.0" ) ]  
2929impl < I >  FusedIterator  for  Fuse < I >  where  I :  Iterator  { } 
3030
31+ /// Fuse the iterator if the expression is `None`. 
32+ macro_rules!  fuse { 
33+     ( $self: ident .  iter .  $( $call: tt) +)  => { 
34+         match  $self. iter { 
35+             Some ( ref mut  iter)  => match  iter. $( $call) + { 
36+                 None  => { 
37+                     $self. iter = None ; 
38+                     None 
39+                 } 
40+                 item => item, 
41+             } , 
42+             None  => None , 
43+         } 
44+     } ; 
45+ } 
46+ 
3147#[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
3248impl < I >  Iterator  for  Fuse < I > 
3349where 
@@ -37,35 +53,36 @@ where
3753
3854    #[ inline]  
3955    default  fn  next ( & mut  self )  -> Option < <I  as  Iterator >:: Item >  { 
40-         let  next = self . iter . as_mut ( ) ?. next ( ) ; 
41-         if  next. is_none ( )  { 
42-             self . iter  = None ; 
43-         } 
44-         next
56+         fuse ! ( self . iter. next( ) ) 
4557    } 
4658
4759    #[ inline]  
4860    default  fn  nth ( & mut  self ,  n :  usize )  -> Option < I :: Item >  { 
49-         let  nth = self . iter . as_mut ( ) ?. nth ( n) ; 
50-         if  nth. is_none ( )  { 
51-             self . iter  = None ; 
52-         } 
53-         nth
61+         fuse ! ( self . iter. nth( n) ) 
5462    } 
5563
5664    #[ inline]  
5765    default  fn  last ( self )  -> Option < I :: Item >  { 
58-         self . iter ?. last ( ) 
66+         match  self . iter  { 
67+             Some ( iter)  => iter. last ( ) , 
68+             None  => None , 
69+         } 
5970    } 
6071
6172    #[ inline]  
6273    default  fn  count ( self )  -> usize  { 
63-         self . iter . map_or ( 0 ,  I :: count) 
74+         match  self . iter  { 
75+             Some ( iter)  => iter. count ( ) , 
76+             None  => 0 , 
77+         } 
6478    } 
6579
6680    #[ inline]  
6781    default  fn  size_hint ( & self )  -> ( usize ,  Option < usize > )  { 
68-         self . iter . as_ref ( ) . map_or ( ( 0 ,  Some ( 0 ) ) ,  I :: size_hint) 
82+         match  self . iter  { 
83+             Some ( ref  iter)  => iter. size_hint ( ) , 
84+             None  => ( 0 ,  Some ( 0 ) ) , 
85+         } 
6986    } 
7087
7188    #[ inline]  
@@ -98,11 +115,7 @@ where
98115    where 
99116        P :  FnMut ( & Self :: Item )  -> bool , 
100117    { 
101-         let  found = self . iter . as_mut ( ) ?. find ( predicate) ; 
102-         if  found. is_none ( )  { 
103-             self . iter  = None ; 
104-         } 
105-         found
118+         fuse ! ( self . iter. find( predicate) ) 
106119    } 
107120} 
108121
@@ -113,20 +126,12 @@ where
113126{ 
114127    #[ inline]  
115128    default  fn  next_back ( & mut  self )  -> Option < <I  as  Iterator >:: Item >  { 
116-         let  next = self . iter . as_mut ( ) ?. next_back ( ) ; 
117-         if  next. is_none ( )  { 
118-             self . iter  = None ; 
119-         } 
120-         next
129+         fuse ! ( self . iter. next_back( ) ) 
121130    } 
122131
123132    #[ inline]  
124133    default  fn  nth_back ( & mut  self ,  n :  usize )  -> Option < <I  as  Iterator >:: Item >  { 
125-         let  nth = self . iter . as_mut ( ) ?. nth_back ( n) ; 
126-         if  nth. is_none ( )  { 
127-             self . iter  = None ; 
128-         } 
129-         nth
134+         fuse ! ( self . iter. nth_back( n) ) 
130135    } 
131136
132137    #[ inline]  
@@ -159,11 +164,7 @@ where
159164    where 
160165        P :  FnMut ( & Self :: Item )  -> bool , 
161166    { 
162-         let  found = self . iter . as_mut ( ) ?. rfind ( predicate) ; 
163-         if  found. is_none ( )  { 
164-             self . iter  = None ; 
165-         } 
166-         found
167+         fuse ! ( self . iter. rfind( predicate) ) 
167168    } 
168169} 
169170
@@ -173,42 +174,30 @@ where
173174    I :  ExactSizeIterator , 
174175{ 
175176    default  fn  len ( & self )  -> usize  { 
176-         self . iter . as_ref ( ) . map_or ( 0 ,  I :: len) 
177-     } 
178- 
179-     default  fn  is_empty ( & self )  -> bool  { 
180-         self . iter . as_ref ( ) . map_or ( true ,  I :: is_empty) 
181-     } 
182- } 
183- 
184- // NOTE: for `I: FusedIterator`, we assume that the iterator is always `Some` 
185- impl < I :  FusedIterator >  Fuse < I >  { 
186-     #[ inline( always) ]  
187-     fn  as_inner ( & self )  -> & I  { 
188177        match  self . iter  { 
189-             Some ( ref  iter)  => iter, 
190-             // SAFETY: the specialized iterator never sets `None` 
191-             None  => unsafe  {  intrinsics:: unreachable ( )  } , 
178+             Some ( ref  iter)  => iter. len ( ) , 
179+             None  => 0 , 
192180        } 
193181    } 
194182
195-     #[ inline( always) ]  
196-     fn  as_inner_mut ( & mut  self )  -> & mut  I  { 
183+     default  fn  is_empty ( & self )  -> bool  { 
197184        match  self . iter  { 
198-             Some ( ref  mut  iter)  => iter, 
199-             // SAFETY: the specialized iterator never sets `None` 
200-             None  => unsafe  {  intrinsics:: unreachable ( )  } , 
185+             Some ( ref  iter)  => iter. is_empty ( ) , 
186+             None  => true , 
201187        } 
202188    } 
189+ } 
203190
204-     #[ inline( always) ]  
205-     fn  into_inner ( self )  -> I  { 
206-         match  self . iter  { 
207-             Some ( iter)  => iter, 
191+ // NOTE: for `I: FusedIterator`, we assume that the iterator is always `Some`. 
192+ // Implementing this as a directly-expanded macro helps codegen performance. 
193+ macro_rules!  unchecked { 
194+     ( $self: ident)  => { 
195+         match  $self { 
196+             Fuse  {  iter:  Some ( iter)  }  => iter, 
208197            // SAFETY: the specialized iterator never sets `None` 
209-             None  => unsafe  {  intrinsics:: unreachable ( )  } , 
198+             Fuse   {  iter :   None   }  => unsafe  {  intrinsics:: unreachable( )  } , 
210199        } 
211-     } 
200+     } ; 
212201} 
213202
214203#[ stable( feature = "fused" ,  since = "1.26.0" ) ]  
@@ -218,27 +207,27 @@ where
218207{ 
219208    #[ inline]  
220209    fn  next ( & mut  self )  -> Option < <I  as  Iterator >:: Item >  { 
221-         self . as_inner_mut ( ) . next ( ) 
210+         unchecked ! ( self ) . next ( ) 
222211    } 
223212
224213    #[ inline]  
225214    fn  nth ( & mut  self ,  n :  usize )  -> Option < I :: Item >  { 
226-         self . as_inner_mut ( ) . nth ( n) 
215+         unchecked ! ( self ) . nth ( n) 
227216    } 
228217
229218    #[ inline]  
230219    fn  last ( self )  -> Option < I :: Item >  { 
231-         self . into_inner ( ) . last ( ) 
220+         unchecked ! ( self ) . last ( ) 
232221    } 
233222
234223    #[ inline]  
235224    fn  count ( self )  -> usize  { 
236-         self . into_inner ( ) . count ( ) 
225+         unchecked ! ( self ) . count ( ) 
237226    } 
238227
239228    #[ inline]  
240229    fn  size_hint ( & self )  -> ( usize ,  Option < usize > )  { 
241-         self . as_inner ( ) . size_hint ( ) 
230+         unchecked ! ( self ) . size_hint ( ) 
242231    } 
243232
244233    #[ inline]  
@@ -248,23 +237,23 @@ where
248237        Fold :  FnMut ( Acc ,  Self :: Item )  -> R , 
249238        R :  Try < Ok  = Acc > , 
250239    { 
251-         self . as_inner_mut ( ) . try_fold ( init,  fold) 
240+         unchecked ! ( self ) . try_fold ( init,  fold) 
252241    } 
253242
254243    #[ inline]  
255244    fn  fold < Acc ,  Fold > ( self ,  init :  Acc ,  fold :  Fold )  -> Acc 
256245    where 
257246        Fold :  FnMut ( Acc ,  Self :: Item )  -> Acc , 
258247    { 
259-         self . into_inner ( ) . fold ( init,  fold) 
248+         unchecked ! ( self ) . fold ( init,  fold) 
260249    } 
261250
262251    #[ inline]  
263252    fn  find < P > ( & mut  self ,  predicate :  P )  -> Option < Self :: Item > 
264253    where 
265254        P :  FnMut ( & Self :: Item )  -> bool , 
266255    { 
267-         self . as_inner_mut ( ) . find ( predicate) 
256+         unchecked ! ( self ) . find ( predicate) 
268257    } 
269258} 
270259
@@ -275,12 +264,12 @@ where
275264{ 
276265    #[ inline]  
277266    fn  next_back ( & mut  self )  -> Option < <I  as  Iterator >:: Item >  { 
278-         self . as_inner_mut ( ) . next_back ( ) 
267+         unchecked ! ( self ) . next_back ( ) 
279268    } 
280269
281270    #[ inline]  
282271    fn  nth_back ( & mut  self ,  n :  usize )  -> Option < <I  as  Iterator >:: Item >  { 
283-         self . as_inner_mut ( ) . nth_back ( n) 
272+         unchecked ! ( self ) . nth_back ( n) 
284273    } 
285274
286275    #[ inline]  
@@ -290,23 +279,23 @@ where
290279        Fold :  FnMut ( Acc ,  Self :: Item )  -> R , 
291280        R :  Try < Ok  = Acc > , 
292281    { 
293-         self . as_inner_mut ( ) . try_rfold ( init,  fold) 
282+         unchecked ! ( self ) . try_rfold ( init,  fold) 
294283    } 
295284
296285    #[ inline]  
297286    fn  rfold < Acc ,  Fold > ( self ,  init :  Acc ,  fold :  Fold )  -> Acc 
298287    where 
299288        Fold :  FnMut ( Acc ,  Self :: Item )  -> Acc , 
300289    { 
301-         self . into_inner ( ) . rfold ( init,  fold) 
290+         unchecked ! ( self ) . rfold ( init,  fold) 
302291    } 
303292
304293    #[ inline]  
305294    fn  rfind < P > ( & mut  self ,  predicate :  P )  -> Option < Self :: Item > 
306295    where 
307296        P :  FnMut ( & Self :: Item )  -> bool , 
308297    { 
309-         self . as_inner_mut ( ) . rfind ( predicate) 
298+         unchecked ! ( self ) . rfind ( predicate) 
310299    } 
311300} 
312301
@@ -316,11 +305,11 @@ where
316305    I :  ExactSizeIterator  + FusedIterator , 
317306{ 
318307    fn  len ( & self )  -> usize  { 
319-         self . as_inner ( ) . len ( ) 
308+         unchecked ! ( self ) . len ( ) 
320309    } 
321310
322311    fn  is_empty ( & self )  -> bool  { 
323-         self . as_inner ( ) . is_empty ( ) 
312+         unchecked ! ( self ) . is_empty ( ) 
324313    } 
325314} 
326315
0 commit comments