@@ -8,8 +8,9 @@ use serde::de::{Deserializer, IgnoredAny, IntoDeserializer, MapAccess, Visitor};
8
8
use serde:: Deserialize ;
9
9
use std:: fmt:: { Debug , Display , Formatter } ;
10
10
use std:: ops:: Range ;
11
- use std:: path:: { Path , PathBuf } ;
11
+ use std:: path:: PathBuf ;
12
12
use std:: str:: FromStr ;
13
+ use std:: sync:: OnceLock ;
13
14
use std:: { cmp, env, fmt, fs, io} ;
14
15
15
16
#[ rustfmt:: skip]
@@ -78,62 +79,35 @@ pub struct TryConf {
78
79
79
80
impl TryConf {
80
81
fn from_toml_error ( file : & SourceFile , error : & toml:: de:: Error ) -> Self {
81
- ConfError :: from_toml ( file, error) . into ( )
82
- }
83
- }
84
-
85
- impl From < ConfError > for TryConf {
86
- fn from ( value : ConfError ) -> Self {
87
82
Self {
88
83
conf : Conf :: default ( ) ,
89
- errors : vec ! [ value ] ,
84
+ errors : vec ! [ ConfError :: from_toml ( file , error ) ] ,
90
85
warnings : vec ! [ ] ,
91
86
}
92
87
}
93
88
}
94
89
95
- impl From < io:: Error > for TryConf {
96
- fn from ( value : io:: Error ) -> Self {
97
- ConfError :: from ( value) . into ( )
98
- }
99
- }
100
-
101
90
#[ derive( Debug ) ]
102
91
pub struct ConfError {
103
92
pub message : String ,
104
- pub span : Option < Span > ,
93
+ pub span : Span ,
105
94
}
106
95
107
96
impl ConfError {
108
97
fn from_toml ( file : & SourceFile , error : & toml:: de:: Error ) -> Self {
109
- if let Some ( span) = error. span ( ) {
110
- Self :: spanned ( file, error. message ( ) , span)
111
- } else {
112
- Self {
113
- message : error. message ( ) . to_string ( ) ,
114
- span : None ,
115
- }
116
- }
98
+ let span = error. span ( ) . unwrap_or ( 0 ..file. source_len . 0 as usize ) ;
99
+ Self :: spanned ( file, error. message ( ) , span)
117
100
}
118
101
119
102
fn spanned ( file : & SourceFile , message : impl Into < String > , span : Range < usize > ) -> Self {
120
103
Self {
121
104
message : message. into ( ) ,
122
- span : Some ( Span :: new (
105
+ span : Span :: new (
123
106
file. start_pos + BytePos :: from_usize ( span. start ) ,
124
107
file. start_pos + BytePos :: from_usize ( span. end ) ,
125
108
SyntaxContext :: root ( ) ,
126
109
None ,
127
- ) ) ,
128
- }
129
- }
130
- }
131
-
132
- impl From < io:: Error > for ConfError {
133
- fn from ( value : io:: Error ) -> Self {
134
- Self {
135
- message : value. to_string ( ) ,
136
- span : None ,
110
+ ) ,
137
111
}
138
112
}
139
113
}
@@ -297,7 +271,7 @@ define_Conf! {
297
271
/// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD, MANUAL_HASH_ONE.
298
272
///
299
273
/// The minimum rust version that the project supports
300
- ( msrv: Option < String > = None ) ,
274
+ ( msrv: crate :: Msrv = crate :: Msrv :: new ( ) ) ,
301
275
/// DEPRECATED LINT: BLACKLISTED_NAME.
302
276
///
303
277
/// Use the Disallowed Names lint instead
@@ -641,14 +615,7 @@ pub fn lookup_conf_file() -> io::Result<(Option<PathBuf>, Vec<String>)> {
641
615
}
642
616
}
643
617
644
- /// Read the `toml` configuration file.
645
- ///
646
- /// In case of error, the function tries to continue as much as possible.
647
- pub fn read ( sess : & Session , path : & Path ) -> TryConf {
648
- let file = match sess. source_map ( ) . load_file ( path) {
649
- Err ( e) => return e. into ( ) ,
650
- Ok ( file) => file,
651
- } ;
618
+ fn deserialize ( file : & SourceFile ) -> TryConf {
652
619
match toml:: de:: Deserializer :: new ( file. src . as_ref ( ) . unwrap ( ) ) . deserialize_map ( ConfVisitor ( & file) ) {
653
620
Ok ( mut conf) => {
654
621
extend_vec_if_indicator_present ( & mut conf. conf . doc_valid_idents , DEFAULT_DOC_VALID_IDENTS ) ;
@@ -672,6 +639,60 @@ fn extend_vec_if_indicator_present(vec: &mut Vec<String>, default: &[&str]) {
672
639
}
673
640
}
674
641
642
+ impl Conf {
643
+ pub fn read ( sess : & Session , path : & io:: Result < ( Option < PathBuf > , Vec < String > ) > ) -> & ' static Conf {
644
+ static CONF : OnceLock < Conf > = OnceLock :: new ( ) ;
645
+ CONF . get_or_init ( || Conf :: read_inner ( sess, path) )
646
+ }
647
+
648
+ fn read_inner ( sess : & Session , path : & io:: Result < ( Option < PathBuf > , Vec < String > ) > ) -> Conf {
649
+ match path {
650
+ Ok ( ( _, warnings) ) => {
651
+ for warning in warnings {
652
+ sess. warn ( warning. clone ( ) ) ;
653
+ }
654
+ } ,
655
+ Err ( error) => {
656
+ sess. err ( format ! ( "error finding Clippy's configuration file: {error}" ) ) ;
657
+ } ,
658
+ }
659
+
660
+ let TryConf {
661
+ mut conf,
662
+ errors,
663
+ warnings,
664
+ } = match path {
665
+ Ok ( ( Some ( path) , _) ) => match sess. source_map ( ) . load_file ( path) {
666
+ Ok ( file) => deserialize ( & file) ,
667
+ Err ( error) => {
668
+ sess. err ( format ! ( "failed to read `{}`: {error}" , path. display( ) ) ) ;
669
+ TryConf :: default ( )
670
+ } ,
671
+ } ,
672
+ _ => TryConf :: default ( ) ,
673
+ } ;
674
+
675
+ conf. msrv . read_cargo ( sess) ;
676
+
677
+ // all conf errors are non-fatal, we just use the default conf in case of error
678
+ for error in errors {
679
+ sess. span_err (
680
+ error. span ,
681
+ format ! ( "error reading Clippy's configuration file: {}" , error. message) ,
682
+ ) ;
683
+ }
684
+
685
+ for warning in warnings {
686
+ sess. span_warn (
687
+ warning. span ,
688
+ format ! ( "error reading Clippy's configuration file: {}" , warning. message) ,
689
+ ) ;
690
+ }
691
+
692
+ conf
693
+ }
694
+ }
695
+
675
696
const SEPARATOR_WIDTH : usize = 4 ;
676
697
677
698
#[ derive( Debug ) ]
0 commit comments