Skip to content

Commit 56224e3

Browse files
committed
rework cargo.toml reading
instead of using the `MetadataCommand`, we read the `Cargo.toml` as a toml file and parse the `rust-version` field out of it. Also moved the validation point of the clippy.toml rust version to an earlier point, because we need it now.
1 parent 66b304e commit 56224e3

File tree

1 file changed

+46
-23
lines changed

1 file changed

+46
-23
lines changed

clippy_lints/src/lib.rs

Lines changed: 46 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,14 @@ extern crate rustc_typeck;
5050
#[macro_use]
5151
extern crate clippy_utils;
5252

53-
use cargo_metadata::MetadataCommand;
5453
use clippy_utils::parse_msrv;
5554
use rustc_data_structures::fx::FxHashSet;
5655
use rustc_lint::LintId;
56+
use rustc_semver::RustcVersion;
5757
use rustc_session::Session;
58+
use std::fs::File;
59+
use std::io::Read;
60+
use toml::Value;
5861

5962
/// Macro used to declare a Clippy lint.
6063
///
@@ -444,6 +447,24 @@ pub fn register_pre_expansion_lints(store: &mut rustc_lint::LintStore, sess: &Se
444447
store.register_pre_expansion_pass(move || Box::new(attrs::EarlyAttributes { msrv }));
445448
}
446449

450+
fn cargo_toml_msrv() -> Option<RustcVersion> {
451+
if_chain! {
452+
if let Ok(manifest_dir) = std::env::var("CARGO_MANIFEST_DIR");
453+
if let Ok(mut file) = File::open(format!("{manifest_dir}/Cargo.toml"));
454+
let mut cargo_content_str = String::new();
455+
if let Ok(_) = file.read_to_string(&mut cargo_content_str);
456+
if let Ok(cargo_content) = toml::from_str::<Value>(&cargo_content_str);
457+
if let Some(package) = cargo_content.get("package");
458+
if let Some(rust_version) = package.get("rust-version");
459+
if let Some(rust_version_str) = rust_version.as_str();
460+
then {
461+
parse_msrv(rust_version_str, None, None)
462+
} else {
463+
None
464+
}
465+
}
466+
}
467+
447468
#[doc(hidden)]
448469
pub fn read_conf(sess: &Session) -> Conf {
449470
let file_name = match utils::conf::lookup_conf_file() {
@@ -459,23 +480,34 @@ pub fn read_conf(sess: &Session) -> Conf {
459480
let TryConf { mut conf, errors } = utils::conf::read(&file_name);
460481
// all conf errors are non-fatal, we just use the default conf in case of error
461482
for error in errors {
462-
sess.struct_err(&format!(
483+
sess.err(&format!(
463484
"error reading Clippy's configuration file `{}`: {}",
464485
file_name.display(),
465486
error
466-
))
467-
.emit();
487+
));
468488
}
469489

470-
if conf.msrv.is_none() {
471-
// let's try to get msrv from `Cargo.toml`s field `rust-version`
472-
if let Ok(metadata) = MetadataCommand::new().no_deps().exec() {
473-
conf.msrv = metadata
474-
.packages
475-
.get(0)
476-
.and_then(|x| x.rust_version.as_ref())
477-
.and_then(|r| r.comparators.get(0))
478-
.map(|v| format!("{}.{}.{}", v.major, v.minor.unwrap_or(0), v.patch.unwrap_or(0)));
490+
let clippy_msrv = conf.msrv.as_ref().and_then(|s| {
491+
parse_msrv(s, None, None).or_else(|| {
492+
sess.err(&format!(
493+
"error reading Clippy's configuration file. `{}` is not a valid Rust version",
494+
s
495+
));
496+
None
497+
})
498+
});
499+
if let Some(cargo_msrv) = cargo_toml_msrv() {
500+
if let Some(clippy_msrv) = clippy_msrv {
501+
// if both files have an msrv, let's compare them and emit a warning if they differ
502+
if clippy_msrv != cargo_msrv {
503+
sess.warn(&format!(
504+
"The MSRV in `clippy.toml` and `Cargo.toml` differ. Using `{}`",
505+
clippy_msrv
506+
));
507+
}
508+
} else {
509+
// assign msrv from cargo.toml if clippy.toml hasn't set one alreay
510+
conf.msrv = Some(cargo_msrv.to_string());
479511
}
480512
}
481513

@@ -584,16 +616,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
584616
store.register_late_pass(|| Box::new(non_octal_unix_permissions::NonOctalUnixPermissions));
585617
store.register_early_pass(|| Box::new(unnecessary_self_imports::UnnecessarySelfImports));
586618

587-
let msrv = conf.msrv.as_ref().and_then(|s| {
588-
parse_msrv(s, None, None).or_else(|| {
589-
sess.err(&format!(
590-
"error reading Clippy's configuration file. `{}` is not a valid Rust version",
591-
s
592-
));
593-
None
594-
})
595-
});
596-
619+
let msrv = conf.msrv.as_ref().and_then(|s| parse_msrv(s, None, None));
597620
let avoid_breaking_exported_api = conf.avoid_breaking_exported_api;
598621
store.register_late_pass(move || Box::new(approx_const::ApproxConstant::new(msrv)));
599622
store.register_late_pass(move || Box::new(methods::Methods::new(avoid_breaking_exported_api, msrv)));

0 commit comments

Comments
 (0)