@@ -137,7 +137,7 @@ enum ResolutionError<'a> {
137137 /// error E0416: identifier is bound more than once in the same pattern
138138 IdentifierBoundMoreThanOnceInSamePattern ( & ' a str ) ,
139139 /// error E0426: use of undeclared label
140- UndeclaredLabel ( & ' a str ) ,
140+ UndeclaredLabel ( & ' a str , Option < Name > ) ,
141141 /// error E0429: `self` imports are only allowed within a { } list
142142 SelfImportsOnlyAllowedWithin ,
143143 /// error E0430: `self` import can only appear once in the list
@@ -263,13 +263,17 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver,
263263 err. span_label ( span, "used in a pattern more than once" ) ;
264264 err
265265 }
266- ResolutionError :: UndeclaredLabel ( name) => {
266+ ResolutionError :: UndeclaredLabel ( name, lev_candidate ) => {
267267 let mut err = struct_span_err ! ( resolver. session,
268268 span,
269269 E0426 ,
270270 "use of undeclared label `{}`" ,
271271 name) ;
272- err. span_label ( span, format ! ( "undeclared label `{}`" , name) ) ;
272+ if let Some ( lev_candidate) = lev_candidate {
273+ err. span_label ( span, format ! ( "did you mean `{}`?" , lev_candidate) ) ;
274+ } else {
275+ err. span_label ( span, format ! ( "undeclared label `{}`" , name) ) ;
276+ }
273277 err
274278 }
275279 ResolutionError :: SelfImportsOnlyAllowedWithin => {
@@ -1790,9 +1794,13 @@ impl<'a> Resolver<'a> {
17901794 }
17911795 }
17921796
1793- /// Searches the current set of local scopes for labels.
1797+ /// Searches the current set of local scopes for labels. Returns the first non-None label that
1798+ /// is returned by the given predicate function
1799+ ///
17941800 /// Stops after meeting a closure.
1795- fn search_label ( & self , mut ident : Ident ) -> Option < Def > {
1801+ fn search_label < P , R > ( & self , mut ident : Ident , pred : P ) -> Option < R >
1802+ where P : Fn ( & Rib , Ident ) -> Option < R >
1803+ {
17961804 for rib in self . label_ribs . iter ( ) . rev ( ) {
17971805 match rib. kind {
17981806 NormalRibKind => { }
@@ -1808,9 +1816,9 @@ impl<'a> Resolver<'a> {
18081816 return None ;
18091817 }
18101818 }
1811- let result = rib . bindings . get ( & ident) . cloned ( ) ;
1812- if result . is_some ( ) {
1813- return result ;
1819+ let r = pred ( rib , ident) ;
1820+ if r . is_some ( ) {
1821+ return r ;
18141822 }
18151823 }
18161824 None
@@ -3202,12 +3210,20 @@ impl<'a> Resolver<'a> {
32023210 }
32033211
32043212 ExprKind :: Break ( Some ( label) , _) | ExprKind :: Continue ( Some ( label) ) => {
3205- match self . search_label ( label. node ) {
3213+ match self . search_label ( label. node , |rib , id| rib . bindings . get ( & id ) . cloned ( ) ) {
32063214 None => {
3215+ // Search again for close matches...
3216+ // Picks the first label that is "close enough", which is not necessarily
3217+ // the closest match
3218+ let close_match = self . search_label ( label. node , |rib, ident| {
3219+ let names = rib. bindings . iter ( ) . map ( |( id, _) | & id. name ) ;
3220+ find_best_match_for_name ( names, & * ident. name . as_str ( ) , None )
3221+ } ) ;
32073222 self . record_def ( expr. id , err_path_resolution ( ) ) ;
32083223 resolve_error ( self ,
32093224 label. span ,
3210- ResolutionError :: UndeclaredLabel ( & label. node . name . as_str ( ) ) ) ;
3225+ ResolutionError :: UndeclaredLabel ( & label. node . name . as_str ( ) ,
3226+ close_match) ) ;
32113227 }
32123228 Some ( def @ Def :: Label ( _) ) => {
32133229 // Since this def is a label, it is never read.
0 commit comments