Skip to content

Commit 8e7af6b

Browse files
committed
Replace is_lang_ctor with is_res_lang_ctor
1 parent f8ba192 commit 8e7af6b

23 files changed

+205
-202
lines changed

clippy_lints/src/if_then_some_else_none.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use clippy_utils::diagnostics::span_lint_and_help;
22
use clippy_utils::eager_or_lazy::switch_to_eager_eval;
33
use clippy_utils::source::snippet_with_macro_callsite;
4-
use clippy_utils::{contains_return, higher, is_else_clause, is_lang_ctor, meets_msrv, msrvs, peel_blocks};
4+
use clippy_utils::{
5+
contains_return, higher, is_else_clause, is_res_lang_ctor, meets_msrv, msrvs, path_res, peel_blocks,
6+
};
57
use rustc_hir::LangItem::{OptionNone, OptionSome};
68
use rustc_hir::{Expr, ExprKind, Stmt, StmtKind};
79
use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -76,10 +78,8 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
7678
&& let ExprKind::Block(then_block, _) = then.kind
7779
&& let Some(then_expr) = then_block.expr
7880
&& let ExprKind::Call(then_call, [then_arg]) = then_expr.kind
79-
&& let ExprKind::Path(ref then_call_qpath) = then_call.kind
80-
&& is_lang_ctor(cx, then_call_qpath, OptionSome)
81-
&& let ExprKind::Path(ref qpath) = peel_blocks(els).kind
82-
&& is_lang_ctor(cx, qpath, OptionNone)
81+
&& is_res_lang_ctor(cx, path_res(cx, then_call), OptionSome)
82+
&& is_res_lang_ctor(cx, path_res(cx, peel_blocks(els)), OptionNone)
8383
&& !stmts_contains_early_return(then_block.stmts)
8484
{
8585
let cond_snip = snippet_with_macro_callsite(cx, cond.span, "[condition]");

clippy_lints/src/loops/manual_find.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::utils::make_iterator_snippet;
22
use super::MANUAL_FIND;
33
use clippy_utils::{
4-
diagnostics::span_lint_and_then, higher, is_lang_ctor, path_res, peel_blocks_with_stmt,
4+
diagnostics::span_lint_and_then, higher, is_res_lang_ctor, path_res, peel_blocks_with_stmt,
55
source::snippet_with_applicability, ty::implements_trait,
66
};
77
use if_chain::if_chain;
@@ -30,8 +30,8 @@ pub(super) fn check<'tcx>(
3030
if let [stmt] = block.stmts;
3131
if let StmtKind::Semi(semi) = stmt.kind;
3232
if let ExprKind::Ret(Some(ret_value)) = semi.kind;
33-
if let ExprKind::Call(Expr { kind: ExprKind::Path(ctor), .. }, [inner_ret]) = ret_value.kind;
34-
if is_lang_ctor(cx, ctor, LangItem::OptionSome);
33+
if let ExprKind::Call(ctor, [inner_ret]) = ret_value.kind;
34+
if is_res_lang_ctor(cx, path_res(cx, ctor), LangItem::OptionSome);
3535
if path_res(cx, inner_ret) == Res::Local(binding_id);
3636
if let Some((last_stmt, last_ret)) = last_stmt_and_ret(cx, expr);
3737
then {
@@ -143,8 +143,7 @@ fn last_stmt_and_ret<'tcx>(
143143
if let Some((_, Node::Block(block))) = parent_iter.next();
144144
if let Some((last_stmt, last_ret)) = extract(block);
145145
if last_stmt.hir_id == node_hir;
146-
if let ExprKind::Path(path) = &last_ret.kind;
147-
if is_lang_ctor(cx, path, LangItem::OptionNone);
146+
if is_res_lang_ctor(cx, path_res(cx, last_ret), LangItem::OptionNone);
148147
if let Some((_, Node::Expr(_block))) = parent_iter.next();
149148
// This includes the function header
150149
if let Some((_, func)) = parent_iter.next();

clippy_lints/src/loops/manual_flatten.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ use super::MANUAL_FLATTEN;
33
use clippy_utils::diagnostics::span_lint_and_then;
44
use clippy_utils::higher;
55
use clippy_utils::visitors::is_local_used;
6-
use clippy_utils::{is_lang_ctor, path_to_local_id, peel_blocks_with_stmt};
6+
use clippy_utils::{path_to_local_id, peel_blocks_with_stmt};
77
use if_chain::if_chain;
88
use rustc_errors::Applicability;
9-
use rustc_hir::LangItem::{OptionSome, ResultOk};
9+
use rustc_hir::def::{DefKind, Res};
1010
use rustc_hir::{Expr, Pat, PatKind};
1111
use rustc_lint::LateContext;
12-
use rustc_middle::ty;
12+
use rustc_middle::ty::{self, DefIdTree};
1313
use rustc_span::source_map::Span;
1414

1515
/// Check for unnecessary `if let` usage in a for loop where only the `Some` or `Ok` variant of the
@@ -30,8 +30,10 @@ pub(super) fn check<'tcx>(
3030
if path_to_local_id(let_expr, pat_hir_id);
3131
// Ensure the `if let` statement is for the `Some` variant of `Option` or the `Ok` variant of `Result`
3232
if let PatKind::TupleStruct(ref qpath, _, _) = let_pat.kind;
33-
let some_ctor = is_lang_ctor(cx, qpath, OptionSome);
34-
let ok_ctor = is_lang_ctor(cx, qpath, ResultOk);
33+
if let Res::Def(DefKind::Ctor(..), ctor_id) = cx.qpath_res(qpath, let_pat.hir_id);
34+
if let Some(variant_id) = cx.tcx.opt_parent(ctor_id);
35+
let some_ctor = cx.tcx.lang_items().option_some_variant() == Some(variant_id);
36+
let ok_ctor = cx.tcx.lang_items().result_ok_variant() == Some(variant_id);
3537
if some_ctor || ok_ctor;
3638
// Ensure expr in `if let` is not used afterwards
3739
if !is_local_used(cx, if_then, pat_hir_id);

clippy_lints/src/loops/while_let_on_iterator.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
33
use clippy_utils::higher;
44
use clippy_utils::source::snippet_with_applicability;
55
use clippy_utils::{
6-
get_enclosing_loop_or_multi_call_closure, is_refutable, is_trait_method, match_def_path, paths,
7-
visitors::is_res_used,
6+
get_enclosing_loop_or_multi_call_closure, is_refutable, is_res_lang_ctor, is_trait_method, visitors::is_res_used,
87
};
98
use if_chain::if_chain;
109
use rustc_errors::Applicability;
1110
use rustc_hir::intravisit::{walk_expr, Visitor};
12-
use rustc_hir::{def::Res, Closure, Expr, ExprKind, HirId, Local, Mutability, PatKind, QPath, UnOp};
11+
use rustc_hir::{def::Res, Closure, Expr, ExprKind, HirId, LangItem, Local, Mutability, PatKind, UnOp};
1312
use rustc_lint::LateContext;
1413
use rustc_middle::hir::nested_filter::OnlyBodies;
1514
use rustc_middle::ty::adjustment::Adjust;
@@ -19,9 +18,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
1918
let (scrutinee_expr, iter_expr_struct, iter_expr, some_pat, loop_expr) = if_chain! {
2019
if let Some(higher::WhileLet { if_then, let_pat, let_expr }) = higher::WhileLet::hir(expr);
2120
// check for `Some(..)` pattern
22-
if let PatKind::TupleStruct(QPath::Resolved(None, pat_path), some_pat, _) = let_pat.kind;
23-
if let Res::Def(_, pat_did) = pat_path.res;
24-
if match_def_path(cx, pat_did, &paths::OPTION_SOME);
21+
if let PatKind::TupleStruct(ref pat_path, some_pat, _) = let_pat.kind;
22+
if is_res_lang_ctor(cx, cx.qpath_res(pat_path, let_pat.hir_id), LangItem::OptionSome);
2523
// check for call to `Iterator::next`
2624
if let ExprKind::MethodCall(method_name, iter_expr, [], _) = let_expr.kind;
2725
if method_name.ident.name == sym::next;

clippy_lints/src/matches/collapsible_match.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use clippy_utils::diagnostics::span_lint_and_then;
22
use clippy_utils::higher::IfLetOrMatch;
33
use clippy_utils::visitors::is_local_used;
4-
use clippy_utils::{is_lang_ctor, is_unit_expr, path_to_local, peel_blocks_with_stmt, peel_ref_operators, SpanlessEq};
4+
use clippy_utils::{
5+
is_res_lang_ctor, is_unit_expr, path_to_local, peel_blocks_with_stmt, peel_ref_operators, SpanlessEq,
6+
};
57
use if_chain::if_chain;
68
use rustc_errors::MultiSpan;
79
use rustc_hir::LangItem::OptionNone;
@@ -110,7 +112,7 @@ fn arm_is_wild_like(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool {
110112
}
111113
match arm.pat.kind {
112114
PatKind::Binding(..) | PatKind::Wild => true,
113-
PatKind::Path(ref qpath) => is_lang_ctor(cx, qpath, OptionNone),
115+
PatKind::Path(ref qpath) => is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), OptionNone),
114116
_ => false,
115117
}
116118
}

clippy_lints/src/matches/manual_map.rs

+15-15
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
33
use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
44
use clippy_utils::ty::{is_type_diagnostic_item, peel_mid_ty_refs_is_mutable, type_is_unsafe_function};
55
use clippy_utils::{
6-
can_move_expr_to_closure, is_else_clause, is_lang_ctor, is_lint_allowed, path_to_local_id, peel_blocks,
7-
peel_hir_expr_refs, peel_hir_expr_while, CaptureKind,
6+
can_move_expr_to_closure, is_else_clause, is_lint_allowed, is_res_lang_ctor, path_res, path_to_local_id,
7+
peel_blocks, peel_hir_expr_refs, peel_hir_expr_while, CaptureKind,
88
};
99
use rustc_ast::util::parser::PREC_POSTFIX;
1010
use rustc_errors::Applicability;
@@ -251,9 +251,11 @@ fn try_parse_pattern<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, ctxt: Syn
251251
match pat.kind {
252252
PatKind::Wild => Some(OptionPat::Wild),
253253
PatKind::Ref(pat, _) => f(cx, pat, ref_count + 1, ctxt),
254-
PatKind::Path(ref qpath) if is_lang_ctor(cx, qpath, OptionNone) => Some(OptionPat::None),
254+
PatKind::Path(ref qpath) if is_res_lang_ctor(cx, cx.qpath_res(qpath, pat.hir_id), OptionNone) => {
255+
Some(OptionPat::None)
256+
},
255257
PatKind::TupleStruct(ref qpath, [pattern], _)
256-
if is_lang_ctor(cx, qpath, OptionSome) && pat.span.ctxt() == ctxt =>
258+
if is_res_lang_ctor(cx, cx.qpath_res(qpath, pat.hir_id), OptionSome) && pat.span.ctxt() == ctxt =>
257259
{
258260
Some(OptionPat::Some { pattern, ref_count })
259261
},
@@ -272,16 +274,14 @@ fn get_some_expr<'tcx>(
272274
) -> Option<SomeExpr<'tcx>> {
273275
// TODO: Allow more complex expressions.
274276
match expr.kind {
275-
ExprKind::Call(
276-
Expr {
277-
kind: ExprKind::Path(ref qpath),
278-
..
279-
},
280-
[arg],
281-
) if ctxt == expr.span.ctxt() && is_lang_ctor(cx, qpath, OptionSome) => Some(SomeExpr {
282-
expr: arg,
283-
needs_unsafe_block,
284-
}),
277+
ExprKind::Call(callee, [arg])
278+
if ctxt == expr.span.ctxt() && is_res_lang_ctor(cx, path_res(cx, callee), OptionSome) =>
279+
{
280+
Some(SomeExpr {
281+
expr: arg,
282+
needs_unsafe_block,
283+
})
284+
},
285285
ExprKind::Block(
286286
Block {
287287
stmts: [],
@@ -302,5 +302,5 @@ fn get_some_expr<'tcx>(
302302

303303
// Checks for the `None` value.
304304
fn is_none_expr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
305-
matches!(peel_blocks(expr).kind, ExprKind::Path(ref qpath) if is_lang_ctor(cx, qpath, OptionNone))
305+
is_res_lang_ctor(cx, path_res(cx, peel_blocks(expr)), OptionNone)
306306
}

clippy_lints/src/matches/manual_unwrap_or.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
33
use clippy_utils::source::{indent_of, reindent_multiline, snippet_opt};
44
use clippy_utils::ty::is_type_diagnostic_item;
55
use clippy_utils::usage::contains_return_break_continue_macro;
6-
use clippy_utils::{is_lang_ctor, path_to_local_id, sugg};
6+
use clippy_utils::{is_res_lang_ctor, path_to_local_id, sugg};
77
use if_chain::if_chain;
88
use rustc_errors::Applicability;
9-
use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
9+
use rustc_hir::def::{DefKind, Res};
10+
use rustc_hir::LangItem::{OptionNone, ResultErr};
1011
use rustc_hir::{Arm, Expr, PatKind};
1112
use rustc_lint::LateContext;
13+
use rustc_middle::ty::DefIdTree;
1214
use rustc_span::sym;
1315

1416
use super::MANUAL_UNWRAP_OR;
@@ -59,15 +61,19 @@ fn applicable_or_arm<'a>(cx: &LateContext<'_>, arms: &'a [Arm<'a>]) -> Option<&'
5961
if arms.iter().all(|arm| arm.guard.is_none());
6062
if let Some((idx, or_arm)) = arms.iter().enumerate().find(|(_, arm)| {
6163
match arm.pat.kind {
62-
PatKind::Path(ref qpath) => is_lang_ctor(cx, qpath, OptionNone),
64+
PatKind::Path(ref qpath) => is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), OptionNone),
6365
PatKind::TupleStruct(ref qpath, [pat], _) =>
64-
matches!(pat.kind, PatKind::Wild) && is_lang_ctor(cx, qpath, ResultErr),
66+
matches!(pat.kind, PatKind::Wild)
67+
&& is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), ResultErr),
6568
_ => false,
6669
}
6770
});
6871
let unwrap_arm = &arms[1 - idx];
6972
if let PatKind::TupleStruct(ref qpath, [unwrap_pat], _) = unwrap_arm.pat.kind;
70-
if is_lang_ctor(cx, qpath, OptionSome) || is_lang_ctor(cx, qpath, ResultOk);
73+
if let Res::Def(DefKind::Ctor(..), ctor_id) = cx.qpath_res(qpath, unwrap_arm.pat.hir_id);
74+
if let Some(variant_id) = cx.tcx.opt_parent(ctor_id);
75+
if cx.tcx.lang_items().option_some_variant() == Some(variant_id)
76+
|| cx.tcx.lang_items().result_ok_variant() == Some(variant_id);
7177
if let PatKind::Binding(_, binding_hir_id, ..) = unwrap_pat.kind;
7278
if path_to_local_id(unwrap_arm.body, binding_hir_id);
7379
if cx.typeck_results().expr_adjustments(unwrap_arm.body).is_empty();

