@@ -20,8 +20,8 @@ use regex::{Regex, escape};
20
20
mod version;
21
21
use self :: version:: Version ;
22
22
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" ;
25
25
26
26
#[ derive( Debug , PartialEq , Clone ) ]
27
27
pub enum Status {
@@ -47,7 +47,6 @@ pub struct Feature {
47
47
pub since : Option < Version > ,
48
48
pub has_gate_test : bool ,
49
49
pub tracking_issue : Option < u32 > ,
50
- pub group : Option < String > ,
51
50
}
52
51
53
52
pub type Features = HashMap < String , Feature > ;
@@ -139,31 +138,28 @@ pub fn check(path: &Path, bad: &mut bool, quiet: bool) {
139
138
}
140
139
141
140
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" ) ) ;
158
143
159
144
lines. sort ( ) ;
160
145
for line in lines {
161
146
println ! ( "* {}" , line) ;
162
147
}
163
148
}
164
149
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
+
165
161
fn 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) ) )
167
163
. expect ( "malformed regex for find_attr_val" ) ;
168
164
r. captures ( line)
169
165
. and_then ( |c| c. get ( 1 ) )
@@ -219,6 +215,15 @@ pub fn collect_lang_features(base_src_path: &Path, bad: &mut bool) -> Features {
219
215
}
220
216
221
217
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
+
222
227
let group = line. trim_start_matches ( FEATURE_GROUP_START_PREFIX ) . trim ( ) ;
223
228
next_feature_group = Some ( group. to_owned ( ) ) ;
224
229
prev_since = None ;
@@ -286,7 +291,6 @@ pub fn collect_lang_features(base_src_path: &Path, bad: &mut bool) -> Features {
286
291
since,
287
292
has_gate_test : false ,
288
293
tracking_issue,
289
- group : next_feature_group. clone ( ) ,
290
294
} ) )
291
295
} )
292
296
. collect ( )
@@ -304,7 +308,6 @@ pub fn collect_lib_features(base_src_path: &Path) -> Features {
304
308
since : None ,
305
309
has_gate_test : false ,
306
310
tracking_issue : None ,
307
- group : None ,
308
311
} ) ;
309
312
310
313
map_lib_features ( base_src_path,
@@ -399,7 +402,7 @@ fn map_lib_features(base_src_path: &Path,
399
402
// `const fn` features are handled specially.
400
403
let feature_name = match find_attr_val ( line, "feature" ) {
401
404
Some ( name) => name,
402
- None => err ! ( "malformed stability attribute" ) ,
405
+ None => err ! ( "malformed stability attribute: missing `feature` key " ) ,
403
406
} ;
404
407
let feature = Feature {
405
408
level : Status :: Unstable ,
@@ -409,7 +412,6 @@ fn map_lib_features(base_src_path: &Path,
409
412
// although we would like to have specific tracking issues for each
410
413
// `rustc_const_unstable` in the future.
411
414
tracking_issue : Some ( 57563 ) ,
412
- group : None ,
413
415
} ;
414
416
mf ( Ok ( ( feature_name, feature) ) , file, i + 1 ) ;
415
417
continue ;
@@ -423,15 +425,15 @@ fn map_lib_features(base_src_path: &Path,
423
425
} ;
424
426
let feature_name = match find_attr_val ( line, "feature" ) {
425
427
Some ( name) => name,
426
- None => err ! ( "malformed stability attribute" ) ,
428
+ None => err ! ( "malformed stability attribute: missing `feature` key " ) ,
427
429
} ;
428
430
let since = match find_attr_val ( line, "since" ) . map ( |x| x. parse ( ) ) {
429
431
Some ( Ok ( since) ) => Some ( since) ,
430
432
Some ( Err ( _err) ) => {
431
- err ! ( "malformed since attribute" ) ;
433
+ err ! ( "malformed stability attribute: can't parse `since` key " ) ;
432
434
} ,
433
435
None if level == Status :: Stable => {
434
- err ! ( "malformed stability attribute" ) ;
436
+ err ! ( "malformed stability attribute: missing the `since` key " ) ;
435
437
}
436
438
None => None ,
437
439
} ;
@@ -442,7 +444,6 @@ fn map_lib_features(base_src_path: &Path,
442
444
since,
443
445
has_gate_test : false ,
444
446
tracking_issue,
445
- group : None ,
446
447
} ;
447
448
if line. contains ( ']' ) {
448
449
mf ( Ok ( ( feature_name, feature) ) , file, i + 1 ) ;
0 commit comments