Skip to content

Commit

Permalink
Auto merge of #4446 - mikerite:fix-4437, r=phansch
Browse files Browse the repository at this point in the history
Fix `match_as_ref` bad suggestion

Fixes #4437

changelog: Fix `match_as_ref` bad suggestion
  • Loading branch information
bors committed Aug 30, 2019
2 parents 28a8a6a + 0c83325 commit 2bff3d8
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 3 deletions.
23 changes: 21 additions & 2 deletions clippy_lints/src/matches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,24 @@ fn check_match_as_ref(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &
} else {
"as_mut"
};

let output_ty = cx.tables.expr_ty(expr);
let input_ty = cx.tables.expr_ty(ex);

let cast = if_chain! {
if let ty::Adt(_, substs) = input_ty.sty;
let input_ty = substs.type_at(0);
if let ty::Adt(_, substs) = output_ty.sty;
let output_ty = substs.type_at(0);
if let ty::Ref(_, output_ty, _) = output_ty.sty;
if input_ty != output_ty;
then {
".map(|x| x as _)"
} else {
""
}
};

let mut applicability = Applicability::MachineApplicable;
span_lint_and_sugg(
cx,
Expand All @@ -632,9 +650,10 @@ fn check_match_as_ref(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &
&format!("use {}() instead", suggestion),
"try this",
format!(
"{}.{}()",
"{}.{}(){}",
snippet_with_applicability(cx, ex.span, "_", &mut applicability),
suggestion
suggestion,
cast,
),
applicability,
)
Expand Down
21 changes: 21 additions & 0 deletions tests/ui/match_as_ref.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,25 @@ fn match_as_ref() {
let borrow_mut: Option<&mut ()> = mut_owned.as_mut();
}

mod issue4437 {
use std::{error::Error, fmt, num::ParseIntError};

#[derive(Debug)]
struct E {
source: Option<ParseIntError>,
}

impl Error for E {
fn source(&self) -> Option<&(dyn Error + 'static)> {
self.source.as_ref().map(|x| x as _)
}
}

impl fmt::Display for E {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
unimplemented!()
}
}
}

fn main() {}
24 changes: 24 additions & 0 deletions tests/ui/match_as_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,28 @@ fn match_as_ref() {
};
}

mod issue4437 {
use std::{error::Error, fmt, num::ParseIntError};

#[derive(Debug)]
struct E {
source: Option<ParseIntError>,
}

impl Error for E {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self.source {
Some(ref s) => Some(s),
None => None,
}
}
}

impl fmt::Display for E {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
unimplemented!()
}
}
}

fn main() {}
11 changes: 10 additions & 1 deletion tests/ui/match_as_ref.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,14 @@ LL | | Some(ref mut v) => Some(v),
LL | | };
| |_____^ help: try this: `mut_owned.as_mut()`

error: aborting due to 2 previous errors
error: use as_ref() instead
--> $DIR/match_as_ref.rs:30:13
|
LL | / match self.source {
LL | | Some(ref s) => Some(s),
LL | | None => None,
LL | | }
| |_____________^ help: try this: `self.source.as_ref().map(|x| x as _)`

error: aborting due to 3 previous errors

0 comments on commit 2bff3d8

Please sign in to comment.