Remove all usages of match_path, match_qpath and match_path_ast except the author lint.

Add note to fix `MATCH_TYPE_ON_DIAG_ITEM`
Add false negative test for `uninit_assumed_init`
This commit is contained in:
Jason Newcomb
2021-04-07 16:19:25 -04:00
parent b1c675f3fc
commit f6c5d8d599
34 changed files with 271 additions and 337 deletions

View File

@@ -397,6 +397,29 @@ pub fn match_qpath(path: &QPath<'_>, segments: &[&str]) -> bool {
}
}
/// If the expression is a path, resolve it. Otherwise, return `Res::Err`.
pub fn expr_path_res(cx: &LateContext<'_>, expr: &Expr<'_>) -> Res {
if let ExprKind::Path(p) = &expr.kind {
cx.qpath_res(p, expr.hir_id)
} else {
Res::Err
}
}
/// Resolves the path to a `DefId` and checks if it matches the given path.
pub fn is_qpath_def_path(cx: &LateContext<'_>, path: &QPath<'_>, hir_id: HirId, segments: &[&str]) -> bool {
cx.qpath_res(path, hir_id)
.opt_def_id()
.map_or(false, |id| match_def_path(cx, id, segments))
}
/// If the expression is a path, resolves it to a `DefId` and checks if it matches the given path.
pub fn is_expr_path_def_path(cx: &LateContext<'_>, expr: &Expr<'_>, segments: &[&str]) -> bool {
expr_path_res(cx, expr)
.opt_def_id()
.map_or(false, |id| match_def_path(cx, id, segments))
}
/// THIS METHOD IS DEPRECATED and will eventually be removed since it does not match against the
/// entire path or resolved `DefId`. Prefer using `match_def_path`. Consider getting a `DefId` from
/// `QPath::Resolved.1.res.opt_def_id()`.
@@ -425,20 +448,6 @@ pub fn match_path(path: &Path<'_>, segments: &[&str]) -> bool {
.all(|(a, b)| a.ident.name.as_str() == *b)
}
/// Matches a `Path` against a slice of segment string literals, e.g.
///
/// # Examples
/// ```rust,ignore
/// match_path_ast(path, &["std", "rt", "begin_unwind"])
/// ```
pub fn match_path_ast(path: &ast::Path, segments: &[&str]) -> bool {
path.segments
.iter()
.rev()
.zip(segments.iter().rev())
.all(|(a, b)| a.ident.name.as_str() == *b)
}
/// If the expression is a path to a local, returns the canonical `HirId` of the local.
pub fn path_to_local(expr: &Expr<'_>) -> Option<HirId> {
if let ExprKind::Path(QPath::Resolved(None, ref path)) = expr.kind {
@@ -1148,29 +1157,47 @@ pub fn match_function_call<'tcx>(
None
}
pub fn match_def_path<'tcx>(cx: &LateContext<'tcx>, did: DefId, syms: &[&str]) -> bool {
// We have to convert `syms` to `&[Symbol]` here because rustc's `match_def_path`
// accepts only that. We should probably move to Symbols in Clippy as well.
let syms = syms.iter().map(|p| Symbol::intern(p)).collect::<Vec<Symbol>>();
cx.match_def_path(did, &syms)
/// Checks if the given `DefId` matches any of the paths. Returns the index of matching path, if
/// any.
pub fn match_any_def_paths(cx: &LateContext<'_>, did: DefId, paths: &[&[&str]]) -> Option<usize> {
let search_path = cx.get_def_path(did);
paths
.iter()
.position(|p| p.iter().map(|x| Symbol::intern(x)).eq(search_path.iter().cloned()))
}
pub fn match_panic_call<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx [Expr<'tcx>]> {
match_function_call(cx, expr, &paths::BEGIN_PANIC)
.or_else(|| match_function_call(cx, expr, &paths::BEGIN_PANIC_FMT))
.or_else(|| match_function_call(cx, expr, &paths::PANIC_ANY))
.or_else(|| match_function_call(cx, expr, &paths::PANICKING_PANIC))
.or_else(|| match_function_call(cx, expr, &paths::PANICKING_PANIC_FMT))
.or_else(|| match_function_call(cx, expr, &paths::PANICKING_PANIC_STR))
/// Checks if the given `DefId` matches the path.
pub fn match_def_path<'tcx>(cx: &LateContext<'tcx>, did: DefId, syms: &[&str]) -> bool {
// We should probably move to Symbols in Clippy as well rather than interning every time.
let path = cx.get_def_path(did);
syms.iter().map(|x| Symbol::intern(x)).eq(path.iter().cloned())
}
pub fn match_panic_call(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
if let ExprKind::Call(func, [arg]) = expr.kind {
expr_path_res(cx, func)
.opt_def_id()
.map_or(false, |id| match_panic_def_id(cx, id))
.then(|| arg)
} else {
None
}
}
pub fn match_panic_def_id(cx: &LateContext<'_>, did: DefId) -> bool {
match_def_path(cx, did, &paths::BEGIN_PANIC)
|| match_def_path(cx, did, &paths::BEGIN_PANIC_FMT)
|| match_def_path(cx, did, &paths::PANIC_ANY)
|| match_def_path(cx, did, &paths::PANICKING_PANIC)
|| match_def_path(cx, did, &paths::PANICKING_PANIC_FMT)
|| match_def_path(cx, did, &paths::PANICKING_PANIC_STR)
match_any_def_paths(
cx,
did,
&[
&paths::BEGIN_PANIC,
&paths::BEGIN_PANIC_FMT,
&paths::PANIC_ANY,
&paths::PANICKING_PANIC,
&paths::PANICKING_PANIC_FMT,
&paths::PANICKING_PANIC_STR,
],
)
.is_some()
}
/// Returns the list of condition expressions and the list of blocks in a

View File

@@ -4,7 +4,7 @@
//! Whenever possible, please consider diagnostic items over hardcoded paths.
//! See <https://github.com/rust-lang/rust-clippy/issues/5393> for more information.
pub const ANY_TRAIT: [&str; 3] = ["std", "any", "Any"];
pub const ANY_TRAIT: [&str; 3] = ["core", "any", "Any"];
pub const ARC_PTR_EQ: [&str; 4] = ["alloc", "sync", "Arc", "ptr_eq"];
pub const ASMUT_TRAIT: [&str; 3] = ["core", "convert", "AsMut"];
pub const ASREF_TRAIT: [&str; 3] = ["core", "convert", "AsRef"];
@@ -42,6 +42,8 @@ pub const FMT_ARGUMENTS_NEW_V1_FORMATTED: [&str; 4] = ["core", "fmt", "Arguments
pub const FMT_ARGUMENTV1_NEW: [&str; 4] = ["core", "fmt", "ArgumentV1", "new"];
pub const FROM_FROM: [&str; 4] = ["core", "convert", "From", "from"];
pub const FROM_ITERATOR: [&str; 5] = ["core", "iter", "traits", "collect", "FromIterator"];
pub const FROM_ITERATOR_METHOD: [&str; 6] = ["core", "iter", "traits", "collect", "FromIterator", "from_iter"];
pub const FROM_STR_METHOD: [&str; 5] = ["core", "str", "traits", "FromStr", "from_str"];
pub const FUTURE_FROM_GENERATOR: [&str; 3] = ["core", "future", "from_generator"];
pub const HASH: [&str; 3] = ["core", "hash", "Hash"];
pub const HASHMAP: [&str; 5] = ["std", "collections", "hash", "map", "HashMap"];
@@ -58,8 +60,9 @@ pub const INTO: [&str; 3] = ["core", "convert", "Into"];
pub const INTO_ITERATOR: [&str; 5] = ["core", "iter", "traits", "collect", "IntoIterator"];
pub const IO_READ: [&str; 3] = ["std", "io", "Read"];
pub const IO_WRITE: [&str; 3] = ["std", "io", "Write"];
pub const IPADDR_V4: [&str; 4] = ["std", "net", "IpAddr", "V4"];
pub const IPADDR_V6: [&str; 4] = ["std", "net", "IpAddr", "V6"];
pub const IPADDR_V4: [&str; 5] = ["std", "net", "ip", "IpAddr", "V4"];
pub const IPADDR_V6: [&str; 5] = ["std", "net", "ip", "IpAddr", "V6"];
pub const ITER_REPEAT: [&str; 5] = ["core", "iter", "sources", "repeat", "repeat"];
#[cfg(feature = "internal-lints")]
pub const KW_MODULE: [&str; 3] = ["rustc_span", "symbol", "kw"];
#[cfg(feature = "internal-lints")]
@@ -126,7 +129,6 @@ pub const REGEX_BYTES_NEW: [&str; 4] = ["regex", "re_bytes", "Regex", "new"];
pub const REGEX_BYTES_SET_NEW: [&str; 5] = ["regex", "re_set", "bytes", "RegexSet", "new"];
pub const REGEX_NEW: [&str; 4] = ["regex", "re_unicode", "Regex", "new"];
pub const REGEX_SET_NEW: [&str; 5] = ["regex", "re_set", "unicode", "RegexSet", "new"];
pub const REPEAT: [&str; 3] = ["core", "iter", "repeat"];
pub const RESULT: [&str; 3] = ["core", "result", "Result"];
pub const RESULT_ERR: [&str; 4] = ["core", "result", "Result", "Err"];
pub const RESULT_OK: [&str; 4] = ["core", "result", "Result", "Ok"];
@@ -140,7 +142,7 @@ pub const SLICE_INTO_VEC: [&str; 4] = ["alloc", "slice", "<impl [T]>", "into_vec
pub const SLICE_ITER: [&str; 4] = ["core", "slice", "iter", "Iter"];
pub const STDERR: [&str; 4] = ["std", "io", "stdio", "stderr"];
pub const STDOUT: [&str; 4] = ["std", "io", "stdio", "stdout"];
pub const STD_CONVERT_IDENTITY: [&str; 3] = ["std", "convert", "identity"];
pub const CONVERT_IDENTITY: [&str; 3] = ["core", "convert", "identity"];
pub const STD_FS_CREATE_DIR: [&str; 3] = ["std", "fs", "create_dir"];
pub const STRING_AS_MUT_STR: [&str; 4] = ["alloc", "string", "String", "as_mut_str"];
pub const STRING_AS_STR: [&str; 4] = ["alloc", "string", "String", "as_str"];