Merge remote-tracking branch 'upstream/master' into rustup
This commit is contained in:
commit
4e6cf0036e
241 changed files with 4457 additions and 1730 deletions
|
|
@ -6,7 +6,8 @@ use serde::de::{Deserializer, IgnoredAny, IntoDeserializer, MapAccess, Visitor};
|
|||
use serde::Deserialize;
|
||||
use std::error::Error;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{env, fmt, fs, io};
|
||||
use std::str::FromStr;
|
||||
use std::{cmp, env, fmt, fs, io, iter};
|
||||
|
||||
/// Holds information used by `MISSING_ENFORCED_IMPORT_RENAMES` lint.
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
|
|
@ -43,18 +44,33 @@ pub enum DisallowedType {
|
|||
#[derive(Default)]
|
||||
pub struct TryConf {
|
||||
pub conf: Conf,
|
||||
pub errors: Vec<String>,
|
||||
pub errors: Vec<Box<dyn Error>>,
|
||||
}
|
||||
|
||||
impl TryConf {
|
||||
fn from_error(error: impl Error) -> Self {
|
||||
fn from_error(error: impl Error + 'static) -> Self {
|
||||
Self {
|
||||
conf: Conf::default(),
|
||||
errors: vec![error.to_string()],
|
||||
errors: vec![Box::new(error)],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ConfError(String);
|
||||
|
||||
impl fmt::Display for ConfError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
<String as fmt::Display>::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for ConfError {}
|
||||
|
||||
fn conf_error(s: String) -> Box<dyn Error> {
|
||||
Box::new(ConfError(s))
|
||||
}
|
||||
|
||||
macro_rules! define_Conf {
|
||||
($(
|
||||
$(#[doc = $doc:literal])+
|
||||
|
|
@ -103,11 +119,11 @@ macro_rules! define_Conf {
|
|||
while let Some(name) = map.next_key::<&str>()? {
|
||||
match Field::deserialize(name.into_deserializer())? {
|
||||
$(Field::$name => {
|
||||
$(errors.push(format!("deprecated field `{}`. {}", name, $dep));)?
|
||||
$(errors.push(conf_error(format!("deprecated field `{}`. {}", name, $dep)));)?
|
||||
match map.next_value() {
|
||||
Err(e) => errors.push(e.to_string()),
|
||||
Err(e) => errors.push(conf_error(e.to_string())),
|
||||
Ok(value) => match $name {
|
||||
Some(_) => errors.push(format!("duplicate field `{}`", name)),
|
||||
Some(_) => errors.push(conf_error(format!("duplicate field `{}`", name))),
|
||||
None => $name = Some(value),
|
||||
}
|
||||
}
|
||||
|
|
@ -316,6 +332,14 @@ define_Conf! {
|
|||
///
|
||||
/// The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes
|
||||
(max_include_file_size: u64 = 1_000_000),
|
||||
/// Lint: EXPECT_USED.
|
||||
///
|
||||
/// Whether `expect` should be allowed in test functions
|
||||
(allow_expect_in_tests: bool = false),
|
||||
/// Lint: UNWRAP_USED.
|
||||
///
|
||||
/// Whether `unwrap` should be allowed in test functions
|
||||
(allow_unwrap_in_tests: bool = false),
|
||||
}
|
||||
|
||||
/// Search for the configuration file.
|
||||
|
|
@ -375,3 +399,102 @@ pub fn read(path: &Path) -> TryConf {
|
|||
};
|
||||
toml::from_str(&content).unwrap_or_else(TryConf::from_error)
|
||||
}
|
||||
|
||||
const SEPARATOR_WIDTH: usize = 4;
|
||||
|
||||
// Check whether the error is "unknown field" and, if so, list the available fields sorted and at
|
||||
// least one per line, more if `CLIPPY_TERMINAL_WIDTH` is set and allows it.
|
||||
pub fn format_error(error: Box<dyn Error>) -> String {
|
||||
let s = error.to_string();
|
||||
|
||||
if_chain! {
|
||||
if error.downcast::<toml::de::Error>().is_ok();
|
||||
if let Some((prefix, mut fields, suffix)) = parse_unknown_field_message(&s);
|
||||
then {
|
||||
use fmt::Write;
|
||||
|
||||
fields.sort_unstable();
|
||||
|
||||
let (rows, column_widths) = calculate_dimensions(&fields);
|
||||
|
||||
let mut msg = String::from(prefix);
|
||||
for row in 0..rows {
|
||||
write!(msg, "\n").unwrap();
|
||||
for (column, column_width) in column_widths.iter().copied().enumerate() {
|
||||
let index = column * rows + row;
|
||||
let field = fields.get(index).copied().unwrap_or_default();
|
||||
write!(
|
||||
msg,
|
||||
"{:separator_width$}{:field_width$}",
|
||||
" ",
|
||||
field,
|
||||
separator_width = SEPARATOR_WIDTH,
|
||||
field_width = column_width
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
write!(msg, "\n{}", suffix).unwrap();
|
||||
msg
|
||||
} else {
|
||||
s
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// `parse_unknown_field_message` will become unnecessary if
|
||||
// https://github.com/alexcrichton/toml-rs/pull/364 is merged.
|
||||
fn parse_unknown_field_message(s: &str) -> Option<(&str, Vec<&str>, &str)> {
|
||||
// An "unknown field" message has the following form:
|
||||
// unknown field `UNKNOWN`, expected one of `FIELD0`, `FIELD1`, ..., `FIELDN` at line X column Y
|
||||
// ^^ ^^^^ ^^
|
||||
if_chain! {
|
||||
if s.starts_with("unknown field");
|
||||
let slices = s.split("`, `").collect::<Vec<_>>();
|
||||
let n = slices.len();
|
||||
if n >= 2;
|
||||
if let Some((prefix, first_field)) = slices[0].rsplit_once(" `");
|
||||
if let Some((last_field, suffix)) = slices[n - 1].split_once("` ");
|
||||
then {
|
||||
let fields = iter::once(first_field)
|
||||
.chain(slices[1..n - 1].iter().copied())
|
||||
.chain(iter::once(last_field))
|
||||
.collect::<Vec<_>>();
|
||||
Some((prefix, fields, suffix))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn calculate_dimensions(fields: &[&str]) -> (usize, Vec<usize>) {
|
||||
let columns = env::var("CLIPPY_TERMINAL_WIDTH")
|
||||
.ok()
|
||||
.and_then(|s| <usize as FromStr>::from_str(&s).ok())
|
||||
.map_or(1, |terminal_width| {
|
||||
let max_field_width = fields.iter().map(|field| field.len()).max().unwrap();
|
||||
cmp::max(1, terminal_width / (SEPARATOR_WIDTH + max_field_width))
|
||||
});
|
||||
|
||||
let rows = (fields.len() + (columns - 1)) / columns;
|
||||
|
||||
let column_widths = (0..columns)
|
||||
.map(|column| {
|
||||
if column < columns - 1 {
|
||||
(0..rows)
|
||||
.map(|row| {
|
||||
let index = column * rows + row;
|
||||
let field = fields.get(index).copied().unwrap_or_default();
|
||||
field.len()
|
||||
})
|
||||
.max()
|
||||
.unwrap()
|
||||
} else {
|
||||
// Avoid adding extra space to the last column.
|
||||
0
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
(rows, column_widths)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue