Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clippy_lints/src/booleans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ fn simplify_not(cx: &LateContext<'_>, curr_msrv: Msrv, expr: &Expr<'_>) -> Optio
},
ExprKind::MethodCall(path, receiver, args, _) => {
let type_of_receiver = cx.typeck_results().expr_ty(receiver);
if !type_of_receiver.is_diag_item(cx, sym::Option) && !type_of_receiver.is_diag_item(cx, sym::Result) {
if !matches!(type_of_receiver.opt_diag_name(cx), Some(sym::Option | sym::Result)) {
return None;
}
METHODS_WITH_NEGATION
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/fallible_impl_from.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ fn lint_impl_body(cx: &LateContext<'_>, item_def_id: hir::OwnerId, impl_span: Sp
// check for `unwrap`
if let Some(arglists) = method_chain_args(expr, &[sym::unwrap]) {
let receiver_ty = self.typeck_results.expr_ty(arglists[0].0).peel_refs();
if receiver_ty.is_diag_item(self.lcx, sym::Option) || receiver_ty.is_diag_item(self.lcx, sym::Result) {
if matches!(receiver_ty.opt_diag_name(self.lcx), Some(sym::Option | sym::Result)) {
self.result.push(expr.span);
}
}
Expand Down
23 changes: 9 additions & 14 deletions clippy_lints/src/implicit_hasher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,25 +223,20 @@ impl<'tcx> ImplicitHasherType<'tcx> {
_ => None,
})
.collect();
let params_len = params.len();

let ty = lower_ty(cx.tcx, hir_ty);

if ty.is_diag_item(cx, sym::HashMap) && params_len == 2 {
Some(ImplicitHasherType::HashMap(
match (ty.opt_diag_name(cx), &params[..]) {
(Some(sym::HashMap), [k, v]) => Some(ImplicitHasherType::HashMap(
hir_ty.span,
ty,
snippet(cx, params[0].span, "K"),
snippet(cx, params[1].span, "V"),
))
} else if ty.is_diag_item(cx, sym::HashSet) && params_len == 1 {
Some(ImplicitHasherType::HashSet(
hir_ty.span,
ty,
snippet(cx, params[0].span, "T"),
))
} else {
None
snippet(cx, k.span, "K"),
snippet(cx, v.span, "V"),
)),
(Some(sym::HashSet), [t]) => {
Some(ImplicitHasherType::HashSet(hir_ty.span, ty, snippet(cx, t.span, "T")))
},
_ => None,
}
} else {
None
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/loops/for_kv_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx
_ => arg,
};

if ty.is_diag_item(cx, sym::HashMap) || ty.is_diag_item(cx, sym::BTreeMap) {
if matches!(ty.opt_diag_name(cx), Some(sym::HashMap | sym::BTreeMap)) {
span_lint_and_then(
cx,
FOR_KV_MAP,
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/manual_let_else.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ fn pat_allowed_for_else(cx: &LateContext<'_>, pat: &'_ Pat<'_>, check_types: boo
}
let ty = typeck_results.pat_ty(pat);
// Option and Result are allowed, everything else isn't.
if !(ty.is_diag_item(cx, sym::Option) || ty.is_diag_item(cx, sym::Result)) {
if !matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)) {
has_disallowed = true;
}
});
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/matches/match_wild_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
let ty = cx.typeck_results().expr_ty(ex).peel_refs();
let adt_def = match ty.kind() {
ty::Adt(adt_def, _)
if adt_def.is_enum() && !(ty.is_diag_item(cx, sym::Option) || ty.is_diag_item(cx, sym::Result)) =>
if adt_def.is_enum() && !matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)) =>
{
adt_def
},
Expand Down
10 changes: 4 additions & 6 deletions clippy_lints/src/methods/expect_fun_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,10 @@ pub(super) fn check<'tcx>(
let arg_root = get_arg_root(cx, arg);
if contains_call(cx, arg_root) && !contains_return(arg_root) {
let receiver_type = cx.typeck_results().expr_ty_adjusted(receiver);
let closure_args = if receiver_type.is_diag_item(cx, sym::Option) {
"||"
} else if receiver_type.is_diag_item(cx, sym::Result) {
"|_|"
} else {
return;
let closure_args = match receiver_type.opt_diag_name(cx) {
Some(sym::Option) => "||",
Some(sym::Result) => "|_|",
_ => return,
};

let span_replace_word = method_span.with_hi(expr.span.hi());
Expand Down
31 changes: 11 additions & 20 deletions clippy_lints/src/methods/iter_count.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,17 @@ use super::ITER_COUNT;

pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx Expr<'tcx>, iter_method: Symbol) {
let ty = cx.typeck_results().expr_ty(recv);
let caller_type = if derefs_to_slice(cx, recv, ty).is_some() {
"slice"
} else if ty.is_diag_item(cx, sym::Vec) {
"Vec"
} else if ty.is_diag_item(cx, sym::VecDeque) {
"VecDeque"
} else if ty.is_diag_item(cx, sym::HashSet) {
"HashSet"
} else if ty.is_diag_item(cx, sym::HashMap) {
"HashMap"
} else if ty.is_diag_item(cx, sym::BTreeMap) {
"BTreeMap"
} else if ty.is_diag_item(cx, sym::BTreeSet) {
"BTreeSet"
} else if ty.is_diag_item(cx, sym::LinkedList) {
"LinkedList"
} else if ty.is_diag_item(cx, sym::BinaryHeap) {
"BinaryHeap"
} else {
return;
let caller_type = match ty.opt_diag_name(cx) {
_ if derefs_to_slice(cx, recv, ty).is_some() => "slice",
Some(sym::Vec) => "Vec",
Some(sym::VecDeque) => "VecDeque",
Some(sym::HashSet) => "HashSet",
Some(sym::HashMap) => "HashMap",
Some(sym::BTreeMap) => "BTreeMap",
Some(sym::BTreeSet) => "BTreeSet",
Some(sym::LinkedList) => "LinkedList",
Some(sym::BinaryHeap) => "BinaryHeap",
_ => return,
};
let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg(
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/methods/iter_kv_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub(super) fn check<'tcx>(
_ => return,
}
&& let ty = cx.typeck_results().expr_ty_adjusted(recv).peel_refs()
&& (ty.is_diag_item(cx, sym::HashMap) || ty.is_diag_item(cx, sym::BTreeMap))
&& matches!(ty.opt_diag_name(cx), Some(sym::HashMap | sym::BTreeMap))
{
let mut applicability = rustc_errors::Applicability::MachineApplicable;
let recv_snippet = snippet_with_applicability(cx, recv.span, "map", &mut applicability);
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/methods/join_absolute_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use super::JOIN_ABSOLUTE_PATHS;

pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, recv: &'tcx Expr<'tcx>, join_arg: &'tcx Expr<'tcx>, expr_span: Span) {
let ty = cx.typeck_results().expr_ty(recv).peel_refs();
if (ty.is_diag_item(cx, sym::Path) || ty.is_diag_item(cx, sym::PathBuf))
if matches!(ty.opt_diag_name(cx), Some(sym::Path | sym::PathBuf))
&& let ExprKind::Lit(spanned) = expr_or_init(cx, join_arg).kind
&& let LitKind::Str(symbol, _) = spanned.node
&& let sym_str = symbol.as_str()
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/methods/map_clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn should_run_lint(cx: &LateContext<'_>, e: &hir::Expr<'_>, method_parent_id: De
}
// We check if it's an `Option` or a `Result`.
if let Some(ty) = method_parent_id.opt_impl_ty(cx) {
if !ty.is_diag_item(cx, sym::Option) && !ty.is_diag_item(cx, sym::Result) {
if !matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)) {
return false;
}
} else {
Expand Down
38 changes: 21 additions & 17 deletions clippy_lints/src/methods/or_then_unwrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,28 @@ pub(super) fn check<'tcx>(
let title;
let or_arg_content: Span;

if ty.is_diag_item(cx, sym::Option) {
title = "found `.or(Some(…)).unwrap()`";
if let Some(content) = get_content_if_ctor_matches(cx, or_arg, LangItem::OptionSome) {
or_arg_content = content;
} else {
match ty.opt_diag_name(cx) {
Some(sym::Option) => {
title = "found `.or(Some(…)).unwrap()`";
if let Some(content) = get_content_if_ctor_matches(cx, or_arg, LangItem::OptionSome) {
or_arg_content = content;
} else {
return;
}
},
Some(sym::Result) => {
title = "found `.or(Ok(…)).unwrap()`";
if let Some(content) = get_content_if_ctor_matches(cx, or_arg, LangItem::ResultOk) {
or_arg_content = content;
} else {
return;
}
},
_ => {
// Someone has implemented a struct with .or(...).unwrap() chaining,
// but it's not an Option or a Result, so bail
return;
}
} else if ty.is_diag_item(cx, sym::Result) {
title = "found `.or(Ok(…)).unwrap()`";
if let Some(content) = get_content_if_ctor_matches(cx, or_arg, LangItem::ResultOk) {
or_arg_content = content;
} else {
return;
}
} else {
// Someone has implemented a struct with .or(...).unwrap() chaining,
// but it's not an Option or a Result, so bail
return;
},
}

let mut applicability = Applicability::MachineApplicable;
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/methods/unnecessary_get_then_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ use rustc_span::{Span, sym};
use super::UNNECESSARY_GET_THEN_CHECK;

fn is_a_std_set_type(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
ty.is_diag_item(cx, sym::HashSet) || ty.is_diag_item(cx, sym::BTreeSet)
matches!(ty.opt_diag_name(cx), Some(sym::HashSet | sym::BTreeSet))
}

fn is_a_std_map_type(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
ty.is_diag_item(cx, sym::HashMap) || ty.is_diag_item(cx, sym::BTreeMap)
matches!(ty.opt_diag_name(cx), Some(sym::HashMap | sym::BTreeMap))
}

pub(super) fn check(
Expand Down
24 changes: 12 additions & 12 deletions clippy_lints/src/methods/unwrap_expect_used.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,19 @@ pub(super) fn check(
) {
let ty = cx.typeck_results().expr_ty(recv).peel_refs();

let (kind, none_value, none_prefix) = if ty.is_diag_item(cx, sym::Option) && !is_err {
("an `Option`", "None", "")
} else if ty.is_diag_item(cx, sym::Result)
&& let ty::Adt(_, substs) = ty.kind()
&& let Some(t_or_e_ty) = substs[usize::from(!is_err)].as_type()
{
if is_never_like(t_or_e_ty) {
return;
}
let (kind, none_value, none_prefix) = match ty.opt_diag_name(cx) {
Some(sym::Option) if !is_err => ("an `Option`", "None", ""),
Some(sym::Result)
if let ty::Adt(_, substs) = ty.kind()
&& let Some(t_or_e_ty) = substs[usize::from(!is_err)].as_type() =>
{
if is_never_like(t_or_e_ty) {
return;
}

("a `Result`", if is_err { "Ok" } else { "Err" }, "an ")
} else {
return;
("a `Result`", if is_err { "Ok" } else { "Err" }, "an ")
},
_ => return,
};

let method_suffix = if is_err { "_err" } else { "" };
Expand Down
12 changes: 8 additions & 4 deletions clippy_lints/src/missing_fields_in_debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,14 @@ fn should_lint<'tcx>(
if let ExprKind::MethodCall(path, recv, ..) = &expr.kind {
let recv_ty = typeck_results.expr_ty(recv).peel_refs();

if path.ident.name == sym::debug_struct && recv_ty.is_diag_item(cx, sym::Formatter) {
has_debug_struct = true;
} else if path.ident.name == sym::finish_non_exhaustive && recv_ty.is_diag_item(cx, sym::DebugStruct) {
has_finish_non_exhaustive = true;
match (path.ident.name, recv_ty.opt_diag_name(cx)) {
(sym::debug_struct, Some(sym::Formatter)) => {
has_debug_struct = true;
},
(sym::finish_non_exhaustive, Some(sym::DebugStruct)) => {
has_finish_non_exhaustive = true;
},
_ => {},
}
}
ControlFlow::<!, _>::Continue(())
Expand Down
16 changes: 8 additions & 8 deletions clippy_lints/src/time_subtraction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,19 +93,19 @@ impl LateLintPass<'_> for UncheckedTimeSubtraction {
) = expr.kind
{
let typeck = cx.typeck_results();
let lhs_ty = typeck.expr_ty(lhs);
let rhs_ty = typeck.expr_ty(rhs);
let lhs_name = typeck.expr_ty(lhs).opt_diag_name(cx);
let rhs_name = typeck.expr_ty(rhs).opt_diag_name(cx);

if lhs_ty.is_diag_item(cx, sym::Instant) {
if lhs_name == Some(sym::Instant) {
// Instant::now() - instant
if is_instant_now_call(cx, lhs)
&& rhs_ty.is_diag_item(cx, sym::Instant)
&& rhs_name == Some(sym::Instant)
&& let Some(sugg) = Sugg::hir_opt(cx, rhs)
{
print_manual_instant_elapsed_sugg(cx, expr, sugg);
}
// instant - duration
else if rhs_ty.is_diag_item(cx, sym::Duration)
else if rhs_name == Some(sym::Duration)
&& !expr.span.from_expansion()
&& self.msrv.meets(cx, msrvs::TRY_FROM)
{
Expand All @@ -122,8 +122,8 @@ impl LateLintPass<'_> for UncheckedTimeSubtraction {
print_unchecked_duration_subtraction_sugg(cx, lhs, rhs, expr);
}
}
} else if lhs_ty.is_diag_item(cx, sym::Duration)
&& rhs_ty.is_diag_item(cx, sym::Duration)
} else if lhs_name == Some(sym::Duration)
&& rhs_name == Some(sym::Duration)
&& !expr.span.from_expansion()
&& self.msrv.meets(cx, msrvs::TRY_FROM)
{
Expand Down Expand Up @@ -170,7 +170,7 @@ fn is_chained_time_subtraction(cx: &LateContext<'_>, lhs: &Expr<'_>) -> bool {

/// Returns true if the type is Duration or Instant
fn is_time_type(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
ty.is_diag_item(cx, sym::Duration) || ty.is_diag_item(cx, sym::Instant)
matches!(ty.opt_diag_name(cx), Some(sym::Duration | sym::Instant))
}

fn print_manual_instant_elapsed_sugg(cx: &LateContext<'_>, expr: &Expr<'_>, sugg: Sugg<'_>) {
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/zero_sized_map_values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl LateLintPass<'_> for ZeroSizedMapValues {
&& !in_trait_impl(cx, hir_ty.hir_id)
// We don't care about infer vars
&& let ty = ty_from_hir_ty(cx, hir_ty.as_unambig_ty())
&& (ty.is_diag_item(cx, sym::HashMap) || ty.is_diag_item(cx, sym::BTreeMap))
&& matches!(ty.opt_diag_name(cx), Some(sym::HashMap | sym::BTreeMap))
&& let ty::Adt(_, args) = ty.kind()
&& let ty = args.type_at(1)
// Ensure that no type information is missing, to avoid a delayed bug in the compiler if this is not the case.
Expand Down
1 change: 1 addition & 0 deletions clippy_lints_internal/src/internal_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub static TY_CTXT: PathLookup = type_path!(rustc_middle::ty::TyCtxt);

// Paths in clippy itself
pub static CLIPPY_SYM_MODULE: PathLookup = type_path!(clippy_utils::sym);
pub static MAYBE_DEF: PathLookup = type_path!(clippy_utils::res::MaybeDef);
pub static MSRV_STACK: PathLookup = type_path!(clippy_utils::msrvs::MsrvStack);
pub static PATH_LOOKUP_NEW: PathLookup = value_path!(clippy_utils::paths::PathLookup::new);
pub static SPAN_LINT_AND_THEN: PathLookup = value_path!(clippy_utils::diagnostics::span_lint_and_then);
2 changes: 2 additions & 0 deletions clippy_lints_internal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ mod lint_without_lint_pass;
mod msrv_attr_impl;
mod outer_expn_data_pass;
mod produce_ice;
mod repeated_is_diagnostic_item;
mod symbols;
mod unnecessary_def_path;
mod unsorted_clippy_utils_paths;
Expand Down Expand Up @@ -77,4 +78,5 @@ pub fn register_lints(store: &mut LintStore) {
store.register_late_pass(|_| Box::new(msrv_attr_impl::MsrvAttrImpl));
store.register_late_pass(|_| Box::new(almost_standard_lint_formulation::AlmostStandardFormulation::new()));
store.register_late_pass(|_| Box::new(unusual_names::UnusualNames));
store.register_late_pass(|_| Box::new(repeated_is_diagnostic_item::RepeatedIsDiagnosticItem));
}
Loading
Loading