1
+ use std:: collections:: HashMap ;
2
+
1
3
use crate :: config:: file_lines:: FileLines ;
2
4
use crate :: config:: options:: { IgnoreList , WidthHeuristics } ;
3
5
@@ -50,6 +52,78 @@ impl ConfigType for IgnoreList {
50
52
}
51
53
}
52
54
55
+ /// Store a map of all Unstable options used in in the configuration.
56
+ #[ derive( Clone , Debug ) ]
57
+ pub struct UnstableOptions {
58
+ options : HashMap < & ' static str , String > ,
59
+ }
60
+
61
+ impl UnstableOptions {
62
+ /// Create a new UnstableOptions struct
63
+ pub ( crate ) fn new ( ) -> Self {
64
+ Self {
65
+ options : HashMap :: new ( ) ,
66
+ }
67
+ }
68
+
69
+ /// Insert an unstable option and a user supplied value for that unstable option
70
+ pub ( crate ) fn insert ( & mut self , option : & ' static str , user_supplied_value : String ) {
71
+ self . options . insert ( option, user_supplied_value) ;
72
+ }
73
+
74
+ /// Check if any unstable options have been set
75
+ pub ( crate ) fn has_unstable_options ( & self ) -> bool {
76
+ !self . options . is_empty ( )
77
+ }
78
+
79
+ // primarily used for testing
80
+ #[ allow( dead_code) ]
81
+ pub ( crate ) fn options ( & self ) -> & HashMap < & ' static str , String > {
82
+ & self . options
83
+ }
84
+
85
+ /// Generate the Warning message
86
+ pub fn warning_message ( & self ) -> Option < String > {
87
+ if self . options . is_empty ( ) {
88
+ return None ;
89
+ }
90
+ let mut result = String :: new ( ) ;
91
+
92
+ for ( k, v) in self . options . iter ( ) {
93
+ result. push_str ( & format ! (
94
+ "Warning: can't set `{} = {}`, unstable features are only \
95
+ available in nightly channel.\n ",
96
+ k, v,
97
+ ) ) ;
98
+ }
99
+
100
+ let upgrade_to_abort_message = "\n Set `abort_on_unrecognised_options = true` \
101
+ to convert this warning into an error\n \n ";
102
+
103
+ result. push_str ( upgrade_to_abort_message) ;
104
+
105
+ Some ( result)
106
+ }
107
+
108
+ /// Generate the Abort message
109
+ pub fn abort_message ( & self ) -> Option < String > {
110
+ if self . options . is_empty ( ) {
111
+ return None ;
112
+ }
113
+
114
+ let mut result = String :: new ( ) ;
115
+ result. push_str ( "Can't set nightly options when using stable rustfmt\n " ) ;
116
+
117
+ for ( k, v) in self . options . iter ( ) {
118
+ result. push_str ( & format ! ( " - `{} = {}`\n " , k, v) ) ;
119
+ }
120
+ let to_warning_message = "\n Set `abort_on_unrecognised_options = false` \
121
+ to convert this error into a warning\n \n ";
122
+ result. push_str ( to_warning_message) ;
123
+ Some ( result)
124
+ }
125
+ }
126
+
53
127
macro_rules! create_config {
54
128
( $( $i: ident: $ty: ty, $def: expr, $stb: expr, $( $dstring: expr ) ,+ ) ;+ $( ; ) * ) => (
55
129
#[ cfg( test) ]
@@ -65,7 +139,7 @@ macro_rules! create_config {
65
139
// into a regex, it will be stored here
66
140
pub license_template: Option <Regex >,
67
141
// Unstable Options specified on the stable channel
68
- configured_unstable_options: std :: collections :: HashMap < String , String > ,
142
+ configured_unstable_options: UnstableOptions ,
69
143
// For each config item, we store a bool indicating whether it has
70
144
// been accessed and the value, and a bool whether the option was
71
145
// manually initialised, or taken from the default,
@@ -147,103 +221,33 @@ macro_rules! create_config {
147
221
ConfigWasSet ( self )
148
222
}
149
223
150
- /// Returns None if using nightly or if no unstable options were set.
151
- /// Otherwise, return all unstable options set by the user.
224
+ /// Insert all unstable options and their values into the UnstableOptions struct.
225
+ /// The only exception is the "abort_on_unrecognised_options", which helps
226
+ /// determine if we should abort or warn when using unstable options on stable rustfmt
152
227
#[ allow( unreachable_pub) ]
153
- pub fn unstable_options_set_on_stable_channel( & self ) -> Option <Vec <String >> {
154
- if crate :: is_nightly_channel!( ) {
155
- return None ;
156
- }
157
-
158
- if self . using_unstable_options_on_stable_channel( ) {
159
- Some ( self . configured_unstable_options. iter( )
160
- . map( |( k, v) | format!( "{} = {}" , k, v) )
161
- . collect:: <Vec <_>>( )
162
- )
163
- } else {
164
- None
165
- }
166
- }
167
-
168
- /// Gather all unstable options specified by the user
169
- #[ allow( unreachable_pub) ]
170
- pub fn collect_unstable_options( & mut self ) {
171
- if crate :: is_nightly_channel!( ) {
228
+ pub fn insert_unstable_options( & mut self , option: & ' static str , value: String ) {
229
+ if option == "abort_on_unrecognised_options" {
172
230
return
173
231
}
174
232
175
- let abort_option = "abort_on_unrecognised_options" ;
176
-
177
- $( {
178
- // self.$i.3 = 'is this a stable options'
179
- // self.$1.1 = 'was this set by the user'
180
- // the abort option is currently unstable so it needs to be special cased
181
- // otherwise we would abort when using it.
182
- if !( self . $i. 3 ) && self . $i. 1 && stringify!( $i) != abort_option {
183
- self . configured_unstable_options. insert(
184
- stringify!( $i) . to_owned( ) , format!( "{:?}" , self . $i. 2 )
185
- ) ;
233
+ match option {
234
+ $(
235
+ stringify!( $i) => {
236
+ // If its an unstable option then add it to the unstable list
237
+ if !self . $i. 3 {
238
+ self . configured_unstable_options. insert( option, value) ;
239
+ }
186
240
}
187
-
188
- } ) +
189
- }
190
-
191
- /// Returns true if any unstable options were set while on the stable channel
192
- #[ allow( unreachable_pub) ]
193
- pub fn using_unstable_options_on_stable_channel( & self ) -> bool {
194
- !self . configured_unstable_options. is_empty( )
195
- }
196
-
197
- /// Return a String warning users about all unstable options used on the stable channel
198
- #[ allow( unreachable_pub) ]
199
- pub fn unstable_options_warning_message( & self ) -> Option <String > {
200
- let unstable_options = self . unstable_options_set_on_stable_channel( ) ?;
201
- let upgrade_to_abort_message = "\n Set `abort_on_unrecognised_options = true` \
202
- to convert this warning into an error\n \n ";
203
- // Capacity of 120 * len should be enough space for all options.
204
- // the Warning string below is ~80 characters long so there is
205
- // ~40 char buffer for option name and value
206
- let mut output = String :: with_capacity(
207
- upgrade_to_abort_message. len( ) + unstable_options. len( ) * 120
208
- ) ;
209
-
210
- for option in unstable_options {
211
- output. push_str(
212
- & format!( "Warning: can't set `{}`, unstable features are only \
213
- available in nightly channel.\n ", option
214
- )
215
- ) ;
241
+ ) +
242
+ _ => panic!( "Unknown config key in override: {}" , option)
216
243
}
217
244
218
- output. push_str( upgrade_to_abort_message) ;
219
-
220
- Some ( output)
221
- }
222
-
223
- /// Returns a String explaining why rustfmt exited early when using unstable options
224
- /// on the stable channel
225
- #[ allow( unreachable_pub) ]
226
- pub fn unstable_options_abort_message( & self ) -> Option <String > {
227
- let unstable_options = self . unstable_options_set_on_stable_channel( ) ?;
228
- let first_line = "Can't set nightly options when using stable rustfmt\n " ;
229
- let to_warning_message = "\n Set `abort_on_unrecognised_options = false` \
230
- to convert this error into a warning\n \n ";
231
- // 40 = buffer we'll use for all options. Most will be less than 40 char long
232
- let mut output = String :: with_capacity(
233
- to_warning_message. len( ) + first_line. len( ) + unstable_options. len( ) * 40
234
- ) ;
235
- output. push_str( first_line) ;
236
-
237
- for option in unstable_options {
238
- output. push_str( & format!( " - `{}`\n " , option) ) ;
239
- }
240
- output. push_str( to_warning_message) ;
241
- Some ( output)
242
245
}
243
246
244
247
fn fill_from_parsed_config( mut self , parsed: PartialConfig , dir: & Path ) -> Config {
245
248
$(
246
249
if let Some ( val) = parsed. $i {
250
+ self . insert_unstable_options( stringify!( $i) , format!( "{:?}" , & val) ) ;
247
251
self . $i. 1 = true ;
248
252
self . $i. 2 = val;
249
253
}
@@ -252,7 +256,6 @@ macro_rules! create_config {
252
256
self . set_license_template( ) ;
253
257
self . set_ignore( dir) ;
254
258
self . set_merge_imports( ) ;
255
- self . collect_unstable_options( ) ;
256
259
self
257
260
}
258
261
@@ -307,6 +310,12 @@ macro_rules! create_config {
307
310
}
308
311
}
309
312
313
+ /// Get a reference to the UnstableOptions set on the configuration.
314
+ #[ allow( unreachable_pub) ]
315
+ pub fn unstable_options( & self ) -> & UnstableOptions {
316
+ & self . configured_unstable_options
317
+ }
318
+
310
319
#[ allow( unreachable_pub) ]
311
320
pub fn override_value( & mut self , key: & str , val: & str )
312
321
{
@@ -319,6 +328,7 @@ macro_rules! create_config {
319
328
stringify!( $i) ,
320
329
val,
321
330
stringify!( $ty) ) ) ;
331
+ self . insert_unstable_options( stringify!( $i) , val. to_owned( ) ) ;
322
332
}
323
333
) +
324
334
_ => panic!( "Unknown config key in override: {}" , key)
@@ -525,7 +535,7 @@ macro_rules! create_config {
525
535
fn default ( ) -> Config {
526
536
Config {
527
537
license_template: None ,
528
- configured_unstable_options: std :: collections :: HashMap :: new( ) ,
538
+ configured_unstable_options: UnstableOptions :: new( ) ,
529
539
$(
530
540
$i: ( Cell :: new( false ) , false , $def, $stb) ,
531
541
) +
0 commit comments