@@ -1071,13 +1071,13 @@ enum RibKind<'a> {
10711071/// The resolution keeps a separate stack of ribs as it traverses the AST for each namespace. When
10721072/// resolving, the name is looked up from inside out.
10731073#[ derive( Debug ) ]
1074- struct Rib < ' a > {
1075- bindings : FxHashMap < Ident , Res > ,
1074+ struct Rib < ' a , R = Res > {
1075+ bindings : FxHashMap < Ident , R > ,
10761076 kind : RibKind < ' a > ,
10771077}
10781078
1079- impl < ' a > Rib < ' a > {
1080- fn new ( kind : RibKind < ' a > ) -> Rib < ' a > {
1079+ impl < ' a , R > Rib < ' a , R > {
1080+ fn new ( kind : RibKind < ' a > ) -> Rib < ' a , R > {
10811081 Rib {
10821082 bindings : Default :: default ( ) ,
10831083 kind,
@@ -1638,7 +1638,7 @@ pub struct Resolver<'a> {
16381638 ribs : PerNS < Vec < Rib < ' a > > > ,
16391639
16401640 /// The current set of local scopes, for labels.
1641- label_ribs : Vec < Rib < ' a > > ,
1641+ label_ribs : Vec < Rib < ' a , NodeId > > ,
16421642
16431643 /// The trait that the current context can refer to.
16441644 current_trait_ref : Option < ( Module < ' a > , TraitRef ) > ,
@@ -1663,6 +1663,8 @@ pub struct Resolver<'a> {
16631663 partial_res_map : NodeMap < PartialRes > ,
16641664 /// Resolutions for import nodes, which have multiple resolutions in different namespaces.
16651665 import_res_map : NodeMap < PerNS < Option < Res > > > ,
1666+ /// Resolutions for labels (node IDs of their corresponding blocks or loops).
1667+ label_res_map : NodeMap < NodeId > ,
16661668
16671669 pub freevars : FreevarMap ,
16681670 freevars_seen : NodeMap < NodeMap < usize > > ,
@@ -1841,6 +1843,10 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
18411843 self . import_res_map . get ( & id) . cloned ( ) . unwrap_or_default ( )
18421844 }
18431845
1846+ fn get_label_res ( & mut self , id : NodeId ) -> Option < NodeId > {
1847+ self . label_res_map . get ( & id) . cloned ( )
1848+ }
1849+
18441850 fn definitions ( & mut self ) -> & mut Definitions {
18451851 & mut self . definitions
18461852 }
@@ -2024,6 +2030,7 @@ impl<'a> Resolver<'a> {
20242030
20252031 partial_res_map : Default :: default ( ) ,
20262032 import_res_map : Default :: default ( ) ,
2033+ label_res_map : Default :: default ( ) ,
20272034 freevars : Default :: default ( ) ,
20282035 freevars_seen : Default :: default ( ) ,
20292036 export_map : FxHashMap :: default ( ) ,
@@ -2490,7 +2497,7 @@ impl<'a> Resolver<'a> {
24902497 ///
24912498 /// Stops after meeting a closure.
24922499 fn search_label < P , R > ( & self , mut ident : Ident , pred : P ) -> Option < R >
2493- where P : Fn ( & Rib < ' _ > , Ident ) -> Option < R >
2500+ where P : Fn ( & Rib < ' _ , NodeId > , Ident ) -> Option < R >
24942501 {
24952502 for rib in self . label_ribs . iter ( ) . rev ( ) {
24962503 match rib. kind {
@@ -4332,10 +4339,9 @@ impl<'a> Resolver<'a> {
43324339 {
43334340 if let Some ( label) = label {
43344341 self . unused_labels . insert ( id, label. ident . span ) ;
4335- let res = Res :: Label ( id) ;
43364342 self . with_label_rib ( |this| {
43374343 let ident = label. ident . modern_and_legacy ( ) ;
4338- this. label_ribs . last_mut ( ) . unwrap ( ) . bindings . insert ( ident, res ) ;
4344+ this. label_ribs . last_mut ( ) . unwrap ( ) . bindings . insert ( ident, id ) ;
43394345 f ( this) ;
43404346 } ) ;
43414347 } else {
@@ -4366,10 +4372,10 @@ impl<'a> Resolver<'a> {
43664372 }
43674373
43684374 ExprKind :: Break ( Some ( label) , _) | ExprKind :: Continue ( Some ( label) ) => {
4369- let res = self . search_label ( label. ident , |rib, ident| {
4375+ let node_id = self . search_label ( label. ident , |rib, ident| {
43704376 rib. bindings . get ( & ident. modern_and_legacy ( ) ) . cloned ( )
43714377 } ) ;
4372- match res {
4378+ match node_id {
43734379 None => {
43744380 // Search again for close matches...
43754381 // Picks the first label that is "close enough", which is not necessarily
@@ -4390,13 +4396,10 @@ impl<'a> Resolver<'a> {
43904396 ResolutionError :: UndeclaredLabel ( & label. ident . as_str ( ) ,
43914397 close_match) ) ;
43924398 }
4393- Some ( Res :: Label ( id ) ) => {
4399+ Some ( node_id ) => {
43944400 // Since this res is a label, it is never read.
4395- self . record_partial_res ( expr. id , PartialRes :: new ( Res :: Label ( id) ) ) ;
4396- self . unused_labels . remove ( & id) ;
4397- }
4398- Some ( _) => {
4399- span_bug ! ( expr. span, "label wasn't mapped to a label res!" ) ;
4401+ self . label_res_map . insert ( expr. id , node_id) ;
4402+ self . unused_labels . remove ( & node_id) ;
44004403 }
44014404 }
44024405
0 commit comments