+match_if_let

This commit is contained in:
Manish Goregaokar 2014-11-20 00:18:31 +05:30
parent 871641030e
commit 542bfe3570
2 changed files with 50 additions and 3 deletions

View File

@ -1,5 +1,6 @@
#![feature(globs, phase, plugin_registrar)]
#![feature(globs, phase, plugin_registrar, if_let)]
#![allow(unused_imports)]
#[phase(plugin,link)]
extern crate syntax;
@ -12,10 +13,10 @@ use rustc::plugin::Registry;
use rustc::lint::LintPassObject;
pub mod types;
pub mod misc;
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
//reg.register_syntax_extension(intern("jstraceable"), base::ItemDecorator(box expand_jstraceable));
//reg.register_macro("factorial", expand)
reg.register_lint_pass(box types::TypePass as LintPassObject);
reg.register_lint_pass(box misc::MiscPass as LintPassObject);
}

46
src/misc.rs Normal file
View File

@ -0,0 +1,46 @@
use syntax::ptr::P;
use syntax::ast;
use syntax::ast::*;
use rustc::lint::{Context, LintPass, LintArray, Lint, Level};
use syntax::codemap::Span;
use types::span_note_and_lint;
/// Handles uncategorized lints
/// Currently handles linting of if-let-able matches
pub struct MiscPass;
declare_lint!(CLIPPY_SINGLE_MATCH, Warn,
"Warn on usage of matches with a single nontrivial arm")
impl LintPass for MiscPass {
fn get_lints(&self) -> LintArray {
lint_array!(CLIPPY_SINGLE_MATCH)
}
fn check_expr(&mut self, cx: &Context, expr: &Expr) {
if let ExprMatch(ref ex, ref arms, MatchNormal) = expr.node {
if arms.len() == 2 {
if arms[0].guard.is_none() && arms[1].pats.len() == 1 {
match arms[1].body.node {
ExprTup(ref v) if v.len() == 0 && arms[1].guard.is_none() => (),
ExprBlock(ref b) if b.stmts.len() == 0 && arms[1].guard.is_none() => (),
_ => return
}
// In some cases, an exhaustive match is preferred to catch situations when
// an enum is extended. So we only consider cases where a `_` wildcard is used
if arms[1].pats[0].node == PatWild(PatWildSingle) && arms[0].pats.len() == 1 {
let map = cx.sess().codemap();
span_note_and_lint(cx, CLIPPY_SINGLE_MATCH, expr.span,
"You seem to be trying to use match for destructuring a single type. Did you mean to use `if let`?",
format!("Try if let {} = {} {{ ... }}",
map.span_to_snippet(arms[0].pats[0].span).unwrap_or("..".to_string()),
map.span_to_snippet(ex.span).unwrap_or("..".to_string())).as_slice()
);
}
}
}
}
}
}