Skip to content

Commit 1b3d737

Browse files
committed
Auto merge of #51015 - nikomatsakis:issue-50672-remove-extern-crate-idiom, r=alexcrichton
merge unused-extern-crate and unnecessary-extern-crate lints Extend the `unused_extern_crates` lint to offer a suggestion to remove the extern crate and remove the `unnecessary_extern_crate` lint. Still a few minor issues to fix: - [x] this *does* now leave a blank line... (defer to #51176) - idea: extend the span to be replaced by 1 character if the next character is a `\n` - [x] what about macros? do we need to watch out for that? (defer to #48704) - [x] also it doesn't work for `extern crate foo; fn main() { foo::bar(); }` - this is subtle: the `foo` might be shadowing a glob import too, can't always remove - defer to #51177 - [x] we also don't do the `pub use` rewrite thang (#51013) Spun off from #51010 Fixes #50672 r? @alexcrichton
2 parents 2954cb5 + b37cc85 commit 1b3d737

19 files changed

+421
-202
lines changed

src/librustc/hir/lowering.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2433,7 +2433,7 @@ impl<'a> LoweringContext<'a> {
24332433
self.with_hir_id_owner(new_id, |this| {
24342434
let vis = match vis {
24352435
hir::Visibility::Public => hir::Visibility::Public,
2436-
hir::Visibility::Crate => hir::Visibility::Crate,
2436+
hir::Visibility::Crate(sugar) => hir::Visibility::Crate(sugar),
24372437
hir::Visibility::Inherited => hir::Visibility::Inherited,
24382438
hir::Visibility::Restricted { ref path, id: _ } => {
24392439
hir::Visibility::Restricted {
@@ -3704,7 +3704,7 @@ impl<'a> LoweringContext<'a> {
37043704
) -> hir::Visibility {
37053705
match v.node {
37063706
VisibilityKind::Public => hir::Public,
3707-
VisibilityKind::Crate(..) => hir::Visibility::Crate,
3707+
VisibilityKind::Crate(sugar) => hir::Visibility::Crate(sugar),
37083708
VisibilityKind::Restricted { ref path, id, .. } => hir::Visibility::Restricted {
37093709
path: P(self.lower_path(id, path, ParamMode::Explicit)),
37103710
id: if let Some(owner) = explicit_owner {

src/librustc/hir/map/collector.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
463463
fn visit_vis(&mut self, visibility: &'hir Visibility) {
464464
match *visibility {
465465
Visibility::Public |
466-
Visibility::Crate |
466+
Visibility::Crate(_) |
467467
Visibility::Inherited => {}
468468
Visibility::Restricted { id, .. } => {
469469
self.insert(id, NodeVisibility(visibility));

src/librustc/hir/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use mir::mono::Linkage;
3535
use syntax_pos::{Span, DUMMY_SP};
3636
use syntax::codemap::{self, Spanned};
3737
use rustc_target::spec::abi::Abi;
38-
use syntax::ast::{self, Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect};
38+
use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect};
3939
use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
4040
use syntax::attr::InlineAttr;
4141
use syntax::ext::hygiene::SyntaxContext;
@@ -1953,7 +1953,7 @@ pub struct PolyTraitRef {
19531953
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
19541954
pub enum Visibility {
19551955
Public,
1956-
Crate,
1956+
Crate(CrateSugar),
19571957
Restricted { path: P<Path>, id: NodeId },
19581958
Inherited,
19591959
}
@@ -1964,7 +1964,7 @@ impl Visibility {
19641964
match self {
19651965
&Public |
19661966
&Inherited => false,
1967-
&Crate |
1967+
&Crate(_) |
19681968
&Restricted { .. } => true,
19691969
}
19701970
}

src/librustc/hir/print.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -801,15 +801,25 @@ impl<'a> State<'a> {
801801

802802
pub fn print_visibility(&mut self, vis: &hir::Visibility) -> io::Result<()> {
803803
match *vis {
804-
hir::Public => self.word_nbsp("pub"),
805-
hir::Visibility::Crate => self.word_nbsp("pub(crate)"),
804+
hir::Public => self.word_nbsp("pub")?,
805+
hir::Visibility::Crate(ast::CrateSugar::JustCrate) => self.word_nbsp("crate")?,
806+
hir::Visibility::Crate(ast::CrateSugar::PubCrate) => self.word_nbsp("pub(crate)")?,
806807
hir::Visibility::Restricted { ref path, .. } => {
807808
self.s.word("pub(")?;
808-
self.print_path(path, false)?;
809-
self.word_nbsp(")")
809+
if path.segments.len() == 1 && path.segments[0].name == keywords::Super.name() {
810+
// Special case: `super` can print like `pub(super)`.
811+
self.s.word("super")?;
812+
} else {
813+
// Everything else requires `in` at present.
814+
self.word_nbsp("in")?;
815+
self.print_path(path, false)?;
816+
}
817+
self.word_nbsp(")")?;
810818
}
811-
hir::Inherited => Ok(()),
819+
hir::Inherited => ()
812820
}
821+
822+
Ok(())
813823
}
814824

815825
pub fn print_defaultness(&mut self, defaultness: hir::Defaultness) -> io::Result<()> {

src/librustc/ich/impls_hir.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -751,17 +751,24 @@ impl_stable_hash_for!(enum hir::ImplItemKind {
751751
Type(t)
752752
});
753753

754+
impl_stable_hash_for!(enum ::syntax::ast::CrateSugar {
755+
JustCrate,
756+
PubCrate,
757+
});
758+
754759
impl<'a> HashStable<StableHashingContext<'a>> for hir::Visibility {
755760
fn hash_stable<W: StableHasherResult>(&self,
756761
hcx: &mut StableHashingContext<'a>,
757762
hasher: &mut StableHasher<W>) {
758763
mem::discriminant(self).hash_stable(hcx, hasher);
759764
match *self {
760765
hir::Visibility::Public |
761-
hir::Visibility::Crate |
762766
hir::Visibility::Inherited => {
763767
// No fields to hash.
764768
}
769+
hir::Visibility::Crate(sugar) => {
770+
sugar.hash_stable(hcx, hasher);
771+
}
765772
hir::Visibility::Restricted { ref path, id } => {
766773
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
767774
id.hash_stable(hcx, hasher);

src/librustc/ty/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ impl Visibility {
270270
pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: TyCtxt) -> Self {
271271
match *visibility {
272272
hir::Public => Visibility::Public,
273-
hir::Visibility::Crate => Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)),
273+
hir::Visibility::Crate(_) => Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)),
274274
hir::Visibility::Restricted { ref path, .. } => match path.def {
275275
// If there is no resolution, `resolve` will have already reported an error, so
276276
// assume that the visibility is public to avoid reporting more privacy errors.

src/librustc_lint/builtin.rs

-66
Original file line numberDiff line numberDiff line change
@@ -1548,72 +1548,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedBrokenConst {
15481548
}
15491549
}
15501550

1551-
declare_lint! {
1552-
pub UNNECESSARY_EXTERN_CRATES,
1553-
Allow,
1554-
"suggest removing `extern crate` for the 2018 edition"
1555-
}
1556-
1557-
pub struct ExternCrate(/* depth */ u32);
1558-
1559-
impl ExternCrate {
1560-
pub fn new() -> Self {
1561-
ExternCrate(0)
1562-
}
1563-
}
1564-
1565-
impl LintPass for ExternCrate {
1566-
fn get_lints(&self) -> LintArray {
1567-
lint_array!(UNNECESSARY_EXTERN_CRATES)
1568-
}
1569-
}
1570-
1571-
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExternCrate {
1572-
fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
1573-
if !cx.tcx.features().extern_absolute_paths {
1574-
return
1575-
}
1576-
if let hir::ItemExternCrate(ref orig) = it.node {
1577-
if it.attrs.iter().any(|a| a.check_name("macro_use")) {
1578-
return
1579-
}
1580-
let mut err = cx.struct_span_lint(UNNECESSARY_EXTERN_CRATES,
1581-
it.span, "`extern crate` is unnecessary in the new edition");
1582-
if it.vis == hir::Visibility::Public || self.0 > 1 || orig.is_some() {
1583-
let pub_ = if it.vis == hir::Visibility::Public {
1584-
"pub "
1585-
} else {
1586-
""
1587-
};
1588-
1589-
let help = format!("use `{}use`", pub_);
1590-
1591-
if let Some(orig) = orig {
1592-
err.span_suggestion(it.span, &help,
1593-
format!("{}use {} as {};", pub_, orig, it.name));
1594-
} else {
1595-
err.span_suggestion(it.span, &help,
1596-
format!("{}use {};", pub_, it.name));
1597-
}
1598-
} else {
1599-
err.span_suggestion(it.span, "remove it", "".into());
1600-
}
1601-
1602-
err.emit();
1603-
}
1604-
}
1605-
1606-
fn check_mod(&mut self, _: &LateContext, _: &hir::Mod,
1607-
_: Span, _: ast::NodeId) {
1608-
self.0 += 1;
1609-
}
1610-
1611-
fn check_mod_post(&mut self, _: &LateContext, _: &hir::Mod,
1612-
_: Span, _: ast::NodeId) {
1613-
self.0 += 1;
1614-
}
1615-
}
1616-
16171551
/// Lint for trait and lifetime bounds that don't depend on type parameters
16181552
/// which either do nothing, or stop the item from being used.
16191553
pub struct TrivialConstraints;

src/librustc_lint/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
145145
TypeLimits,
146146
MissingDoc,
147147
MissingDebugImplementations,
148-
ExternCrate,
149148
);
150149

151150
add_lint_group!(sess,
@@ -185,7 +184,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
185184
"rust_2018_idioms",
186185
BARE_TRAIT_OBJECTS,
187186
UNREACHABLE_PUB,
188-
UNNECESSARY_EXTERN_CRATES);
187+
UNUSED_EXTERN_CRATES);
189188

190189
// Guidelines for creating a future incompatibility lint:
191190
//

0 commit comments

Comments
 (0)