about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-08-11 09:01:06 +0000
committerbors <bors@rust-lang.org>2014-08-11 09:01:06 +0000
commit5e720f0e5453e7b113f313df7827f3ad0a6dbe46 (patch)
tree3886a48dc274a6598a4ed7fd4354e92c5e614143
parent9c772cd391034ad29a444e748708df5a0bfff0a2 (diff)
parent07aadc2e8b1923b28595393922a816e46d3903f4 (diff)
downloadrust-5e720f0e5453e7b113f313df7827f3ad0a6dbe46.tar.gz
rust-5e720f0e5453e7b113f313df7827f3ad0a6dbe46.zip
auto merge of #16196 : huonw/rust/fail-dead-code, r=alexcrichton
The fail macro defines some function/static items internally, which got
a dead_code warning when `fail!()` is used inside a dead function. This
is ugly and unnecessarily reveals implementation details, so the
warnings can be squashed.

Fixes #16192.
-rw-r--r--src/libcore/macros.rs13
-rw-r--r--src/librustc/middle/dead.rs23
-rw-r--r--src/libstd/macros.rs17
-rw-r--r--src/test/compile-fail/fail-no-dead-code-core.rs29
-rw-r--r--src/test/compile-fail/fail-no-dead-code.rs25
-rw-r--r--src/test/run-pass/dead-code-leading-underscore.rs38
6 files changed, 122 insertions, 23 deletions
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index 5373008612b..c80d1ed3451 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -31,12 +31,17 @@ macro_rules! fail(
         // because it's just a tiny wrapper. Small wins (156K to 149K in size)
         // were seen when forcing this to be inlined, and that number just goes
         // up with the number of calls to fail!()
+        //
+        // The leading _'s are to avoid dead code warnings if this is
+        // used inside a dead function. Just `#[allow(dead_code)]` is
+        // insufficient, since the user may have
+        // `#[forbid(dead_code)]` and which cannot be overridden.
         #[inline(always)]
-        fn run_fmt(fmt: &::std::fmt::Arguments) -> ! {
-            static FILE_LINE: (&'static str, uint) = (file!(), line!());
-            ::core::failure::begin_unwind(fmt, &FILE_LINE)
+        fn _run_fmt(fmt: &::std::fmt::Arguments) -> ! {
+            static _FILE_LINE: (&'static str, uint) = (file!(), line!());
+            ::core::failure::begin_unwind(fmt, &_FILE_LINE)
         }
-        format_args!(run_fmt, $fmt, $($arg)*)
+        format_args!(_run_fmt, $fmt, $($arg)*)
     });
 )
 
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 108bd35424a..86fe6dc0ddc 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -26,7 +26,6 @@ use syntax::ast_util::{local_def, is_local, PostExpansionMethod};
 use syntax::attr::AttrMetaMethods;
 use syntax::attr;
 use syntax::codemap;
-use syntax::parse::token;
 use syntax::visit::Visitor;
 use syntax::visit;
 
@@ -412,10 +411,7 @@ struct DeadVisitor<'a> {
 
 impl<'a> DeadVisitor<'a> {
     fn should_warn_about_field(&mut self, node: &ast::StructField_) -> bool {
-        let (is_named, has_leading_underscore) = match node.ident() {
-            Some(ref ident) => (true, token::get_ident(*ident).get().as_bytes()[0] == ('_' as u8)),
-            _ => (false, false)
-        };
+        let is_named = node.ident().is_some();
         let field_type = ty::node_id_to_type(self.tcx, node.id);
         let is_marker_field = match ty::ty_to_def_id(field_type) {
             Some(def_id) => self.tcx.lang_items.items().any(|(_, item)| *item == Some(def_id)),
@@ -423,7 +419,6 @@ impl<'a> DeadVisitor<'a> {
         };
         is_named
             && !self.symbol_is_live(node.id, None)
-            && !has_leading_underscore
             && !is_marker_field
             && !has_allow_dead_code_or_lang_attr(node.attrs.as_slice())
     }
@@ -468,13 +463,15 @@ impl<'a> DeadVisitor<'a> {
                       id: ast::NodeId,
                       span: codemap::Span,
                       ident: ast::Ident) {
-        self.tcx
-            .sess
-            .add_lint(lint::builtin::DEAD_CODE,
-                      id,
-                      span,
-                      format!("code is never used: `{}`",
-                              token::get_ident(ident)));
+        let name = ident.as_str();
+        if !name.starts_with("_") {
+            self.tcx
+                .sess
+                .add_lint(lint::builtin::DEAD_CODE,
+                          id,
+                          span,
+                          format!("code is never used: `{}`", name));
+        }
     }
 }
 
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index f2d7fb0cea6..85e614ab47e 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -43,8 +43,8 @@ macro_rules! fail(
     });
     ($msg:expr) => ({
         // static requires less code at runtime, more constant data
-        static FILE_LINE: (&'static str, uint) = (file!(), line!());
-        ::std::rt::begin_unwind($msg, &FILE_LINE)
+        static _FILE_LINE: (&'static str, uint) = (file!(), line!());
+        ::std::rt::begin_unwind($msg, &_FILE_LINE)
     });
     ($fmt:expr, $($arg:tt)*) => ({
         // a closure can't have return type !, so we need a full
@@ -58,12 +58,17 @@ macro_rules! fail(
         // because it's just a tiny wrapper. Small wins (156K to 149K in size)
         // were seen when forcing this to be inlined, and that number just goes
         // up with the number of calls to fail!()
+        //
+        // The leading _'s are to avoid dead code warnings if this is
+        // used inside a dead function. Just `#[allow(dead_code)]` is
+        // insufficient, since the user may have
+        // `#[forbid(dead_code)]` and which cannot be overridden.
         #[inline(always)]
-        fn run_fmt(fmt: &::std::fmt::Arguments) -> ! {
-            static FILE_LINE: (&'static str, uint) = (file!(), line!());
-            ::std::rt::begin_unwind_fmt(fmt, &FILE_LINE)
+        fn _run_fmt(fmt: &::std::fmt::Arguments) -> ! {
+            static _FILE_LINE: (&'static str, uint) = (file!(), line!());
+            ::std::rt::begin_unwind_fmt(fmt, &_FILE_LINE)
         }
-        format_args!(run_fmt, $fmt, $($arg)*)
+        format_args!(_run_fmt, $fmt, $($arg)*)
     });
 )
 
diff --git a/src/test/compile-fail/fail-no-dead-code-core.rs b/src/test/compile-fail/fail-no-dead-code-core.rs
new file mode 100644
index 00000000000..b2b04edc787
--- /dev/null
+++ b/src/test/compile-fail/fail-no-dead-code-core.rs
@@ -0,0 +1,29 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(phase)]
+#![deny(dead_code)]
+#![allow(unreachable_code)]
+
+#[phase(link, plugin)] extern crate core;
+
+
+fn foo() { //~ ERROR code is never used
+
+    // none of these should have any dead_code exposed to the user
+    fail!();
+
+    fail!("foo");
+
+    fail!("bar {}", "baz")
+}
+
+
+fn main() {}
diff --git a/src/test/compile-fail/fail-no-dead-code.rs b/src/test/compile-fail/fail-no-dead-code.rs
new file mode 100644
index 00000000000..da59722c3ff
--- /dev/null
+++ b/src/test/compile-fail/fail-no-dead-code.rs
@@ -0,0 +1,25 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![deny(dead_code)]
+#![allow(unreachable_code)]
+
+fn foo() { //~ ERROR code is never used
+
+    // none of these should have any dead_code exposed to the user
+    fail!();
+
+    fail!("foo");
+
+    fail!("bar {}", "baz")
+}
+
+
+fn main() {}
diff --git a/src/test/run-pass/dead-code-leading-underscore.rs b/src/test/run-pass/dead-code-leading-underscore.rs
new file mode 100644
index 00000000000..b588ea9cfd0
--- /dev/null
+++ b/src/test/run-pass/dead-code-leading-underscore.rs
@@ -0,0 +1,38 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![deny(dead_code)]
+
+static _X: uint = 0;
+
+fn _foo() {}
+
+struct _Y {
+    _z: uint
+}
+
+enum _Z {}
+
+impl _Y {
+    fn _bar() {}
+}
+
+type _A = int;
+
+mod _bar {
+    fn _qux() {}
+}
+
+extern {
+    #[link_name = "abort"]
+    fn _abort() -> !;
+}
+
+pub fn main() {}