Last active
August 29, 2015 14:10
-
-
Save payload/5496fd7f3bef17139cc2 to your computer and use it in GitHub Desktop.
rust compiler plugin to check for `if let` opportunities
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(if_let)] | |
#[phase(plugin,link)] | |
extern crate syntax; | |
#[phase(plugin, link)] | |
extern crate rustc; | |
use syntax::ast::{Expr, ExprMatch, PatWild, PatWildSingle, ExprTup}; | |
use rustc::lint::{Context, LintPass, LintArray}; | |
use syntax::codemap::NO_EXPANSION; | |
declare_lint!(IF_LET_LINT, Warn, | |
"Warn about possible `if let` opportunity") | |
pub struct IfLetPass; | |
impl LintPass for IfLetPass { | |
fn get_lints(&self) -> LintArray { | |
lint_array!(IF_LET_LINT) | |
} | |
fn check_expr(&mut self, cx: &Context, expr_match: &Expr) { | |
if expr_match.span.expn_id != NO_EXPANSION { return } | |
if let ExprMatch(_, ref arms, MatchNormal) = expr_match.node { | |
if arms.len() != 2 { return } | |
let ref if_arm = arms[0]; | |
let ref else_arm = arms[1]; | |
if if_arm.pats.len() != 1 | |
|| if_arm.guard != None { | |
return | |
} | |
if else_arm.pats.len() == 0 { | |
cx.span_lint(IF_LET, expr_match.span, "if let") | |
} | |
if else_arm.pats.len() != 1 | |
|| else_arm.guard != None | |
|| else_arm.pats[0].node != PatWild(PatWildSingle) { | |
return | |
} | |
if is_empty_tuple_expr(&*else_arm.body) { | |
cx.span_lint(IF_LET, expr_match.span, "if let") | |
} else { | |
cx.span_lint(IF_LET, expr_match.span, "if let else") | |
} | |
} | |
} | |
} | |
fn is_empty_tuple_expr(expr: &Expr) -> bool { | |
match expr.node { | |
ExprTup(ref vec) if vec.len() == 0 => true, | |
_ => false | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment