Skip to content

Commit e4cd8e7

Browse files
committed
Fix ICE caused in unwrap module
1 parent b20a9cd commit e4cd8e7

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

clippy_lints/src/unwrap.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, HirId, Path, QPath, UnO
88
use rustc_lint::{LateContext, LateLintPass};
99
use rustc_middle::hir::map::Map;
1010
use rustc_middle::lint::in_external_macro;
11+
use rustc_middle::ty::Ty;
1112
use rustc_session::{declare_lint_pass, declare_tool_lint};
1213
use rustc_span::source_map::Span;
1314

@@ -90,6 +91,14 @@ fn collect_unwrap_info<'a, 'tcx>(
9091
branch: &'tcx Expr<'_>,
9192
invert: bool,
9293
) -> Vec<UnwrapInfo<'tcx>> {
94+
fn is_relevant_option_call(cx: &LateContext<'_, '_>, ty: Ty<'_>, method_name: &str) -> bool {
95+
is_type_diagnostic_item(cx, ty, sym!(option_type)) && ["is_some", "is_none"].contains(&method_name)
96+
}
97+
98+
fn is_relevant_result_call(cx: &LateContext<'_, '_>, ty: Ty<'_>, method_name: &str) -> bool {
99+
is_type_diagnostic_item(cx, ty, sym!(result_type)) && ["is_ok", "is_err"].contains(&method_name)
100+
}
101+
93102
if let ExprKind::Binary(op, left, right) = &expr.kind {
94103
match (invert, op.node) {
95104
(false, BinOpKind::And) | (false, BinOpKind::BitAnd) | (true, BinOpKind::Or) | (true, BinOpKind::BitOr) => {
@@ -106,9 +115,8 @@ fn collect_unwrap_info<'a, 'tcx>(
106115
if let ExprKind::MethodCall(method_name, _, args) = &expr.kind;
107116
if let ExprKind::Path(QPath::Resolved(None, path)) = &args[0].kind;
108117
let ty = cx.tables.expr_ty(&args[0]);
109-
if is_type_diagnostic_item(cx, ty, sym!(option_type)) || is_type_diagnostic_item(cx, ty, sym!(result_type));
110118
let name = method_name.ident.as_str();
111-
if ["is_some", "is_none", "is_ok", "is_err"].contains(&&*name);
119+
if is_relevant_option_call(cx, ty, &name) || is_relevant_result_call(cx, ty, &name);
112120
then {
113121
assert!(args.len() == 1);
114122
let unwrappable = match name.as_ref() {

tests/ui/checked_unwrap/simple_conditionals.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,24 @@ fn main() {
7878

7979
assert!(x.is_ok(), "{:?}", x.unwrap_err()); // ok, it's a common test pattern
8080
}
81+
82+
mod issue_5579 {
83+
trait IsErr {
84+
fn is_err(&self, err: &str) -> bool;
85+
}
86+
87+
impl<T> IsErr for Option<T> {
88+
fn is_err(&self, _err: &str) -> bool {
89+
true
90+
}
91+
}
92+
93+
#[allow(unused)]
94+
fn boom() {
95+
let t = Some(1);
96+
97+
if t.is_err("") {
98+
t.unwrap();
99+
}
100+
}
101+
}

0 commit comments

Comments
 (0)