Skip to content

Commit bef93d3

Browse files
committed
Auto merge of rust-lang#7962 - Jarcho:fix_match_type_on_diagnostic_items, r=llogiq
Fix and improve `match_type_on_diagnostic_item` This extracts the fix for the lint out of rust-lang#7647. There's still a couple of other functions to check, but at least this will get lint working again. The two added util functions (`is_diagnostic_item` and `is_lang_item`) are needed to handle `DefId` for unit and tuple struct/variant constructors. The `rustc_diagnostic_item` and `lang` attributes are attached to the struct/variant `DefId`, but most of the time they are used through their constructors which have a different `DefId`. The two utility functions will check if the `DefId` is for a constructor and switch to the associated struct/variant `DefId`. There does seem to be a bug on rustc's side where constructor `DefId`s from external crates seem to be returning `DefKind::Variant` instead of `DefKind::Ctor()`. There's a workaround put in right. changelog: None
2 parents 0341198 + 162aa19 commit bef93d3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+735
-374
lines changed

clippy_lints/src/await_holding_invalid.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_hir::{def::Res, AsyncGeneratorKind, Body, BodyId, GeneratorKind};
66
use rustc_lint::{LateContext, LateLintPass};
77
use rustc_middle::ty::GeneratorInteriorTypeCause;
88
use rustc_session::{declare_tool_lint, impl_lint_pass};
9-
use rustc_span::Span;
9+
use rustc_span::{sym, Span};
1010

1111
use crate::utils::conf::DisallowedType;
1212

@@ -276,9 +276,9 @@ fn emit_invalid_type(cx: &LateContext<'_>, span: Span, disallowed: &DisallowedTy
276276
}
277277

278278
fn is_mutex_guard(cx: &LateContext<'_>, def_id: DefId) -> bool {
279-
match_def_path(cx, def_id, &paths::MUTEX_GUARD)
280-
|| match_def_path(cx, def_id, &paths::RWLOCK_READ_GUARD)
281-
|| match_def_path(cx, def_id, &paths::RWLOCK_WRITE_GUARD)
279+
cx.tcx.is_diagnostic_item(sym::MutexGuard, def_id)
280+
|| cx.tcx.is_diagnostic_item(sym::RwLockReadGuard, def_id)
281+
|| cx.tcx.is_diagnostic_item(sym::RwLockWriteGuard, def_id)
282282
|| match_def_path(cx, def_id, &paths::PARKING_LOT_MUTEX_GUARD)
283283
|| match_def_path(cx, def_id, &paths::PARKING_LOT_RWLOCK_READ_GUARD)
284284
|| match_def_path(cx, def_id, &paths::PARKING_LOT_RWLOCK_WRITE_GUARD)

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/infinite_iter.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::span_lint;
2+
use clippy_utils::higher;
23
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
3-
use clippy_utils::{higher, match_def_path, path_def_id, paths};
44
use rustc_hir::{BorrowKind, Closure, Expr, ExprKind};
55
use rustc_lint::{LateContext, LateLintPass};
66
use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -168,9 +168,16 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
168168
},
169169
ExprKind::Block(block, _) => block.expr.as_ref().map_or(Finite, |e| is_infinite(cx, e)),
170170
ExprKind::Box(e) | ExprKind::AddrOf(BorrowKind::Ref, _, e) => is_infinite(cx, e),
171-
ExprKind::Call(path, _) => path_def_id(cx, path)
172-
.map_or(false, |id| match_def_path(cx, id, &paths::ITER_REPEAT))
173-
.into(),
171+
ExprKind::Call(path, _) => {
172+
if let ExprKind::Path(ref qpath) = path.kind {
173+
cx.qpath_res(qpath, path.hir_id)
174+
.opt_def_id()
175+
.map_or(false, |id| cx.tcx.is_diagnostic_item(sym::iter_repeat, id))
176+
.into()
177+
} else {
178+
Finite
179+
}
180+
},
174181
ExprKind::Struct(..) => higher::Range::hir(expr).map_or(false, |r| r.end.is_none()).into(),
175182
_ => Finite,
176183
}

clippy_lints/src/inherent_to_string.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::span_lint_and_help;
22
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
3-
use clippy_utils::{get_trait_def_id, paths, return_ty, trait_ref_of_method};
3+
use clippy_utils::{return_ty, trait_ref_of_method};
44
use if_chain::if_chain;
55
use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind};
66
use rustc_lint::{LateContext, LateLintPass};
@@ -118,7 +118,10 @@ impl<'tcx> LateLintPass<'tcx> for InherentToString {
118118
}
119119

