Skip to content

Commit bb0d09b

Browse files
authored
Make visit_map happy path more evident (#14376)
This is a small refactor of `ConfVisitor`'s `visit_map` method. It adds comments and reduces `match` nesting by adding `continue` statements. IMHO, the code is easier to read in this form. No one asked for this, so I hope the maintainers agree it is an improvement. changelog: none
2 parents b46b311 + 0af0445 commit bb0d09b

File tree

1 file changed

+33
-22
lines changed

1 file changed

+33
-22
lines changed

clippy_config/src/conf.rs

+33-22
Original file line numberDiff line numberDiff line change
@@ -218,42 +218,53 @@ macro_rules! define_Conf {
218218
let mut value_spans = HashMap::new();
219219
let mut errors = Vec::new();
220220
let mut warnings = Vec::new();
221+
222+
// Declare a local variable for each field field available to a configuration file.
221223
$(let mut $name = None;)*
224+
222225
// could get `Field` here directly, but get `String` first for diagnostics
223226
while let Some(name) = map.next_key::<toml::Spanned<String>>()? {
224-
match Field::deserialize(name.get_ref().as_str().into_deserializer()) {
227+
let field = match Field::deserialize(name.get_ref().as_str().into_deserializer()) {
225228
Err(e) => {
226229
let e: FieldError = e;
227230
errors.push(ConfError::spanned(self.0, e.error, e.suggestion, name.span()));
231+
continue;
228232
}
229-
$(Ok(Field::$name) => {
233+
Ok(field) => field
234+
};
235+
236+
match field {
237+
$(Field::$name => {
238+
// Is this a deprecated field, i.e., is `$dep` set? If so, push a warning.
230239
$(warnings.push(ConfError::spanned(self.0, format!("deprecated field `{}`. {}", name.get_ref(), $dep), None, name.span()));)?
231240
let raw_value = map.next_value::<toml::Spanned<toml::Value>>()?;
232241
let value_span = raw_value.span();
233-
match <$ty>::deserialize(raw_value.into_inner()) {
234-
Err(e) => errors.push(ConfError::spanned(self.0, e.to_string().replace('\n', " ").trim(), None, value_span)),
235-
Ok(value) => match $name {
236-
Some(_) => {
237-
errors.push(ConfError::spanned(self.0, format!("duplicate field `{}`", name.get_ref()), None, name.span()));
238-
}
239-
None => {
240-
$name = Some(value);
241-
value_spans.insert(name.get_ref().as_str().to_string(), value_span);
242-
// $new_conf is the same as one of the defined `$name`s, so
243-
// this variable is defined in line 2 of this function.
244-
$(match $new_conf {
245-
Some(_) => errors.push(ConfError::spanned(self.0, concat!(
246-
"duplicate field `", stringify!($new_conf),
247-
"` (provided as `", stringify!($name), "`)"
248-
), None, name.span())),
249-
None => $new_conf = $name.clone(),
250-
})?
251-
},
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;
252246
}
247+
Ok(value) => value
248+
};
249+
// Was this field set previously?
250+
if $name.is_some() {
251+
errors.push(ConfError::spanned(self.0, format!("duplicate field `{}`", name.get_ref()), None, name.span()));
252+
continue;
253253
}
254+
$name = Some(value);
255+
value_spans.insert(name.get_ref().as_str().to_string(), value_span);
256+
// If this is a deprecated field, was the new field (`$new_conf`) set previously?
257+
// Note that `$new_conf` is one of the defined `$name`s.
258+
$(match $new_conf {
259+
Some(_) => errors.push(ConfError::spanned(self.0, concat!(
260+
"duplicate field `", stringify!($new_conf),
261+
"` (provided as `", stringify!($name), "`)"
262+
), None, name.span())),
263+
None => $new_conf = $name.clone(),
264+
})?
254265
})*
255266
// ignore contents of the third_party key
256-
Ok(Field::third_party) => drop(map.next_value::<IgnoredAny>())
267+
Field::third_party => drop(map.next_value::<IgnoredAny>())
257268
}
258269
}
259270
let conf = Conf { $($name: $name.unwrap_or_else(defaults::$name),)* };

0 commit comments

Comments
 (0)