use crate::consts::{constant, Constant};
use crate::utils::paths;
use crate::utils::sugg::Sugg;
-use crate::utils::sym;
use crate::utils::{
- expr_block, in_macro_or_desugar, is_allowed, is_expn_of, match_qpath, match_type, multispan_sugg, remove_blocks,
- snippet, snippet_with_applicability, span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty,
+ expr_block, is_allowed, is_expn_of, match_qpath, match_type, multispan_sugg, remove_blocks, snippet,
+ snippet_with_applicability, span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty,
};
use if_chain::if_chain;
use rustc::hir::def::CtorKind;
}
declare_clippy_lint! {
- /// **What it does:** Checks for matches with a two arms where an `if let else` will
+ /// **What it does:** Checks for matches with two arms where an `if let else` will
/// usually suffice.
///
/// **Why is this bad?** Just readability – `if let` nests less than a `match`.
/// Using `match`:
///
/// ```rust
+ /// # fn bar(foo: &usize) {}
+ /// # let other_ref: usize = 1;
+ /// # let x: Option<&usize> = Some(&1);
/// match x {
/// Some(ref foo) => bar(foo),
- /// _ => bar(other_ref),
+ /// _ => bar(&other_ref),
/// }
/// ```
///
/// Using `if let` with `else`:
///
/// ```rust
+ /// # fn bar(foo: &usize) {}
+ /// # let other_ref: usize = 1;
+ /// # let x: Option<&usize> = Some(&1);
/// if let Some(ref foo) = x {
/// bar(foo);
/// } else {
- /// bar(other_ref);
+ /// bar(&other_ref);
/// }
/// ```
pub SINGLE_MATCH_ELSE,
pedantic,
- "a match statement with a two arms where the second arm's pattern is a placeholder instead of a specific match pattern"
+ "a match statement with two arms where the second arm's pattern is a placeholder instead of a specific match pattern"
}
declare_clippy_lint! {
///
/// **Example:**
/// ```rust
+ /// # enum Foo { A(usize), B(usize) }
+ /// # let x = Foo::B(1);
/// match x {
/// A => {},
/// _ => {},
) {
// list of candidate `Enum`s we know will never get any more members
let candidates = &[
- (&*paths::COW, "Borrowed"),
- (&*paths::COW, "Cow::Borrowed"),
- (&*paths::COW, "Cow::Owned"),
- (&*paths::COW, "Owned"),
- (&*paths::OPTION, "None"),
- (&*paths::RESULT, "Err"),
- (&*paths::RESULT, "Ok"),
+ (&paths::COW, "Borrowed"),
+ (&paths::COW, "Cow::Borrowed"),
+ (&paths::COW, "Cow::Owned"),
+ (&paths::COW, "Owned"),
+ (&paths::OPTION, "None"),
+ (&paths::RESULT, "Err"),
+ (&paths::RESULT, "Ok"),
];
let path = match arms[1].pats[0].node {
fn check_wild_err_arm(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) {
let ex_ty = walk_ptrs_ty(cx.tables.expr_ty(ex));
- if match_type(cx, ex_ty, &*paths::RESULT) {
+ if match_type(cx, ex_ty, &paths::RESULT) {
for arm in arms {
if let PatKind::TupleStruct(ref path, ref inner, _) = arm.pats[0].node {
let path_str = print::to_string(print::NO_ANN, |s| s.print_qpath(path, false));
fn is_panic_block(block: &Block) -> bool {
match (&block.expr, block.stmts.len(), block.stmts.first()) {
(&Some(ref exp), 0, _) => {
- is_expn_of(exp.span, *sym::panic).is_some() && is_expn_of(exp.span, *sym::unreachable).is_none()
+ is_expn_of(exp.span, "panic").is_some() && is_expn_of(exp.span, "unreachable").is_none()
},
(&None, 1, Some(stmt)) => {
- is_expn_of(stmt.span, *sym::panic).is_some() && is_expn_of(stmt.span, *sym::unreachable).is_none()
+ is_expn_of(stmt.span, "panic").is_some() && is_expn_of(stmt.span, "unreachable").is_none()
},
_ => false,
}
}));
span_lint_and_then(cx, MATCH_REF_PATS, expr.span, title, |db| {
- if !in_macro_or_desugar(expr.span) {
+ if !expr.span.from_expansion() {
multispan_sugg(db, msg.to_owned(), suggs);
}
});
} 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,
&format!("use {}() instead", suggestion),
"try this",
format!(
- "{}.{}()",
+ "{}.{}(){}",
snippet_with_applicability(cx, ex.span, "_", &mut applicability),
- suggestion
+ suggestion,
+ cast,
),
applicability,
)
// Checks if arm has the form `None => None`
fn is_none_arm(arm: &Arm) -> bool {
match arm.pats[0].node {
- PatKind::Path(ref path) if match_qpath(path, &*paths::OPTION_NONE) => true,
+ PatKind::Path(ref path) if match_qpath(path, &paths::OPTION_NONE) => true,
_ => false,
}
}
fn is_ref_some_arm(arm: &Arm) -> Option<BindingAnnotation> {
if_chain! {
if let PatKind::TupleStruct(ref path, ref pats, _) = arm.pats[0].node;
- if pats.len() == 1 && match_qpath(path, &*paths::OPTION_SOME);
+ if pats.len() == 1 && match_qpath(path, &paths::OPTION_SOME);
if let PatKind::Binding(rb, .., ident, _) = pats[0].node;
if rb == BindingAnnotation::Ref || rb == BindingAnnotation::RefMut;
if let ExprKind::Call(ref e, ref args) = remove_blocks(&arm.body).node;
if let ExprKind::Path(ref some_path) = e.node;
- if match_qpath(some_path, &*paths::OPTION_SOME) && args.len() == 1;
+ if match_qpath(some_path, &paths::OPTION_SOME) && args.len() == 1;
if let ExprKind::Path(ref qpath) = args[0].node;
if let &QPath::Resolved(_, ref path2) = qpath;
if path2.segments.len() == 1 && ident.name == path2.segments[0].ident.name;
T: Copy + Ord,
{
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
- enum Kind<'a, T: 'a> {
+ enum Kind<'a, T> {
Start(T, &'a SpannedRange<T>),
End(Bound<T>, &'a SpannedRange<T>),
}