@@ -19,6 +19,15 @@ use std::path::{Path, PathBuf};
19
19
use file_lines:: FileLines ;
20
20
use lists:: { ListTactic , SeparatorPlace , SeparatorTactic } ;
21
21
22
+
23
+ macro_rules! is_nightly_channel {
24
+ ( ) => {
25
+ env:: var( "CFG_RELEASE_CHANNEL" )
26
+ . map( |c| c == "nightly" )
27
+ . unwrap_or( false )
28
+ }
29
+ }
30
+
22
31
macro_rules! configuration_option_enum{
23
32
( $e: ident: $( $x: ident ) ,+ $( , ) * ) => {
24
33
#[ derive( Copy , Clone , Eq , PartialEq , Debug ) ]
@@ -214,13 +223,13 @@ impl ConfigHelpItem {
214
223
}
215
224
216
225
macro_rules! create_config {
217
- ( $( $i: ident: $ty: ty, $def: expr, $( $dstring: expr ) ,+ ) ;+ $( ; ) * ) => (
226
+ ( $( $i: ident: $ty: ty, $def: expr, $stb : expr , $ ( $dstring: expr ) ,+ ) ;+ $( ; ) * ) => (
218
227
#[ derive( Clone ) ]
219
228
pub struct Config {
220
229
// For each config item, we store a bool indicating whether it has
221
230
// been accessed and the value, and a bool whether the option was
222
231
// manually initialised, or taken from the default,
223
- $( $i: ( Cell <bool >, bool , $ty) ) ,+
232
+ $( $i: ( Cell <bool >, bool , $ty, bool ) ) ,+
224
233
}
225
234
226
235
// Just like the Config struct but with each property wrapped
@@ -254,7 +263,15 @@ macro_rules! create_config {
254
263
impl <' a> ConfigSetter <' a> {
255
264
$(
256
265
pub fn $i( & mut self , value: $ty) {
257
- ( self . 0 ) . $i. 2 = value;
266
+ // we check if we are using nightly channel
267
+ let unstable = is_nightly_channel!( ) ;
268
+ if !( self . 0 ) . $i. 3 {
269
+ ( self . 0 ) . $i. 2 = value;
270
+ } else {
271
+ if unstable {
272
+ ( self . 0 ) . $i. 2 = value;
273
+ }
274
+ }
258
275
}
259
276
) +
260
277
}
@@ -460,7 +477,7 @@ macro_rules! create_config {
460
477
fn default ( ) -> Config {
461
478
Config {
462
479
$(
463
- $i: ( Cell :: new( false ) , false , $def) ,
480
+ $i: ( Cell :: new( false ) , false , $def, $stb ) ,
464
481
) +
465
482
}
466
483
}
@@ -493,135 +510,145 @@ pub fn get_toml_path(dir: &Path) -> Result<Option<PathBuf>, Error> {
493
510
494
511
495
512
create_config ! {
496
- unstable_features: bool , false , "Enables unstable features. Only available on nightly channel" ;
497
- verbose: bool , false , "Use verbose output" ;
498
- disable_all_formatting: bool , false , "Don't reformat anything" ;
499
- skip_children: bool , false , "Don't reformat out of line modules" ;
500
- file_lines: FileLines , FileLines :: all( ) ,
513
+ unstable_features: bool , false , true ,
514
+ "Enables unstable features. Only available on nightly channel" ;
515
+ verbose: bool , false , false , "Use verbose output" ;
516
+ disable_all_formatting: bool , false , false , "Don't reformat anything" ;
517
+ skip_children: bool , false , false , "Don't reformat out of line modules" ;
518
+ file_lines: FileLines , FileLines :: all( ) , false ,
501
519
"Lines to format; this is not supported in rustfmt.toml, and can only be specified \
502
520
via the --file-lines option";
503
- max_width: usize , 100 , "Maximum width of each line" ;
504
- error_on_line_overflow: bool , true , "Error if unable to get all lines within max_width" ;
505
- error_on_line_overflow_comments: bool , true , "Error if unable to get comments within max_width" ;
506
- tab_spaces: usize , 4 , "Number of spaces per tab" ;
507
- fn_call_width: usize , 60 ,
521
+ max_width: usize , 100 , false , "Maximum width of each line" ;
522
+ error_on_line_overflow: bool , true , false , "Error if unable to get all lines within max_width" ;
523
+ error_on_line_overflow_comments: bool , true , false ,
524
+ "Error if unable to get comments within max_width" ;
525
+ tab_spaces: usize , 4 , false , "Number of spaces per tab" ;
526
+ fn_call_width: usize , 60 , false ,
508
527
"Maximum width of the args of a function call before falling back to vertical formatting" ;
509
- struct_lit_width: usize , 18 ,
528
+ struct_lit_width: usize , 18 , false ,
510
529
"Maximum width in the body of a struct lit before falling back to vertical formatting" ;
511
- struct_variant_width: usize , 35 ,
530
+ struct_variant_width: usize , 35 , false ,
512
531
"Maximum width in the body of a struct variant before falling back to vertical formatting" ;
513
- force_explicit_abi: bool , true , "Always print the abi for extern items" ;
514
- newline_style: NewlineStyle , NewlineStyle :: Unix , "Unix or Windows line endings" ;
515
- fn_brace_style: BraceStyle , BraceStyle :: SameLineWhere , "Brace style for functions" ;
516
- item_brace_style: BraceStyle , BraceStyle :: SameLineWhere , "Brace style for structs and enums" ;
517
- control_style: Style , Style :: Rfc , "Indent style for control flow statements" ;
518
- control_brace_style: ControlBraceStyle , ControlBraceStyle :: AlwaysSameLine ,
532
+ force_explicit_abi: bool , true , false , "Always print the abi for extern items" ;
533
+ newline_style: NewlineStyle , NewlineStyle :: Unix , false , "Unix or Windows line endings" ;
534
+ fn_brace_style: BraceStyle , BraceStyle :: SameLineWhere , false , "Brace style for functions" ;
535
+ item_brace_style: BraceStyle , BraceStyle :: SameLineWhere , false ,
536
+ "Brace style for structs and enums" ;
537
+ control_style: Style , Style :: Rfc , false , "Indent style for control flow statements" ;
538
+ control_brace_style: ControlBraceStyle , ControlBraceStyle :: AlwaysSameLine , false ,
519
539
"Brace style for control flow constructs" ;
520
- impl_empty_single_line: bool , true , "Put empty-body implementations on a single line" ;
521
- trailing_comma: SeparatorTactic , SeparatorTactic :: Vertical ,
540
+ impl_empty_single_line: bool , true , false , "Put empty-body implementations on a single line" ;
541
+ trailing_comma: SeparatorTactic , SeparatorTactic :: Vertical , false ,
522
542
"How to handle trailing commas for lists" ;
523
- trailing_semicolon: bool , true , "Add trailing semicolon after break, continue and return" ;
524
- fn_empty_single_line: bool , true , "Put empty-body functions on a single line" ;
525
- fn_single_line: bool , false , "Put single-expression functions on a single line" ;
526
- fn_return_indent: ReturnIndent , ReturnIndent :: WithArgs ,
543
+ trailing_semicolon: bool , true , false ,
544
+ "Add trailing semicolon after break, continue and return" ;
545
+ fn_empty_single_line: bool , true , false , "Put empty-body functions on a single line" ;
546
+ fn_single_line: bool , false , false , "Put single-expression functions on a single line" ;
547
+ fn_return_indent: ReturnIndent , ReturnIndent :: WithArgs , false ,
527
548
"Location of return type in function declaration" ;
528
- fn_args_paren_newline: bool , false , "If function argument parenthesis goes on a newline" ;
529
- fn_args_density: Density , Density :: Tall , "Argument density in functions" ;
530
- fn_args_layout: IndentStyle , IndentStyle :: Block ,
549
+ fn_args_paren_newline: bool , false , false , "If function argument parenthesis goes on a newline" ;
550
+ fn_args_density: Density , Density :: Tall , false , "Argument density in functions" ;
551
+ fn_args_layout: IndentStyle , IndentStyle :: Block , false ,
531
552
"Layout of function arguments and tuple structs" ;
532
- array_layout: IndentStyle , IndentStyle :: Block , "Indent on arrays" ;
533
- array_width: usize , 60 ,
553
+ array_layout: IndentStyle , IndentStyle :: Block , false , "Indent on arrays" ;
554
+ array_width: usize , 60 , false ,
534
555
"Maximum width of an array literal before falling back to vertical formatting" ;
535
- array_horizontal_layout_threshold: usize , 0 ,
556
+ array_horizontal_layout_threshold: usize , 0 , false ,
536
557
"How many elements array must have before rustfmt uses horizontal layout." ;
537
- type_punctuation_density: TypeDensity , TypeDensity :: Wide ,
558
+ type_punctuation_density: TypeDensity , TypeDensity :: Wide , false ,
538
559
"Determines if '+' or '=' are wrapped in spaces in the punctuation of types" ;
539
- where_style: Style , Style :: Rfc , "Overall strategy for where clauses" ;
560
+ where_style: Style , Style :: Rfc , false , "Overall strategy for where clauses" ;
540
561
// TODO:
541
562
// 1. Should we at least try to put the where clause on the same line as the rest of the
542
563
// function decl?
543
564
// 2. Currently options `Tall` and `Vertical` produce the same output.
544
- where_density: Density , Density :: Vertical , "Density of a where clause" ;
545
- where_layout: ListTactic , ListTactic :: Vertical , "Element layout inside a where clause" ;
546
- where_pred_indent: IndentStyle , IndentStyle :: Visual ,
565
+ where_density: Density , Density :: Vertical , false , "Density of a where clause" ;
566
+ where_layout: ListTactic , ListTactic :: Vertical , false , "Element layout inside a where clause" ;
567
+ where_pred_indent: IndentStyle , IndentStyle :: Visual , false ,
547
568
"Indentation style of a where predicate" ;
548
- generics_indent: IndentStyle , IndentStyle :: Block , "Indentation of generics" ;
549
- struct_lit_style: IndentStyle , IndentStyle :: Block , "Style of struct definition" ;
550
- struct_lit_multiline_style: MultilineStyle , MultilineStyle :: PreferSingle ,
569
+ generics_indent: IndentStyle , IndentStyle :: Block , false , "Indentation of generics" ;
570
+ struct_lit_style: IndentStyle , IndentStyle :: Block , false , "Style of struct definition" ;
571
+ struct_lit_multiline_style: MultilineStyle , MultilineStyle :: PreferSingle , false ,
551
572
"Multiline style on literal structs" ;
552
- fn_call_style: IndentStyle , IndentStyle :: Block , "Indentation for function calls, etc." ;
553
- report_todo: ReportTactic , ReportTactic :: Never ,
573
+ fn_call_style: IndentStyle , IndentStyle :: Block , false , "Indentation for function calls, etc." ;
574
+ report_todo: ReportTactic , ReportTactic :: Never , false ,
554
575
"Report all, none or unnumbered occurrences of TODO in source file comments" ;
555
- report_fixme: ReportTactic , ReportTactic :: Never ,
576
+ report_fixme: ReportTactic , ReportTactic :: Never , false ,
556
577
"Report all, none or unnumbered occurrences of FIXME in source file comments" ;
557
- chain_indent: IndentStyle , IndentStyle :: Block , "Indentation of chain" ;
558
- chain_one_line_max: usize , 60 , "Maximum length of a chain to fit on a single line" ;
559
- chain_split_single_child: bool , false , "Split a chain with a single child if its length \
578
+ chain_indent: IndentStyle , IndentStyle :: Block , false , "Indentation of chain" ;
579
+ chain_one_line_max: usize , 60 , false , "Maximum length of a chain to fit on a single line" ;
580
+ chain_split_single_child: bool , false , false , "Split a chain with a single child if its length \
560
581
exceeds `chain_one_line_max`";
561
- imports_indent: IndentStyle , IndentStyle :: Visual , "Indent of imports" ;
562
- imports_layout: ListTactic , ListTactic :: Mixed , "Item layout inside a import block" ;
563
- reorder_extern_crates: bool , true , "Reorder extern crate statements alphabetically" ;
564
- reorder_extern_crates_in_group: bool , true , "Reorder extern crate statements in group" ;
565
- reorder_imports: bool , false , "Reorder import statements alphabetically" ;
566
- reorder_imports_in_group: bool , false , "Reorder import statements in group" ;
567
- reorder_imported_names: bool , true ,
582
+ imports_indent: IndentStyle , IndentStyle :: Visual , false , "Indent of imports" ;
583
+ imports_layout: ListTactic , ListTactic :: Mixed , false , "Item layout inside a import block" ;
584
+ reorder_extern_crates: bool , true , false , "Reorder extern crate statements alphabetically" ;
585
+ reorder_extern_crates_in_group: bool , true , false , "Reorder extern crate statements in group" ;
586
+ reorder_imports: bool , false , false , "Reorder import statements alphabetically" ;
587
+ reorder_imports_in_group: bool , false , false , "Reorder import statements in group" ;
588
+ reorder_imported_names: bool , true , false ,
568
589
"Reorder lists of names in import statements alphabetically" ;
569
- single_line_if_else_max_width: usize , 50 , "Maximum line length for single line if-else \
590
+ single_line_if_else_max_width: usize , 50 , false , "Maximum line length for single line if-else \
570
591
expressions. A value of zero means always break \
571
592
if-else expressions.";
572
- format_strings: bool , false , "Format string literals where necessary" ;
573
- force_format_strings: bool , false , "Always format string literals" ;
574
- take_source_hints: bool , false , "Retain some formatting characteristics from the source code" ;
575
- hard_tabs: bool , false , "Use tab characters for indentation, spaces for alignment" ;
576
- wrap_comments: bool , false , "Break comments to fit on the line" ;
577
- comment_width: usize , 80 , "Maximum length of comments. No effect unless wrap_comments = true" ;
578
- normalize_comments: bool , false , "Convert /* */ comments to // comments where possible" ;
579
- wrap_match_arms: bool , true , "Wrap the body of arms in blocks when it does not fit on \
593
+ format_strings: bool , false , false , "Format string literals where necessary" ;
594
+ force_format_strings: bool , false , false , "Always format string literals" ;
595
+ take_source_hints: bool , false , false ,
596
+ "Retain some formatting characteristics from the source code" ;
597
+ hard_tabs: bool , false , false , "Use tab characters for indentation, spaces for alignment" ;
598
+ wrap_comments: bool , false , false , "Break comments to fit on the line" ;
599
+ comment_width: usize , 80 , false ,
600
+ "Maximum length of comments. No effect unless wrap_comments = true" ;
601
+ normalize_comments: bool , false , false , "Convert /* */ comments to // comments where possible" ;
602
+ wrap_match_arms: bool , true , false , "Wrap the body of arms in blocks when it does not fit on \
580
603
the same line with the pattern of arms";
581
- match_block_trailing_comma: bool , false ,
604
+ match_block_trailing_comma: bool , false , false ,
582
605
"Put a trailing comma after a block based match arm (non-block arms are not affected)" ;
583
- indent_match_arms: bool , true , "Indent match arms instead of keeping them at the same \
606
+ indent_match_arms: bool , true , false , "Indent match arms instead of keeping them at the same \
584
607
indentation level as the match keyword";
585
- match_pattern_separator_break_point: SeparatorPlace , SeparatorPlace :: Back ,
608
+ match_pattern_separator_break_point: SeparatorPlace , SeparatorPlace :: Back , false ,
586
609
"Put a match sub-patterns' separator in front or back." ;
587
- closure_block_indent_threshold: isize , 7 , "How many lines a closure must have before it is \
588
- block indented. -1 means never use block indent.";
589
- space_before_type_annotation: bool , false ,
610
+ closure_block_indent_threshold: isize , 7 , false ,
611
+ "How many lines a closure must have before it is block indented. \
612
+ -1 means never use block indent.";
613
+ space_before_type_annotation: bool , false , false ,
590
614
"Leave a space before the colon in a type annotation" ;
591
- space_after_type_annotation_colon: bool , true ,
615
+ space_after_type_annotation_colon: bool , true , false ,
592
616
"Leave a space after the colon in a type annotation" ;
593
- space_before_struct_lit_field_colon: bool , false ,
617
+ space_before_struct_lit_field_colon: bool , false , false ,
594
618
"Leave a space before the colon in a struct literal field" ;
595
- space_after_struct_lit_field_colon: bool , true ,
619
+ space_after_struct_lit_field_colon: bool , true , false ,
596
620
"Leave a space after the colon in a struct literal field" ;
597
- space_before_bound: bool , false , "Leave a space before the colon in a trait or lifetime bound" ;
598
- space_after_bound_colon: bool , true ,
621
+ space_before_bound: bool , false , false ,
622
+ "Leave a space before the colon in a trait or lifetime bound" ;
623
+ space_after_bound_colon: bool , true , false ,
599
624
"Leave a space after the colon in a trait or lifetime bound" ;
600
- spaces_around_ranges: bool , false , "Put spaces around the .. and ... range operators" ;
601
- spaces_within_angle_brackets: bool , false , "Put spaces within non-empty generic arguments" ;
602
- spaces_within_square_brackets: bool , false , "Put spaces within non-empty square brackets" ;
603
- spaces_within_parens: bool , false , "Put spaces within non-empty parentheses" ;
604
- use_try_shorthand: bool , false , "Replace uses of the try! macro by the ? shorthand" ;
605
- write_mode: WriteMode , WriteMode :: Overwrite ,
625
+ spaces_around_ranges: bool , false , false , "Put spaces around the .. and ... range operators" ;
626
+ spaces_within_angle_brackets: bool , false , false ,
627
+ "Put spaces within non-empty generic arguments" ;
628
+ spaces_within_square_brackets: bool , false , false ,
629
+ "Put spaces within non-empty square brackets" ;
630
+ spaces_within_parens: bool , false , false , "Put spaces within non-empty parentheses" ;
631
+ use_try_shorthand: bool , false , false , "Replace uses of the try! macro by the ? shorthand" ;
632
+ write_mode: WriteMode , WriteMode :: Overwrite , false ,
606
633
"What Write Mode to use when none is supplied: \
607
634
Replace, Overwrite, Display, Plain, Diff, Coverage";
608
- condense_wildcard_suffixes: bool , false , "Replace strings of _ wildcards by a single .. in \
609
- tuple patterns";
610
- combine_control_expr: bool , true , "Combine control expressions with funciton calls." ;
611
- struct_field_align_threshold: usize , 0 , "Align struct fields if their diffs fits within \
635
+ condense_wildcard_suffixes: bool , false , false , "Replace strings of _ wildcards by a single \
636
+ .. in tuple patterns";
637
+ combine_control_expr: bool , true , false , "Combine control expressions with funciton calls." ;
638
+ struct_field_align_threshold: usize , 0 , false , "Align struct fields if their diffs fits within \
612
639
threshold.";
613
- remove_blank_lines_at_start_or_end_of_block: bool , true ,
640
+ remove_blank_lines_at_start_or_end_of_block: bool , true , false ,
614
641
"Remove blank lines at start or end of a block" ;
615
- attributes_on_same_line_as_field: bool , true ,
642
+ attributes_on_same_line_as_field: bool , true , false ,
616
643
"Try to put attributes on the same line as fields." ;
617
- attributes_on_same_line_as_variant: bool , true ,
644
+ attributes_on_same_line_as_variant: bool , true , false ,
618
645
"Try to put attributes on the same line as variants in enum declarations." ;
619
- multiline_closure_forces_block: bool , false ,
646
+ multiline_closure_forces_block: bool , false , false ,
620
647
"Force multiline closure bodies to be wrapped in a block" ;
621
- multiline_match_arm_forces_block: bool , false ,
648
+ multiline_match_arm_forces_block: bool , false , false ,
622
649
"Force multiline match arm bodies to be wrapped in a block" ;
623
- merge_derives: bool , true , "Merge multiple `#[derive(...)]` into a single one" ;
624
- binop_separator: SeparatorPlace , SeparatorPlace :: Front ,
650
+ merge_derives: bool , true , false , "Merge multiple `#[derive(...)]` into a single one" ;
651
+ binop_separator: SeparatorPlace , SeparatorPlace :: Front , false ,
625
652
"Where to put a binary operator when a binary expression goes multiline." ;
626
653
}
627
654
@@ -660,4 +687,24 @@ mod test {
660
687
assert_eq ! ( config. was_set( ) . hard_tabs( ) , true ) ;
661
688
assert_eq ! ( config. was_set( ) . verbose( ) , false ) ;
662
689
}
690
+
691
+ #[ test]
692
+ fn test_as_not_nightly_channel ( ) {
693
+ let mut config = Config :: default ( ) ;
694
+ assert_eq ! ( config. was_set( ) . unstable_features( ) , false ) ;
695
+ config. set ( ) . unstable_features ( true ) ;
696
+ assert_eq ! ( config. was_set( ) . unstable_features( ) , false ) ;
697
+ }
698
+
699
+ #[ test]
700
+ fn test_as_nightly_channel ( ) {
701
+ let v = :: std:: env:: var ( "CFG_RELEASE_CHANNEL" ) . unwrap_or ( String :: from ( "" ) ) ;
702
+ :: std:: env:: set_var ( "CFG_RELEASE_CHANNEL" , "nightly" ) ;
703
+ let mut config = Config :: default ( ) ;
704
+ config. set ( ) . unstable_features ( true ) ;
705
+ assert_eq ! ( config. was_set( ) . unstable_features( ) , false ) ;
706
+ config. set ( ) . unstable_features ( true ) ;
707
+ assert_eq ! ( config. unstable_features( ) , true ) ;
708
+ :: std:: env:: set_var ( "CFG_RELEASE_CHANNEL" , v) ;
709
+ }
663
710
}
0 commit comments