Skip to content

Commit 0da1a69

Browse files
committed
Auto merge of #50260 - Manishearth:no-extern-crate, r=nikomatsakis
idiom lints for removing `extern crate` Based off of #49789 This contains two lints: - One that suggests replacing pub extern crates with pub use, and removing non-pub extern crates entirely - One that suggests rewriting `use modulename::...::cratename::foo` as `cratename::foo` The latter is a bit tricky to emit suggestions for; for one this involves splicing spans (never a good idea), and it also won't be able to correctly handle `use module::{cratename, foo}` and use-trees. I'm not sure how to proceed here. Currently it doesn't suggest anything at all. Perhaps we can go the other way and suggest removal of all extern crates _except_ those used through modules (stash node ids somewhere) and suggest replacing those with `<visibility> use`? r? @nikomatsakis fixes #48719
2 parents 715d6a9 + 01791de commit 0da1a69

File tree

4 files changed

+189
-1
lines changed

4 files changed

+189
-1
lines changed

src/librustc_lint/builtin.rs

+63
Original file line numberDiff line numberDiff line change
@@ -1520,3 +1520,66 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedBrokenConst {
15201520
}
15211521
}
15221522
}
1523+
1524+
declare_lint! {
1525+
pub UNNECESSARY_EXTERN_CRATE,
1526+
Allow,
1527+
"suggest removing `extern crate` for the 2018 edition"
1528+
}
1529+
1530+
pub struct ExternCrate(/* depth */ u32);
1531+
1532+
impl ExternCrate {
1533+
pub fn new() -> Self {
1534+
ExternCrate(0)
1535+
}
1536+
}
1537+
1538+
impl LintPass for ExternCrate {
1539+
fn get_lints(&self) -> LintArray {
1540+
lint_array!(UNNECESSARY_EXTERN_CRATE)
1541+
}
1542+
}
1543+
1544+
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExternCrate {
1545+
fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
1546+
if let hir::ItemExternCrate(ref orig) = it.node {
1547+
if it.attrs.iter().any(|a| a.check_name("macro_use")) {
1548+
return
1549+
}
1550+
let mut err = cx.struct_span_lint(UNNECESSARY_EXTERN_CRATE,
1551+
it.span, "`extern crate` is unnecessary in the new edition");
1552+
if it.vis == hir::Visibility::Public || self.0 > 1 || orig.is_some() {
1553+
let pub_ = if it.vis == hir::Visibility::Public {
1554+
"pub "
1555+
} else {
1556+
""
1557+
};
1558+
1559+
let help = format!("use `{}use`", pub_);
1560+
1561+
if let Some(orig) = orig {
1562+
err.span_suggestion(it.span, &help,
1563+
format!("{}use {} as {}", pub_, orig, it.name));
1564+
} else {
1565+
err.span_suggestion(it.span, &help,
1566+
format!("{}use {}", pub_, it.name));
1567+
}
1568+
} else {
1569+
err.span_suggestion(it.span, "remove it", "".into());
1570+
}
1571+
1572+
err.emit();
1573+
}
1574+
}
1575+
1576+
fn check_mod(&mut self, _: &LateContext, _: &hir::Mod,
1577+
_: Span, _: ast::NodeId) {
1578+
self.0 += 1;
1579+
}
1580+
1581+
fn check_mod_post(&mut self, _: &LateContext, _: &hir::Mod,
1582+
_: Span, _: ast::NodeId) {
1583+
self.0 += 1;
1584+
}
1585+
}

src/librustc_lint/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
143143
TypeLimits,
144144
MissingDoc,
145145
MissingDebugImplementations,
146+
ExternCrate,
146147
);
147148

148149
add_lint_group!(sess,
@@ -180,7 +181,8 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
180181
add_lint_group!(sess,
181182
"rust_2018_migration",
182183
BARE_TRAIT_OBJECT,
183-
UNREACHABLE_PUB);
184+
UNREACHABLE_PUB,
185+
UNNECESSARY_EXTERN_CRATE);
184186

