]> git.lizzy.rs Git - rust.git/commitdiff
merge UNNECESSARY_EXTERN_CRATE and UNUSED_EXTERN_CRATES
authorNiko Matsakis <niko@alum.mit.edu>
Fri, 25 May 2018 20:53:49 +0000 (16:53 -0400)
committerNiko Matsakis <niko@alum.mit.edu>
Fri, 1 Jun 2018 15:00:18 +0000 (11:00 -0400)
19 files changed:
src/librustc/hir/lowering.rs
src/librustc/hir/map/collector.rs
src/librustc/hir/mod.rs
src/librustc/hir/print.rs
src/librustc/ich/impls_hir.rs
src/librustc/ty/mod.rs
src/librustc_lint/builtin.rs
src/librustc_lint/lib.rs
src/librustc_typeck/check_unused.rs
src/librustdoc/clean/mod.rs
src/test/compile-fail/edition-extern-crate-allowed.rs
src/test/ui-fulldeps/unnecessary-extern-crate.rs
src/test/ui-fulldeps/unnecessary-extern-crate.stderr
src/test/ui/rfc-2166-underscore-imports/basic.stderr
src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed
src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs
src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr
src/test/ui/suggestions/removing-extern-crate.fixed
src/test/ui/suggestions/removing-extern-crate.stderr

