Auto merge of #51015 - nikomatsakis:issue-50672-remove-extern-crate-idiom, r=alexcrichton
merge unused-extern-crate and unnecessary-extern-crate lints Extend the `unused_extern_crates` lint to offer a suggestion to remove the extern crate and remove the `unnecessary_extern_crate` lint. Still a few minor issues to fix: - [x] this *does* now leave a blank line... (defer to https://github.com/rust-lang/rust/issues/51176) - idea: extend the span to be replaced by 1 character if the next character is a `\n` - [x] what about macros? do we need to watch out for that? (defer to https://github.com/rust-lang/rust/issues/48704) - [x] also it doesn't work for `extern crate foo; fn main() { foo::bar(); }` - this is subtle: the `foo` might be shadowing a glob import too, can't always remove - defer to https://github.com/rust-lang/rust/issues/51177 - [x] we also don't do the `pub use` rewrite thang (https://github.com/rust-lang/rust/issues/51013) Spun off from https://github.com/rust-lang/rust/pull/51010 Fixes #50672 r? @alexcrichton
This commit is contained in:
commit
1b3d737716
@ -2433,7 +2433,7 @@ impl<'a> LoweringContext<'a> {
|
||||
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 @@ impl<'a> LoweringContext<'a> {
|
||||
) -> 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 {
|
||||
|
@ -463,7 +463,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
||||
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));
|
||||
|
@ -35,7 +35,7 @@ use mir::mono::Linkage;
|
||||
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 @@ impl Visibility {
|
||||
match self {
|
||||
&Public |
|
||||
&Inherited => false,
|
||||
&Crate |
|
||||
&Crate(_) |
|
||||
&Restricted { .. } => true,
|
||||
}
|
||||
}
|
||||
|
@ -801,15 +801,25 @@ impl<'a> State<'a> {
|
||||
|
||||
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(")?;
|
||||
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(()),
|
||||
self.word_nbsp(")")?;
|
||||
}
|
||||
hir::Inherited => ()
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn print_defaultness(&mut self, defaultness: hir::Defaultness) -> io::Result<()> {
|
||||
|
@ -751,6 +751,11 @@ impl_stable_hash_for!(enum hir::ImplItemKind {
|
||||
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 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Visibility {
|
||||
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);
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
/// which either do nothing, or stop the item from being used.
|
||||
pub struct TrivialConstraints;
|
||||
|
@ -145,7 +145,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||
TypeLimits,
|
||||
MissingDoc,
|
||||
MissingDebugImplementations,
|
||||
ExternCrate,
|
||||
);
|
||||
|
||||
add_lint_group!(sess,
|
||||
@ -185,7 +184,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
||||
"rust_2018_idioms",
|
||||
BARE_TRAIT_OBJECTS,
|
||||
UNREACHABLE_PUB,
|
||||
UNNECESSARY_EXTERN_CRATES);
|
||||
UNUSED_EXTERN_CRATES);
|
||||
|
||||
// Guidelines for creating a future incompatibility lint:
|
||||
//
|
||||
|
@ -14,11 +14,46 @@ use rustc::ty::TyCtxt;
|
||||
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,36 +80,16 @@ impl<'a, 'tcx> CheckVisitor<'a, '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 unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) {
|
||||
let lint = lint::builtin::UNUSED_EXTERN_CRATES;
|
||||
|
||||
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
// 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,
|
||||
@ -91,24 +106,112 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||
// point in time otherwise.
|
||||
if let Some(id) = tcx.hir.as_local_node_id(def_id) {
|
||||
if tcx.hir.find(id).is_none() {
|
||||
continue
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
})
|
||||
.filter(|&&(def_id, _)| {
|
||||
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);
|
||||
!tcx.is_compiler_builtins(cnum)
|
||||
&& !tcx.is_panic_runtime(cnum)
|
||||
&& !tcx.has_global_allocator(cnum)
|
||||
})
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
// Collect all the extern crates (in a reliable order).
|
||||
let mut crates_to_lint = vec![];
|
||||
tcx.hir.krate().visit_all_item_likes(&mut CollectExternCrateVisitor {
|
||||
tcx,
|
||||
crates_to_lint: &mut crates_to_lint,
|
||||
});
|
||||
|
||||
for extern_crate in &crates_to_lint {
|
||||
assert!(extern_crate.def_id.is_local());
|
||||
|
||||
// If the crate is fully unused, we suggest removing it altogether.
|
||||
// We do this in any edition.
|
||||
if let Some(&span) = unused_extern_crates.get(&extern_crate.def_id) {
|
||||
assert_eq!(extern_crate.def_id.krate, LOCAL_CRATE);
|
||||
let hir_id = tcx.hir.definitions().def_index_to_hir_id(extern_crate.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.lint_node(lint, id, span, msg);
|
||||
tcx.struct_span_lint_node(lint, id, span, msg)
|
||||
.span_suggestion_short(span, "remove it", "".to_string())
|
||||
.emit();
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we are not in Rust 2018 edition, then we don't make any further
|
||||
// suggestions.
|
||||
if !tcx.sess.rust_2018() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the extern crate has any attributes, they may have funky
|
||||
// semantics we can't faithfully represent using `use` (most
|
||||
// notably `#[macro_use]`). Ignore it.
|
||||
if !tcx.get_attrs(extern_crate.def_id).is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise, we can convert it into a `use` of some kind.
|
||||
let hir_id = tcx.hir.definitions().def_index_to_hir_id(extern_crate.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 extern_crate.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, extern_crate.span, msg)
|
||||
.span_suggestion_short(extern_crate.span, &help, replacement)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
struct CollectExternCrateVisitor<'a, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
crates_to_lint: &'a mut Vec<ExternCrateToLint>,
|
||||
}
|
||||
|
||||
struct ExternCrateToLint {
|
||||
/// 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) {
|
||||
if let hir::ItemExternCrate(orig_name) = item.node {
|
||||
let extern_crate_def_id = self.tcx.hir.local_def_id(item.id);
|
||||
self.crates_to_lint.push(
|
||||
ExternCrateToLint {
|
||||
def_id: extern_crate_def_id,
|
||||
span: item.span,
|
||||
orig_name,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3030,7 +3030,7 @@ impl Clean<Option<Visibility>> for hir::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);
|
||||
|
@ -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() {}
|
||||
|
@ -10,48 +10,90 @@
|
||||
|
||||
// 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`
|
||||
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 {
|
||||
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(); }
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
error: `extern crate` is unnecessary in the new edition
|
||||
error: unused extern crate
|
||||
--> $DIR/unnecessary-extern-crate.rs:16:1
|
||||
|
|
||||
LL | extern crate alloc;
|
||||
@ -7,62 +7,92 @@ LL | extern crate alloc;
|
||||
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: `extern crate` is unnecessary in the new edition
|
||||
--> $DIR/unnecessary-extern-crate.rs:25:1
|
||||
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
|
||||
|
|
||||
LL | pub extern crate test;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use test;`
|
||||
|
||||
error: `extern crate` is unnecessary in the new edition
|
||||
error: `extern crate` is not idiomatic 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;`
|
||||
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:47:9
|
||||
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: unused extern crate
|
||||
--> $DIR/unnecessary-extern-crate.rs:51:5
|
||||
|
|
||||
LL | extern crate alloc;
|
||||
| ^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc;`
|
||||
| ^^^^^^^^^^^^^^^^^^^ help: remove it
|
||||
|
||||
error: `extern crate` is unnecessary in the new edition
|
||||
--> $DIR/unnecessary-extern-crate.rs:50:9
|
||||
error: unused extern crate
|
||||
--> $DIR/unnecessary-extern-crate.rs:55:5
|
||||
|
|
||||
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: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: 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: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: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
|
||||
|
||||
|
@ -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
|
||||
|
36
src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed
Normal file
36
src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:edition-lint-paths.rs
|
||||
// run-rustfix
|
||||
// compile-flags:--edition 2018
|
||||
|
||||
// The "normal case". Ideally we would remove the `extern crate` here,
|
||||
// but we don't.
|
||||
|
||||
#![feature(rust_2018_preview)]
|
||||
#![deny(rust_2018_idioms)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
|
||||
//~^ ERROR unused extern crate
|
||||
|
||||
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:
|
||||
use edition_lint_paths::foo;
|
||||
foo();
|
||||
|
||||
// But this should be a use of the (renamed) crate:
|
||||
crate::bar::foo();
|
||||
}
|
||||
|
36
src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs
Normal file
36
src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:edition-lint-paths.rs
|
||||
// run-rustfix
|
||||
// compile-flags:--edition 2018
|
||||
|
||||
// The "normal case". Ideally we would remove the `extern crate` here,
|
||||
// but we don't.
|
||||
|
||||
#![feature(rust_2018_preview)]
|
||||
#![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:
|
||||
use edition_lint_paths::foo;
|
||||
foo();
|
||||
|
||||
// But this should be a use of the (renamed) crate:
|
||||
crate::bar::foo();
|
||||
}
|
||||
|
21
src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr
Normal file
21
src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr
Normal file
@ -0,0 +1,21 @@
|
||||
error: unused extern crate
|
||||
--> $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:19:9
|
||||
|
|
||||
LL | #![deny(rust_2018_idioms)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
= note: #[deny(unused_extern_crates)] implied by #[deny(rust_2018_idioms)]
|
||||
|
||||
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
|
||||
|
@ -16,12 +16,12 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use std as foo;
|
||||
|
||||
|
||||
|
||||
mod another {
|
||||
use std as foo;
|
||||
use std;
|
||||
|
||||
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,31 +1,31 @@
|
||||
warning: `extern crate` is unnecessary in the new edition
|
||||
warning: unused extern crate
|
||||
--> $DIR/removing-extern-crate.rs:19:1
|
||||
|
|
||||
LL | extern crate std as foo;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use std as foo;`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
warning: unused extern crate
|
||||
--> $DIR/removing-extern-crate.rs:24:5
|
||||
|
|
||||
LL | extern crate std;
|
||||
| ^^^^^^^^^^^^^^^^^ help: use `use`: `use std;`
|
||||
| ^^^^^^^^^^^^^^^^^ help: remove it
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user