@@ -122,7 +122,11 @@ impl IfLetRescope {
122122 }
123123 let tcx = cx. tcx ;
124124 let source_map = tcx. sess . source_map ( ) ;
125- let expr_end = expr. span . shrink_to_hi ( ) ;
125+ let expr_end = match expr. kind {
126+ hir:: ExprKind :: If ( _cond, conseq, None ) => conseq. span . shrink_to_hi ( ) ,
127+ hir:: ExprKind :: If ( _cond, _conseq, Some ( alt) ) => alt. span . shrink_to_hi ( ) ,
128+ _ => return ,
129+ } ;
126130 let mut add_bracket_to_match_head = match_head_needs_bracket ( tcx, expr) ;
127131 let mut significant_droppers = vec ! [ ] ;
128132 let mut lifetime_ends = vec ! [ ] ;
@@ -145,7 +149,10 @@ impl IfLetRescope {
145149 recovered : Recovered :: No ,
146150 } ) = cond. kind
147151 {
148- let if_let_pat = expr. span . shrink_to_lo ( ) . between ( init. span ) ;
152+ // Peel off round braces
153+ let if_let_pat = source_map
154+ . span_take_while ( expr. span , |& ch| ch == '(' || ch. is_whitespace ( ) )
155+ . between ( init. span ) ;
149156 // The consequent fragment is always a block.
150157 let before_conseq = conseq. span . shrink_to_lo ( ) ;
151158 let lifetime_end = source_map. end_point ( conseq. span ) ;
@@ -159,6 +166,8 @@ impl IfLetRescope {
159166 if ty_ascription. is_some ( )
160167 || !expr. span . can_be_used_for_suggestions ( )
161168 || !pat. span . can_be_used_for_suggestions ( )
169+ || !if_let_pat. can_be_used_for_suggestions ( )
170+ || !before_conseq. can_be_used_for_suggestions ( )
162171 {
163172 // Our `match` rewrites does not support type ascription,
164173 // so we just bail.
@@ -240,6 +249,22 @@ impl<'tcx> LateLintPass<'tcx> for IfLetRescope {
240249 if let ( Level :: Allow , _) = cx. tcx . lint_level_at_node ( IF_LET_RESCOPE , expr. hir_id ) {
241250 return ;
242251 }
252+ if let hir:: ExprKind :: Loop ( block, _label, hir:: LoopSource :: While , _span) = expr. kind
253+ && let Some ( value) = block. expr
254+ && let hir:: ExprKind :: If ( cond, _conseq, _alt) = value. kind
255+ && let hir:: ExprKind :: Let ( ..) = cond. kind
256+ {
257+ // Recall that `while let` is lowered into this:
258+ // ```
259+ // loop {
260+ // if let .. { body } else { break; }
261+ // }
262+ // ```
263+ // There is no observable from the `{ break; }` block so the edition change
264+ // means nothing substantial to this `while` statement.
265+ self . skip . insert ( value. hir_id ) ;
266+ return ;
267+ }
243268 if expr_parent_is_stmt ( cx. tcx , expr. hir_id )
244269 && matches ! ( expr. kind, hir:: ExprKind :: If ( _cond, _conseq, None ) )
245270 {
0 commit comments