Skip to content

Commit d5a11b3

Browse files
authored
Rollup merge of rust-lang#41907 - est31:macro_unused, r=jseyfried
Add lint for unused macros Addresses parts of rust-lang#34938, to add a lint for unused macros. We now output warnings by default when we encounter a macro that we didn't use for expansion. Issues to be resolved before this PR is ready for merge: - [x] fix the NodeId issue described above - [x] remove all unused macros from rustc and the libraries or set `#[allow(unused_macros)]` next to them if they should be kept for some reason. This is needed for successful boostrap and bors to accept the PR. -> rust-lang#41934 - [x] ~~implement the full extent of rust-lang#34938, that means the macro match arm checking as well.~~ *let's not do this for now*
2 parents 403fde8 + 25b7f10 commit d5a11b3

31 files changed

+137
-19
lines changed

src/libcore/num/wrapping.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use super::Wrapping;
1212

1313
use ops::*;
1414

15+
#[allow(unused_macros)]
1516
macro_rules! sh_impl_signed {
1617
($t:ident, $f:ident) => (
1718
#[stable(feature = "rust1", since = "1.0.0")]

src/libcore/ops.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,7 @@ macro_rules! neg_impl_numeric {
799799
($($t:ty)*) => { neg_impl_core!{ x => -x, $($t)*} }
800800
}
801801

802+
#[allow(unused_macros)]
802803
macro_rules! neg_impl_unsigned {
803804
($($t:ty)*) => {
804805
neg_impl_core!{ x => {

src/librustc/lint/builtin.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ declare_lint! {
7676
"detects unreachable patterns"
7777
}
7878

79+
declare_lint! {
80+
pub UNUSED_MACROS,
81+
Warn,
82+
"detects macros that were not used"
83+
}
84+
7985
declare_lint! {
8086
pub WARNINGS,
8187
Warn,
@@ -259,6 +265,7 @@ impl LintPass for HardwiredLints {
259265
DEAD_CODE,
260266
UNREACHABLE_CODE,
261267
UNREACHABLE_PATTERNS,
268+
UNUSED_MACROS,
262269
WARNINGS,
263270
UNUSED_FEATURES,
264271
STABLE_FEATURES,

src/librustc/lint/context.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ use hir;
4949
use hir::def_id::LOCAL_CRATE;
5050
use hir::intravisit as hir_visit;
5151
use syntax::visit as ast_visit;
52+
use syntax::tokenstream::ThinTokenStream;
5253

5354
/// Information about the registered lints.
5455
///
@@ -1125,6 +1126,13 @@ impl<'a> ast_visit::Visitor<'a> for EarlyContext<'a> {
11251126
fn visit_attribute(&mut self, attr: &'a ast::Attribute) {
11261127
run_lints!(self, check_attribute, early_passes, attr);
11271128
}
1129+
1130+
fn visit_mac_def(&mut self, _mac: &'a ThinTokenStream, id: ast::NodeId) {
1131+
let lints = self.sess.lints.borrow_mut().take(id);
1132+
for early_lint in lints {
1133+
self.early_lint(&early_lint);
1134+
}
1135+
}
11281136
}
11291137

11301138
enum CheckLintNameResult {

src/librustc_driver/driver.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,8 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
699699

700700
let krate = ecx.monotonic_expander().expand_crate(krate);
701701

702+
ecx.check_unused_macros();
703+
702704
let mut missing_fragment_specifiers: Vec<_> =
703705
ecx.parse_sess.missing_fragment_specifiers.borrow().iter().cloned().collect();
704706
missing_fragment_specifiers.sort();

src/librustc_incremental/persist/preds/compress/test_macro.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,3 @@ macro_rules! graph {
3737
}
3838
}
3939
}
40-
41-
macro_rules! set {
42-
($( $value:expr ),*) => {
43-
{
44-
use $crate::rustc_data_structures::fx::FxHashSet;
45-
let mut set = FxHashSet();
46-
$(set.insert($value);)*
47-
set
48-
}
49-
}
50-
}

src/librustc_lint/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
171171
UNUSED_MUST_USE,
172172
UNUSED_UNSAFE,
173173
PATH_STATEMENTS,
174-
UNUSED_ATTRIBUTES);
174+
UNUSED_ATTRIBUTES,
175+
UNUSED_MACROS);
175176

176177
// Guidelines for creating a future incompatibility lint:
177178
//

src/librustc_plugin/registry.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ impl<'a> Registry<'a> {
103103
}
104104
self.syntax_exts.push((name, match extension {
105105
NormalTT(ext, _, allow_internal_unstable) => {
106-
NormalTT(ext, Some(self.krate_span), allow_internal_unstable)
106+
let nid = ast::CRATE_NODE_ID;
107+
NormalTT(ext, Some((nid, self.krate_span)), allow_internal_unstable)
107108
}
108109
IdentTT(ext, _, allow_internal_unstable) => {
109110
IdentTT(ext, Some(self.krate_span), allow_internal_unstable)

src/librustc_resolve/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,10 @@ pub struct Resolver<'a> {
11871187
pub whitelisted_legacy_custom_derives: Vec<Name>,
11881188
pub found_unresolved_macro: bool,
11891189

1190+
// List of crate local macros that we need to warn about as being unused.
1191+
// Right now this only includes macro_rules! macros.
1192+
unused_macros: FxHashSet<DefId>,
1193+
11901194
// Maps the `Mark` of an expansion to its containing module or block.
11911195
invocations: FxHashMap<Mark, &'a InvocationData<'a>>,
11921196

@@ -1392,6 +1396,7 @@ impl<'a> Resolver<'a> {
13921396
potentially_unused_imports: Vec::new(),
13931397
struct_constructors: DefIdMap(),
13941398
found_unresolved_macro: false,
1399+
unused_macros: FxHashSet(),
13951400
}
13961401
}
13971402

src/librustc_resolve/macros.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use resolve_imports::ImportResolver;
1616
use rustc::hir::def_id::{DefId, BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, DefIndex};
1717
use rustc::hir::def::{Def, Export};
1818
use rustc::hir::map::{self, DefCollector};
19-
use rustc::ty;
19+
use rustc::{ty, lint};
2020
use syntax::ast::{self, Name, Ident};
2121
use syntax::attr::{self, HasAttrs};
2222
use syntax::errors::DiagnosticBuilder;
@@ -291,12 +291,32 @@ impl<'a> base::Resolver for Resolver<'a> {
291291
},
292292
};
293293
self.macro_defs.insert(invoc.expansion_data.mark, def.def_id());
294+
self.unused_macros.remove(&def.def_id());
294295
Ok(Some(self.get_macro(def)))
295296
}
296297

297298
fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool)
298299
-> Result<Rc<SyntaxExtension>, Determinacy> {
299-
self.resolve_macro_to_def(scope, path, kind, force).map(|def| self.get_macro(def))
300+
self.resolve_macro_to_def(scope, path, kind, force).map(|def| {
301+
self.unused_macros.remove(&def.def_id());
302+
self.get_macro(def)
303+
})
304+
}
305+
306+
fn check_unused_macros(&self) {
307+
for did in self.unused_macros.iter() {
308+
let id_span = match *self.macro_map[did] {
309+
SyntaxExtension::NormalTT(_, isp, _) => isp,
310+
_ => None,
311+
};
312+
if let Some((id, span)) = id_span {
313+
let lint = lint::builtin::UNUSED_MACROS;
314+
let msg = "unused macro definition".to_string();
315+
self.session.add_lint(lint, id, span, msg);
316+
} else {
317+
bug!("attempted to create unused macro error, but span not available");
318+
}
319+
}
300320
}
301321
}
302322

@@ -687,6 +707,8 @@ impl<'a> Resolver<'a> {
687707
if attr::contains_name(&item.attrs, "macro_export") {
688708
let def = Def::Macro(def_id, MacroKind::Bang);
689709
self.macro_exports.push(Export { name: ident.name, def: def, span: item.span });
710+
} else {
711+
self.unused_macros.insert(def_id);
690712
}
691713
}
692714

0 commit comments

Comments
 (0)