mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-13 04:26:48 +00:00
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:
parent
b1c675f3fc
commit
f6c5d8d599
@ -127,10 +127,9 @@ fn match_assert_with_message<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>)
|
||||
_ => &block.expr,
|
||||
};
|
||||
// function call
|
||||
if let Some(args) = match_panic_call(cx, begin_panic_call);
|
||||
if args.len() == 1;
|
||||
if let Some(arg) = match_panic_call(cx, begin_panic_call);
|
||||
// bind the second argument of the `assert!` macro if it exists
|
||||
if let panic_message = snippet_opt(cx, args[0].span);
|
||||
if let panic_message = snippet_opt(cx, arg.span);
|
||||
// second argument of begin_panic is irrelevant
|
||||
// as is the second match arm
|
||||
then {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use clippy_utils::{in_macro, match_path_ast};
|
||||
use clippy_utils::in_macro;
|
||||
use rustc_ast::ast::{AssocItemKind, Extern, FnKind, FnSig, ImplKind, Item, ItemKind, TraitKind, Ty, TyKind};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
@ -126,7 +126,9 @@ impl_lint_pass!(ExcessiveBools => [STRUCT_EXCESSIVE_BOOLS, FN_PARAMS_EXCESSIVE_B
|
||||
|
||||
fn is_bool_ty(ty: &Ty) -> bool {
|
||||
if let TyKind::Path(None, path) = &ty.kind {
|
||||
return match_path_ast(path, &["bool"]);
|
||||
if let [name] = path.segments.as_slice() {
|
||||
return name.ident.name == sym::bool;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then};
|
||||
use clippy_utils::paths;
|
||||
use clippy_utils::source::{snippet, snippet_opt};
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::{differing_macro_contexts, match_path};
|
||||
use clippy_utils::{differing_macro_contexts, match_def_path};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for public `impl` or `fn` missing generalization
|
||||
@ -333,12 +333,13 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 't
|
||||
if let ExprKind::Call(fun, args) = e.kind;
|
||||
if let ExprKind::Path(QPath::TypeRelative(ty, method)) = fun.kind;
|
||||
if let TyKind::Path(QPath::Resolved(None, ty_path)) = ty.kind;
|
||||
if let Some(ty_did) = ty_path.res.opt_def_id();
|
||||
then {
|
||||
if !TyS::same_type(self.target.ty(), self.maybe_typeck_results.unwrap().expr_ty(e)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if match_path(ty_path, &paths::HASHMAP) {
|
||||
if match_def_path(self.cx, ty_did, &paths::HASHMAP) {
|
||||
if method.ident.name == sym::new {
|
||||
self.suggestions
|
||||
.insert(e.span, "HashMap::default()".to_string());
|
||||
@ -351,7 +352,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 't
|
||||
),
|
||||
);
|
||||
}
|
||||
} else if match_path(ty_path, &paths::HASHSET) {
|
||||
} else if match_def_path(self.cx, ty_did, &paths::HASHSET) {
|
||||
if method.ident.name == sym::new {
|
||||
self.suggestions
|
||||
.insert(e.span, "HashSet::default()".to_string());
|
||||
|
@ -1,9 +1,9 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::{in_macro, match_qpath, SpanlessEq};
|
||||
use clippy_utils::{in_macro, SpanlessEq};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind, QPath, StmtKind};
|
||||
use rustc_hir::{lang_items::LangItem, BinOpKind, Expr, ExprKind, QPath, StmtKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
|
||||
@ -87,7 +87,13 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
|
||||
|
||||
// Get the variable name
|
||||
let var_name = ares_path.segments[0].ident.name.as_str();
|
||||
const INT_TYPES: [&str; 5] = ["i8", "i16", "i32", "i64", "i128"];
|
||||
const INT_TYPES: [LangItem; 5] = [
|
||||
LangItem::I8,
|
||||
LangItem::I16,
|
||||
LangItem::I32,
|
||||
LangItem::I64,
|
||||
LangItem::Isize
|
||||
];
|
||||
|
||||
match cond_num_val.kind {
|
||||
ExprKind::Lit(ref cond_lit) => {
|
||||
@ -99,17 +105,30 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
|
||||
};
|
||||
}
|
||||
},
|
||||
ExprKind::Path(ref cond_num_path) => {
|
||||
if INT_TYPES.iter().any(|int_type| match_qpath(cond_num_path, &[int_type, "MIN"])) {
|
||||
print_lint_and_sugg(cx, &var_name, expr);
|
||||
};
|
||||
},
|
||||
ExprKind::Call(func, _) => {
|
||||
if let ExprKind::Path(ref cond_num_path) = func.kind {
|
||||
if INT_TYPES.iter().any(|int_type| match_qpath(cond_num_path, &[int_type, "min_value"])) {
|
||||
print_lint_and_sugg(cx, &var_name, expr);
|
||||
ExprKind::Path(QPath::TypeRelative(_, name)) => {
|
||||
if_chain! {
|
||||
if name.ident.as_str() == "MIN";
|
||||
if let Some(const_id) = cx.typeck_results().type_dependent_def_id(cond_num_val.hir_id);
|
||||
if let Some(impl_id) = cx.tcx.impl_of_method(const_id);
|
||||
let mut int_ids = INT_TYPES.iter().filter_map(|&ty| cx.tcx.lang_items().require(ty).ok());
|
||||
if int_ids.any(|int_id| int_id == impl_id);
|
||||
then {
|
||||
print_lint_and_sugg(cx, &var_name, expr)
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
ExprKind::Call(func, []) => {
|
||||
if_chain! {
|
||||
if let ExprKind::Path(QPath::TypeRelative(_, name)) = func.kind;
|
||||
if name.ident.as_str() == "min_value";
|
||||
if let Some(func_id) = cx.typeck_results().type_dependent_def_id(func.hir_id);
|
||||
if let Some(impl_id) = cx.tcx.impl_of_method(func_id);
|
||||
let mut int_ids = INT_TYPES.iter().filter_map(|&ty| cx.tcx.lang_items().require(ty).ok());
|
||||
if int_ids.any(|int_id| int_id == impl_id);
|
||||
then {
|
||||
print_lint_and_sugg(cx, &var_name, expr)
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::ty::{implements_trait, match_type};
|
||||
use clippy_utils::{get_trait_def_id, higher, match_qpath, paths};
|
||||
use clippy_utils::{get_trait_def_id, higher, is_qpath_def_path, paths};
|
||||
use rustc_hir::{BorrowKind, Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
@ -163,7 +163,7 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
|
||||
ExprKind::Box(e) | ExprKind::AddrOf(BorrowKind::Ref, _, e) => is_infinite(cx, e),
|
||||
ExprKind::Call(path, _) => {
|
||||
if let ExprKind::Path(ref qpath) = path.kind {
|
||||
match_qpath(qpath, &paths::REPEAT).into()
|
||||
is_qpath_def_path(cx, qpath, path.hir_id, &paths::ITER_REPEAT).into()
|
||||
} else {
|
||||
Finite
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::{is_adjusted, is_trait_method, match_path, match_var, paths, remove_blocks};
|
||||
use clippy_utils::{is_adjusted, is_qpath_def_path, is_trait_method, match_var, paths, remove_blocks};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Body, Expr, ExprKind, Pat, PatKind, QPath, StmtKind};
|
||||
@ -80,7 +80,7 @@ fn get_map_argument<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<&'a
|
||||
fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||
match expr.kind {
|
||||
ExprKind::Closure(_, _, body_id, _, _) => is_body_identity_function(cx, cx.tcx.hir().body(body_id)),
|
||||
ExprKind::Path(QPath::Resolved(_, path)) => match_path(path, &paths::STD_CONVERT_IDENTITY),
|
||||
ExprKind::Path(ref path) => is_qpath_def_path(cx, path, expr.hir_id, &paths::CONVERT_IDENTITY),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -1701,7 +1701,7 @@ mod redundant_pattern_match {
|
||||
use super::REDUNDANT_PATTERN_MATCHING;
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::{is_lang_ctor, is_trait_method, match_qpath, paths};
|
||||
use clippy_utils::{is_lang_ctor, is_qpath_def_path, is_trait_method, paths};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
@ -1735,8 +1735,8 @@ mod redundant_pattern_match {
|
||||
kind = &inner.kind;
|
||||
}
|
||||
let good_method = match kind {
|
||||
PatKind::TupleStruct(ref path, patterns, _) if patterns.len() == 1 => {
|
||||
if let PatKind::Wild = patterns[0].kind {
|
||||
PatKind::TupleStruct(ref path, [sub_pat], _) => {
|
||||
if let PatKind::Wild = sub_pat.kind {
|
||||
if is_lang_ctor(cx, path, ResultOk) {
|
||||
"is_ok()"
|
||||
} else if is_lang_ctor(cx, path, ResultErr) {
|
||||
@ -1745,9 +1745,9 @@ mod redundant_pattern_match {
|
||||
"is_some()"
|
||||
} else if is_lang_ctor(cx, path, PollReady) {
|
||||
"is_ready()"
|
||||
} else if match_qpath(path, &paths::IPADDR_V4) {
|
||||
} else if is_qpath_def_path(cx, path, sub_pat.hir_id, &paths::IPADDR_V4) {
|
||||
"is_ipv4()"
|
||||
} else if match_qpath(path, &paths::IPADDR_V6) {
|
||||
} else if is_qpath_def_path(cx, path, sub_pat.hir_id, &paths::IPADDR_V6) {
|
||||
"is_ipv6()"
|
||||
} else {
|
||||
return;
|
||||
@ -1821,6 +1821,7 @@ mod redundant_pattern_match {
|
||||
) if patterns_left.len() == 1 && patterns_right.len() == 1 => {
|
||||
if let (PatKind::Wild, PatKind::Wild) = (&patterns_left[0].kind, &patterns_right[0].kind) {
|
||||
find_good_method_for_match(
|
||||
cx,
|
||||
arms,
|
||||
path_left,
|
||||
path_right,
|
||||
@ -1831,6 +1832,7 @@ mod redundant_pattern_match {
|
||||
)
|
||||
.or_else(|| {
|
||||
find_good_method_for_match(
|
||||
cx,
|
||||
arms,
|
||||
path_left,
|
||||
path_right,
|
||||
@ -1850,6 +1852,7 @@ mod redundant_pattern_match {
|
||||
{
|
||||
if let PatKind::Wild = patterns[0].kind {
|
||||
find_good_method_for_match(
|
||||
cx,
|
||||
arms,
|
||||
path_left,
|
||||
path_right,
|
||||
@ -1860,6 +1863,7 @@ mod redundant_pattern_match {
|
||||
)
|
||||
.or_else(|| {
|
||||
find_good_method_for_match(
|
||||
cx,
|
||||
arms,
|
||||
path_left,
|
||||
path_right,
|
||||
@ -1900,7 +1904,9 @@ mod redundant_pattern_match {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn find_good_method_for_match<'a>(
|
||||
cx: &LateContext<'_>,
|
||||
arms: &[Arm<'_>],
|
||||
path_left: &QPath<'_>,
|
||||
path_right: &QPath<'_>,
|
||||
@ -1909,9 +1915,13 @@ mod redundant_pattern_match {
|
||||
should_be_left: &'a str,
|
||||
should_be_right: &'a str,
|
||||
) -> Option<&'a str> {
|
||||
let body_node_pair = if match_qpath(path_left, expected_left) && match_qpath(path_right, expected_right) {
|
||||
let body_node_pair = if is_qpath_def_path(cx, path_left, arms[0].pat.hir_id, expected_left)
|
||||
&& is_qpath_def_path(cx, path_right, arms[1].pat.hir_id, expected_right)
|
||||
{
|
||||
(&(*arms[0].body).kind, &(*arms[1].body).kind)
|
||||
} else if match_qpath(path_right, expected_left) && match_qpath(path_left, expected_right) {
|
||||
} else if is_qpath_def_path(cx, path_right, arms[1].pat.hir_id, expected_left)
|
||||
&& is_qpath_def_path(cx, path_left, arms[0].pat.hir_id, expected_right)
|
||||
{
|
||||
(&(*arms[1].body).kind, &(*arms[0].body).kind)
|
||||
} else {
|
||||
return None;
|
||||
|
@ -1,5 +1,5 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::{is_trait_method, match_qpath, path_to_local_id, paths};
|
||||
use clippy_utils::{is_expr_path_def_path, is_trait_method, path_to_local_id, paths};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
@ -33,14 +33,8 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, filter_map_arg:
|
||||
}
|
||||
}
|
||||
|
||||
if_chain! {
|
||||
if let hir::ExprKind::Path(ref qpath) = filter_map_arg.kind;
|
||||
|
||||
if match_qpath(qpath, &paths::STD_CONVERT_IDENTITY);
|
||||
|
||||
then {
|
||||
apply_lint("called `filter_map(std::convert::identity)` on an `Iterator`");
|
||||
}
|
||||
if is_expr_path_def_path(cx, filter_map_arg, &paths::CONVERT_IDENTITY) {
|
||||
apply_lint("called `filter_map(std::convert::identity)` on an `Iterator`");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::{is_trait_method, match_qpath, paths};
|
||||
use clippy_utils::{is_expr_path_def_path, is_trait_method, paths};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
@ -16,8 +16,6 @@ pub(super) fn check<'tcx>(
|
||||
flat_map_span: Span,
|
||||
) {
|
||||
if is_trait_method(cx, expr, sym::Iterator) {
|
||||
let arg_node = &flat_map_arg.kind;
|
||||
|
||||
let apply_lint = |message: &str| {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
@ -31,8 +29,8 @@ pub(super) fn check<'tcx>(
|
||||
};
|
||||
|
||||
if_chain! {
|
||||
if let hir::ExprKind::Closure(_, _, body_id, _, _) = arg_node;
|
||||
let body = cx.tcx.hir().body(*body_id);
|
||||
if let hir::ExprKind::Closure(_, _, body_id, _, _) = flat_map_arg.kind;
|
||||
let body = cx.tcx.hir().body(body_id);
|
||||
|
||||
if let hir::PatKind::Binding(_, _, binding_ident, _) = body.params[0].pat.kind;
|
||||
if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = body.value.kind;
|
||||
@ -45,14 +43,8 @@ pub(super) fn check<'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
if_chain! {
|
||||
if let hir::ExprKind::Path(ref qpath) = arg_node;
|
||||
|
||||
if match_qpath(qpath, &paths::STD_CONVERT_IDENTITY);
|
||||
|
||||
then {
|
||||
apply_lint("called `flat_map(std::convert::identity)` on an `Iterator`");
|
||||
}
|
||||
if is_expr_path_def_path(cx, flat_map_arg, &paths::CONVERT_IDENTITY) {
|
||||
apply_lint("called `flat_map(std::convert::identity)` on an `Iterator`");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +1,23 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::ty::implements_trait;
|
||||
use clippy_utils::{get_trait_def_id, match_qpath, paths, sugg};
|
||||
use clippy_utils::{is_expr_path_def_path, paths, sugg};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::ExprKind;
|
||||
use rustc_lint::{LateContext, LintContext};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::sym;
|
||||
|
||||
use super::FROM_ITER_INSTEAD_OF_COLLECT;
|
||||
|
||||
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>], func_kind: &ExprKind<'_>) {
|
||||
pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>], func: &hir::Expr<'_>) {
|
||||
if_chain! {
|
||||
if let hir::ExprKind::Path(path) = func_kind;
|
||||
if match_qpath(path, &["from_iter"]);
|
||||
if is_expr_path_def_path(cx, func, &paths::FROM_ITERATOR_METHOD);
|
||||
let ty = cx.typeck_results().expr_ty(expr);
|
||||
let arg_ty = cx.typeck_results().expr_ty(&args[0]);
|
||||
if let Some(from_iter_id) = get_trait_def_id(cx, &paths::FROM_ITERATOR);
|
||||
if let Some(iter_id) = cx.tcx.get_diagnostic_item(sym::Iterator);
|
||||
|
||||
if implements_trait(cx, ty, from_iter_id, &[]) && implements_trait(cx, arg_ty, iter_id, &[]);
|
||||
if implements_trait(cx, arg_ty, iter_id, &[]);
|
||||
then {
|
||||
// `expr` implements `FromIterator` trait
|
||||
let iter_expr = sugg::Sugg::hir(cx, &args[0], "..").maybe_par();
|
||||
|
@ -1,5 +1,5 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::match_qpath;
|
||||
use clippy_utils::is_qpath_def_path;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast;
|
||||
@ -94,11 +94,11 @@ fn is_min_or_max<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>) -> Option<M
|
||||
|
||||
// `std::T::MAX` `std::T::MIN` constants
|
||||
if let hir::ExprKind::Path(path) = &expr.kind {
|
||||
if match_qpath(path, &["core", &ty_str, "MAX"][..]) {
|
||||
if is_qpath_def_path(cx, path, expr.hir_id, &["core", &ty_str, "MAX"][..]) {
|
||||
return Some(MinMax::Max);
|
||||
}
|
||||
|
||||
if match_qpath(path, &["core", &ty_str, "MIN"][..]) {
|
||||
if is_qpath_def_path(cx, path, expr.hir_id, &["core", &ty_str, "MIN"][..]) {
|
||||
return Some(MinMax::Min);
|
||||
}
|
||||
}
|
||||
|
@ -1708,7 +1708,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
||||
|
||||
match expr.kind {
|
||||
hir::ExprKind::Call(func, args) => {
|
||||
from_iter_instead_of_collect::check(cx, expr, args, &func.kind);
|
||||
from_iter_instead_of_collect::check(cx, expr, args, func);
|
||||
},
|
||||
hir::ExprKind::MethodCall(method_call, ref method_span, args, _) => {
|
||||
or_fun_call::check(cx, expr, *method_span, &method_call.ident.as_str(), args);
|
||||
|
@ -1,5 +1,5 @@
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::{match_def_path, match_qpath, paths};
|
||||
use clippy_utils::{is_expr_path_def_path, match_def_path, paths};
|
||||
use if_chain::if_chain;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint::LateContext;
|
||||
@ -12,8 +12,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
|
||||
if_chain! {
|
||||
if let hir::ExprKind::Call(callee, args) = recv.kind;
|
||||
if args.is_empty();
|
||||
if let hir::ExprKind::Path(ref path) = callee.kind;
|
||||
if match_qpath(path, &paths::MEM_MAYBEUNINIT_UNINIT);
|
||||
if is_expr_path_def_path(cx, callee, &paths::MEM_MAYBEUNINIT_UNINIT);
|
||||
if !is_maybe_uninit_ty_valid(cx, cx.typeck_results().expr_ty_adjusted(expr));
|
||||
then {
|
||||
span_lint(
|
||||
|
@ -61,8 +61,6 @@ fn check_expression<'tcx>(cx: &LateContext<'tcx>, arg_id: hir::HirId, expr: &'tc
|
||||
}
|
||||
return (true, false);
|
||||
}
|
||||
// We don't know. It might do anything.
|
||||
return (true, true);
|
||||
}
|
||||
(true, true)
|
||||
},
|
||||
|
@ -20,8 +20,8 @@ use rustc_span::symbol::sym;
|
||||
use crate::consts::{constant, Constant};
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::{
|
||||
get_item_name, get_parent_expr, higher, in_constant, is_diag_trait_item, is_integer_const, iter_input_pats,
|
||||
last_path_segment, match_qpath, unsext, SpanlessEq,
|
||||
expr_path_res, get_item_name, get_parent_expr, higher, in_constant, is_diag_trait_item, is_integer_const,
|
||||
iter_input_pats, last_path_segment, match_any_def_paths, paths, unsext, SpanlessEq,
|
||||
};
|
||||
|
||||
declare_clippy_lint! {
|
||||
@ -564,13 +564,13 @@ fn check_to_owned(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left:
|
||||
}
|
||||
)
|
||||
},
|
||||
ExprKind::Call(path, v) if v.len() == 1 => {
|
||||
if let ExprKind::Path(ref path) = path.kind {
|
||||
if match_qpath(path, &["String", "from_str"]) || match_qpath(path, &["String", "from"]) {
|
||||
(cx.typeck_results().expr_ty(&v[0]), snippet(cx, v[0].span, ".."))
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
ExprKind::Call(path, [arg]) => {
|
||||
if expr_path_res(cx, path)
|
||||
.opt_def_id()
|
||||
.and_then(|id| match_any_def_paths(cx, id, &[&paths::FROM_STR_METHOD, &paths::FROM_FROM]))
|
||||
.is_some()
|
||||
{
|
||||
(cx.typeck_results().expr_ty(arg), snippet(cx, arg.span, ".."))
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_the
|
||||
use clippy_utils::ptr::get_spans;
|
||||
use clippy_utils::source::snippet_opt;
|
||||
use clippy_utils::ty::{is_type_diagnostic_item, match_type, walk_ptrs_hir_ty};
|
||||
use clippy_utils::{is_allowed, match_def_path, paths};
|
||||
use clippy_utils::{expr_path_res, is_allowed, match_any_def_paths, paths};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{
|
||||
@ -417,14 +417,11 @@ fn get_rptr_lm<'tcx>(ty: &'tcx Ty<'tcx>) -> Option<(&'tcx Lifetime, Mutability,
|
||||
}
|
||||
|
||||
fn is_null_path(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||
if_chain! {
|
||||
if let ExprKind::Call(path, []) = expr.kind;
|
||||
if let ExprKind::Path(ref qpath) = path.kind;
|
||||
if let Some(fn_def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id();
|
||||
then {
|
||||
match_def_path(cx, fn_def_id, &paths::PTR_NULL) || match_def_path(cx, fn_def_id, &paths::PTR_NULL_MUT)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
if let ExprKind::Call(pathexp, []) = expr.kind {
|
||||
expr_path_res(cx, pathexp).opt_def_id().map_or(false, |id| {
|
||||
match_any_def_paths(cx, id, &[&paths::PTR_NULL, &paths::PTR_NULL_MUT]).is_some()
|
||||
})
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,10 @@ use clippy_utils::is_lang_ctor;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::{eq_expr_value, match_qpath};
|
||||
use clippy_utils::{eq_expr_value, path_to_local_id};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::LangItem::OptionNone;
|
||||
use rustc_hir::LangItem::{OptionNone, OptionSome};
|
||||
use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, MatchSource, PatKind, StmtKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
@ -101,15 +101,14 @@ impl QuestionMark {
|
||||
if Self::is_option(cx, subject);
|
||||
|
||||
if let PatKind::TupleStruct(path1, fields, None) = &arms[0].pat.kind;
|
||||
if match_qpath(path1, &["Some"]);
|
||||
if let PatKind::Binding(annot, _, bind, _) = &fields[0].kind;
|
||||
if is_lang_ctor(cx, path1, OptionSome);
|
||||
if let PatKind::Binding(annot, bind_id, _, _) = fields[0].kind;
|
||||
let by_ref = matches!(annot, BindingAnnotation::Ref | BindingAnnotation::RefMut);
|
||||
|
||||
if let ExprKind::Block(block, None) = &arms[0].body.kind;
|
||||
if block.stmts.is_empty();
|
||||
if let Some(trailing_expr) = &block.expr;
|
||||
if let ExprKind::Path(path) = &trailing_expr.kind;
|
||||
if match_qpath(path, &[&bind.as_str()]);
|
||||
if path_to_local_id(trailing_expr, bind_id);
|
||||
|
||||
if let PatKind::Wild = arms[1].pat.kind;
|
||||
if Self::expression_returns_none(cx, arms[1].body);
|
||||
|
@ -1,6 +1,6 @@
|
||||
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
|
||||
use clippy_utils::source::snippet_opt;
|
||||
use clippy_utils::{fn_def_id, in_macro, match_qpath};
|
||||
use clippy_utils::{fn_def_id, in_macro, path_to_local_id};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::Attribute;
|
||||
use rustc_errors::Applicability;
|
||||
@ -84,9 +84,8 @@ impl<'tcx> LateLintPass<'tcx> for Return {
|
||||
if local.ty.is_none();
|
||||
if cx.tcx.hir().attrs(local.hir_id).is_empty();
|
||||
if let Some(initexpr) = &local.init;
|
||||
if let PatKind::Binding(.., ident, _) = local.pat.kind;
|
||||
if let ExprKind::Path(qpath) = &retexpr.kind;
|
||||
if match_qpath(qpath, &[&*ident.name.as_str()]);
|
||||
if let PatKind::Binding(_, local_id, _, _) = local.pat.kind;
|
||||
if path_to_local_id(retexpr, local_id);
|
||||
if !last_statement_borrows(cx, initexpr);
|
||||
if !in_external_macro(cx.sess(), initexpr.span);
|
||||
if !in_external_macro(cx.sess(), retexpr.span);
|
||||
|
@ -1,6 +1,7 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::{get_enclosing_block, match_qpath, SpanlessEq};
|
||||
use clippy_utils::ty::is_type_diagnostic_item;
|
||||
use clippy_utils::{get_enclosing_block, is_expr_path_def_path, path_to_local, path_to_local_id, paths, SpanlessEq};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::LitKind;
|
||||
use rustc_errors::Applicability;
|
||||
@ -9,7 +10,7 @@ use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, PatKind, QPath,
|
||||
use rustc_lint::{LateContext, LateLintPass, Lint};
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::symbol::sym;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks slow zero-filled vector initialization
|
||||
@ -46,8 +47,8 @@ declare_lint_pass!(SlowVectorInit => [SLOW_VECTOR_INITIALIZATION]);
|
||||
/// assigned to a variable. For example, `let mut vec = Vec::with_capacity(0)` or
|
||||
/// `vec = Vec::with_capacity(0)`
|
||||
struct VecAllocation<'tcx> {
|
||||
/// Symbol of the local variable name
|
||||
variable_name: Symbol,
|
||||
/// HirId of the variable
|
||||
local_id: HirId,
|
||||
|
||||
/// Reference to the expression which allocates the vector
|
||||
allocation_expr: &'tcx Expr<'tcx>,
|
||||
@ -72,16 +73,15 @@ impl<'tcx> LateLintPass<'tcx> for SlowVectorInit {
|
||||
if_chain! {
|
||||
if let ExprKind::Assign(left, right, _) = expr.kind;
|
||||
|
||||
// Extract variable name
|
||||
if let ExprKind::Path(QPath::Resolved(_, path)) = left.kind;
|
||||
if let Some(variable_name) = path.segments.get(0);
|
||||
// Extract variable
|
||||
if let Some(local_id) = path_to_local(left);
|
||||
|
||||
// Extract len argument
|
||||
if let Some(len_arg) = Self::is_vec_with_capacity(right);
|
||||
if let Some(len_arg) = Self::is_vec_with_capacity(cx, right);
|
||||
|
||||
then {
|
||||
let vi = VecAllocation {
|
||||
variable_name: variable_name.ident.name,
|
||||
local_id,
|
||||
allocation_expr: right,
|
||||
len_expr: len_arg,
|
||||
};
|
||||
@ -95,13 +95,13 @@ impl<'tcx> LateLintPass<'tcx> for SlowVectorInit {
|
||||
// Matches statements which initializes vectors. For example: `let mut vec = Vec::with_capacity(10)`
|
||||
if_chain! {
|
||||
if let StmtKind::Local(local) = stmt.kind;
|
||||
if let PatKind::Binding(BindingAnnotation::Mutable, .., variable_name, None) = local.pat.kind;
|
||||
if let PatKind::Binding(BindingAnnotation::Mutable, local_id, _, None) = local.pat.kind;
|
||||
if let Some(init) = local.init;
|
||||
if let Some(len_arg) = Self::is_vec_with_capacity(init);
|
||||
if let Some(len_arg) = Self::is_vec_with_capacity(cx, init);
|
||||
|
||||
then {
|
||||
let vi = VecAllocation {
|
||||
variable_name: variable_name.name,
|
||||
local_id,
|
||||
allocation_expr: init,
|
||||
len_expr: len_arg,
|
||||
};
|
||||
@ -115,19 +115,18 @@ impl<'tcx> LateLintPass<'tcx> for SlowVectorInit {
|
||||
impl SlowVectorInit {
|
||||
/// Checks if the given expression is `Vec::with_capacity(..)`. It will return the expression
|
||||
/// of the first argument of `with_capacity` call if it matches or `None` if it does not.
|
||||
fn is_vec_with_capacity<'tcx>(expr: &Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {
|
||||
fn is_vec_with_capacity<'tcx>(cx: &LateContext<'_>, expr: &Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {
|
||||
if_chain! {
|
||||
if let ExprKind::Call(func, args) = expr.kind;
|
||||
if let ExprKind::Path(ref path) = func.kind;
|
||||
if match_qpath(path, &["Vec", "with_capacity"]);
|
||||
if args.len() == 1;
|
||||
|
||||
if let ExprKind::Call(func, [arg]) = expr.kind;
|
||||
if let ExprKind::Path(QPath::TypeRelative(ty, name)) = func.kind;
|
||||
if name.ident.as_str() == "with_capacity";
|
||||
if is_type_diagnostic_item(cx, cx.typeck_results().node_type(ty.hir_id), sym::vec_type);
|
||||
then {
|
||||
return Some(&args[0]);
|
||||
Some(arg)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// Search initialization for the given vector
|
||||
@ -208,11 +207,9 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
|
||||
fn search_slow_extend_filling(&mut self, expr: &'tcx Expr<'_>) {
|
||||
if_chain! {
|
||||
if self.initialization_found;
|
||||
if let ExprKind::MethodCall(path, _, args, _) = expr.kind;
|
||||
if let ExprKind::Path(ref qpath_subj) = args[0].kind;
|
||||
if match_qpath(qpath_subj, &[&*self.vec_alloc.variable_name.as_str()]);
|
||||
if let ExprKind::MethodCall(path, _, [self_arg, extend_arg], _) = expr.kind;
|
||||
if path_to_local_id(self_arg, self.vec_alloc.local_id);
|
||||
if path.ident.name == sym!(extend);
|
||||
if let Some(extend_arg) = args.get(1);
|
||||
if self.is_repeat_take(extend_arg);
|
||||
|
||||
then {
|
||||
@ -225,11 +222,9 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
|
||||
fn search_slow_resize_filling(&mut self, expr: &'tcx Expr<'_>) {
|
||||
if_chain! {
|
||||
if self.initialization_found;
|
||||
if let ExprKind::MethodCall(path, _, args, _) = expr.kind;
|
||||
if let ExprKind::Path(ref qpath_subj) = args[0].kind;
|
||||
if match_qpath(qpath_subj, &[&*self.vec_alloc.variable_name.as_str()]);
|
||||
if let ExprKind::MethodCall(path, _, [self_arg, len_arg, fill_arg], _) = expr.kind;
|
||||
if path_to_local_id(self_arg, self.vec_alloc.local_id);
|
||||
if path.ident.name == sym!(resize);
|
||||
if let (Some(len_arg), Some(fill_arg)) = (args.get(1), args.get(2));
|
||||
|
||||
// Check that is filled with 0
|
||||
if let ExprKind::Lit(ref lit) = fill_arg.kind;
|
||||
@ -252,7 +247,7 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
|
||||
|
||||
// Check that take is applied to `repeat(0)`
|
||||
if let Some(repeat_expr) = take_args.get(0);
|
||||
if Self::is_repeat_zero(repeat_expr);
|
||||
if self.is_repeat_zero(repeat_expr);
|
||||
|
||||
// Check that len expression is equals to `with_capacity` expression
|
||||
if let Some(len_arg) = take_args.get(1);
|
||||
@ -267,21 +262,19 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
|
||||
}
|
||||
|
||||
/// Returns `true` if given expression is `repeat(0)`
|
||||
fn is_repeat_zero(expr: &Expr<'_>) -> bool {
|
||||
fn is_repeat_zero(&self, expr: &Expr<'_>) -> bool {
|
||||
if_chain! {
|
||||
if let ExprKind::Call(fn_expr, repeat_args) = expr.kind;
|
||||
if let ExprKind::Path(ref qpath_repeat) = fn_expr.kind;
|
||||
if match_qpath(qpath_repeat, &["repeat"]);
|
||||
if let Some(repeat_arg) = repeat_args.get(0);
|
||||
if let ExprKind::Call(fn_expr, [repeat_arg]) = expr.kind;
|
||||
if is_expr_path_def_path(self.cx, fn_expr, &paths::ITER_REPEAT);
|
||||
if let ExprKind::Lit(ref lit) = repeat_arg.kind;
|
||||
if let LitKind::Int(0, _) = lit.node;
|
||||
|
||||
then {
|
||||
return true
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::consts::{constant_context, Constant};
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::{match_def_path, paths};
|
||||
use clippy_utils::{is_expr_path_def_path, paths};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::LitKind;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
@ -37,18 +37,15 @@ impl<'tcx> LateLintPass<'tcx> for TransmutingNull {
|
||||
}
|
||||
|
||||
if_chain! {
|
||||
if let ExprKind::Call(func, args) = expr.kind;
|
||||
if args.len() == 1;
|
||||
if let ExprKind::Path(ref path) = func.kind;
|
||||
if let Some(func_def_id) = cx.qpath_res(path, func.hir_id).opt_def_id();
|
||||
if match_def_path(cx, func_def_id, &paths::TRANSMUTE);
|
||||
then {
|
||||
if let ExprKind::Call(func, [arg]) = expr.kind;
|
||||
if is_expr_path_def_path(cx, func, &paths::TRANSMUTE);
|
||||
|
||||
then {
|
||||
// Catching transmute over constants that resolve to `null`.
|
||||
let mut const_eval_context = constant_context(cx, cx.typeck_results());
|
||||
if_chain! {
|
||||
if let ExprKind::Path(ref _qpath) = args[0].kind;
|
||||
let x = const_eval_context.expr(&args[0]);
|
||||
if let ExprKind::Path(ref _qpath) = arg.kind;
|
||||
let x = const_eval_context.expr(arg);
|
||||
if let Some(Constant::RawPtr(0)) = x;
|
||||
then {
|
||||
span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG)
|
||||
@ -58,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for TransmutingNull {
|
||||
// Catching:
|
||||
// `std::mem::transmute(0 as *const i32)`
|
||||
if_chain! {
|
||||
if let ExprKind::Cast(inner_expr, _cast_ty) = args[0].kind;
|
||||
if let ExprKind::Cast(inner_expr, _cast_ty) = arg.kind;
|
||||
if let ExprKind::Lit(ref lit) = inner_expr.kind;
|
||||
if let LitKind::Int(0, _) = lit.node;
|
||||
then {
|
||||
@ -69,10 +66,8 @@ impl<'tcx> LateLintPass<'tcx> for TransmutingNull {
|
||||
// Catching:
|
||||
// `std::mem::transmute(std::ptr::null::<i32>())`
|
||||
if_chain! {
|
||||
if let ExprKind::Call(func1, []) = args[0].kind;
|
||||
if let ExprKind::Path(ref path1) = func1.kind;
|
||||
if let Some(func1_def_id) = cx.qpath_res(path1, func1.hir_id).opt_def_id();
|
||||
if match_def_path(cx, func1_def_id, &paths::PTR_NULL);
|
||||
if let ExprKind::Call(func1, []) = arg.kind;
|
||||
if is_expr_path_def_path(cx, func1, &paths::PTR_NULL);
|
||||
then {
|
||||
span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG)
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::{match_path, paths};
|
||||
use clippy_utils::{match_def_path, paths};
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{
|
||||
@ -28,7 +28,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
|
||||
_ => None,
|
||||
});
|
||||
then {
|
||||
if is_any_trait(inner) {
|
||||
if is_any_trait(cx, inner) {
|
||||
// Ignore `Box<Any>` types; see issue #1884 for details.
|
||||
return false;
|
||||
}
|
||||
@ -84,13 +84,14 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
|
||||
}
|
||||
|
||||
// Returns true if given type is `Any` trait.
|
||||
fn is_any_trait(t: &hir::Ty<'_>) -> bool {
|
||||
fn is_any_trait(cx: &LateContext<'_>, t: &hir::Ty<'_>) -> bool {
|
||||
if_chain! {
|
||||
if let TyKind::TraitObject(traits, ..) = t.kind;
|
||||
if !traits.is_empty();
|
||||
if let Some(trait_did) = traits[0].trait_ref.trait_def_id();
|
||||
// Only Send/Sync can be used as additional traits, so it is enough to
|
||||
// check only the first trait.
|
||||
if match_path(traits[0].trait_ref.path, &paths::ANY_TRAIT);
|
||||
if match_def_path(cx, trait_did, &paths::ANY_TRAIT);
|
||||
then {
|
||||
return true;
|
||||
}
|
||||
|
@ -104,14 +104,12 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
|
||||
if_chain! {
|
||||
if !in_macro(ret_expr.span);
|
||||
// Check if a function call.
|
||||
if let ExprKind::Call(func, args) = ret_expr.kind;
|
||||
// Get the Path of the function call.
|
||||
if let ExprKind::Path(ref qpath) = func.kind;
|
||||
if let ExprKind::Call(func, [arg]) = ret_expr.kind;
|
||||
// Check if OPTION_SOME or RESULT_OK, depending on return type.
|
||||
if let ExprKind::Path(qpath) = &func.kind;
|
||||
if is_lang_ctor(cx, qpath, lang_item);
|
||||
if args.len() == 1;
|
||||
// Make sure the function argument does not contain a return expression.
|
||||
if !contains_return(&args[0]);
|
||||
if !contains_return(arg);
|
||||
then {
|
||||
suggs.push(
|
||||
(
|
||||
@ -119,7 +117,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
|
||||
if inner_type.is_unit() {
|
||||
"".to_string()
|
||||
} else {
|
||||
snippet(cx, args[0].span.source_callsite(), "..").to_string()
|
||||
snippet(cx, arg.span.source_callsite(), "..").to_string()
|
||||
}
|
||||
)
|
||||
);
|
||||
|
@ -3,7 +3,8 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_sug
|
||||
use clippy_utils::source::snippet;
|
||||
use clippy_utils::ty::match_type;
|
||||
use clippy_utils::{
|
||||
is_else_clause, is_expn_of, match_def_path, match_qpath, method_calls, path_to_res, paths, run_lints, SpanlessEq,
|
||||
is_else_clause, is_expn_of, is_expr_path_def_path, match_def_path, method_calls, path_to_res, paths, run_lints,
|
||||
SpanlessEq,
|
||||
};
|
||||
use if_chain::if_chain;
|
||||
use rustc_ast::ast::{Crate as AstCrate, ItemKind, LitKind, ModKind, NodeId};
|
||||
@ -578,8 +579,7 @@ impl<'tcx> LateLintPass<'tcx> for CollapsibleCalls {
|
||||
|
||||
if_chain! {
|
||||
if let ExprKind::Call(func, and_then_args) = expr.kind;
|
||||
if let ExprKind::Path(ref path) = func.kind;
|
||||
if match_qpath(path, &["span_lint_and_then"]);
|
||||
if is_expr_path_def_path(cx, func, &["clippy_utils", "diagnostics", "span_lint_and_then"]);
|
||||
if and_then_args.len() == 5;
|
||||
if let ExprKind::Closure(_, _, body_id, _, _) = &and_then_args[4].kind;
|
||||
let body = cx.tcx.hir().body(*body_id);
|
||||
@ -761,8 +761,7 @@ impl<'tcx> LateLintPass<'tcx> for MatchTypeOnDiagItem {
|
||||
if_chain! {
|
||||
// Check if this is a call to utils::match_type()
|
||||
if let ExprKind::Call(fn_path, [context, ty, ty_path]) = expr.kind;
|
||||
if let ExprKind::Path(fn_qpath) = &fn_path.kind;
|
||||
if match_qpath(fn_qpath, &["utils", "match_type"]);
|
||||
if is_expr_path_def_path(cx, fn_path, &["clippy_utils", "ty", "match_type"]);
|
||||
// Extract the path to the matched type
|
||||
if let Some(segments) = path_to_matched_type(cx, ty_path);
|
||||
let segments: Vec<&str> = segments.iter().map(|sym| &**sym).collect();
|
||||
@ -771,6 +770,7 @@ impl<'tcx> LateLintPass<'tcx> for MatchTypeOnDiagItem {
|
||||
let diag_items = cx.tcx.diagnostic_items(ty_did.krate);
|
||||
if let Some(item_name) = diag_items.iter().find_map(|(k, v)| if *v == ty_did { Some(k) } else { None });
|
||||
then {
|
||||
// TODO: check paths constants from external crates.
|
||||
let cx_snippet = snippet(cx, context.span, "_");
|
||||
let ty_snippet = snippet(cx, ty.span, "_");
|
||||
|
||||
@ -778,9 +778,9 @@ impl<'tcx> LateLintPass<'tcx> for MatchTypeOnDiagItem {
|
||||
cx,
|
||||
MATCH_TYPE_ON_DIAGNOSTIC_ITEM,
|
||||
expr.span,
|
||||
"usage of `utils::match_type()` on a type diagnostic item",
|
||||
"usage of `clippy_utils::ty::match_type()` on a type diagnostic item",
|
||||
"try",
|
||||
format!("utils::is_type_diagnostic_item({}, {}, sym::{})", cx_snippet, ty_snippet, item_name),
|
||||
format!("clippy_utils::ty::is_type_diagnostic_item({}, {}, sym::{})", cx_snippet, ty_snippet, item_name),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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"];
|
||||
|
@ -625,7 +625,7 @@ in the following steps:
|
||||
Here are some pointers to things you are likely going to need for every lint:
|
||||
|
||||
* [Clippy utils][utils] - Various helper functions. Maybe the function you need
|
||||
is already in here (`implements_trait`, `match_path`, `snippet`, etc)
|
||||
is already in here (`implements_trait`, `match_def_path`, `snippet`, etc)
|
||||
* [Clippy diagnostics][diagnostics]
|
||||
* [The `if_chain` macro][if_chain]
|
||||
* [`from_expansion`][from_expansion] and [`in_external_macro`][in_external_macro]
|
||||
|
@ -2,58 +2,18 @@
|
||||
#![deny(clippy::internal)]
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate clippy_utils;
|
||||
extern crate rustc_ast;
|
||||
extern crate rustc_errors;
|
||||
extern crate rustc_lint;
|
||||
extern crate rustc_session;
|
||||
extern crate rustc_span;
|
||||
|
||||
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then};
|
||||
use rustc_ast::ast::Expr;
|
||||
use rustc_errors::{Applicability, DiagnosticBuilder};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, Lint, LintContext};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::source_map::Span;
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub fn span_lint_and_then<'a, T: LintContext, F>(cx: &'a T, lint: &'static Lint, sp: Span, msg: &str, f: F)
|
||||
where
|
||||
F: for<'b> FnOnce(&mut DiagnosticBuilder<'b>),
|
||||
{
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn span_lint_and_help<'a, T: LintContext>(
|
||||
cx: &'a T,
|
||||
lint: &'static Lint,
|
||||
span: Span,
|
||||
msg: &str,
|
||||
option_span: Option<Span>,
|
||||
help: &str,
|
||||
) {
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn span_lint_and_note<'a, T: LintContext>(
|
||||
cx: &'a T,
|
||||
lint: &'static Lint,
|
||||
span: Span,
|
||||
msg: &str,
|
||||
note_span: Option<Span>,
|
||||
note: &str,
|
||||
) {
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn span_lint_and_sugg<'a, T: LintContext>(
|
||||
cx: &'a T,
|
||||
lint: &'static Lint,
|
||||
sp: Span,
|
||||
msg: &str,
|
||||
help: &str,
|
||||
sugg: String,
|
||||
applicability: Applicability,
|
||||
) {
|
||||
}
|
||||
|
||||
declare_tool_lint! {
|
||||
pub clippy::TEST_LINT,
|
||||
|
@ -2,58 +2,18 @@
|
||||
#![deny(clippy::internal)]
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate clippy_utils;
|
||||
extern crate rustc_ast;
|
||||
extern crate rustc_errors;
|
||||
extern crate rustc_lint;
|
||||
extern crate rustc_session;
|
||||
extern crate rustc_span;
|
||||
|
||||
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then};
|
||||
use rustc_ast::ast::Expr;
|
||||
use rustc_errors::{Applicability, DiagnosticBuilder};
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass, Lint, LintContext};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_span::source_map::Span;
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub fn span_lint_and_then<'a, T: LintContext, F>(cx: &'a T, lint: &'static Lint, sp: Span, msg: &str, f: F)
|
||||
where
|
||||
F: for<'b> FnOnce(&mut DiagnosticBuilder<'b>),
|
||||
{
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn span_lint_and_help<'a, T: LintContext>(
|
||||
cx: &'a T,
|
||||
lint: &'static Lint,
|
||||
span: Span,
|
||||
msg: &str,
|
||||
option_span: Option<Span>,
|
||||
help: &str,
|
||||
) {
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn span_lint_and_note<'a, T: LintContext>(
|
||||
cx: &'a T,
|
||||
lint: &'static Lint,
|
||||
span: Span,
|
||||
msg: &str,
|
||||
note_span: Option<Span>,
|
||||
note: &str,
|
||||
) {
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn span_lint_and_sugg<'a, T: LintContext>(
|
||||
cx: &'a T,
|
||||
lint: &'static Lint,
|
||||
sp: Span,
|
||||
msg: &str,
|
||||
help: &str,
|
||||
sugg: String,
|
||||
applicability: Applicability,
|
||||
) {
|
||||
}
|
||||
|
||||
declare_tool_lint! {
|
||||
pub clippy::TEST_LINT,
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: this call is collapsible
|
||||
--> $DIR/collapsible_span_lint_calls.rs:75:9
|
||||
--> $DIR/collapsible_span_lint_calls.rs:35:9
|
||||
|
|
||||
LL | / span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
|
||||
LL | | db.span_suggestion(expr.span, help_msg, sugg.to_string(), Applicability::MachineApplicable);
|
||||
@ -14,7 +14,7 @@ LL | #![deny(clippy::internal)]
|
||||
= note: `#[deny(clippy::collapsible_span_lint_calls)]` implied by `#[deny(clippy::internal)]`
|
||||
|
||||
error: this call is collapsible
|
||||
--> $DIR/collapsible_span_lint_calls.rs:78:9
|
||||
--> $DIR/collapsible_span_lint_calls.rs:38:9
|
||||
|
|
||||
LL | / span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
|
||||
LL | | db.span_help(expr.span, help_msg);
|
||||
@ -22,7 +22,7 @@ LL | | });
|
||||
| |__________^ help: collapse into: `span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), help_msg)`
|
||||
|
||||
error: this call is collapsible
|
||||
--> $DIR/collapsible_span_lint_calls.rs:81:9
|
||||
--> $DIR/collapsible_span_lint_calls.rs:41:9
|
||||
|
|
||||
LL | / span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
|
||||
LL | | db.help(help_msg);
|
||||
@ -30,7 +30,7 @@ LL | | });
|
||||
| |__________^ help: collapse into: `span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, None, help_msg)`
|
||||
|
||||
error: this call is collspible
|
||||
--> $DIR/collapsible_span_lint_calls.rs:84:9
|
||||
--> $DIR/collapsible_span_lint_calls.rs:44:9
|
||||
|
|
||||
LL | / span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
|
||||
LL | | db.span_note(expr.span, note_msg);
|
||||
@ -38,7 +38,7 @@ LL | | });
|
||||
| |__________^ help: collapse into: `span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), note_msg)`
|
||||
|
||||
error: this call is collspible
|
||||
--> $DIR/collapsible_span_lint_calls.rs:87:9
|
||||
--> $DIR/collapsible_span_lint_calls.rs:47:9
|
||||
|
|
||||
LL | / span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
|
||||
LL | | db.note(note_msg);
|
||||
|
@ -1,29 +1,18 @@
|
||||
#![deny(clippy::internal)]
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate clippy_utils;
|
||||
extern crate rustc_hir;
|
||||
extern crate rustc_lint;
|
||||
extern crate rustc_middle;
|
||||
|
||||
#[macro_use]
|
||||
extern crate rustc_session;
|
||||
use clippy_utils::{paths, ty::match_type};
|
||||
use rustc_hir::Expr;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::Ty;
|
||||
|
||||
mod paths {
|
||||
pub const VEC: [&str; 3] = ["alloc", "vec", "Vec"];
|
||||
}
|
||||
|
||||
mod utils {
|
||||
use super::*;
|
||||
|
||||
pub fn match_type(_cx: &LateContext<'_>, _ty: Ty<'_>, _path: &[&str]) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
use utils::match_type;
|
||||
|
||||
declare_lint! {
|
||||
pub TEST_LINT,
|
||||
Warn,
|
||||
@ -38,12 +27,12 @@ impl<'tcx> LateLintPass<'tcx> for Pass {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr) {
|
||||
let ty = cx.typeck_results().expr_ty(expr);
|
||||
|
||||
let _ = match_type(cx, ty, &paths::VEC);
|
||||
let _ = match_type(cx, ty, &paths::VEC); // FIXME: Doesn't lint external paths
|
||||
let _ = match_type(cx, ty, &OPTION);
|
||||
let _ = match_type(cx, ty, &["core", "result", "Result"]);
|
||||
|
||||
let rc_path = &["alloc", "rc", "Rc"];
|
||||
let _ = utils::match_type(cx, ty, rc_path);
|
||||
let _ = clippy_utils::ty::match_type(cx, ty, rc_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: usage of `utils::match_type()` on a type diagnostic item
|
||||
--> $DIR/match_type_on_diag_item.rs:41:17
|
||||
error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item
|
||||
--> $DIR/match_type_on_diag_item.rs:31:17
|
||||
|
|
||||
LL | let _ = match_type(cx, ty, &paths::VEC);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `utils::is_type_diagnostic_item(cx, ty, sym::vec_type)`
|
||||
LL | let _ = match_type(cx, ty, &OPTION);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::option_type)`
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/match_type_on_diag_item.rs:1:9
|
||||
@ -11,23 +11,17 @@ LL | #![deny(clippy::internal)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
= note: `#[deny(clippy::match_type_on_diagnostic_item)]` implied by `#[deny(clippy::internal)]`
|
||||
|
||||
error: usage of `utils::match_type()` on a type diagnostic item
|
||||
--> $DIR/match_type_on_diag_item.rs:42:17
|
||||
|
|
||||
LL | let _ = match_type(cx, ty, &OPTION);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `utils::is_type_diagnostic_item(cx, ty, sym::option_type)`
|
||||
|
||||
error: usage of `utils::match_type()` on a type diagnostic item
|
||||
--> $DIR/match_type_on_diag_item.rs:43:17
|
||||
error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item
|
||||
--> $DIR/match_type_on_diag_item.rs:32:17
|
||||
|
|
||||
LL | let _ = match_type(cx, ty, &["core", "result", "Result"]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `utils::is_type_diagnostic_item(cx, ty, sym::result_type)`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::result_type)`
|
||||
|
||||
error: usage of `utils::match_type()` on a type diagnostic item
|
||||
--> $DIR/match_type_on_diag_item.rs:46:17
|
||||
error: usage of `clippy_utils::ty::match_type()` on a type diagnostic item
|
||||
--> $DIR/match_type_on_diag_item.rs:35:17
|
||||
|
|
||||
LL | let _ = utils::match_type(cx, ty, rc_path);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `utils::is_type_diagnostic_item(cx, ty, sym::Rc)`
|
||||
LL | let _ = clippy_utils::ty::match_type(cx, ty, rc_path);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clippy_utils::ty::is_type_diagnostic_item(cx, ty, sym::Rc)`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#![allow(deprecated, invalid_value)]
|
||||
#![warn(clippy::all)]
|
||||
#![allow(deprecated, invalid_value, clippy::uninit_assumed_init)]
|
||||
#![warn(clippy::mem_replace_with_uninit)]
|
||||
|
||||
use std::mem;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#![feature(stmt_expr_attributes)]
|
||||
|
||||
use std::mem::MaybeUninit;
|
||||
use std::mem::{self, MaybeUninit};
|
||||
|
||||
fn main() {
|
||||
let _: usize = unsafe { MaybeUninit::uninit().assume_init() };
|
||||
@ -19,4 +19,7 @@ fn main() {
|
||||
|
||||
// This is OK, because all constitutent types are uninit-compatible.
|
||||
let _: (MaybeUninit<usize>, [MaybeUninit<bool>; 2]) = unsafe { MaybeUninit::uninit().assume_init() };
|
||||
|
||||
// Was a false negative.
|
||||
let _: usize = unsafe { mem::MaybeUninit::uninit().assume_init() };
|
||||
}
|
||||
|
@ -12,5 +12,11 @@ error: this call for this type may be undefined behavior
|
||||
LL | let _: [u8; 0] = unsafe { MaybeUninit::uninit().assume_init() };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: this call for this type may be undefined behavior
|
||||
--> $DIR/uninit.rs:24:29
|
||||
|
|
||||
LL | let _: usize = unsafe { mem::MaybeUninit::uninit().assume_init() };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user