Skip to content

Commit 53a09d4

Browse files
committed
Auto merge of rust-lang#9252 - Metaswitch:use-deprecated-config, r=Jarcho
Read and use deprecated configuration (as well as emitting a warning) Original change written by `@flip1995` I've simply rebased to master and fixed up the formatting/tests. This change teaches the configuration parser which config key replaced a deprecated key and attempts to populate the latter from the former. If both keys are provided this fails with a duplicate key error (rather than attempting to guess which the user intended). Currently this on affects `cyclomatic-complexity-threshold` -> `cognitive-complexity-threshold` but will also be used in rust-lang#8974 to handle `blacklisted-names` -> `disallowed-names`. ``` changelog: deprecated configuration keys are still applied as if they were provided as their non-deprecated name. ``` - [x] `cargo test` passes locally - [x] Run `cargo dev fmt`
2 parents 3c7e7db + ea25ef1 commit 53a09d4

File tree

8 files changed

+69
-13
lines changed

8 files changed

+69
-13
lines changed

clippy_lints/src/lib.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ pub fn read_conf(sess: &Session) -> Conf {
486486
},
487487
};
488488

489-
let TryConf { conf, errors } = utils::conf::read(&file_name);
489+
let TryConf { conf, errors, warnings } = utils::conf::read(&file_name);
490490
// all conf errors are non-fatal, we just use the default conf in case of error
491491
for error in errors {
492492
sess.err(&format!(
@@ -496,6 +496,15 @@ pub fn read_conf(sess: &Session) -> Conf {
496496
));
497497
}
498498

499+
for warning in warnings {
500+
sess.struct_warn(&format!(
501+
"error reading Clippy's configuration file `{}`: {}",
502+
file_name.display(),
503+
format_error(warning)
504+
))
505+
.emit();
506+
}
507+
499508
conf
500509
}
501510

clippy_lints/src/utils/conf.rs

