Skip to content

Commit bf08faf

Browse files
committed
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.
2 parents 8a02304 + 963e8a4 commit bf08faf

File tree

6 files changed

+122
-23
lines changed

6 files changed

+122
-23
lines changed

src/libcore/macros.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,17 @@ macro_rules! fail(
3131
// because it's just a tiny wrapper. Small wins (156K to 149K in size)
3232
// were seen when forcing this to be inlined, and that number just goes
3333
// up with the number of calls to fail!()
34+
//
35+
// The leading _'s are to avoid dead code warnings if this is
36+
// used inside a dead function. Just `#[allow(dead_code)]` is
37+
// insufficient, since the user may have
38+
// `#[forbid(dead_code)]` and which cannot be overridden.
3439
#[inline(always)]
35-
fn run_fmt(fmt: &::std::fmt::Arguments) -> ! {
36-
static FILE_LINE: (&'static str, uint) = (file!(), line!());
37-
::core::failure::begin_unwind(fmt, &FILE_LINE)
40+
fn _run_fmt(fmt: &::std::fmt::Arguments) -> ! {
41+
static _FILE_LINE: (&'static str, uint) = (file!(), line!());
42+
::core::failure::begin_unwind(fmt, &_FILE_LINE)
3843
}
39-
format_args!(run_fmt, $fmt, $($arg)*)
44+
format_args!(_run_fmt, $fmt, $($arg)*)
4045
});
4146
)
4247

src/librustc/middle/dead.rs

+10-13
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ use syntax::ast_util::{local_def, is_local, PostExpansionMethod};
2626
use syntax::attr::AttrMetaMethods;
2727
use syntax::attr;
2828
use syntax::codemap;
29-
use syntax::parse::token;
3029
use syntax::visit::Visitor;
3130
use syntax::visit;
3231

@@ -412,18 +411,14 @@ struct DeadVisitor<'a> {
412411

413412
impl<'a> DeadVisitor<'a> {
414413
fn should_warn_about_field(&mut self, node: &ast::StructField_) -> bool {
415-
let (is_named, has_leading_underscore) = match node.ident() {
416-
Some(ref ident) => (true, token::get_ident(*ident).get().as_bytes()[0] == ('_' as u8)),
417-
_ => (false, false)
418-
};
414+
let is_named = node.ident().is_some();
419415
let field_type = ty::node_id_to_type(self.tcx, node.id);
420416
let is_marker_field = match ty::ty_to_def_id(field_type) {
421417
Some(def_id) => self.tcx.lang_items.items().any(|(_, item)| *item == Some(def_id)),
422418
_ => false
423419
};
424420
is_named
425421
&& !self.symbol_is_live(node.id, None)
426-
&& !has_leading_underscore
427422
&& !is_marker_field
428423
&& !has_allow_dead_code_or_lang_attr(node.attrs.as_slice())
429424
}
@@ -468,13 +463,15 @@ impl<'a> DeadVisitor<'a> {
468463
id: ast::NodeId,
469464
span: codemap::Span,
470465
ident: ast::Ident) {
471-
self.tcx
472-
.sess
473-
.add_lint(lint::builtin::DEAD_CODE,
474-
id,
475-
span,
476-
format!("code is never used: `{}`",
477-
token::get_ident(ident)));
466+
let name = ident.as_str();
467+
if !name.starts_with("_") {
468+
self.tcx
469+
.sess
470+
.add_lint(lint::builtin::DEAD_CODE,
471+
id,
472+
span,
473+
format!("code is never used: `{}`", name));
474+
}
478475
}
479476
}
480477

src/libstd/macros.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ macro_rules! fail(
7676
});
7777
($msg:expr) => ({
7878
// static requires less code at runtime, more constant data
79-
static FILE_LINE: (&'static str, uint) = (file!(), line!());
80-
let (file, line) = FILE_LINE;
79+
static _FILE_LINE: (&'static str, uint) = (file!(), line!());
80+
let (file, line) = _FILE_LINE;
8181
::std::rt::begin_unwind($msg, file, line)
8282
});
8383
($fmt:expr, $($arg:tt)*) => ({
@@ -92,12 +92,17 @@ macro_rules! fail(
9292
// because it's just a tiny wrapper. Small wins (156K to 149K in size)
9393
// were seen when forcing this to be inlined, and that number just goes
9494
// up with the number of calls to fail!()
95+
//
96+
// The leading _'s are to avoid dead code warnings if this is
97+
// used inside a dead function. Just `#[allow(dead_code)]` is
98+
// insufficient, since the user may have
99+
// `#[forbid(dead_code)]` and which cannot be overridden.
95100
#[inline(always)]
96-
fn run_fmt(fmt: &::std::fmt::Arguments) -> ! {
97-
static FILE_LINE: (&'static str, uint) = (file!(), line!());
98-
::std::rt::begin_unwind_fmt(fmt, &FILE_LINE)
101+
fn _run_fmt(fmt: &::std::fmt::Arguments) -> ! {
102+
static _FILE_LINE: (&'static str, uint) = (file!(), line!());
103+
::std::rt::begin_unwind_fmt(fmt, &_FILE_LINE)
99104
}
100-
format_args!(run_fmt, $fmt, $($arg)*)
105+
format_args!(_run_fmt, $fmt, $($arg)*)
101106
});
102107
)
103108

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(phase)]
12+
#![deny(dead_code)]
13+
#![allow(unreachable_code)]
14+
15+
#[phase(link, syntax)] extern crate core;
16+
17+
18+
fn foo() { //~ ERROR code is never used
19+
20+
// none of these should have any dead_code exposed to the user
21+
fail!();
22+
23+
fail!("foo");
24+
25+
fail!("bar {}", "baz")
26+
}
27+
28+
29+
fn main() {}
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![deny(dead_code)]
12+
#![allow(unreachable_code)]
13+
14+
fn foo() { //~ ERROR code is never used
15+
16+
// none of these should have any dead_code exposed to the user
17+
fail!();
18+
19+
fail!("foo");
20+
21+
fail!("bar {}", "baz")
22+
}
23+
24+
25+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![deny(dead_code)]
12+
13+
static _X: uint = 0;
14+
15+
fn _foo() {}
16+
17+
struct _Y {
18+
_z: uint
19+
}
20+
21+
enum _Z {}
22+
23+
impl _Y {
24+
fn _bar() {}
25+
}
26+
27+
type _A = int;
28+
29+
mod _bar {
30+
fn _qux() {}
31+
}
32+
33+
extern {
34+
#[link_name = "abort"]
35+
fn _abort() -> !;
36+
}
37+
38+
fn main() {}

0 commit comments

Comments
 (0)