120120
fn show_lint(cx: &LateContext<'_>, item: &ImplItem<'_>) {
121-
let display_trait_id = get_trait_def_id(cx, &paths::DISPLAY_TRAIT).expect("Failed to get trait ID of `Display`!");
121+
let display_trait_id = cx
122+
.tcx
123+
.get_diagnostic_item(sym::Display)
124+
.expect("Failed to get trait ID of `Display`!");
122125

123126
// Get the real type of 'self'
124127
let self_type = cx.tcx.fn_sig(item.def_id).input(0);

clippy_lints/src/lib.register_internal.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ store.register_group(true, "clippy::internal", Some("clippy_internal"), vec![
1313
LintId::of(utils::internal_lints::INVALID_CLIPPY_VERSION_ATTRIBUTE),
1414
LintId::of(utils::internal_lints::INVALID_PATHS),
1515
LintId::of(utils::internal_lints::LINT_WITHOUT_LINT_PASS),
16-
LintId::of(utils::internal_lints::MATCH_TYPE_ON_DIAGNOSTIC_ITEM),
1716
LintId::of(utils::internal_lints::MISSING_CLIPPY_VERSION_ATTRIBUTE),
1817
LintId::of(utils::internal_lints::MISSING_MSRV_ATTR_IMPL),
1918
LintId::of(utils::internal_lints::OUTER_EXPN_EXPN_DATA),
2019
LintId::of(utils::internal_lints::PRODUCE_ICE),
20+
LintId::of(utils::internal_lints::UNNECESSARY_DEF_PATH),
2121
LintId::of(utils::internal_lints::UNNECESSARY_SYMBOL_STR),
2222
])

clippy_lints/src/lib.register_lints.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ store.register_lints(&[
2424
#[cfg(feature = "internal")]
2525
utils::internal_lints::LINT_WITHOUT_LINT_PASS,
2626
#[cfg(feature = "internal")]
27-
utils::internal_lints::MATCH_TYPE_ON_DIAGNOSTIC_ITEM,
28-
#[cfg(feature = "internal")]
2927
utils::internal_lints::MISSING_CLIPPY_VERSION_ATTRIBUTE,
3028
#[cfg(feature = "internal")]
3129
utils::internal_lints::MISSING_MSRV_ATTR_IMPL,
@@ -34,6 +32,8 @@ store.register_lints(&[
3432
#[cfg(feature = "internal")]
3533
utils::internal_lints::PRODUCE_ICE,
3634
#[cfg(feature = "internal")]
35+
utils::internal_lints::UNNECESSARY_DEF_PATH,
36+
#[cfg(feature = "internal")]
3737
utils::internal_lints::UNNECESSARY_SYMBOL_STR,
3838
almost_complete_letter_range::ALMOST_COMPLETE_LETTER_RANGE,
3939
approx_const::APPROX_CONSTANT,

clippy_lints/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
535535
store.register_late_pass(|_| Box::new(utils::internal_lints::InvalidPaths));
536536
store.register_late_pass(|_| Box::<utils::internal_lints::InterningDefinedSymbol>::default());
537537
store.register_late_pass(|_| Box::<utils::internal_lints::LintWithoutLintPass>::default());
538-
store.register_late_pass(|_| Box::new(utils::internal_lints::MatchTypeOnDiagItem));
538+
store.register_late_pass(|_| Box::new(utils::internal_lints::UnnecessaryDefPath));
539539
store.register_late_pass(|_| Box::new(utils::internal_lints::OuterExpnDataPass));
540540
store.register_late_pass(|_| Box::new(utils::internal_lints::MsrvAttrImpl));
541541
}

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/manual_retain.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ fn check_into_iter(
9292
&& match_def_path(cx, filter_def_id, &paths::CORE_ITER_FILTER)
9393
&& let hir::ExprKind::MethodCall(_, struct_expr, [], _) = &into_iter_expr.kind
9494
&& let Some(into_iter_def_id) = cx.typeck_results().type_dependent_def_id(into_iter_expr.hir_id)
95-
&& match_def_path(cx, into_iter_def_id, &paths::CORE_ITER_INTO_ITER)
95+
&& cx.tcx.lang_items().require(hir::LangItem::IntoIterIntoIter).ok() == Some(into_iter_def_id)
9696
&& match_acceptable_type(cx, left_expr, msrv)
9797
&& SpanlessEq::new(cx).eq_expr(left_expr, struct_expr) {
9898
suggest(cx, parent_expr, left_expr, target_expr);

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();

0 commit comments

Comments
 (0)