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 {
) -> 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 {
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));
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;
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum Visibility {
Public,
- Crate,
+ Crate(CrateSugar),
Restricted { path: P<Path>, id: NodeId },
Inherited,
}
match self {
&Public |
&Inherited => false,
- &Crate |
+ &Crate(_) |
&Restricted { .. } => true,
}
}
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<()> {
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>,
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);
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.
}
}
-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;
TypeLimits,
MissingDoc,
MissingDebugImplementations,
- ExternCrate,
);
add_lint_group!(sess,
"rust_2018_idioms",
BARE_TRAIT_OBJECTS,
UNREACHABLE_PUB,
- UNNECESSARY_EXTERN_CRATES);
+ UNUSED_EXTERN_CRATES);
// Guidelines for creating a future incompatibility lint:
//
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,
}
}
-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) {
}
}
+
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);
// 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() {}
// 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(); }
+}
-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
--> $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
// 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:
// 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:
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
#![warn(rust_2018_idioms)]
#![allow(unused_imports)]
-use std as foo;
+
mod another {
- use std as foo;
- use std;
+
+
}
fn main() {}
-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