index f816ba9ab8143b68e3b06a83ab21f99153b8c90d..1e48a54e018d6b1e70aba0ba8924d33ec4a911e2 100644 (file)
@@ -2433,7 +2433,7 @@ fn lower_use_tree(
                     self.with_hir_id_owner(new_id, |this| {
                         let vis = match vis {
                             hir::Visibility::Public => hir::Visibility::Public,
-                            hir::Visibility::Crate => hir::Visibility::Crate,
+                            hir::Visibility::Crate(sugar) => hir::Visibility::Crate(sugar),
                             hir::Visibility::Inherited => hir::Visibility::Inherited,
                             hir::Visibility::Restricted { ref path, id: _ } => {
                                 hir::Visibility::Restricted {
@@ -3704,7 +3704,7 @@ fn lower_visibility(
     ) -> hir::Visibility {
         match v.node {
             VisibilityKind::Public => hir::Public,
-            VisibilityKind::Crate(..) => hir::Visibility::Crate,
+            VisibilityKind::Crate(sugar) => hir::Visibility::Crate(sugar),
             VisibilityKind::Restricted { ref path, id, .. } => hir::Visibility::Restricted {
                 path: P(self.lower_path(id, path, ParamMode::Explicit)),
                 id: if let Some(owner) = explicit_owner {
index 13df1ced6032e02880d31c5ca73d5eda8cf95384..7835d4e782c430e86ad8231f98007a3833b53804 100644 (file)
@@ -463,7 +463,7 @@ fn visit_lifetime(&mut self, lifetime: &'hir Lifetime) {
     fn visit_vis(&mut self, visibility: &'hir Visibility) {
         match *visibility {
             Visibility::Public |
-            Visibility::Crate |
+            Visibility::Crate(_) |
             Visibility::Inherited => {}
             Visibility::Restricted { id, .. } => {
                 self.insert(id, NodeVisibility(visibility));
index ebc59964172ac340fb21a79375ab2df9f3c60727..b7c66398f8500e3119d129f3aa30c358dc59612d 100644 (file)
@@ -35,7 +35,7 @@
 use syntax_pos::{Span, DUMMY_SP};
 use syntax::codemap::{self, Spanned};
 use rustc_target::spec::abi::Abi;
-use syntax::ast::{self, Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect};
+use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect};
 use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
 use syntax::attr::InlineAttr;
 use syntax::ext::hygiene::SyntaxContext;
@@ -1953,7 +1953,7 @@ pub struct PolyTraitRef {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Visibility {
     Public,
-    Crate,
+    Crate(CrateSugar),
     Restricted { path: P<Path>, id: NodeId },
     Inherited,
 }
@@ -1964,7 +1964,7 @@ pub fn is_pub_restricted(&self) -> bool {
         match self {
             &Public |
             &Inherited => false,
-            &Crate |
+            &Crate(_) |
             &Restricted { .. } => true,
         }
     }
index 4bee4f9add025136d7a8a8268ba5e03ab07d2776..2cf627fdc162f556e409b4b6e2110829780aa3fa 100644 (file)
@@ -801,15 +801,25 @@ pub fn print_variants(&mut self,
 
     pub fn print_visibility(&mut self, vis: &hir::Visibility) -> io::Result<()> {
         match *vis {
-            hir::Public => self.word_nbsp("pub"),
-            hir::Visibility::Crate => self.word_nbsp("pub(crate)"),
+            hir::Public => self.word_nbsp("pub")?,
+            hir::Visibility::Crate(ast::CrateSugar::JustCrate) => self.word_nbsp("crate")?,
+            hir::Visibility::Crate(ast::CrateSugar::PubCrate) => self.word_nbsp("pub(crate)")?,
             hir::Visibility::Restricted { ref path, .. } => {
                 self.s.word("pub(")?;
-                self.print_path(path, false)?;
-                self.word_nbsp(")")
+                if path.segments.len() == 1 && path.segments[0].name == keywords::Super.name() {
+                    // Special case: `super` can print like `pub(super)`.
+                    self.s.word("super")?;
+                } else {
+                    // Everything else requires `in` at present.
+                    self.word_nbsp("in")?;
+                    self.print_path(path, false)?;
+                }
+                self.word_nbsp(")")?;
             }
-            hir::Inherited => Ok(()),
+            hir::Inherited => ()
         }
+
+        Ok(())
     }
 
     pub fn print_defaultness(&mut self, defaultness: hir::Defaultness) -> io::Result<()> {
index 9b202f55f3c0a23fd313d8d683fde6dd99022f2c..397638fc55d4b6739c7dc1e30ac0979b65ee39e3 100644 (file)
@@ -751,6 +751,11 @@ fn hash_stable<W: StableHasherResult>(&self,
     Type(t)
 });
 
+impl_stable_hash_for!(enum ::syntax::ast::CrateSugar {
+    JustCrate,
+    PubCrate,
+});
+
 impl<'a> HashStable<StableHashingContext<'a>> for hir::Visibility {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
@@ -758,10 +763,12 @@ fn hash_stable<W: StableHasherResult>(&self,
         mem::discriminant(self).hash_stable(hcx, hasher);
         match *self {
             hir::Visibility::Public |
-            hir::Visibility::Crate |
             hir::Visibility::Inherited => {
                 // No fields to hash.
             }
+            hir::Visibility::Crate(sugar) => {
+                sugar.hash_stable(hcx, hasher);
+            }
             hir::Visibility::Restricted { ref path, id } => {
                 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
                     id.hash_stable(hcx, hasher);
index 646c60c139c85f3d59b9f4c7864fefc4e5a5a964..419bffcae0643c59e18d13c888c36156be1bf6f5 100644 (file)
@@ -270,7 +270,7 @@ impl Visibility {
     pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: TyCtxt) -> Self {
         match *visibility {
             hir::Public => Visibility::Public,
-            hir::Visibility::Crate => Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)),
+            hir::Visibility::Crate(_) => Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)),
             hir::Visibility::Restricted { ref path, .. } => match path.def {
                 // If there is no resolution, `resolve` will have already reported an error, so
                 // assume that the visibility is public to avoid reporting more privacy errors.
index 8a0850595c889c9eee14ef155f5bb62c50e4086b..79c7a79114761785fc8e1cb9e8ce99ae88b01055 100644 (file)
@@ -1548,72 +1548,6 @@ fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
     }
 }
 
-declare_lint! {
-    pub UNNECESSARY_EXTERN_CRATES,
-    Allow,
-    "suggest removing `extern crate` for the 2018 edition"
-}
-
-pub struct ExternCrate(/* depth */ u32);
-
-impl ExternCrate {
-    pub fn new() -> Self {
-        ExternCrate(0)
-    }
-}
-
-impl LintPass for ExternCrate {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(UNNECESSARY_EXTERN_CRATES)
-    }
-}
-
-impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExternCrate {
-    fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
-        if !cx.tcx.features().extern_absolute_paths {
-            return
-        }
-        if let hir::ItemExternCrate(ref orig) =  it.node {
-            if it.attrs.iter().any(|a| a.check_name("macro_use")) {
-                return
-            }
-            let mut err = cx.struct_span_lint(UNNECESSARY_EXTERN_CRATES,
-                it.span, "`extern crate` is unnecessary in the new edition");
-            if it.vis == hir::Visibility::Public || self.0 > 1 || orig.is_some() {
-                let pub_ = if it.vis == hir::Visibility::Public {
-                    "pub "
-                } else {
-                    ""
-                };
-
-                let help = format!("use `{}use`", pub_);
-
-                if let Some(orig) = orig {
-                    err.span_suggestion(it.span, &help,
-                        format!("{}use {} as {};", pub_, orig, it.name));
-                } else {
-                    err.span_suggestion(it.span, &help,
-                        format!("{}use {};", pub_, it.name));
-                }
-            } else {
-                err.span_suggestion(it.span, "remove it", "".into());
-            }
-
-            err.emit();
-        }
-    }
-
-    fn check_mod(&mut self, _: &LateContext, _: &hir::Mod,
-                 _: Span, _: ast::NodeId) {
-        self.0 += 1;
-    }
-
-    fn check_mod_post(&mut self, _: &LateContext, _: &hir::Mod,
-                      _: Span, _: ast::NodeId) {
-        self.0 += 1;
-    }
-}
-
 /// Lint for trait and lifetime bounds that don't depend on type parameters
 /// which either do nothing, or stop the item from being used.
 pub struct TrivialConstraints;
index c5994d0536ee007299bc6ac9a528b6331896a05e..d6ce5b2ea57fe2228b2f0c6acf3aafda399b3098 100644 (file)
@@ -145,7 +145,6 @@ macro_rules! add_lint_group {
                           TypeLimits,
                           MissingDoc,
                           MissingDebugImplementations,
-                          ExternCrate,
                           );
 
     add_lint_group!(sess,
@@ -185,7 +184,7 @@ macro_rules! add_lint_group {
                     "rust_2018_idioms",
                     BARE_TRAIT_OBJECTS,
                     UNREACHABLE_PUB,
-                    UNNECESSARY_EXTERN_CRATES);
+                    UNUSED_EXTERN_CRATES);
 
     // Guidelines for creating a future incompatibility lint:
     //
index b5772df1306ed2ad096771f424eb114059ae3cf5..66dc76b1d94a081475e69b5a317d28f622188098 100644 (file)
 use syntax::ast;
 use syntax_pos::{Span, DUMMY_SP};
 
-use rustc::hir::def_id::LOCAL_CRATE;
+use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
+use rustc::hir::print::visibility_qualified;
 use rustc::hir;
 use rustc::util::nodemap::DefIdSet;
 
+use rustc_data_structures::fx::FxHashMap;
+
+pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
+    let mut used_trait_imports = DefIdSet();
+    for &body_id in tcx.hir.krate().bodies.keys() {
+        let item_def_id = tcx.hir.body_owner_def_id(body_id);
+        let imports = tcx.used_trait_imports(item_def_id);
+        debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports);
+        used_trait_imports.extend(imports.iter());
+    }
+
+    let mut visitor = CheckVisitor { tcx, used_trait_imports };
+    tcx.hir.krate().visit_all_item_likes(&mut visitor);
+
+    unused_crates_lint(tcx);
+}
+
+impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CheckVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, item: &hir::Item) {
+        if item.vis == hir::Public || item.span == DUMMY_SP {
+            return;
+        }
+        if let hir::ItemUse(ref path, _) = item.node {
+            self.check_import(item.id, path.span);
+        }
+    }
+
+    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
+    }
+
+    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
+    }
+}
+
 struct CheckVisitor<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     used_trait_imports: DefIdSet,
@@ -45,72 +80,146 @@ fn check_import(&self, id: ast::NodeId, span: Span) {
     }
 }
 
-impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CheckVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, item: &hir::Item) {
-        if item.vis == hir::Public || item.span == DUMMY_SP {
-            return;
-        }
-        if let hir::ItemUse(ref path, _) = item.node {
-            self.check_import(item.id, path.span);
-        }
+fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) {
+    let lint = lint::builtin::UNUSED_EXTERN_CRATES;
+
+    // Collect first the crates that are completely unused.  These we
+    // can always suggest removing (no matter which edition we are
+    // in).
+    let unused_extern_crates: FxHashMap<DefId, Span> =
+        tcx.maybe_unused_extern_crates(LOCAL_CRATE)
+        .iter()
+        .filter(|&&(def_id, _)| {
+            // The `def_id` here actually was calculated during resolution (at least
+            // at the time of this writing) and is being shipped to us via a side
+            // channel of the tcx. There may have been extra expansion phases,
+            // however, which ended up removing the `def_id` *after* expansion such
+            // as the `ReplaceBodyWithLoop` pass (which is a bit of a hack, but hey)
+            //
+            // As a result we need to verify that `def_id` is indeed still valid for
+            // our AST and actually present in the HIR map. If it's not there then
+            // there's safely nothing to warn about, and otherwise we carry on with
+            // our execution.
+            //
+            // Note that if we carry through to the `extern_mod_stmt_cnum` query
+            // below it'll cause a panic because `def_id` is actually bogus at this
+            // point in time otherwise.
+            if let Some(id) = tcx.hir.as_local_node_id(def_id) {
+                if tcx.hir.find(id).is_none() {
+                    return false;
+                }
+            }
+            true
+        })
+        .filter(|&&(def_id, _)| {
+            let cnum = tcx.extern_mod_stmt_cnum(def_id).unwrap();
+            !tcx.is_compiler_builtins(cnum)
+                && !tcx.is_panic_runtime(cnum)
+                && !tcx.has_global_allocator(cnum)
+        })
+        .cloned()
+        .collect();
+
+    // Issue lints for fully unused crates that suggest removing them.
+    for (&def_id, &span) in &unused_extern_crates {
+        assert_eq!(def_id.krate, LOCAL_CRATE);
+        let hir_id = tcx.hir.definitions().def_index_to_hir_id(def_id.index);
+        let id = tcx.hir.hir_to_node_id(hir_id);
+        let msg = "unused extern crate";
+        tcx.struct_span_lint_node(lint, id, span, msg)
+            .span_suggestion_short(span, "remove it", "".to_string())
+            .emit();
     }
 
-    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
+    // If we are not in Rust 2018 edition, we are done.
+    if !tcx.sess.rust_2018() {
+        return;
     }
 
-    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
+    // Otherwise, we can *also* suggest rewriting `extern crate`
+    // into `use` etc.
+    let mut crates_to_convert_to_use = vec![];
+    tcx.hir.krate().visit_all_item_likes(&mut CollectExternCrateVisitor {
+        tcx,
+        unused_extern_crates: &unused_extern_crates,
+        crates_to_convert_to_use: &mut crates_to_convert_to_use,
+    });
+
+    for to_convert in &crates_to_convert_to_use {
+        assert_eq!(to_convert.def_id.krate, LOCAL_CRATE);
+        let hir_id = tcx.hir.definitions().def_index_to_hir_id(to_convert.def_id.index);
+        let id = tcx.hir.hir_to_node_id(hir_id);
+        let item = tcx.hir.expect_item(id);
+        let msg = "`extern crate` is not idiomatic in the new edition";
+
+        let help = format!(
+            "convert it to a `{}`",
+            visibility_qualified(&item.vis, "use")
+        );
+
+        let base_replacement = match to_convert.orig_name {
+            Some(orig_name) => format!("use {} as {};", orig_name, item.name),
+            None => format!("use {};", item.name),
+        };
+        let replacement = visibility_qualified(&item.vis, &base_replacement);
+
+        tcx.struct_span_lint_node(lint, id, to_convert.span, msg)
+            .span_suggestion_short(to_convert.span, &help, replacement)
+            .emit();
     }
 }
 
-pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-    let mut used_trait_imports = DefIdSet();
-    for &body_id in tcx.hir.krate().bodies.keys() {
-        let item_def_id = tcx.hir.body_owner_def_id(body_id);
-        let imports = tcx.used_trait_imports(item_def_id);
-        debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports);
-        used_trait_imports.extend(imports.iter());
-    }
+struct CollectExternCrateVisitor<'a, 'tcx: 'a> {
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    unused_extern_crates: &'a FxHashMap<DefId, Span>,
+    crates_to_convert_to_use: &'a mut Vec<ExternCrateToConvertToUse>,
+}
 
-    let mut visitor = CheckVisitor { tcx, used_trait_imports };
-    tcx.hir.krate().visit_all_item_likes(&mut visitor);
+struct ExternCrateToConvertToUse {
+    /// def-id of the extern crate
+    def_id: DefId,
+
+    /// span from the item
+    span: Span,
 
-    for &(def_id, span) in tcx.maybe_unused_extern_crates(LOCAL_CRATE).iter() {
-        // The `def_id` here actually was calculated during resolution (at least
-        // at the time of this writing) and is being shipped to us via a side
-        // channel of the tcx. There may have been extra expansion phases,
-        // however, which ended up removing the `def_id` *after* expansion such
-        // as the `ReplaceBodyWithLoop` pass (which is a bit of a hack, but hey)
-        //
-        // As a result we need to verify that `def_id` is indeed still valid for
-        // our AST and actually present in the HIR map. If it's not there then
-        // there's safely nothing to warn about, and otherwise we carry on with
-        // our execution.
-        //
-        // Note that if we carry through to the `extern_mod_stmt_cnum` query
-        // below it'll cause a panic because `def_id` is actually bogus at this
-        // point in time otherwise.
-        if let Some(id) = tcx.hir.as_local_node_id(def_id) {
-            if tcx.hir.find(id).is_none() {
-                continue
+    /// if `Some`, then this is renamed (`extern crate orig_name as
+    /// crate_name`), and -- perhaps surprisingly -- this stores the
+    /// *original* name (`item.name` will contain the new name)
+    orig_name: Option<ast::Name>,
+}
+
+impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CollectExternCrateVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, item: &hir::Item) {
+        if let hir::ItemExternCrate(orig_name) = item.node {
+            let extern_crate_def_id = self.tcx.hir.local_def_id(item.id);
+
+            // If the crate is fully unused, we are going to suggest
+            // removing it anyway, so ignore it.
+            if self.unused_extern_crates.contains_key(&extern_crate_def_id) {
+                return;
             }
+
+            // If the extern crate has any attributes, they may have funky
+            // semantics we can't entirely understand. Ignore it.
+            if !self.tcx.get_attrs(extern_crate_def_id).is_empty() {
+                return;
+            }
+
+            // Otherwise, we can convert it into a `use` of some kind.
+            self.crates_to_convert_to_use.push(
+                ExternCrateToConvertToUse {
+                    def_id: extern_crate_def_id,
+                    span: item.span,
+                    orig_name,
+                }
+            );
         }
-        let cnum = tcx.extern_mod_stmt_cnum(def_id).unwrap();
-        if tcx.is_compiler_builtins(cnum) {
-            continue
-        }
-        if tcx.is_panic_runtime(cnum) {
-            continue
-        }
-        if tcx.has_global_allocator(cnum) {
-            continue
-        }
-        assert_eq!(def_id.krate, LOCAL_CRATE);
-        let hir_id = tcx.hir.definitions().def_index_to_hir_id(def_id.index);
-        let id = tcx.hir.hir_to_node_id(hir_id);
-        let lint = lint::builtin::UNUSED_EXTERN_CRATES;
-        let msg = "unused extern crate";
-        tcx.struct_span_lint_node(lint, id, span, msg)
-            .span_suggestion_short(span, "remove it", "".to_string())
-            .emit();
+    }
+
+    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
+    }
+
+    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
     }
 }
+
index 2e3ea3de7b0b7455dd18ae69ff4536ac16dbf748..a57f3a42939ee049838e3eccf2311b328a1426ae 100644 (file)
@@ -3030,7 +3030,7 @@ fn clean(&self, cx: &DocContext) -> Option<Visibility> {
         Some(match *self {
             hir::Visibility::Public => Visibility::Public,
             hir::Visibility::Inherited => Visibility::Inherited,
-            hir::Visibility::Crate => Visibility::Crate,
+            hir::Visibility::Crate(_) => Visibility::Crate,
             hir::Visibility::Restricted { ref path, .. } => {
                 let path = path.clean(cx);
                 let did = register_def(cx, path.def);
index 286ee896161a6a5e40c8a2d05e02913d75f0a2a7..7368564e250d1b7a7e9a8c487f417e6ca125196f 100644 (file)
@@ -12,8 +12,9 @@
 // compile-flags: --edition 2015
 // compile-pass
 
-#![deny(rust_2018_idioms)]
+#![warn(rust_2018_idioms)]
 
 extern crate edition_extern_crate_allowed;
+//~^ WARNING unused extern crate
 
 fn main() {}
index fc6cb6bd053e6402c23e48870f08b308b8259eda..0811c79b0a4b9d5d50a4abd343c8756934c855d5 100644 (file)
 
 // compile-flags: --edition 2018
 
-#![deny(unnecessary_extern_crates)]
+#![deny(unused_extern_crates)]
 #![feature(alloc, test, libc)]
 
 extern crate alloc;
-//~^ ERROR `extern crate` is unnecessary in the new edition
+//~^ ERROR unused extern crate
 //~| HELP remove
 extern crate alloc as x;
-//~^ ERROR `extern crate` is unnecessary in the new edition
-//~| HELP use `use`
+//~^ ERROR unused extern crate
+//~| HELP remove
 
 #[macro_use]
 extern crate test;
+
 pub extern crate test as y;
-//~^ ERROR `extern crate` is unnecessary in the new edition
-//~| HELP use `pub use`
+//~^ ERROR `extern crate` is not idiomatic in the new edition
+//~| HELP convert it to a `pub use`
+
 pub extern crate libc;
-//~^ ERROR `extern crate` is unnecessary in the new edition
-//~| HELP use `pub use`
+//~^ ERROR `extern crate` is not idiomatic in the new edition
+//~| HELP convert it to a `pub use`
+
+pub(crate) extern crate libc as a;
+//~^ ERROR `extern crate` is not idiomatic in the new edition
+//~| HELP convert it to a `pub(crate) use`
 
+crate extern crate libc as b;
+//~^ ERROR `extern crate` is not idiomatic in the new edition
+//~| HELP convert it to a `crate use`
 
 mod foo {
+    pub(in crate::foo) extern crate libc as c;
+    //~^ ERROR `extern crate` is not idiomatic in the new edition
+    //~| HELP convert it to a `pub(in crate::foo) use`
+
+    pub(super) extern crate libc as d;
+    //~^ ERROR `extern crate` is not idiomatic in the new edition
+    //~| HELP convert it to a `pub(super) use`
+
     extern crate alloc;
-    //~^ ERROR `extern crate` is unnecessary in the new edition
-    //~| HELP use `use`
+    //~^ ERROR unused extern crate
+    //~| HELP remove
+
     extern crate alloc as x;
-    //~^ ERROR `extern crate` is unnecessary in the new edition
-    //~| HELP use `use`
+    //~^ ERROR unused extern crate
+    //~| HELP remove
+
     pub extern crate test;
-    //~^ ERROR `extern crate` is unnecessary in the new edition
-    //~| HELP use `pub use`
+    //~^ ERROR `extern crate` is not idiomatic in the new edition
+    //~| HELP convert it
+
     pub extern crate test as y;
-    //~^ ERROR `extern crate` is unnecessary in the new edition
-    //~| HELP use `pub use`
+    //~^ ERROR `extern crate` is not idiomatic in the new edition
+    //~| HELP convert it
+
     mod bar {
         extern crate alloc;
-        //~^ ERROR `extern crate` is unnecessary in the new edition
-        //~| HELP use `use`
+        //~^ ERROR unused extern crate
+        //~| HELP remove
+
         extern crate alloc as x;
-        //~^ ERROR `extern crate` is unnecessary in the new edition
-        //~| HELP use `use`
+        //~^ ERROR unused extern crate
+        //~| HELP remove
+
+        pub(in crate::foo::bar) extern crate libc as e;
+        //~^ ERROR `extern crate` is not idiomatic in the new edition
+        //~| HELP convert it to a `pub(in crate::foo::bar) use`
+
+        fn dummy() {
+            unsafe {
+                e::getpid();
+            }
+        }
+    }
+
+    fn dummy() {
+        unsafe {
+            c::getpid();
+            d::getpid();
+        }
     }
 }
 
 
-fn main() {}
+fn main() {
+    unsafe { a::getpid(); }
+    unsafe { b::getpid(); }
+}
index b9ccf5b19e03a50c44879f83c1fb19ad2c9e717c..a64125c794379cb34c31517618c8ed8897e3336d 100644 (file)
@@ -1,68 +1,98 @@
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:16:1
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:51:5
    |
-LL | extern crate alloc;
-   | ^^^^^^^^^^^^^^^^^^^ help: remove it
+LL |     extern crate alloc;
+   |     ^^^^^^^^^^^^^^^^^^^ help: remove it
    |
 note: lint level defined here
   --> $DIR/unnecessary-extern-crate.rs:13:9
    |
-LL | #![deny(unnecessary_extern_crates)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(unused_extern_crates)]
+   |         ^^^^^^^^^^^^^^^^^^^^
 
-error: `extern crate` is unnecessary in the new edition
+error: unused extern crate
   --> $DIR/unnecessary-extern-crate.rs:19:1
    |
 LL | extern crate alloc as x;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc as x;`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:55:5
+   |
+LL |     extern crate alloc as x;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:68:9
+   |
+LL |         extern crate alloc;
+   |         ^^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:16:1
+   |
+LL | extern crate alloc;
+   | ^^^^^^^^^^^^^^^^^^^ help: remove it
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:25:1
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:72:9
+   |
+LL |         extern crate alloc as x;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:26:1
    |
 LL | pub extern crate test as y;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use test as y;`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub use`
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:28:1
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:30:1
    |
 LL | pub extern crate libc;
-   | ^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use libc;`
+   | ^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub use`
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:34:5
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:34:1
    |
-LL |     extern crate alloc;
-   |     ^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc;`
+LL | pub(crate) extern crate libc as a;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub(crate) use`
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:37:5
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:38:1
    |
-LL |     extern crate alloc as x;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc as x;`
+LL | crate extern crate libc as b;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `crate use`
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:40:5
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:43:5
    |
-LL |     pub extern crate test;
-   |     ^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use test;`
+LL |     pub(in crate::foo) extern crate libc as c;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub(in crate::foo) use`
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:43:5
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:47:5
    |
-LL |     pub extern crate test as y;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use test as y;`
+LL |     pub(super) extern crate libc as d;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub(super) use`
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:47:9
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:59:5
    |
-LL |         extern crate alloc;
-   |         ^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc;`
+LL |     pub extern crate test;
+   |     ^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub use`
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:50:9
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:63:5
    |
-LL |         extern crate alloc as x;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc as x;`
+LL |     pub extern crate test as y;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub use`
+
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:76:9
+   |
+LL |         pub(in crate::foo::bar) extern crate libc as e;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub(in crate::foo::bar) use`
 
-error: aborting due to 10 previous errors
+error: aborting due to 15 previous errors
 
index 4530d0fa604aa8721604ece3e254b69fd0794f48..c12c74b50e26402bbb54b2e5042dd19337073160 100644 (file)
@@ -20,7 +20,7 @@ warning: unused extern crate
   --> $DIR/basic.rs:33:5
    |
 LL |     extern crate core as _; //~ WARN unused extern crate
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
    |
 note: lint level defined here
   --> $DIR/basic.rs:14:25
index d8bf656cf2dd68c0aa000c111e6ba4de15c2eb72..4f99c1240f8f49a65baf52352a6e6ee8e91ca146 100644 (file)
 // but we don't.
 
 #![feature(rust_2018_preview)]
-#![deny(absolute_path_not_starting_with_crate)]
-#![deny(unused_extern_crates)]
+#![deny(rust_2018_idioms)]
 #![allow(dead_code)]
 
 
 //~^ ERROR unused extern crate
 
-extern crate edition_lint_paths as bar;
+use edition_lint_paths as bar;
+//~^ ERROR `extern crate` is not idiomatic in the new edition
 
 fn main() {
     // This is not considered to *use* the `extern crate` in Rust 2018:
index 6e741257d80891b30f6a8d80c335a167fbc4c276..9c1235a296799cdd238f5a55705e3c7e18cd28fe 100644 (file)
 // but we don't.
 
 #![feature(rust_2018_preview)]
-#![deny(absolute_path_not_starting_with_crate)]
-#![deny(unused_extern_crates)]
+#![deny(rust_2018_idioms)]
 #![allow(dead_code)]
 
 extern crate edition_lint_paths;
 //~^ ERROR unused extern crate
 
 extern crate edition_lint_paths as bar;
+//~^ ERROR `extern crate` is not idiomatic in the new edition
 
 fn main() {
     // This is not considered to *use* the `extern crate` in Rust 2018:
index 8fae69e8bd5a3ad4ab1454a8f0864e8cdee3d8e8..b3afa2bd1d59289bb9c7ffd23a23829793436a7b 100644 (file)
@@ -1,14 +1,21 @@
 error: unused extern crate
-  --> $DIR/extern-crate-idiomatic-in-2018.rs:23:1
+  --> $DIR/extern-crate-idiomatic-in-2018.rs:22:1
    |
 LL | extern crate edition_lint_paths;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
    |
 note: lint level defined here
-  --> $DIR/extern-crate-idiomatic-in-2018.rs:20:9
+  --> $DIR/extern-crate-idiomatic-in-2018.rs:19:9
    |
-LL | #![deny(unused_extern_crates)]
-   |         ^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rust_2018_idioms)]
+   |         ^^^^^^^^^^^^^^^^
+   = note: #[deny(unused_extern_crates)] implied by #[deny(rust_2018_idioms)]
 
-error: aborting due to previous error
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/extern-crate-idiomatic-in-2018.rs:25:1
+   |
+LL | extern crate edition_lint_paths as bar;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use`
+
+error: aborting due to 2 previous errors
 
index 723137f5db0c12d68175827b0a61d9fa8160eaf9..83b35cec80956847ff2141afc27d63697b8b209f 100644 (file)
 #![warn(rust_2018_idioms)]
 #![allow(unused_imports)]
 
-use std as foo;
+
 
 
 mod another {
-    use std as foo;
-    use std;
+    
+    
 }
 
 fn main() {}
index 39d22de02776c915dab94cd6ce9e5f5f62876270..e7caab5ec54594c257aae4fbf7cee0ba4dafdeb2 100644 (file)
@@ -1,31 +1,31 @@
-warning: `extern crate` is unnecessary in the new edition
-  --> $DIR/removing-extern-crate.rs:19:1
+warning: unused extern crate
+  --> $DIR/removing-extern-crate.rs:24:5
    |
-LL | extern crate std as foo;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use std as foo;`
+LL |     extern crate std;
+   |     ^^^^^^^^^^^^^^^^^ help: remove it
    |
 note: lint level defined here
   --> $DIR/removing-extern-crate.rs:16:9
    |
 LL | #![warn(rust_2018_idioms)]
    |         ^^^^^^^^^^^^^^^^
-   = note: #[warn(unnecessary_extern_crates)] implied by #[warn(rust_2018_idioms)]
+   = note: #[warn(unused_extern_crates)] implied by #[warn(rust_2018_idioms)]
 
-warning: `extern crate` is unnecessary in the new edition
+warning: unused extern crate
   --> $DIR/removing-extern-crate.rs:20:1
    |
 LL | extern crate core;
    | ^^^^^^^^^^^^^^^^^^ help: remove it
 
-warning: `extern crate` is unnecessary in the new edition
+warning: unused extern crate
   --> $DIR/removing-extern-crate.rs:23:5
    |
 LL |     extern crate std as foo;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use std as foo;`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
 
-warning: `extern crate` is unnecessary in the new edition
-  --> $DIR/removing-extern-crate.rs:24:5
+warning: unused extern crate
+  --> $DIR/removing-extern-crate.rs:19:1
    |
-LL |     extern crate std;
-   |     ^^^^^^^^^^^^^^^^^ help: use `use`: `use std;`
+LL | extern crate std as foo;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it