]> git.lizzy.rs Git - rust.git/commitdiff
Allow explicit returns with cfg attributes
authorsinkuu <sinkuupump@gmail.com>
Sat, 19 Nov 2016 11:10:04 +0000 (20:10 +0900)
committersinkuu <sinkuupump@gmail.com>
Sun, 20 Nov 2016 01:02:41 +0000 (10:02 +0900)
clippy_lints/src/returns.rs
tests/run-pass/needless_return.rs [new file with mode: 0644]

index 0e6de0d39b22201c663baaec4287006530cb802b..334e7142cff27411be3590e9f4dcc7ec4989312a 100644 (file)
@@ -58,10 +58,21 @@ fn check_block_return(&mut self, cx: &EarlyContext, block: &ast::Block) {
 
     // Check a the final expression in a block if it's a return.
     fn check_final_expr(&mut self, cx: &EarlyContext, expr: &ast::Expr, span: Option<Span>) {
+        fn attr_is_cfg(attr: &ast::Attribute) -> bool {
+            if let ast::MetaItemKind::List(ref key, _) = attr.node.value.node {
+                *key == "cfg"
+            } else {
+                false
+            }
+        }
+
         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) => {
diff --git a/tests/run-pass/needless_return.rs b/tests/run-pass/needless_return.rs
new file mode 100644 (file)
index 0000000..5a0225f
--- /dev/null
@@ -0,0 +1,9 @@
+#[deny(warnings)]
+fn cfg_return() -> i32 {
+    #[cfg(msvc)] return 1;
+    #[cfg(not(msvc))] return 2;
+}
+
+fn main() {
+    cfg_return();
+}