diff --git a/src/lib.rs b/src/lib.rs index a7fe2c1aab31..1088e4bc139a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -111,24 +111,30 @@ mod reexport { #[plugin_registrar] #[cfg_attr(rustfmt, rustfmt_skip)] pub fn plugin_registrar(reg: &mut Registry) { - let conferr = match utils::conf::conf_file(reg.args()) { - Ok(Some(file_name)) => { - utils::conf::read_conf(&file_name, true) - } - Ok(None) => { - utils::conf::read_conf("Clippy.toml", false) + let conf = match utils::conf::conf_file(reg.args()) { + Ok(file_name) => { + // if the user specified a file, it must exist, otherwise default to `Clippy.toml` but + // do not require the file to exist + let (ref file_name, must_exist) = if let Some(ref file_name) = file_name { + (&**file_name, true) + } else { + ("Clippy.toml", false) + }; + + let (conf, errors) = utils::conf::read_conf(&file_name, must_exist); + + // all conf errors are non-fatal, we just use the default conf in case of error + for error in errors { + reg.sess.struct_err(&format!("error reading Clippy's configuration file: {}", error)).emit(); + } + + conf } Err((err, span)) => { - reg.sess.struct_span_err(span, err).emit(); - return; - } - }; - - let conf = match conferr { - Ok(conf) => conf, - Err(err) => { - reg.sess.struct_err(&format!("error reading Clippy's configuration file: {}", err)).emit(); - return; + reg.sess.struct_span_err(span, err) + .span_note(span, "Clippy will use defaulf configuration") + .emit(); + utils::conf::Conf::default() } }; diff --git a/src/utils/conf.rs b/src/utils/conf.rs index 93caa1edca32..8c36570c8339 100644 --- a/src/utils/conf.rs +++ b/src/utils/conf.rs @@ -157,20 +157,28 @@ define_Conf! { /// Read the `toml` configuration file. The function will ignore “File not found” errors iif /// `!must_exist`, in which case, it will return the default configuration. -pub fn read_conf(path: &str, must_exist: bool) -> Result { +/// In case of error, the function tries to continue as much as possible. +pub fn read_conf(path: &str, must_exist: bool) -> (Conf, Vec) { let mut conf = Conf::default(); + let mut errors = Vec::new(); let file = match fs::File::open(path) { Ok(mut file) => { let mut buf = String::new(); - try!(file.read_to_string(&mut buf)); + + if let Err(err) = file.read_to_string(&mut buf) { + errors.push(err.into()); + return (conf, errors); + } + buf } Err(ref err) if !must_exist && err.kind() == io::ErrorKind::NotFound => { - return Ok(conf); + return (conf, errors); } Err(err) => { - return Err(err.into()); + errors.push(err.into()); + return (conf, errors); } }; @@ -178,12 +186,15 @@ pub fn read_conf(path: &str, must_exist: bool) -> Result { let toml = if let Some(toml) = parser.parse() { toml } else { - return Err(ConfError::TomlError(parser.errors)); + errors.push(ConfError::TomlError(parser.errors)); + return (conf, errors); }; for (key, value) in toml { - try!(conf.set(key, value)); + if let Err(err) = conf.set(key, value) { + errors.push(err); + } } - Ok(conf) + (conf, errors) }