use syntax::ast::LitKind;
use syntax::codemap::Span;
use utils::{COW_PATH, OPTION_PATH, RESULT_PATH};
-use utils::{match_type, snippet, span_lint, span_note_and_lint, span_lint_and_then, in_external_macro, expr_block};
+use utils::{match_type, snippet, span_note_and_lint, span_lint_and_then, in_external_macro, expr_block};
/// **What it does:** This lint checks for matches with a single arm where an `if let` will usually suffice.
///
if has_only_ref_pats(arms) {
if let ExprAddrOf(Mutability::MutImmutable, ref inner) = ex.node {
let template = match_template(cx, expr.span, source, "", inner);
- span_lint(cx,
- MATCH_REF_PATS,
- expr.span,
- &format!("you don't need to add `&` to both the expression and the patterns: use `{}`",
- template));
+ span_lint_and_then(cx,
+ MATCH_REF_PATS,
+ expr.span,
+ "you don't need to add `&` to both the expression and the patterns",
+ |db| {
+ db.span_suggestion(expr.span,
+ "try",
+ template);
+ });
} else {
let template = match_template(cx, expr.span, source, "*", ex);
- span_lint(cx,
- MATCH_REF_PATS,
- expr.span,
- &format!("instead of prefixing all patterns with `&`, you can dereference the expression: `{}`",
- template));
+ span_lint_and_then(cx,
+ MATCH_REF_PATS,
+ expr.span,
+ "you don't need to add `&` to all patterns",
+ |db| {
+ db.span_suggestion(expr.span,
+ "instead of prefixing all patterns with `&`, you can dereference the expression",
+ template);
+ });
}
}
}
fn match_template(cx: &LateContext, span: Span, source: MatchSource, op: &str, expr: &Expr) -> String {
let expr_snippet = snippet(cx, expr.span, "..");
match source {
- MatchSource::Normal => format!("match {}{} {{ ...", op, expr_snippet),
- MatchSource::IfLetDesugar { .. } => format!("if let ... = {}{} {{", op, expr_snippet),
- MatchSource::WhileLetDesugar => format!("while let ... = {}{} {{", op, expr_snippet),
+ MatchSource::Normal => format!("match {}{} {{ .. }}", op, expr_snippet),
+ MatchSource::IfLetDesugar { .. } => format!("if let .. = {}{} {{ .. }}", op, expr_snippet),
+ MatchSource::WhileLetDesugar => format!("while let .. = {}{} {{ .. }}", op, expr_snippet),
MatchSource::ForLoopDesugar => cx.sess().span_bug(span, "for loop desugared to match with &-patterns!"),
MatchSource::TryDesugar => cx.sess().span_bug(span, "`?` operator desugared to match with &-patterns!")
}
fn ref_pats() {
{
let v = &Some(0);
- match v { //~ERROR dereference the expression: `match *v { ...`
+ match v {
+ //~^ERROR add `&` to all patterns
+ //~|HELP instead of
+ //~|SUGGESTION `match *v { .. }`
&Some(v) => println!("{:?}", v),
&None => println!("none"),
}
}
}
let tup =& (1, 2);
- match tup { //~ERROR dereference the expression: `match *tup { ...`
+ match tup {
+ //~^ERROR add `&` to all patterns
+ //~|HELP instead of
+ //~|SUGGESTION `match *tup { .. }`
&(v, 1) => println!("{}", v),
_ => println!("none"),
}
// special case: using & both in expr and pats
let w = Some(0);
- match &w { //~ERROR use `match w { ...`
+ match &w {
+ //~^ERROR add `&` to both
+ //~|HELP try
+ //~|SUGGESTION `match w { .. }`
&Some(v) => println!("{:?}", v),
&None => println!("none"),
}
}
let a = &Some(0);
- if let &None = a { //~ERROR dereference the expression: `if let ... = *a {`
+ if let &None = a {
+ //~^ERROR add `&` to all patterns
+ //~|HELP instead of
+ //~|SUGGESTION `if let ... = *a { .. }`
println!("none");
}
let b = Some(0);
- if let &None = &b { //~ERROR use `if let ... = b {`
+ if let &None = &b {
+ //~^ERROR add `&` to both
+ //~|HELP try
+ //~|SUGGESTION `if let ... = b { .. }`
println!("none");
}
}