185187
// Guidelines for creating a future incompatibility lint:
186188
//
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright 2015 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(unnecessary_extern_crate)]
12+
#![feature(alloc, test, libc)]
13+
14+
extern crate alloc;
15+
//~^ ERROR `extern crate` is unnecessary in the new edition
16+
//~| HELP remove
17+
extern crate alloc as x;
18+
//~^ ERROR `extern crate` is unnecessary in the new edition
19+
//~| HELP use `use`
20+
21+
#[macro_use]
22+
extern crate test;
23+
pub extern crate test as y;
24+
//~^ ERROR `extern crate` is unnecessary in the new edition
25+
//~| HELP use `pub use`
26+
pub extern crate libc;
27+
//~^ ERROR `extern crate` is unnecessary in the new edition
28+
//~| HELP use `pub use`
29+
30+
31+
mod foo {
32+
extern crate alloc;
33+
//~^ ERROR `extern crate` is unnecessary in the new edition
34+
//~| HELP use `use`
35+
extern crate alloc as x;
36+
//~^ ERROR `extern crate` is unnecessary in the new edition
37+
//~| HELP use `use`
38+
pub extern crate test;
39+
//~^ ERROR `extern crate` is unnecessary in the new edition
40+
//~| HELP use `pub use`
41+
pub extern crate test as y;
42+
//~^ ERROR `extern crate` is unnecessary in the new edition
43+
//~| HELP use `pub use`
44+
mod bar {
45+
extern crate alloc;
46+
//~^ ERROR `extern crate` is unnecessary in the new edition
47+
//~| HELP use `use`
48+
extern crate alloc as x;
49+
//~^ ERROR `extern crate` is unnecessary in the new edition
50+
//~| HELP use `use`
51+
}
52+
}
53+
54+
55+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
error: `extern crate` is unnecessary in the new edition
2+
--> $DIR/unnecessary-extern-crate.rs:14:1
3+
|
4+
LL | extern crate alloc;
5+
| ^^^^^^^^^^^^^^^^^^^ help: remove it
6+
|
7+
note: lint level defined here
8+
--> $DIR/unnecessary-extern-crate.rs:11:9
9+
|
10+
LL | #![deny(unnecessary_extern_crate)]
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: `extern crate` is unnecessary in the new edition
14+
--> $DIR/unnecessary-extern-crate.rs:17:1
15+
|
16+
LL | extern crate alloc as x;
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc as x`
18+
19+
error: `extern crate` is unnecessary in the new edition
20+
--> $DIR/unnecessary-extern-crate.rs:23:1
21+
|
22+
LL | pub extern crate test as y;
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use test as y`
24+
25+
error: `extern crate` is unnecessary in the new edition
26+
--> $DIR/unnecessary-extern-crate.rs:26:1
27+
|
28+
LL | pub extern crate libc;
29+
| ^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use libc`
30+
31+
error: `extern crate` is unnecessary in the new edition
32+
--> $DIR/unnecessary-extern-crate.rs:32:5
33+
|
34+
LL | extern crate alloc;
35+
| ^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc`
36+
37+
error: `extern crate` is unnecessary in the new edition
38+
--> $DIR/unnecessary-extern-crate.rs:35:5
39+
|
40+
LL | extern crate alloc as x;
41+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc as x`
42+
43+
error: `extern crate` is unnecessary in the new edition
44+
--> $DIR/unnecessary-extern-crate.rs:38:5
45+
|
46+
LL | pub extern crate test;
47+
| ^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use test`
48+
49+
error: `extern crate` is unnecessary in the new edition
50+
--> $DIR/unnecessary-extern-crate.rs:41:5
51+
|
52+
LL | pub extern crate test as y;
53+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use test as y`
54+
55+
error: `extern crate` is unnecessary in the new edition
56+
--> $DIR/unnecessary-extern-crate.rs:45:9
57+
|
58+
LL | extern crate alloc;
59+
| ^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc`
60+
61+
error: `extern crate` is unnecessary in the new edition
62+
--> $DIR/unnecessary-extern-crate.rs:48:9
63+
|
64+
LL | extern crate alloc as x;
65+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc as x`
66+
67+
error: aborting due to 10 previous errors
68+

0 commit comments

Comments
 (0)