Merge remote-tracking branch 'upstream/master' into rustup

This commit is contained in:
Philipp Krones 2023-10-21 13:22:39 +02:00
commit 5f031561ef
No known key found for this signature in database
GPG key ID: 1CA0DF2AF59D68A5
139 changed files with 2370 additions and 884 deletions

View file

@ -268,8 +268,8 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
fn qpath(&self, qpath: &Binding<&QPath<'_>>) {
if let QPath::LangItem(lang_item, ..) = *qpath.value {
chain!(self, "matches!({qpath}, QPath::LangItem(LangItem::{lang_item:?}, _))");
} else {
chain!(self, "match_qpath({qpath}, &[{}])", path_to_string(qpath.value));
} else if let Ok(path) = path_to_string(qpath.value) {
chain!(self, "match_qpath({qpath}, &[{}])", path);
}
}
@ -738,8 +738,8 @@ fn has_attr(cx: &LateContext<'_>, hir_id: hir::HirId) -> bool {
get_attr(cx.sess(), attrs, "author").count() > 0
}
fn path_to_string(path: &QPath<'_>) -> String {
fn inner(s: &mut String, path: &QPath<'_>) {
fn path_to_string(path: &QPath<'_>) -> Result<String, ()> {
fn inner(s: &mut String, path: &QPath<'_>) -> Result<(), ()> {
match *path {
QPath::Resolved(_, path) => {
for (i, segment) in path.segments.iter().enumerate() {
@ -751,16 +751,18 @@ fn path_to_string(path: &QPath<'_>) -> String {
},
QPath::TypeRelative(ty, segment) => match &ty.kind {
hir::TyKind::Path(inner_path) => {
inner(s, inner_path);
inner(s, inner_path)?;
*s += ", ";
write!(s, "{:?}", segment.ident.as_str()).unwrap();
},
other => write!(s, "/* unimplemented: {other:?}*/").unwrap(),
},
QPath::LangItem(..) => panic!("path_to_string: called for lang item qpath"),
QPath::LangItem(..) => return Err(()),
}
Ok(())
}
let mut s = String::new();
inner(&mut s, path);
s
inner(&mut s, path)?;
Ok(s)
}

View file

@ -8,8 +8,9 @@ use serde::de::{Deserializer, IgnoredAny, IntoDeserializer, MapAccess, Visitor};
use serde::Deserialize;
use std::fmt::{Debug, Display, Formatter};
use std::ops::Range;
use std::path::{Path, PathBuf};
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::OnceLock;
use std::{cmp, env, fmt, fs, io};
#[rustfmt::skip]
@ -78,62 +79,35 @@ pub struct TryConf {
impl TryConf {
fn from_toml_error(file: &SourceFile, error: &toml::de::Error) -> Self {
ConfError::from_toml(file, error).into()
}
}
impl From<ConfError> for TryConf {
fn from(value: ConfError) -> Self {
Self {
conf: Conf::default(),
errors: vec![value],
errors: vec![ConfError::from_toml(file, error)],
warnings: vec![],
}
}
}
impl From<io::Error> for TryConf {
fn from(value: io::Error) -> Self {
ConfError::from(value).into()
}
}
#[derive(Debug)]
pub struct ConfError {
pub message: String,
pub span: Option<Span>,
pub span: Span,
}
impl ConfError {
fn from_toml(file: &SourceFile, error: &toml::de::Error) -> Self {
if let Some(span) = error.span() {
Self::spanned(file, error.message(), span)
} else {
Self {
message: error.message().to_string(),
span: None,
}
}
let span = error.span().unwrap_or(0..file.source_len.0 as usize);
Self::spanned(file, error.message(), span)
}
fn spanned(file: &SourceFile, message: impl Into<String>, span: Range<usize>) -> Self {
Self {
message: message.into(),
span: Some(Span::new(
span: Span::new(
file.start_pos + BytePos::from_usize(span.start),
file.start_pos + BytePos::from_usize(span.end),
SyntaxContext::root(),
None,
)),
}
}
}
impl From<io::Error> for ConfError {
fn from(value: io::Error) -> Self {
Self {
message: value.to_string(),
span: None,
),
}
}
}
@ -297,7 +271,7 @@ define_Conf! {
/// 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.
///
/// The minimum rust version that the project supports
(msrv: Option<String> = None),
(msrv: crate::Msrv = crate::Msrv::empty()),
/// DEPRECATED LINT: BLACKLISTED_NAME.
///
/// Use the Disallowed Names lint instead
@ -360,6 +334,10 @@ define_Conf! {
///
/// The minimum number of enum variants for the lints about variant names to trigger
(enum_variant_name_threshold: u64 = 3),
/// Lint: STRUCT_VARIANT_NAMES.
///
/// The minimum number of struct fields for the lints about field names to trigger
(struct_field_name_threshold: u64 = 3),
/// Lint: LARGE_ENUM_VARIANT.
///
/// The maximum size of an enum's variant to avoid box suggestion
@ -641,15 +619,8 @@ pub fn lookup_conf_file() -> io::Result<(Option<PathBuf>, Vec<String>)> {
}
}
/// Read the `toml` configuration file.
///
/// In case of error, the function tries to continue as much as possible.
pub fn read(sess: &Session, path: &Path) -> TryConf {
let file = match sess.source_map().load_file(path) {
Err(e) => return e.into(),
Ok(file) => file,
};
match toml::de::Deserializer::new(file.src.as_ref().unwrap()).deserialize_map(ConfVisitor(&file)) {
fn deserialize(file: &SourceFile) -> TryConf {
match toml::de::Deserializer::new(file.src.as_ref().unwrap()).deserialize_map(ConfVisitor(file)) {
Ok(mut conf) => {
extend_vec_if_indicator_present(&mut conf.conf.doc_valid_idents, DEFAULT_DOC_VALID_IDENTS);
extend_vec_if_indicator_present(&mut conf.conf.disallowed_names, DEFAULT_DISALLOWED_NAMES);
@ -662,7 +633,7 @@ pub fn read(sess: &Session, path: &Path) -> TryConf {
conf
},
Err(e) => TryConf::from_toml_error(&file, &e),
Err(e) => TryConf::from_toml_error(file, &e),
}
}
@ -672,6 +643,60 @@ fn extend_vec_if_indicator_present(vec: &mut Vec<String>, default: &[&str]) {
}
}
impl Conf {
pub fn read(sess: &Session, path: &io::Result<(Option<PathBuf>, Vec<String>)>) -> &'static Conf {
static CONF: OnceLock<Conf> = OnceLock::new();
CONF.get_or_init(|| Conf::read_inner(sess, path))
}
fn read_inner(sess: &Session, path: &io::Result<(Option<PathBuf>, Vec<String>)>) -> Conf {
match path {
Ok((_, warnings)) => {
for warning in warnings {
sess.warn(warning.clone());
}
},
Err(error) => {
sess.err(format!("error finding Clippy's configuration file: {error}"));
},
}
let TryConf {
mut conf,
errors,
warnings,
} = match path {
Ok((Some(path), _)) => match sess.source_map().load_file(path) {
Ok(file) => deserialize(&file),
Err(error) => {
sess.err(format!("failed to read `{}`: {error}", path.display()));
TryConf::default()
},
},
_ => TryConf::default(),
};
conf.msrv.read_cargo(sess);
// all conf errors are non-fatal, we just use the default conf in case of error
for error in errors {
sess.span_err(
error.span,
format!("error reading Clippy's configuration file: {}", error.message),
);
}
for warning in warnings {
sess.span_warn(
warning.span,
format!("error reading Clippy's configuration file: {}", warning.message),
);
}
conf
}
}
const SEPARATOR_WIDTH: usize = 4;
#[derive(Debug)]

View file

@ -30,7 +30,7 @@ impl<'tcx> LateLintPass<'tcx> for IfChainStyle {
if_chain_local_span(cx, local, if_chain_span),
"`let` expression should be above the `if_chain!`",
);
} else if local.span.ctxt() == block.span.ctxt() && is_if_chain_then(after, block.expr, if_chain_span) {
} else if local.span.eq_ctxt(block.span) && is_if_chain_then(after, block.expr, if_chain_span) {
span_lint(
cx,
IF_CHAIN_STYLE,

View file

@ -13,6 +13,7 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::mir::ConstValue;
use rustc_middle::ty;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::sym;
use rustc_span::symbol::Symbol;
use std::borrow::Cow;
@ -160,12 +161,8 @@ impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol {
impl InterningDefinedSymbol {
fn symbol_str_expr<'tcx>(&self, expr: &'tcx Expr<'tcx>, cx: &LateContext<'tcx>) -> Option<SymbolStrExpr<'tcx>> {
static IDENT_STR_PATHS: &[&[&str]] = &[&paths::IDENT_AS_STR, &paths::TO_STRING_METHOD];
static SYMBOL_STR_PATHS: &[&[&str]] = &[
&paths::SYMBOL_AS_STR,
&paths::SYMBOL_TO_IDENT_STRING,
&paths::TO_STRING_METHOD,
];
static IDENT_STR_PATHS: &[&[&str]] = &[&paths::IDENT_AS_STR];
static SYMBOL_STR_PATHS: &[&[&str]] = &[&paths::SYMBOL_AS_STR, &paths::SYMBOL_TO_IDENT_STRING];
let call = if_chain! {
if let ExprKind::AddrOf(_, _, e) = expr.kind;
if let ExprKind::Unary(UnOp::Deref, e) = e.kind;
@ -186,9 +183,19 @@ impl InterningDefinedSymbol {
};
// ...which converts it to a string
let paths = if is_ident { IDENT_STR_PATHS } else { SYMBOL_STR_PATHS };
if let Some(path) = paths.iter().find(|path| match_def_path(cx, did, path));
if let Some(is_to_owned) = paths
.iter()
.find_map(|path| if match_def_path(cx, did, path) {
Some(path == &paths::SYMBOL_TO_IDENT_STRING)
} else {
None
})
.or_else(|| if cx.tcx.is_diagnostic_item(sym::to_string_method, did) {
Some(true)
} else {
None
});
then {
let is_to_owned = path.last().unwrap().ends_with("string");
return Some(SymbolStrExpr::Expr {
item,
is_ident,