@@ -137,7 +137,7 @@ enum ResolutionError<'a> {
137
137
/// error E0416: identifier is bound more than once in the same pattern
138
138
IdentifierBoundMoreThanOnceInSamePattern ( & ' a str ) ,
139
139
/// error E0426: use of undeclared label
140
- UndeclaredLabel ( & ' a str ) ,
140
+ UndeclaredLabel ( & ' a str , Option < Name > ) ,
141
141
/// error E0429: `self` imports are only allowed within a { } list
142
142
SelfImportsOnlyAllowedWithin ,
143
143
/// error E0430: `self` import can only appear once in the list
@@ -263,13 +263,17 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver,
263
263
err. span_label ( span, "used in a pattern more than once" ) ;
264
264
err
265
265
}
266
- ResolutionError :: UndeclaredLabel ( name) => {
266
+ ResolutionError :: UndeclaredLabel ( name, lev_candidate ) => {
267
267
let mut err = struct_span_err ! ( resolver. session,
268
268
span,
269
269
E0426 ,
270
270
"use of undeclared label `{}`" ,
271
271
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
+ }
273
277
err
274
278
}
275
279
ResolutionError :: SelfImportsOnlyAllowedWithin => {
@@ -1790,9 +1794,13 @@ impl<'a> Resolver<'a> {
1790
1794
}
1791
1795
}
1792
1796
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
+ ///
1794
1800
/// 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
+ {
1796
1804
for rib in self . label_ribs . iter ( ) . rev ( ) {
1797
1805
match rib. kind {
1798
1806
NormalRibKind => { }
@@ -1808,9 +1816,9 @@ impl<'a> Resolver<'a> {
1808
1816
return None ;
1809
1817
}
1810
1818
}
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 ;
1814
1822
}
1815
1823
}
1816
1824
None
@@ -3202,12 +3210,20 @@ impl<'a> Resolver<'a> {
3202
3210
}
3203
3211
3204
3212
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 ( ) ) {
3206
3214
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
+ } ) ;
3207
3222
self . record_def ( expr. id , err_path_resolution ( ) ) ;
3208
3223
resolve_error ( self ,
3209
3224
label. span ,
3210
- ResolutionError :: UndeclaredLabel ( & label. node . name . as_str ( ) ) ) ;
3225
+ ResolutionError :: UndeclaredLabel ( & label. node . name . as_str ( ) ,
3226
+ close_match) ) ;
3211
3227
}
3212
3228
Some ( def @ Def :: Label ( _) ) => {
3213
3229
// Since this def is a label, it is never read.
0 commit comments