@@ -20,8 +20,8 @@ use regex::{Regex, escape};
2020mod version;
2121use self :: version:: Version ;
2222
23- const FEATURE_GROUP_START_PREFIX : & str = "// feature group start:" ;
24- const FEATURE_GROUP_END_PREFIX : & str = "// feature group end" ;
23+ const FEATURE_GROUP_START_PREFIX : & str = "// feature- group- start:" ;
24+ const FEATURE_GROUP_END_PREFIX : & str = "// feature- group- end" ;
2525
2626#[ derive( Debug , PartialEq , Clone ) ]
2727pub enum Status {
@@ -47,7 +47,6 @@ pub struct Feature {
4747 pub since : Option < Version > ,
4848 pub has_gate_test : bool ,
4949 pub tracking_issue : Option < u32 > ,
50- pub group : Option < String > ,
5150}
5251
5352pub type Features = HashMap < String , Feature > ;
@@ -139,31 +138,28 @@ pub fn check(path: &Path, bad: &mut bool, quiet: bool) {
139138 }
140139
141140 let mut lines = Vec :: new ( ) ;
142- for ( name, feature) in features. iter ( ) {
143- lines. push ( format ! ( "{:<32} {:<8} {:<12} {:<8}" ,
144- name,
145- "lang" ,
146- feature. level,
147- feature. since. as_ref( ) . map_or( "None" . to_owned( ) ,
148- |since| since. to_string( ) ) ) ) ;
149- }
150- for ( name, feature) in lib_features {
151- lines. push ( format ! ( "{:<32} {:<8} {:<12} {:<8}" ,
152- name,
153- "lib" ,
154- feature. level,
155- feature. since. as_ref( ) . map_or( "None" . to_owned( ) ,
156- |since| since. to_string( ) ) ) ) ;
157- }
141+ lines. extend ( format_features ( & features, "lang" ) ) ;
142+ lines. extend ( format_features ( & lib_features, "lib" ) ) ;
158143
159144 lines. sort ( ) ;
160145 for line in lines {
161146 println ! ( "* {}" , line) ;
162147 }
163148}
164149
150+ fn format_features < ' a > ( features : & ' a Features , family : & ' a str ) -> impl Iterator < Item =String > + ' a {
151+ features. iter ( ) . map ( move |( name, feature) | {
152+ format ! ( "{:<32} {:<8} {:<12} {:<8}" ,
153+ name,
154+ family,
155+ feature. level,
156+ feature. since. as_ref( ) . map_or( "None" . to_owned( ) ,
157+ |since| since. to_string( ) ) )
158+ } )
159+ }
160+
165161fn find_attr_val < ' a > ( line : & ' a str , attr : & str ) -> Option < & ' a str > {
166- let r = Regex :: new ( & format ! ( r#"{} *= *"([^"]*)""# , escape( attr) ) )
162+ let r = Regex :: new ( & format ! ( r#"{}\s*=\s *"([^"]*)""# , escape( attr) ) )
167163 . expect ( "malformed regex for find_attr_val" ) ;
168164 r. captures ( line)
169165 . and_then ( |c| c. get ( 1 ) )
@@ -219,6 +215,15 @@ pub fn collect_lang_features(base_src_path: &Path, bad: &mut bool) -> Features {
219215 }
220216
221217 if line. starts_with ( FEATURE_GROUP_START_PREFIX ) {
218+ if next_feature_group. is_some ( ) {
219+ tidy_error ! (
220+ bad,
221+ // ignore-tidy-linelength
222+ "libsyntax/feature_gate.rs:{}: new feature group is started without ending the previous one" ,
223+ line_number,
224+ ) ;
225+ }
226+
222227 let group = line. trim_start_matches ( FEATURE_GROUP_START_PREFIX ) . trim ( ) ;
223228 next_feature_group = Some ( group. to_owned ( ) ) ;
224229 prev_since = None ;
@@ -286,7 +291,6 @@ pub fn collect_lang_features(base_src_path: &Path, bad: &mut bool) -> Features {
286291 since,
287292 has_gate_test : false ,
288293 tracking_issue,
289- group : next_feature_group. clone ( ) ,
290294 } ) )
291295 } )
292296 . collect ( )
@@ -304,7 +308,6 @@ pub fn collect_lib_features(base_src_path: &Path) -> Features {
304308 since : None ,
305309 has_gate_test : false ,
306310 tracking_issue : None ,
307- group : None ,
308311 } ) ;
309312
310313 map_lib_features ( base_src_path,
@@ -399,7 +402,7 @@ fn map_lib_features(base_src_path: &Path,
399402 // `const fn` features are handled specially.
400403 let feature_name = match find_attr_val ( line, "feature" ) {
401404 Some ( name) => name,
402- None => err ! ( "malformed stability attribute" ) ,
405+ None => err ! ( "malformed stability attribute: missing `feature` key " ) ,
403406 } ;
404407 let feature = Feature {
405408 level : Status :: Unstable ,
@@ -409,7 +412,6 @@ fn map_lib_features(base_src_path: &Path,
409412 // although we would like to have specific tracking issues for each
410413 // `rustc_const_unstable` in the future.
411414 tracking_issue : Some ( 57563 ) ,
412- group : None ,
413415 } ;
414416 mf ( Ok ( ( feature_name, feature) ) , file, i + 1 ) ;
415417 continue ;
@@ -423,15 +425,15 @@ fn map_lib_features(base_src_path: &Path,
423425 } ;
424426 let feature_name = match find_attr_val ( line, "feature" ) {
425427 Some ( name) => name,
426- None => err ! ( "malformed stability attribute" ) ,
428+ None => err ! ( "malformed stability attribute: missing `feature` key " ) ,
427429 } ;
428430 let since = match find_attr_val ( line, "since" ) . map ( |x| x. parse ( ) ) {
429431 Some ( Ok ( since) ) => Some ( since) ,
430432 Some ( Err ( _err) ) => {
431- err ! ( "malformed since attribute" ) ;
433+ err ! ( "malformed stability attribute: can't parse `since` key " ) ;
432434 } ,
433435 None if level == Status :: Stable => {
434- err ! ( "malformed stability attribute" ) ;
436+ err ! ( "malformed stability attribute: missing the `since` key " ) ;
435437 }
436438 None => None ,
437439 } ;
@@ -442,7 +444,6 @@ fn map_lib_features(base_src_path: &Path,
442444 since,
443445 has_gate_test : false ,
444446 tracking_issue,
445- group : None ,
446447 } ;
447448 if line. contains ( ']' ) {
448449 mf ( Ok ( ( feature_name, feature) ) , file, i + 1 ) ;
0 commit comments