@@ -258,7 +258,7 @@ fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features
258258 let mut next_feature_omits_tracking_issue = false ;
259259
260260 let mut in_feature_group = false ;
261- let mut prev_name = None ;
261+ let mut prev_names = vec ! [ ] ;
262262
263263 contents
264264 . lines ( )
@@ -291,11 +291,11 @@ fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features
291291 }
292292
293293 in_feature_group = true ;
294- prev_name = None ;
294+ prev_names = vec ! [ ] ;
295295 return None ;
296296 } else if line. starts_with ( FEATURE_GROUP_END_PREFIX ) {
297297 in_feature_group = false ;
298- prev_name = None ;
298+ prev_names = vec ! [ ] ;
299299 return None ;
300300 }
301301
@@ -325,16 +325,49 @@ fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features
325325 }
326326 } ;
327327 if in_feature_group {
328- if prev_name > Some ( name) {
328+ if prev_names. last ( ) > Some ( & name) {
329+ // This assumes the user adds the feature name at the end of the list, as we're
330+ // not looking ahead.
331+ let correct_index = match prev_names. binary_search ( & name) {
332+ Ok ( _) => {
333+ // This only occurs when the feature name has already been declared.
334+ tidy_error ! (
335+ bad,
336+ "{}:{}: duplicate feature {}" ,
337+ path. display( ) ,
338+ line_number,
339+ name,
340+ ) ;
341+ // skip any additional checks for this line
342+ return None ;
343+ }
344+ Err ( index) => index,
345+ } ;
346+
347+ let correct_placement = if correct_index == 0 {
348+ "at the beginning of the feature group" . to_owned ( )
349+ } else if correct_index == prev_names. len ( ) {
350+ // I don't believe this is reachable given the above assumption, but it
351+ // doesn't hurt to be safe.
352+ "at the end of the feature group" . to_owned ( )
353+ } else {
354+ format ! (
355+ "between {} and {}" ,
356+ prev_names[ correct_index - 1 ] ,
357+ prev_names[ correct_index] ,
358+ )
359+ } ;
360+
329361 tidy_error ! (
330362 bad,
331- "{}:{}: feature {} is not sorted by feature name" ,
363+ "{}:{}: feature {} is not sorted by feature name (should be {}) " ,
332364 path. display( ) ,
333365 line_number,
334366 name,
367+ correct_placement,
335368 ) ;
336369 }
337- prev_name = Some ( name) ;
370+ prev_names . push ( name) ;
338371 }
339372
340373 let issue_str = parts. next ( ) . unwrap ( ) . trim ( ) ;
0 commit comments