@@ -50,11 +50,13 @@ extern crate rustc_typeck;
50
50
#[ macro_use]
51
51
extern crate clippy_utils;
52
52
53
- use cargo_metadata:: MetadataCommand ;
54
53
use clippy_utils:: parse_msrv;
55
54
use rustc_data_structures:: fx:: FxHashSet ;
56
55
use rustc_lint:: LintId ;
57
56
use rustc_session:: Session ;
57
+ use std:: fs:: File ;
58
+ use std:: io:: Read ;
59
+ use toml:: Value ;
58
60
59
61
/// Macro used to declare a Clippy lint.
60
62
///
@@ -444,6 +446,23 @@ pub fn register_pre_expansion_lints(store: &mut rustc_lint::LintStore, sess: &Se
444
446
store. register_pre_expansion_pass ( move || Box :: new ( attrs:: EarlyAttributes { msrv } ) ) ;
445
447
}
446
448
449
+ fn cargo_toml_msrv ( ) -> Option < String > {
450
+ if_chain ! {
451
+ if let Ok ( manifest_dir) = std:: env:: var( "CARGO_MANIFEST_DIR" ) ;
452
+ if let Ok ( mut file) = File :: open( format!( "{manifest_dir}/Cargo.toml" ) ) ;
453
+ let mut cargo_content_str = String :: new( ) ;
454
+ if let Ok ( _) = file. read_to_string( & mut cargo_content_str) ;
455
+ if let Ok ( cargo_content) = toml:: from_str:: <Value >( & cargo_content_str) ;
456
+ if let Some ( package) = cargo_content. get( "package" ) ;
457
+ if let Some ( rust_version) = package. get( "rust-version" ) ;
458
+ then {
459
+ rust_version. as_str( ) . map( str :: to_string)
460
+ } else {
461
+ None
462
+ }
463
+ }
464
+ }
465
+
447
466
#[ doc( hidden) ]
448
467
pub fn read_conf ( sess : & Session ) -> Conf {
449
468
let file_name = match utils:: conf:: lookup_conf_file ( ) {
@@ -459,23 +478,35 @@ pub fn read_conf(sess: &Session) -> Conf {
459
478
let TryConf { mut conf, errors } = utils:: conf:: read ( & file_name) ;
460
479
// all conf errors are non-fatal, we just use the default conf in case of error
461
480
for error in errors {
462
- sess. struct_err ( & format ! (
481
+ sess. err ( & format ! (
463
482
"error reading Clippy's configuration file `{}`: {}" ,
464
483
file_name. display( ) ,
465
484
error
466
- ) )
467
- . emit ( ) ;
485
+ ) ) ;
468
486
}
469
487
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 ) ) ) ;
488
+ let clippy_msrv = conf. msrv . as_ref ( ) . and_then ( |s| {
489
+ parse_msrv ( s, None , None ) . or_else ( || {
490
+ sess. err ( & format ! (
491
+ "error reading Clippy's configuration file. `{}` is not a valid Rust version" ,
492
+ s
493
+ ) ) ;
494
+ None
495
+ } )
496
+ } ) ;
497
+ if let Some ( cargo_msrv) = cargo_toml_msrv ( ) {
498
+ if let Some ( clippy_msrv) = clippy_msrv {
499
+ // if both files have an msrv, let's compare them and emit a warning if they differ
500
+ let cargo_msrv = parse_msrv ( & cargo_msrv, None , None ) . unwrap ( ) ; // cargo already check this for us
501
+ if clippy_msrv != cargo_msrv {
502
+ sess. warn ( & format ! (
503
+ "The MSRV in `clippy.toml` and `Cargo.toml` differ. Using `{}`" ,
504
+ clippy_msrv
505
+ ) ) ;
506
+ }
507
+ } else {
508
+ // assign msrv from cargo.toml if clippy.toml hasn't set one alreay
509
+ conf. msrv = Some ( cargo_msrv) ;
479
510
}
480
511
}
481
512
@@ -584,16 +615,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
584
615
store. register_late_pass ( || Box :: new ( non_octal_unix_permissions:: NonOctalUnixPermissions ) ) ;
585
616
store. register_early_pass ( || Box :: new ( unnecessary_self_imports:: UnnecessarySelfImports ) ) ;
586
617
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
-
618
+ let msrv = conf. msrv . as_ref ( ) . and_then ( |s| parse_msrv ( s, None , None ) ) ;
597
619
let avoid_breaking_exported_api = conf. avoid_breaking_exported_api ;
598
620
store. register_late_pass ( move || Box :: new ( approx_const:: ApproxConstant :: new ( msrv) ) ) ;
599
621
store. register_late_pass ( move || Box :: new ( methods:: Methods :: new ( avoid_breaking_exported_api, msrv) ) ) ;
0 commit comments