+22-8
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,15 @@ pub enum DisallowedType {
6868
pub struct TryConf {
6969
pub conf: Conf,
7070
pub errors: Vec<Box<dyn Error>>,
71+
pub warnings: Vec<Box<dyn Error>>,
7172
}
7273

7374
impl TryConf {
7475
fn from_error(error: impl Error + 'static) -> Self {
7576
Self {
7677
conf: Conf::default(),
7778
errors: vec![Box::new(error)],
79+
warnings: vec![],
7880
}
7981
}
8082
}
@@ -90,14 +92,14 @@ impl fmt::Display for ConfError {
9092

9193
impl Error for ConfError {}
9294

93-
fn conf_error(s: String) -> Box<dyn Error> {
94-
Box::new(ConfError(s))
95+
fn conf_error(s: impl Into<String>) -> Box<dyn Error> {
96+
Box::new(ConfError(s.into()))
9597
}
9698

9799
macro_rules! define_Conf {
98100
($(
99101
$(#[doc = $doc:literal])+
100-
$(#[conf_deprecated($dep:literal)])?
102+
$(#[conf_deprecated($dep:literal, $new_conf:ident)])?
101103
($name:ident: $ty:ty = $default:expr),
102104
)*) => {
103105
/// Clippy lint configuration
@@ -137,17 +139,29 @@ macro_rules! define_Conf {
137139

138140
fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error> where V: MapAccess<'de> {
139141
let mut errors = Vec::new();
142+
let mut warnings = Vec::new();
140143
$(let mut $name = None;)*
141144
// could get `Field` here directly, but get `str` first for diagnostics
142145
while let Some(name) = map.next_key::<&str>()? {
143146
match Field::deserialize(name.into_deserializer())? {
144147
$(Field::$name => {
145-
$(errors.push(conf_error(format!("deprecated field `{}`. {}", name, $dep)));)?
148+
$(warnings.push(conf_error(format!("deprecated field `{}`. {}", name, $dep)));)?
146149
match map.next_value() {
147150
Err(e) => errors.push(conf_error(e.to_string())),
148151
Ok(value) => match $name {
149152
Some(_) => errors.push(conf_error(format!("duplicate field `{}`", name))),
150-
None => $name = Some(value),
153+
None => {
154+
$name = Some(value);
155+
// $new_conf is the same as one of the defined `$name`s, so
156+
// this variable is defined in line 2 of this function.
157+
$(match $new_conf {
158+
Some(_) => errors.push(conf_error(concat!(
159+
"duplicate field `", stringify!($new_conf),
160+
"` (provided as `", stringify!($name), "`)"
161+
))),
162+
None => $new_conf = Some(value),
163+
})?
164+
},
151165
}
152166
}
153167
})*
@@ -156,7 +170,7 @@ macro_rules! define_Conf {
156170
}
157171
}
158172
let conf = Conf { $($name: $name.unwrap_or_else(defaults::$name),)* };
159-
Ok(TryConf { conf, errors })
173+
Ok(TryConf { conf, errors, warnings })
160174
}
161175
}
162176

@@ -216,8 +230,8 @@ define_Conf! {
216230
/// DEPRECATED LINT: CYCLOMATIC_COMPLEXITY.
217231
///
218232
/// Use the Cognitive Complexity lint instead.
219-
#[conf_deprecated("Please use `cognitive-complexity-threshold` instead")]
220-
(cyclomatic_complexity_threshold: Option<u64> = None),
233+
#[conf_deprecated("Please use `cognitive-complexity-threshold` instead", cognitive_complexity_threshold)]
234+
(cyclomatic_complexity_threshold: u64 = 25),
221235
/// Lint: DOC_MARKDOWN.
222236
///
223237
/// The list of words this lint should not consider as identifiers needing ticks. The value

tests/ui-toml/conf_deprecated_key/clippy.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# that one is an error
2-
cyclomatic-complexity-threshold = 42
1+
# that one is a warning
2+
cyclomatic-complexity-threshold = 2
33

44
# that one is white-listed
55
[third-party]
Original file line numberDiff line numberDiff line change
@@ -1 +1,11 @@
11
fn main() {}
2+
3+
#[warn(clippy::cognitive_complexity)]
4+
fn cognitive_complexity() {
5+
let x = vec![1, 2, 3];
6+
for i in x {
7+
if i == 1 {
8+
println!("{}", i);
9+
}
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
error: error reading Clippy's configuration file `$DIR/clippy.toml`: deprecated field `cyclomatic-complexity-threshold`. Please use `cognitive-complexity-threshold` instead
1+
warning: error reading Clippy's configuration file `$DIR/clippy.toml`: deprecated field `cyclomatic-complexity-threshold`. Please use `cognitive-complexity-threshold` instead
22

3-
error: aborting due to previous error
3+
error: the function has a cognitive complexity of (3/2)
4+
--> $DIR/conf_deprecated_key.rs:4:4
5+
|
6+
LL | fn cognitive_complexity() {
7+
| ^^^^^^^^^^^^^^^^^^^^
8+
|
9+
= note: `-D clippy::cognitive-complexity` implied by `-D warnings`
10+
= help: you could split it up into multiple smaller functions
11+
12+
error: aborting due to previous error; 1 warning emitted
413

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
cognitive-complexity-threshold = 2
2+
# This is the deprecated name for the same key
3+
cyclomatic-complexity-threshold = 3
4+
# Check we get duplication warning regardless of order
5+
cognitive-complexity-threshold = 4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: error reading Clippy's configuration file `$DIR/clippy.toml`: duplicate field `cognitive_complexity_threshold` (provided as `cyclomatic_complexity_threshold`)
2+
3+
error: error reading Clippy's configuration file `$DIR/clippy.toml`: duplicate field `cognitive-complexity-threshold`
4+
5+
warning: error reading Clippy's configuration file `$DIR/clippy.toml`: deprecated field `cyclomatic-complexity-threshold`. Please use `cognitive-complexity-threshold` instead
6+
7+
error: aborting due to 2 previous errors; 1 warning emitted
8+

0 commit comments

Comments
 (0)