Skip to content

Commit 87066a7

Browse files
committed
Make visit_map happy path more evident
1 parent f83c94c commit 87066a7

File tree

1 file changed

+32
-21
lines changed

1 file changed

+32
-21
lines changed

clippy_config/src/conf.rs

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -212,41 +212,52 @@ macro_rules! define_Conf {
212212
fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error> where V: MapAccess<'de> {
213213
let mut errors = Vec::new();
214214
let mut warnings = Vec::new();
215+
216+
// Declare a local variable for each field in the configuration file.
215217
$(let mut $name = None;)*
218+
216219
// could get `Field` here directly, but get `String` first for diagnostics
217220
while let Some(name) = map.next_key::<toml::Spanned<String>>()? {
218-
match Field::deserialize(name.get_ref().as_str().into_deserializer()) {
221+
let field = match Field::deserialize(name.get_ref().as_str().into_deserializer()) {
219222
Err(e) => {
220223
let e: FieldError = e;
221224
errors.push(ConfError::spanned(self.0, e.error, e.suggestion, name.span()));
225+
continue;
222226
}
223-
$(Ok(Field::$name) => {
227+
Ok(field) => field
228+
};
229+
230+
match field {
231+
$(Field::$name => {
232+
// Is this a deprecated field, i.e., is `$dep` set? If so, push a warning.
224233
$(warnings.push(ConfError::spanned(self.0, format!("deprecated field `{}`. {}", name.get_ref(), $dep), None, name.span()));)?
225234
let raw_value = map.next_value::<toml::Spanned<toml::Value>>()?;
226235
let value_span = raw_value.span();
227-
match <$ty>::deserialize(raw_value.into_inner()) {
228-
Err(e) => errors.push(ConfError::spanned(self.0, e.to_string().replace('\n', " ").trim(), None, value_span)),
229-
Ok(value) => match $name {
230-
Some(_) => {
231-
errors.push(ConfError::spanned(self.0, format!("duplicate field `{}`", name.get_ref()), None, name.span()));
232-
}
233-
None => {
234-
$name = Some(value);
235-
// $new_conf is the same as one of the defined `$name`s, so
236-
// this variable is defined in line 2 of this function.
237-
$(match $new_conf {
238-
Some(_) => errors.push(ConfError::spanned(self.0, concat!(
239-
"duplicate field `", stringify!($new_conf),
240-
"` (provided as `", stringify!($name), "`)"
241-
), None, name.span())),
242-
None => $new_conf = $name.clone(),
243-
})?
244-
},
236+
let value = match <$ty>::deserialize(raw_value.into_inner()) {
237+
Err(e) => {
238+
errors.push(ConfError::spanned(self.0, e.to_string().replace('\n', " ").trim(), None, value_span));
239+
continue;
245240
}
241+
Ok(value) => value
242+
};
243+
// Was this field set previously?
244+
if $name.is_some() {
245+
errors.push(ConfError::spanned(self.0, format!("duplicate field `{}`", name.get_ref()), None, name.span()));
246+
continue;
246247
}
248+
$name = Some(value);
249+
// If this is a deprecated field, was the new field (`$new_conf`) set previously?
250+
// Note that `$new_conf` is one of the defined `$name`s.
251+
$(match $new_conf {
252+
Some(_) => errors.push(ConfError::spanned(self.0, concat!(
253+
"duplicate field `", stringify!($new_conf),
254+
"` (provided as `", stringify!($name), "`)"
255+
), None, name.span())),
256+
None => $new_conf = $name.clone(),
257+
})?
247258
})*
248259
// ignore contents of the third_party key
249-
Ok(Field::third_party) => drop(map.next_value::<IgnoredAny>())
260+
Field::third_party => drop(map.next_value::<IgnoredAny>())
250261
}
251262
}
252263
let conf = Conf { $($name: $name.unwrap_or_else(defaults::$name),)* };

0 commit comments

Comments
 (0)