@@ -658,7 +658,7 @@ struct LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
658
658
last_block_rib : Option < Rib < ' a > > ,
659
659
660
660
/// The current set of local scopes, for labels.
661
- label_ribs : Vec < Rib < ' a , NodeId > > ,
661
+ label_ribs : Vec < Rib < ' a , ( NodeId , bool , Span ) > > ,
662
662
663
663
/// The current set of local scopes for lifetimes.
664
664
lifetime_ribs : Vec < LifetimeRib > ,
@@ -2215,7 +2215,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
2215
2215
2216
2216
/// Searches the current set of local scopes for labels. Returns the `NodeId` of the resolved
2217
2217
/// label and reports an error if the label is not found or is unreachable.
2218
- fn resolve_label ( & mut self , mut label : Ident ) -> Result < ( NodeId , Span ) , ResolutionError < ' a > > {
2218
+ fn resolve_label (
2219
+ & mut self ,
2220
+ mut label : Ident ,
2221
+ ) -> Result < ( ( NodeId , bool , Span ) , Span ) , ResolutionError < ' a > > {
2219
2222
let mut suggestion = None ;
2220
2223
2221
2224
for i in ( 0 ..self . label_ribs . len ( ) ) . rev ( ) {
@@ -4184,7 +4187,14 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
4184
4187
Ok ( Some ( result) )
4185
4188
}
4186
4189
4187
- fn with_resolved_label ( & mut self , label : Option < Label > , id : NodeId , f : impl FnOnce ( & mut Self ) ) {
4190
+ fn with_resolved_label (
4191
+ & mut self ,
4192
+ label : Option < Label > ,
4193
+ id : NodeId ,
4194
+ is_loop : bool ,
4195
+ span : Span ,
4196
+ f : impl FnOnce ( & mut Self ) ,
4197
+ ) {
4188
4198
if let Some ( label) = label {
4189
4199
if label. ident . as_str ( ) . as_bytes ( ) [ 1 ] != b'_' {
4190
4200
self . diagnostic_metadata . unused_labels . insert ( id, label. ident . span ) ;
@@ -4196,16 +4206,22 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
4196
4206
4197
4207
self . with_label_rib ( RibKind :: Normal , |this| {
4198
4208
let ident = label. ident . normalize_to_macro_rules ( ) ;
4199
- this. label_ribs . last_mut ( ) . unwrap ( ) . bindings . insert ( ident, id ) ;
4209
+ this. label_ribs . last_mut ( ) . unwrap ( ) . bindings . insert ( ident, ( id , is_loop , span ) ) ;
4200
4210
f ( this) ;
4201
4211
} ) ;
4202
4212
} else {
4203
4213
f ( self ) ;
4204
4214
}
4205
4215
}
4206
4216
4207
- fn resolve_labeled_block ( & mut self , label : Option < Label > , id : NodeId , block : & ' ast Block ) {
4208
- self . with_resolved_label ( label, id, |this| this. visit_block ( block) ) ;
4217
+ fn resolve_labeled_block (
4218
+ & mut self ,
4219
+ label : Option < Label > ,
4220
+ id : NodeId ,
4221
+ block : & ' ast Block ,
4222
+ is_loop : bool ,
4223
+ ) {
4224
+ self . with_resolved_label ( label, id, is_loop, block. span , |this| this. visit_block ( block) ) ;
4209
4225
}
4210
4226
4211
4227
fn resolve_block ( & mut self , block : & ' ast Block ) {
@@ -4348,10 +4364,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
4348
4364
4349
4365
ExprKind :: Break ( Some ( label) , _) | ExprKind :: Continue ( Some ( label) ) => {
4350
4366
match self . resolve_label ( label. ident ) {
4351
- Ok ( ( node_id , _) ) => {
4367
+ Ok ( ( node , _) ) => {
4352
4368
// Since this res is a label, it is never read.
4353
- self . r . label_res_map . insert ( expr. id , node_id ) ;
4354
- self . diagnostic_metadata . unused_labels . remove ( & node_id ) ;
4369
+ self . r . label_res_map . insert ( expr. id , node ) ;
4370
+ self . diagnostic_metadata . unused_labels . remove ( & node . 0 ) ;
4355
4371
}
4356
4372
Err ( error) => {
4357
4373
self . report_error ( label. ident . span , error) ;
@@ -4386,11 +4402,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
4386
4402
}
4387
4403
4388
4404
ExprKind :: Loop ( ref block, label, _) => {
4389
- self . resolve_labeled_block ( label, expr. id , block)
4405
+ self . resolve_labeled_block ( label, expr. id , block, true )
4390
4406
}
4391
4407
4392
4408
ExprKind :: While ( ref cond, ref block, label) => {
4393
- self . with_resolved_label ( label, expr. id , |this| {
4409
+ self . with_resolved_label ( label, expr. id , true , block . span , |this| {
4394
4410
this. with_rib ( ValueNS , RibKind :: Normal , |this| {
4395
4411
let old = this. diagnostic_metadata . in_if_condition . replace ( cond) ;
4396
4412
this. visit_expr ( cond) ;
@@ -4404,11 +4420,13 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
4404
4420
self . visit_expr ( iter) ;
4405
4421
self . with_rib ( ValueNS , RibKind :: Normal , |this| {
4406
4422
this. resolve_pattern_top ( pat, PatternSource :: For ) ;
4407
- this. resolve_labeled_block ( label, expr. id , body) ;
4423
+ this. resolve_labeled_block ( label, expr. id , body, true ) ;
4408
4424
} ) ;
4409
4425
}
4410
4426
4411
- ExprKind :: Block ( ref block, label) => self . resolve_labeled_block ( label, block. id , block) ,
4427
+ ExprKind :: Block ( ref block, label) => {
4428
+ self . resolve_labeled_block ( label, block. id , block, false )
4429
+ }
4412
4430
4413
4431
// Equivalent to `visit::walk_expr` + passing some context to children.
4414
4432
ExprKind :: Field ( ref subexpression, _) => {
0 commit comments