From 6d5f9478b22da27dc59d204cf94060bf949b6746 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Wed, 12 Aug 2015 07:48:00 +0200 Subject: [PATCH] utils: implement if_let_chain macro as suggested by isHavvy --- src/lib.rs | 3 ++- src/returns.rs | 26 ++++++++++++-------------- src/utils.rs | 29 +++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c5469c198..fef678f66 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -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; diff --git a/src/returns.rs b/src/returns.rs index 9bfc99972..5a361d3a7 100644 --- a/src/returns.rs +++ b/src/returns.rs @@ -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); } } } diff --git a/src/utils.rs b/src/utils.rs index 107f5c6f9..575d39b0c 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -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 + } + }; +}