merge UNNECESSARY_EXTERN_CRATE and UNUSED_EXTERN_CRATES

This commit is contained in:
Niko Matsakis 2018-05-25 16:53:49 -04:00
parent d5010ecf44
commit 8b39808ffe
19 changed files with 378 additions and 239 deletions

View File

@ -2433,7 +2433,7 @@ impl<'a> LoweringContext<'a> {
self.with_hir_id_owner(new_id, |this| { self.with_hir_id_owner(new_id, |this| {
let vis = match vis { let vis = match vis {
hir::Visibility::Public => hir::Visibility::Public, 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::Inherited => hir::Visibility::Inherited,
hir::Visibility::Restricted { ref path, id: _ } => { hir::Visibility::Restricted { ref path, id: _ } => {
hir::Visibility::Restricted { hir::Visibility::Restricted {
@ -3704,7 +3704,7 @@ impl<'a> LoweringContext<'a> {
) -> hir::Visibility { ) -> hir::Visibility {
match v.node { match v.node {
VisibilityKind::Public => hir::Public, VisibilityKind::Public => hir::Public,
VisibilityKind::Crate(..) => hir::Visibility::Crate, VisibilityKind::Crate(sugar) => hir::Visibility::Crate(sugar),
VisibilityKind::Restricted { ref path, id, .. } => hir::Visibility::Restricted { VisibilityKind::Restricted { ref path, id, .. } => hir::Visibility::Restricted {
path: P(self.lower_path(id, path, ParamMode::Explicit)), path: P(self.lower_path(id, path, ParamMode::Explicit)),
id: if let Some(owner) = explicit_owner { id: if let Some(owner) = explicit_owner {

View File

@ -463,7 +463,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
fn visit_vis(&mut self, visibility: &'hir Visibility) { fn visit_vis(&mut self, visibility: &'hir Visibility) {
match *visibility { match *visibility {
Visibility::Public | Visibility::Public |
Visibility::Crate | Visibility::Crate(_) |
Visibility::Inherited => {} Visibility::Inherited => {}
Visibility::Restricted { id, .. } => { Visibility::Restricted { id, .. } => {
self.insert(id, NodeVisibility(visibility)); self.insert(id, NodeVisibility(visibility));

View File

@ -35,7 +35,7 @@ use mir::mono::Linkage;
use syntax_pos::{Span, DUMMY_SP}; use syntax_pos::{Span, DUMMY_SP};
use syntax::codemap::{self, Spanned}; use syntax::codemap::{self, Spanned};
use rustc_target::spec::abi::Abi; 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::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
use syntax::attr::InlineAttr; use syntax::attr::InlineAttr;
use syntax::ext::hygiene::SyntaxContext; use syntax::ext::hygiene::SyntaxContext;
@ -1953,7 +1953,7 @@ pub struct PolyTraitRef {
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum Visibility { pub enum Visibility {
Public, Public,
Crate, Crate(CrateSugar),
Restricted { path: P<Path>, id: NodeId }, Restricted { path: P<Path>, id: NodeId },
Inherited, Inherited,
} }
@ -1964,7 +1964,7 @@ impl Visibility {
match self { match self {
&Public | &Public |
&Inherited => false, &Inherited => false,
&Crate | &Crate(_) |
&Restricted { .. } => true, &Restricted { .. } => true,
} }
} }

View File

@ -801,15 +801,25 @@ impl<'a> State<'a> {
pub fn print_visibility(&mut self, vis: &hir::Visibility) -> io::Result<()> { pub fn print_visibility(&mut self, vis: &hir::Visibility) -> io::Result<()> {
match *vis { match *vis {
hir::Public => self.word_nbsp("pub"), hir::Public => self.word_nbsp("pub")?,
hir::Visibility::Crate => self.word_nbsp("pub(crate)"), 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, .. } => { hir::Visibility::Restricted { ref path, .. } => {
self.s.word("pub(")?; self.s.word("pub(")?;
self.print_path(path, false)?; if path.segments.len() == 1 && path.segments[0].name == keywords::Super.name() {
self.word_nbsp(")") // 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<()> { pub fn print_defaultness(&mut self, defaultness: hir::Defaultness) -> io::Result<()> {

View File

@ -751,6 +751,11 @@ impl_stable_hash_for!(enum hir::ImplItemKind {
Type(t) Type(t)
}); });
impl_stable_hash_for!(enum ::syntax::ast::CrateSugar {
JustCrate,
PubCrate,
});
impl<'a> HashStable<StableHashingContext<'a>> for hir::Visibility { impl<'a> HashStable<StableHashingContext<'a>> for hir::Visibility {
fn hash_stable<W: StableHasherResult>(&self, fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'a>, hcx: &mut StableHashingContext<'a>,
@ -758,10 +763,12 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Visibility {
mem::discriminant(self).hash_stable(hcx, hasher); mem::discriminant(self).hash_stable(hcx, hasher);
match *self { match *self {
hir::Visibility::Public | hir::Visibility::Public |
hir::Visibility::Crate |
hir::Visibility::Inherited => { hir::Visibility::Inherited => {
// No fields to hash. // No fields to hash.
} }
hir::Visibility::Crate(sugar) => {
sugar.hash_stable(hcx, hasher);
}
hir::Visibility::Restricted { ref path, id } => { hir::Visibility::Restricted { ref path, id } => {
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
id.hash_stable(hcx, hasher); id.hash_stable(hcx, hasher);

View File

@ -270,7 +270,7 @@ impl Visibility {
pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: TyCtxt) -> Self { pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: TyCtxt) -> Self {
match *visibility { match *visibility {
hir::Public => Visibility::Public, 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 { hir::Visibility::Restricted { ref path, .. } => match path.def {
// If there is no resolution, `resolve` will have already reported an error, so // 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. // assume that the visibility is public to avoid reporting more privacy errors.

View File

@ -1548,72 +1548,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedBrokenConst {
} }
} }
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 /// Lint for trait and lifetime bounds that don't depend on type parameters
/// which either do nothing, or stop the item from being used. /// which either do nothing, or stop the item from being used.
pub struct TrivialConstraints; pub struct TrivialConstraints;

View File

@ -145,7 +145,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
TypeLimits, TypeLimits,
MissingDoc, MissingDoc,
MissingDebugImplementations, MissingDebugImplementations,
ExternCrate,
); );
add_lint_group!(sess, add_lint_group!(sess,
@ -185,7 +184,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
"rust_2018_idioms", "rust_2018_idioms",
BARE_TRAIT_OBJECTS, BARE_TRAIT_OBJECTS,
UNREACHABLE_PUB, UNREACHABLE_PUB,
UNNECESSARY_EXTERN_CRATES); UNUSED_EXTERN_CRATES);
// Guidelines for creating a future incompatibility lint: // Guidelines for creating a future incompatibility lint:
// //

View File

@ -14,11 +14,46 @@ use rustc::ty::TyCtxt;
use syntax::ast; use syntax::ast;
use syntax_pos::{Span, DUMMY_SP}; 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::itemlikevisit::ItemLikeVisitor;
use rustc::hir::print::visibility_qualified;
use rustc::hir; use rustc::hir;
use rustc::util::nodemap::DefIdSet; 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> { struct CheckVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
used_trait_imports: DefIdSet, used_trait_imports: DefIdSet,
@ -45,13 +80,139 @@ impl<'a, 'tcx> CheckVisitor<'a, 'tcx> {
} }
} }
impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CheckVisitor<'a, 'tcx> { 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();
}
// If we are not in Rust 2018 edition, we are done.
if !tcx.sess.rust_2018() {
return;
}
// 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();
}
}
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>,
}
struct ExternCrateToConvertToUse {
/// def-id of the extern crate
def_id: DefId,
/// span from the item
span: Span,
/// 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) { fn visit_item(&mut self, item: &hir::Item) {
if item.vis == hir::Public || item.span == DUMMY_SP { if let hir::ItemExternCrate(orig_name) = item.node {
return; let extern_crate_def_id = self.tcx.hir.local_def_id(item.id);
}
if let hir::ItemUse(ref path, _) = item.node { // If the crate is fully unused, we are going to suggest
self.check_import(item.id, path.span); // 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,
}
);
} }
} }
@ -62,55 +223,3 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CheckVisitor<'a, 'tcx> {
} }
} }
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);
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
}
}
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();
}
}

View File

@ -3030,7 +3030,7 @@ impl Clean<Option<Visibility>> for hir::Visibility {
Some(match *self { Some(match *self {
hir::Visibility::Public => Visibility::Public, hir::Visibility::Public => Visibility::Public,
hir::Visibility::Inherited => Visibility::Inherited, hir::Visibility::Inherited => Visibility::Inherited,
hir::Visibility::Crate => Visibility::Crate, hir::Visibility::Crate(_) => Visibility::Crate,
hir::Visibility::Restricted { ref path, .. } => { hir::Visibility::Restricted { ref path, .. } => {
let path = path.clean(cx); let path = path.clean(cx);
let did = register_def(cx, path.def); let did = register_def(cx, path.def);

View File

@ -12,8 +12,9 @@
// compile-flags: --edition 2015 // compile-flags: --edition 2015
// compile-pass // compile-pass
#![deny(rust_2018_idioms)] #![warn(rust_2018_idioms)]
extern crate edition_extern_crate_allowed; extern crate edition_extern_crate_allowed;
//~^ WARNING unused extern crate
fn main() {} fn main() {}

View File

@ -10,48 +10,90 @@
// compile-flags: --edition 2018 // compile-flags: --edition 2018
#![deny(unnecessary_extern_crates)] #![deny(unused_extern_crates)]
#![feature(alloc, test, libc)] #![feature(alloc, test, libc)]
extern crate alloc; extern crate alloc;
//~^ ERROR `extern crate` is unnecessary in the new edition //~^ ERROR unused extern crate
//~| HELP remove //~| HELP remove
extern crate alloc as x; extern crate alloc as x;
//~^ ERROR `extern crate` is unnecessary in the new edition //~^ ERROR unused extern crate
//~| HELP use `use` //~| HELP remove
#[macro_use] #[macro_use]
extern crate test; extern crate test;
pub extern crate test as y;
//~^ ERROR `extern crate` is unnecessary in the new edition
//~| HELP use `pub use`
pub extern crate libc;
//~^ ERROR `extern crate` is unnecessary in the new edition
//~| HELP use `pub use`
pub extern crate test as y;
//~^ 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 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 { 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; extern crate alloc;
//~^ ERROR `extern crate` is unnecessary in the new edition //~^ ERROR unused extern crate
//~| HELP use `use` //~| HELP remove
extern crate alloc as x; extern crate alloc as x;
//~^ ERROR `extern crate` is unnecessary in the new edition //~^ ERROR unused extern crate
//~| HELP use `use` //~| HELP remove
pub extern crate test; pub extern crate test;
//~^ ERROR `extern crate` is unnecessary in the new edition //~^ ERROR `extern crate` is not idiomatic in the new edition
//~| HELP use `pub use` //~| HELP convert it
pub extern crate test as y; pub extern crate test as y;
//~^ ERROR `extern crate` is unnecessary in the new edition //~^ ERROR `extern crate` is not idiomatic in the new edition
//~| HELP use `pub use` //~| HELP convert it
mod bar { mod bar {
extern crate alloc; extern crate alloc;
//~^ ERROR `extern crate` is unnecessary in the new edition //~^ ERROR unused extern crate
//~| HELP use `use` //~| HELP remove
extern crate alloc as x; extern crate alloc as x;
//~^ ERROR `extern crate` is unnecessary in the new edition //~^ ERROR unused extern crate
//~| HELP use `use` //~| 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(); }
}

View File

@ -1,68 +1,98 @@
error: `extern crate` is unnecessary in the new edition error: unused extern crate
--> $DIR/unnecessary-extern-crate.rs:16:1 --> $DIR/unnecessary-extern-crate.rs:51:5
| |
LL | extern crate alloc; LL | extern crate alloc;
| ^^^^^^^^^^^^^^^^^^^ help: remove it | ^^^^^^^^^^^^^^^^^^^ help: remove it
| |
note: lint level defined here note: lint level defined here
--> $DIR/unnecessary-extern-crate.rs:13:9 --> $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 --> $DIR/unnecessary-extern-crate.rs:19:1
| |
LL | extern crate alloc as x; LL | extern crate alloc as x;
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc as x;` | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
error: `extern crate` is unnecessary in the new edition error: unused extern crate
--> $DIR/unnecessary-extern-crate.rs:25:1 --> $DIR/unnecessary-extern-crate.rs:55:5
|
LL | pub extern crate test as y;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use test as y;`
error: `extern crate` is unnecessary in the new edition
--> $DIR/unnecessary-extern-crate.rs:28:1
|
LL | pub extern crate libc;
| ^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use libc;`
error: `extern crate` is unnecessary in the new edition
--> $DIR/unnecessary-extern-crate.rs:34:5
|
LL | extern crate alloc;
| ^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc;`
error: `extern crate` is unnecessary in the new edition
--> $DIR/unnecessary-extern-crate.rs:37:5
| |
LL | extern crate alloc as x; LL | extern crate alloc as x;
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc as x;` | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
error: `extern crate` is unnecessary in the new edition error: unused extern crate
--> $DIR/unnecessary-extern-crate.rs:40:5 --> $DIR/unnecessary-extern-crate.rs:68:9
|
LL | pub extern crate test;
| ^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use test;`
error: `extern crate` is unnecessary in the new edition
--> $DIR/unnecessary-extern-crate.rs:43:5
|
LL | pub extern crate test as y;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use test as y;`
error: `extern crate` is unnecessary in the new edition
--> $DIR/unnecessary-extern-crate.rs:47:9
| |
LL | extern crate alloc; LL | extern crate alloc;
| ^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc;` | ^^^^^^^^^^^^^^^^^^^ help: remove it
error: `extern crate` is unnecessary in the new edition error: unused extern crate
--> $DIR/unnecessary-extern-crate.rs:50:9 --> $DIR/unnecessary-extern-crate.rs:16:1
|
LL | extern crate alloc;
| ^^^^^^^^^^^^^^^^^^^ help: remove it
error: unused extern crate
--> $DIR/unnecessary-extern-crate.rs:72:9
| |
LL | extern crate alloc as x; LL | extern crate alloc as x;
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc as x;` | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
error: aborting due to 10 previous errors 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: convert it to a `pub use`
error: `extern crate` is not idiomatic in the new edition
--> $DIR/unnecessary-extern-crate.rs:30:1
|
LL | pub extern crate libc;
| ^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub use`
error: `extern crate` is not idiomatic in the new edition
--> $DIR/unnecessary-extern-crate.rs:34:1
|
LL | pub(crate) extern crate libc as a;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub(crate) use`
error: `extern crate` is not idiomatic in the new edition
--> $DIR/unnecessary-extern-crate.rs:38:1
|
LL | crate extern crate libc as b;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `crate use`
error: `extern crate` is not idiomatic in the new edition
--> $DIR/unnecessary-extern-crate.rs:43:5
|
LL | pub(in crate::foo) extern crate libc as c;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub(in crate::foo) use`
error: `extern crate` is not idiomatic in the new edition
--> $DIR/unnecessary-extern-crate.rs:47:5
|
LL | pub(super) extern crate libc as d;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub(super) use`
error: `extern crate` is not idiomatic in the new edition
--> $DIR/unnecessary-extern-crate.rs:59:5
|
LL | pub extern crate test;
| ^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub use`
error: `extern crate` is not idiomatic in the new edition
--> $DIR/unnecessary-extern-crate.rs:63:5
|
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 15 previous errors

View File

@ -20,7 +20,7 @@ warning: unused extern crate
--> $DIR/basic.rs:33:5 --> $DIR/basic.rs:33:5
| |
LL | extern crate core as _; //~ WARN unused extern crate LL | extern crate core as _; //~ WARN unused extern crate
| ^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
| |
note: lint level defined here note: lint level defined here
--> $DIR/basic.rs:14:25 --> $DIR/basic.rs:14:25

View File

@ -16,14 +16,14 @@
// but we don't. // but we don't.
#![feature(rust_2018_preview)] #![feature(rust_2018_preview)]
#![deny(absolute_path_not_starting_with_crate)] #![deny(rust_2018_idioms)]
#![deny(unused_extern_crates)]
#![allow(dead_code)] #![allow(dead_code)]
//~^ ERROR unused extern crate //~^ 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() { fn main() {
// This is not considered to *use* the `extern crate` in Rust 2018: // This is not considered to *use* the `extern crate` in Rust 2018:

View File

@ -16,14 +16,14 @@
// but we don't. // but we don't.
#![feature(rust_2018_preview)] #![feature(rust_2018_preview)]
#![deny(absolute_path_not_starting_with_crate)] #![deny(rust_2018_idioms)]
#![deny(unused_extern_crates)]
#![allow(dead_code)] #![allow(dead_code)]
extern crate edition_lint_paths; extern crate edition_lint_paths;
//~^ ERROR unused extern crate //~^ ERROR unused extern crate
extern crate edition_lint_paths as bar; extern crate edition_lint_paths as bar;
//~^ ERROR `extern crate` is not idiomatic in the new edition
fn main() { fn main() {
// This is not considered to *use* the `extern crate` in Rust 2018: // This is not considered to *use* the `extern crate` in Rust 2018:

View File

@ -1,14 +1,21 @@
error: unused extern crate 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; LL | extern crate edition_lint_paths;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
| |
note: lint level defined here 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

View File

@ -16,12 +16,12 @@
#![warn(rust_2018_idioms)] #![warn(rust_2018_idioms)]
#![allow(unused_imports)] #![allow(unused_imports)]
use std as foo;
mod another { mod another {
use std as foo;
use std;
} }
fn main() {} fn main() {}

View File

@ -1,31 +1,31 @@
warning: `extern crate` is unnecessary in the new edition warning: unused extern crate
--> $DIR/removing-extern-crate.rs:19:1 --> $DIR/removing-extern-crate.rs:24:5
| |
LL | extern crate std as foo; LL | extern crate std;
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use std as foo;` | ^^^^^^^^^^^^^^^^^ help: remove it
| |
note: lint level defined here note: lint level defined here
--> $DIR/removing-extern-crate.rs:16:9 --> $DIR/removing-extern-crate.rs:16:9
| |
LL | #![warn(rust_2018_idioms)] 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 --> $DIR/removing-extern-crate.rs:20:1
| |
LL | extern crate core; LL | extern crate core;
| ^^^^^^^^^^^^^^^^^^ help: remove it | ^^^^^^^^^^^^^^^^^^ help: remove it
warning: `extern crate` is unnecessary in the new edition warning: unused extern crate
--> $DIR/removing-extern-crate.rs:23:5 --> $DIR/removing-extern-crate.rs:23:5
| |
LL | extern crate std as foo; 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 warning: unused extern crate
--> $DIR/removing-extern-crate.rs:24:5 --> $DIR/removing-extern-crate.rs:19:1
| |
LL | extern crate std; LL | extern crate std as foo;
| ^^^^^^^^^^^^^^^^^ help: use `use`: `use std;` | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it