Merge pull request #134 from birkenfeld/if_let_chain_macro

utils: implement if_let_chain macro as suggested by isHavvy
This commit is contained in:
Manish Goregaokar 2015-08-12 13:07:37 +05:30
commit 2ec933377c
3 changed files with 43 additions and 15 deletions

View File

@ -13,6 +13,8 @@ extern crate collections;
use rustc::plugin::Registry;
use rustc::lint::LintPassObject;
#[macro_use]
pub mod utils;
pub mod types;
pub mod misc;
pub mod eq_op;
@ -27,7 +29,6 @@ pub mod len_zero;
pub mod attrs;
pub mod collapsible_if;
pub mod unicode;
pub mod utils;
pub mod strings;
pub mod methods;
pub mod returns;

View File

@ -67,20 +67,18 @@ impl ReturnPass {
// Check for "let x = EXPR; x"
fn check_let_return(&mut self, cx: &Context, block: &Block) {
// we need both a let-binding stmt and an expr
if let Some(stmt) = block.stmts.last() {
if let StmtDecl(ref decl, _) = stmt.node {
if let DeclLocal(ref local) = decl.node {
if let Some(ref initexpr) = local.init {
if let PatIdent(_, Spanned { node: id, .. }, _) = local.pat.node {
if let Some(ref retexpr) = block.expr {
if let ExprPath(_, ref path) = retexpr.node {
if match_path(path, &[&*id.name.as_str()]) {
self.emit_let_lint(cx, retexpr.span, initexpr.span);
}
}
}
}
}
if_let_chain! {
[
Some(stmt) = block.stmts.last(),
StmtDecl(ref decl, _) = stmt.node,
DeclLocal(ref local) = decl.node,
Some(ref initexpr) = local.init,
PatIdent(_, Spanned { node: id, .. }, _) = local.pat.node,
Some(ref retexpr) = block.expr,
ExprPath(_, ref path) = retexpr.node
], {
if match_path(path, &[&*id.name.as_str()]) {
self.emit_let_lint(cx, retexpr.span, initexpr.span);
}
}
}

View File

@ -92,3 +92,32 @@ pub fn walk_ptrs_ty<'t>(ty: ty::Ty<'t>) -> ty::Ty<'t> {
_ => ty
}
}
/// Produce a nested chain of if-lets from the patterns:
///
/// if_let_chain! {[Some(y) = x, Some(z) = y],
/// {
/// block
/// }
/// }
///
/// becomes
///
/// if let Some(y) = x {
/// if let Some(z) = y {
/// block
/// }
/// }
#[macro_export]
macro_rules! if_let_chain {
([$pat:pat = $expr:expr, $($p2:pat = $e2:expr),+], $block:block) => {
if let $pat = $expr {
if_let_chain!{ [$($p2 = $e2),+], $block }
}
};
([$pat:pat = $expr:expr], $block:block) => {
if let $pat = $expr {
$block
}
};
}