clippy_lints/src/matches/match_as_ref.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::source::snippet_with_applicability;
3-
use clippy_utils::{is_lang_ctor, peel_blocks};
3+
use clippy_utils::{is_res_lang_ctor, path_res, peel_blocks};
44
use rustc_errors::Applicability;
55
use rustc_hir::{Arm, BindingAnnotation, ByRef, Expr, ExprKind, LangItem, Mutability, PatKind, QPath};
66
use rustc_lint::LateContext;
@@ -59,18 +59,20 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr:
5959

6060
// Checks if arm has the form `None => None`
6161
fn is_none_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool {
62-
matches!(arm.pat.kind, PatKind::Path(ref qpath) if is_lang_ctor(cx, qpath, LangItem::OptionNone))
62+
matches!(
63+
arm.pat.kind,
64+
PatKind::Path(ref qpath) if is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), LangItem::OptionNone)
65+
)
6366
}
6467

6568
// Checks if arm has the form `Some(ref v) => Some(v)` (checks for `ref` and `ref mut`)
6669
fn is_ref_some_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> Option<Mutability> {
6770
if_chain! {
6871
if let PatKind::TupleStruct(ref qpath, [first_pat, ..], _) = arm.pat.kind;
69-
if is_lang_ctor(cx, qpath, LangItem::OptionSome);
72+
if is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), LangItem::OptionSome);
7073
if let PatKind::Binding(BindingAnnotation(ByRef::Yes, mutabl), .., ident, _) = first_pat.kind;
7174
if let ExprKind::Call(e, [arg]) = peel_blocks(arm.body).kind;
72-
if let ExprKind::Path(ref some_path) = e.kind;
73-
if is_lang_ctor(cx, some_path, LangItem::OptionSome);
75+
if is_res_lang_ctor(cx, path_res(cx, e), LangItem::OptionSome);
7476
if let ExprKind::Path(QPath::Resolved(_, path2)) = arg.kind;
7577
if path2.segments.len() == 1 && ident.name == path2.segments[0].ident.name;
7678
then {

clippy_lints/src/matches/needless_match.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
33
use clippy_utils::source::snippet_with_applicability;
44
use clippy_utils::ty::{is_type_diagnostic_item, same_type_and_consts};
55
use clippy_utils::{
6-
eq_expr_value, get_parent_expr_for_hir, get_parent_node, higher, is_else_clause, is_lang_ctor, over,
6+
eq_expr_value, get_parent_expr_for_hir, get_parent_node, higher, is_else_clause, is_res_lang_ctor, over, path_res,
77
peel_blocks_with_stmt,
88
};
99
use rustc_errors::Applicability;
@@ -112,10 +112,7 @@ fn check_if_let_inner(cx: &LateContext<'_>, if_let: &higher::IfLet<'_>) -> bool
112112
let ret = strip_return(else_expr);
113113
let let_expr_ty = cx.typeck_results().expr_ty(if_let.let_expr);
114114
if is_type_diagnostic_item(cx, let_expr_ty, sym::Option) {
115-
if let ExprKind::Path(ref qpath) = ret.kind {
116-
return is_lang_ctor(cx, qpath, OptionNone) || eq_expr_value(cx, if_let.let_expr, ret);
117-
}
118-
return false;
115+
return is_res_lang_ctor(cx, path_res(cx, ret), OptionNone) || eq_expr_value(cx, if_let.let_expr, ret);
119116
}
120117
return eq_expr_value(cx, if_let.let_expr, ret);
121118
}

clippy_lints/src/matches/redundant_pattern_match.rs

+15-8
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ use clippy_utils::source::snippet;
44
use clippy_utils::sugg::Sugg;
55
use clippy_utils::ty::{is_type_diagnostic_item, needs_ordered_drop};
66
use clippy_utils::visitors::any_temporaries_need_ordered_drop;
7-
use clippy_utils::{higher, is_lang_ctor, is_trait_method};
7+
use clippy_utils::{higher, is_trait_method};
88
use if_chain::if_chain;
99
use rustc_ast::ast::LitKind;
1010
use rustc_errors::Applicability;
11+
use rustc_hir::def::{DefKind, Res};
1112
use rustc_hir::LangItem::{self, OptionNone, OptionSome, PollPending, PollReady, ResultErr, ResultOk};
1213
use rustc_hir::{Arm, Expr, ExprKind, Node, Pat, PatKind, QPath, UnOp};
1314
use rustc_lint::LateContext;
@@ -87,15 +88,21 @@ fn find_sugg_for_if_let<'tcx>(
8788
}
8889
},
8990
PatKind::Path(ref path) => {
90-
let method = if is_lang_ctor(cx, path, OptionNone) {
91-
"is_none()"
92-
} else if is_lang_ctor(cx, path, PollPending) {
93-
"is_pending()"
91+
if let Res::Def(DefKind::Ctor(..), ctor_id) = cx.qpath_res(path, check_pat.hir_id)
92+
&& let Some(variant_id) = cx.tcx.opt_parent(ctor_id)
93+
{
94+
let method = if cx.tcx.lang_items().option_none_variant() == Some(variant_id) {
95+
"is_none()"
96+
} else if cx.tcx.lang_items().poll_pending_variant() == Some(variant_id) {
97+
"is_pending()"
98+
} else {
99+
return;
100+
};
101+
// `None` and `Pending` don't have an inner type.
102+
(method, cx.tcx.types.unit)
94103
} else {
95104
return;
96-
};
97-
// `None` and `Pending` don't have an inner type.
98-
(method, cx.tcx.types.unit)
105+
}
99106
},
100107
_ => return,
101108
};

clippy_lints/src/matches/try_err.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::source::snippet_with_applicability;
33
use clippy_utils::ty::is_type_diagnostic_item;
4-
use clippy_utils::{get_parent_expr, is_lang_ctor, match_def_path, paths};
4+
use clippy_utils::{get_parent_expr, is_res_lang_ctor, match_def_path, path_res, paths};
55
use if_chain::if_chain;
66
use rustc_errors::Applicability;
77
use rustc_hir::LangItem::ResultErr;
@@ -27,8 +27,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, scrutine
2727
if let ExprKind::Path(ref match_fun_path) = match_fun.kind;
2828
if matches!(match_fun_path, QPath::LangItem(LangItem::TryTraitBranch, ..));
2929
if let ExprKind::Call(err_fun, [err_arg, ..]) = try_arg.kind;
30-
if let ExprKind::Path(ref err_fun_path) = err_fun.kind;
31-
if is_lang_ctor(cx, err_fun_path, ResultErr);
30+
if is_res_lang_ctor(cx, path_res(cx, err_fun), ResultErr);
3231
if let Some(return_ty) = find_return_type(cx, &expr.kind);
3332
then {
3433
let prefix;

0 commit comments

Comments
 (0)