@@ -120,12 +120,7 @@ impl ConfError {
120
120
Self {
121
121
message : message. into ( ) ,
122
122
suggestion,
123
- span : Span :: new (
124
- file. start_pos + BytePos :: from_usize ( span. start ) ,
125
- file. start_pos + BytePos :: from_usize ( span. end ) ,
126
- SyntaxContext :: root ( ) ,
127
- None ,
128
- ) ,
123
+ span : span_from_toml_range ( file, span) ,
129
124
}
130
125
}
131
126
}
@@ -176,11 +171,61 @@ macro_rules! default_text {
176
171
} ;
177
172
}
178
173
174
+ macro_rules! deserialize {
175
+ ( $map: expr, $ty: ty, $errors: expr, $file: expr) => { {
176
+ let raw_value = $map. next_value:: <toml:: Spanned <toml:: Value >>( ) ?;
177
+ let value_span = raw_value. span( ) ;
178
+ let value = match <$ty>:: deserialize( raw_value. into_inner( ) ) {
179
+ Err ( e) => {
180
+ $errors. push( ConfError :: spanned(
181
+ $file,
182
+ e. to_string( ) . replace( '\n' , " " ) . trim( ) ,
183
+ None ,
184
+ value_span,
185
+ ) ) ;
186
+ continue ;
187
+ } ,
188
+ Ok ( value) => value,
189
+ } ;
190
+ ( value, value_span)
191
+ } } ;
192
+
193
+ ( $map: expr, $ty: ty, $errors: expr, $file: expr, $replacements_allowed: expr) => { {
194
+ let array = $map. next_value:: <Vec <toml:: Spanned <toml:: Value >>>( ) ?;
195
+ let mut disallowed_paths_span = Range {
196
+ start: usize :: MAX ,
197
+ end: usize :: MIN ,
198
+ } ;
199
+ let mut disallowed_paths = Vec :: new( ) ;
200
+ for raw_value in array {
201
+ let value_span = raw_value. span( ) ;
202
+ let mut disallowed_path = match DisallowedPath :: <$replacements_allowed>:: deserialize( raw_value. into_inner( ) )
203
+ {
204
+ Err ( e) => {
205
+ $errors. push( ConfError :: spanned(
206
+ $file,
207
+ e. to_string( ) . replace( '\n' , " " ) . trim( ) ,
208
+ None ,
209
+ value_span,
210
+ ) ) ;
211
+ continue ;
212
+ } ,
213
+ Ok ( disallowed_path) => disallowed_path,
214
+ } ;
215
+ disallowed_paths_span = union ( & disallowed_paths_span, & value_span) ;
216
+ disallowed_path. set_span( span_from_toml_range( $file, value_span) ) ;
217
+ disallowed_paths. push( disallowed_path) ;
218
+ }
219
+ ( disallowed_paths, disallowed_paths_span)
220
+ } } ;
221
+ }
222
+
179
223
macro_rules! define_Conf {
180
224
( $(
181
225
$( #[ doc = $doc: literal] ) +
182
226
$( #[ conf_deprecated( $dep: literal, $new_conf: ident) ] ) ?
183
227
$( #[ default_text = $default_text: expr] ) ?
228
+ $( #[ disallowed_paths_allow_replacements = $replacements_allowed: expr] ) ?
184
229
$( #[ lints( $( $for_lints: ident) ,* $( , ) ?) ] ) ?
185
230
$name: ident: $ty: ty = $default: expr,
186
231
) * ) => {
@@ -219,7 +264,7 @@ macro_rules! define_Conf {
219
264
let mut errors = Vec :: new( ) ;
220
265
let mut warnings = Vec :: new( ) ;
221
266
222
- // Declare a local variable for each field field available to a configuration file.
267
+ // Declare a local variable for each field available to a configuration file.
223
268
$( let mut $name = None ; ) *
224
269
225
270
// could get `Field` here directly, but get `String` first for diagnostics
@@ -237,15 +282,8 @@ macro_rules! define_Conf {
237
282
$( Field :: $name => {
238
283
// Is this a deprecated field, i.e., is `$dep` set? If so, push a warning.
239
284
$( warnings. push( ConfError :: spanned( self . 0 , format!( "deprecated field `{}`. {}" , name. get_ref( ) , $dep) , None , name. span( ) ) ) ; ) ?
240
- let raw_value = map. next_value:: <toml:: Spanned <toml:: Value >>( ) ?;
241
- let value_span = raw_value. span( ) ;
242
- let value = match <$ty>:: deserialize( raw_value. into_inner( ) ) {
243
- Err ( e) => {
244
- errors. push( ConfError :: spanned( self . 0 , e. to_string( ) . replace( '\n' , " " ) . trim( ) , None , value_span) ) ;
245
- continue ;
246
- }
247
- Ok ( value) => value
248
- } ;
285
+ let ( value, value_span) =
286
+ deserialize!( map, $ty, errors, self . 0 $( , $replacements_allowed) ?) ;
249
287
// Was this field set previously?
250
288
if $name. is_some( ) {
251
289
errors. push( ConfError :: spanned( self . 0 , format!( "duplicate field `{}`" , name. get_ref( ) ) , None , name. span( ) ) ) ;
@@ -286,6 +324,22 @@ macro_rules! define_Conf {
286
324
} ;
287
325
}
288
326
327
+ fn union ( x : & Range < usize > , y : & Range < usize > ) -> Range < usize > {
328
+ Range {
329
+ start : cmp:: min ( x. start , y. start ) ,
330
+ end : cmp:: max ( x. end , y. end ) ,
331
+ }
332
+ }
333
+
334
+ fn span_from_toml_range ( file : & SourceFile , span : Range < usize > ) -> Span {
335
+ Span :: new (
336
+ file. start_pos + BytePos :: from_usize ( span. start ) ,
337
+ file. start_pos + BytePos :: from_usize ( span. end ) ,
338
+ SyntaxContext :: root ( ) ,
339
+ None ,
340
+ )
341
+ }
342
+
289
343
define_Conf ! {
290
344
/// Which crates to allow absolute paths from
291
345
#[ lints( absolute_paths) ]
@@ -472,6 +526,7 @@ define_Conf! {
472
526
) ]
473
527
avoid_breaking_exported_api: bool = true ,
474
528
/// The list of types which may not be held across an await point.
529
+ #[ disallowed_paths_allow_replacements = false ]
475
530
#[ lints( await_holding_invalid_type) ]
476
531
await_holding_invalid_types: Vec <DisallowedPathWithoutReplacement > = Vec :: new( ) ,
477
532
/// DEPRECATED LINT: BLACKLISTED_NAME.
@@ -517,9 +572,11 @@ define_Conf! {
517
572
#[ conf_deprecated( "Please use `cognitive-complexity-threshold` instead" , cognitive_complexity_threshold) ]
518
573
cyclomatic_complexity_threshold: u64 = 25 ,
519
574
/// The list of disallowed macros, written as fully qualified paths.
575
+ #[ disallowed_paths_allow_replacements = true ]
520
576
#[ lints( disallowed_macros) ]
521
577
disallowed_macros: Vec <DisallowedPath > = Vec :: new( ) ,
522
578
/// The list of disallowed methods, written as fully qualified paths.
579
+ #[ disallowed_paths_allow_replacements = true ]
523
580
#[ lints( disallowed_methods) ]
524
581
disallowed_methods: Vec <DisallowedPath > = Vec :: new( ) ,
525
582
/// The list of disallowed names to lint about. NB: `bar` is not here since it has legitimate uses. The value
@@ -528,6 +585,7 @@ define_Conf! {
528
585
#[ lints( disallowed_names) ]
529
586
disallowed_names: Vec <String > = DEFAULT_DISALLOWED_NAMES . iter( ) . map( ToString :: to_string) . collect( ) ,
530
587
/// The list of disallowed types, written as fully qualified paths.
588
+ #[ disallowed_paths_allow_replacements = true ]
531
589
#[ lints( disallowed_types) ]
532
590
disallowed_types: Vec <DisallowedPath > = Vec :: new( ) ,
533
591
/// The list of words this lint should not consider as identifiers needing ticks. The value
0 commit comments