Skip to content

Commit 08ea04b

Browse files
committed
try reading rust-version from Cargo.toml
Cargo.toml can contain a field `rust-version`, that acts like a MSRV of clippy.toml file: https://doc.rust-lang.org/cargo/reference/manifest.html#the-rust-version-field This will try to read that field and use it, if the clippy.toml config has no `msrv` entry
1 parent 95f8b26 commit 08ea04b

File tree

1 file changed

+51
-13
lines changed

1 file changed

+51
-13
lines changed

clippy_lints/src/lib.rs

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@ extern crate clippy_utils;
5353
use clippy_utils::parse_msrv;
5454
use rustc_data_structures::fx::FxHashSet;
5555
use rustc_lint::LintId;
56+
use rustc_semver::RustcVersion;
5657
use rustc_session::Session;
58+
use std::fs::File;
59+
use std::io::Read;
60+
use toml::Value;
5761

5862
/// Macro used to declare a Clippy lint.
5963
///
@@ -443,6 +447,50 @@ pub fn register_pre_expansion_lints(store: &mut rustc_lint::LintStore, sess: &Se
443447
store.register_pre_expansion_pass(move || Box::new(attrs::EarlyAttributes { msrv }));
444448
}
445449

450+
fn read_msrv(conf: &Conf, sess: &Session) -> Option<RustcVersion> {
451+
let clippy_msrv = conf.msrv.as_ref().and_then(|s| {
452+
parse_msrv(s, None, None).or_else(|| {
453+
sess.err(&format!(
454+
"error reading Clippy's configuration file. `{}` is not a valid Rust version",
455+
s
456+
));
457+
None
458+
})
459+
});
460+
461+
let cargo_msrv = if_chain! {
462+
if let Ok(manifest_dir) = std::env::var("CARGO_MANIFEST_DIR");
463+
if let Ok(mut file) = File::open(format!("{manifest_dir}/Cargo.toml"));
464+
let mut cargo_content_str = String::new();
465+
if let Ok(_) = file.read_to_string(&mut cargo_content_str);
466+
if let Ok(cargo_content) = toml::from_str::<Value>(&cargo_content_str);
467+
if let Some(package) = cargo_content.get("package");
468+
if let Some(rust_version) = package.get("rust-version");
469+
if let Some(rust_version_str) = rust_version.as_str();
470+
then {
471+
parse_msrv(rust_version_str, None, None)
472+
} else {
473+
None
474+
}
475+
};
476+
477+
if let Some(cargo_msrv) = cargo_msrv {
478+
if let Some(clippy_msrv) = clippy_msrv {
479+
// if both files have an msrv, let's compare them and emit a warning if they differ
480+
if clippy_msrv != cargo_msrv {
481+
sess.warn(&format!(
482+
"the MSRV in `clippy.toml` and `Cargo.toml` differ; using `{}`",
483+
clippy_msrv
484+
));
485+
return Some(clippy_msrv);
486+
}
487+
}
488+
Some(cargo_msrv)
489+
} else {
490+
clippy_msrv
491+
}
492+
}
493+
446494
#[doc(hidden)]
447495
pub fn read_conf(sess: &Session) -> Conf {
448496
let file_name = match utils::conf::lookup_conf_file() {
@@ -458,12 +506,11 @@ pub fn read_conf(sess: &Session) -> Conf {
458506
let TryConf { conf, errors } = utils::conf::read(&file_name);
459507
// all conf errors are non-fatal, we just use the default conf in case of error
460508
for error in errors {
461-
sess.struct_err(&format!(
509+
sess.err(&format!(
462510
"error reading Clippy's configuration file `{}`: {}",
463511
file_name.display(),
464512
error
465-
))
466-
.emit();
513+
));
467514
}
468515

469516
conf
@@ -571,16 +618,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
571618
store.register_late_pass(|| Box::new(non_octal_unix_permissions::NonOctalUnixPermissions));
572619
store.register_early_pass(|| Box::new(unnecessary_self_imports::UnnecessarySelfImports));
573620

574-
let msrv = conf.msrv.as_ref().and_then(|s| {
575-
parse_msrv(s, None, None).or_else(|| {
576-
sess.err(&format!(
577-
"error reading Clippy's configuration file. `{}` is not a valid Rust version",
578-
s
579-
));
580-
None
581-
})
582-
});
583-
621+
let msrv = read_msrv(&conf, sess);
584622
let avoid_breaking_exported_api = conf.avoid_breaking_exported_api;
585623
store.register_late_pass(move || Box::new(approx_const::ApproxConstant::new(msrv)));
586624
store.register_late_pass(move || Box::new(methods::Methods::new(avoid_breaking_exported_api, msrv)));

0 commit comments

Comments
 (0)