Skip to content

Commit

Permalink
Auto merge of #5590 - ebroto:issue_5579, r=phansch
Browse files Browse the repository at this point in the history
Fix ICE caused in unwrap module

changelog: Fix ICE in unwrap module with unexpected number of parameters for method of Option/Result

Fixes #5579
  • Loading branch information
bors committed May 14, 2020
2 parents b20a9cd + 8d1029d commit 7147068
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
12 changes: 10 additions & 2 deletions clippy_lints/src/unwrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, HirId, Path, QPath, UnO
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::map::Map;
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::Ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span;

Expand Down Expand Up @@ -90,6 +91,14 @@ fn collect_unwrap_info<'a, 'tcx>(
branch: &'tcx Expr<'_>,
invert: bool,
) -> Vec<UnwrapInfo<'tcx>> {
fn is_relevant_option_call(cx: &LateContext<'_, '_>, ty: Ty<'_>, method_name: &str) -> bool {
is_type_diagnostic_item(cx, ty, sym!(option_type)) && ["is_some", "is_none"].contains(&method_name)
}

fn is_relevant_result_call(cx: &LateContext<'_, '_>, ty: Ty<'_>, method_name: &str) -> bool {
is_type_diagnostic_item(cx, ty, sym!(result_type)) && ["is_ok", "is_err"].contains(&method_name)
}

if let ExprKind::Binary(op, left, right) = &expr.kind {
match (invert, op.node) {
(false, BinOpKind::And) | (false, BinOpKind::BitAnd) | (true, BinOpKind::Or) | (true, BinOpKind::BitOr) => {
Expand All @@ -106,9 +115,8 @@ fn collect_unwrap_info<'a, 'tcx>(
if let ExprKind::MethodCall(method_name, _, args) = &expr.kind;
if let ExprKind::Path(QPath::Resolved(None, path)) = &args[0].kind;
let ty = cx.tables.expr_ty(&args[0]);
if is_type_diagnostic_item(cx, ty, sym!(option_type)) || is_type_diagnostic_item(cx, ty, sym!(result_type));
let name = method_name.ident.as_str();
if ["is_some", "is_none", "is_ok", "is_err"].contains(&&*name);
if is_relevant_option_call(cx, ty, &name) || is_relevant_result_call(cx, ty, &name);
then {
assert!(args.len() == 1);
let unwrappable = match name.as_ref() {
Expand Down
17 changes: 17 additions & 0 deletions tests/ui/crashes/ice-5579.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
trait IsErr {
fn is_err(&self, err: &str) -> bool;
}

impl<T> IsErr for Option<T> {
fn is_err(&self, _err: &str) -> bool {
true
}
}

fn main() {
let t = Some(1);

if t.is_err("") {
t.unwrap();
}
}

0 comments on commit 7147068

Please sign in to comment.