diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index 0e6de0d39b22..b19d7b9b4c1f 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -61,7 +61,10 @@ impl ReturnPass { match expr.node { // simple return is always "bad" ast::ExprKind::Ret(Some(ref inner)) => { - self.emit_return_lint(cx, span.expect("`else return` is not possible"), inner.span); + // allow `#[cfg(a)] return a; #[cfg(b)] return b;` + if !expr.attrs.iter().any(attr_is_cfg) { + self.emit_return_lint(cx, span.expect("`else return` is not possible"), inner.span); + } } // a whole block? check it! ast::ExprKind::Block(ref block) => { @@ -105,6 +108,7 @@ impl ReturnPass { let ast::StmtKind::Expr(ref retexpr) = retexpr.node, let Some(stmt) = it.next_back(), let ast::StmtKind::Local(ref local) = stmt.node, + !local.attrs.iter().any(attr_is_cfg), let Some(ref initexpr) = local.init, let ast::PatKind::Ident(_, Spanned { node: id, .. }, _) = local.pat.node, let ast::ExprKind::Path(_, ref path) = retexpr.node, @@ -140,3 +144,12 @@ impl EarlyLintPass for ReturnPass { self.check_let_return(cx, block); } } + +fn attr_is_cfg(attr: &ast::Attribute) -> bool { + if let ast::MetaItemKind::List(ref key, _) = attr.node.value.node { + *key == "cfg" + } else { + false + } +} + diff --git a/tests/run-pass/returns.rs b/tests/run-pass/returns.rs new file mode 100644 index 000000000000..882d3aa7f326 --- /dev/null +++ b/tests/run-pass/returns.rs @@ -0,0 +1,19 @@ +#[deny(warnings)] +fn cfg_return() -> i32 { + #[cfg(unix)] return 1; + #[cfg(not(unix))] return 2; +} + +#[deny(warnings)] +fn cfg_let_and_return() -> i32 { + #[cfg(unix)] + let x = 1; + #[cfg(not(unix))] + let x = 2; + x +} + +fn main() { + cfg_return(); + cfg_let_and_return(); +}