Rollup merge of #121958 - chenyukang:yukang-fix-121915-import, r=petrochenkov
Fix redundant import errors for preload extern crate Fixes #121915
This commit is contained in:
commit
550b8a2cf9
@ -143,7 +143,11 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di
|
||||
BuiltinLintDiag::RedundantImport(spans, ident) => {
|
||||
for (span, is_imported) in spans {
|
||||
let introduced = if is_imported { "imported" } else { "defined" };
|
||||
diag.span_label(span, format!("the item `{ident}` is already {introduced} here"));
|
||||
let span_msg = if span.is_dummy() { "by prelude" } else { "here" };
|
||||
diag.span_label(
|
||||
span,
|
||||
format!("the item `{ident}` is already {introduced} {span_msg}"),
|
||||
);
|
||||
}
|
||||
}
|
||||
BuiltinLintDiag::DeprecatedMacro(suggestion, span) => {
|
||||
|
@ -137,6 +137,81 @@ fn check_imports_as_underscore(&mut self, items: &[(ast::UseTree, ast::NodeId)])
|
||||
self.check_import_as_underscore(item, *id);
|
||||
}
|
||||
}
|
||||
|
||||
fn report_unused_extern_crate_items(
|
||||
&mut self,
|
||||
maybe_unused_extern_crates: FxHashMap<ast::NodeId, Span>,
|
||||
) {
|
||||
let tcx = self.r.tcx();
|
||||
for extern_crate in &self.extern_crate_items {
|
||||
let warn_if_unused = !extern_crate.ident.name.as_str().starts_with('_');
|
||||
|
||||
// If the crate is fully unused, we suggest removing it altogether.
|
||||
// We do this in any edition.
|
||||
if warn_if_unused {
|
||||
if let Some(&span) = maybe_unused_extern_crates.get(&extern_crate.id) {
|
||||
self.r.lint_buffer.buffer_lint_with_diagnostic(
|
||||
UNUSED_EXTERN_CRATES,
|
||||
extern_crate.id,
|
||||
span,
|
||||
"unused extern crate",
|
||||
BuiltinLintDiag::UnusedExternCrate {
|
||||
removal_span: extern_crate.span_with_attributes,
|
||||
},
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If we are not in Rust 2018 edition, then we don't make any further
|
||||
// suggestions.
|
||||
if !tcx.sess.at_least_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 extern_crate.has_attrs {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the extern crate is renamed, then we cannot suggest replacing it with a use as this
|
||||
// would not insert the new name into the prelude, where other imports in the crate may be
|
||||
// expecting it.
|
||||
if extern_crate.renames {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the extern crate isn't in the extern prelude,
|
||||
// there is no way it can be written as a `use`.
|
||||
if !self
|
||||
.r
|
||||
.extern_prelude
|
||||
.get(&extern_crate.ident)
|
||||
.is_some_and(|entry| !entry.introduced_by_item)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let vis_span = extern_crate
|
||||
.vis_span
|
||||
.find_ancestor_inside(extern_crate.span)
|
||||
.unwrap_or(extern_crate.vis_span);
|
||||
let ident_span = extern_crate
|
||||
.ident
|
||||
.span
|
||||
.find_ancestor_inside(extern_crate.span)
|
||||
.unwrap_or(extern_crate.ident.span);
|
||||
self.r.lint_buffer.buffer_lint_with_diagnostic(
|
||||
UNUSED_EXTERN_CRATES,
|
||||
extern_crate.id,
|
||||
extern_crate.span,
|
||||
"`extern crate` is not idiomatic in the new edition",
|
||||
BuiltinLintDiag::ExternCrateNotIdiomatic { vis_span, ident_span },
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
|
||||
@ -335,6 +410,8 @@ pub(crate) fn check_unused(&mut self, krate: &ast::Crate) {
|
||||
};
|
||||
visit::walk_crate(&mut visitor, krate);
|
||||
|
||||
visitor.report_unused_extern_crate_items(maybe_unused_extern_crates);
|
||||
|
||||
for unused in visitor.unused_imports.values() {
|
||||
let mut fixes = Vec::new();
|
||||
let spans = match calc_unused_spans(unused, &unused.use_tree, unused.use_tree_id) {
|
||||
@ -416,75 +493,6 @@ pub(crate) fn check_unused(&mut self, krate: &ast::Crate) {
|
||||
);
|
||||
}
|
||||
|
||||
for extern_crate in visitor.extern_crate_items {
|
||||
let warn_if_unused = !extern_crate.ident.name.as_str().starts_with('_');
|
||||
|
||||
// If the crate is fully unused, we suggest removing it altogether.
|
||||
// We do this in any edition.
|
||||
if warn_if_unused {
|
||||
if let Some(&span) = maybe_unused_extern_crates.get(&extern_crate.id) {
|
||||
visitor.r.lint_buffer.buffer_lint_with_diagnostic(
|
||||
UNUSED_EXTERN_CRATES,
|
||||
extern_crate.id,
|
||||
span,
|
||||
"unused extern crate",
|
||||
BuiltinLintDiag::UnusedExternCrate {
|
||||
removal_span: extern_crate.span_with_attributes,
|
||||
},
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If we are not in Rust 2018 edition, then we don't make any further
|
||||
// suggestions.
|
||||
if !tcx.sess.at_least_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 extern_crate.has_attrs {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the extern crate is renamed, then we cannot suggest replacing it with a use as this
|
||||
// would not insert the new name into the prelude, where other imports in the crate may be
|
||||
// expecting it.
|
||||
if extern_crate.renames {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the extern crate isn't in the extern prelude,
|
||||
// there is no way it can be written as a `use`.
|
||||
if !visitor
|
||||
.r
|
||||
.extern_prelude
|
||||
.get(&extern_crate.ident)
|
||||
.is_some_and(|entry| !entry.introduced_by_item)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let vis_span = extern_crate
|
||||
.vis_span
|
||||
.find_ancestor_inside(extern_crate.span)
|
||||
.unwrap_or(extern_crate.vis_span);
|
||||
let ident_span = extern_crate
|
||||
.ident
|
||||
.span
|
||||
.find_ancestor_inside(extern_crate.span)
|
||||
.unwrap_or(extern_crate.ident.span);
|
||||
visitor.r.lint_buffer.buffer_lint_with_diagnostic(
|
||||
UNUSED_EXTERN_CRATES,
|
||||
extern_crate.id,
|
||||
extern_crate.span,
|
||||
"`extern crate` is not idiomatic in the new edition",
|
||||
BuiltinLintDiag::ExternCrateNotIdiomatic { vis_span, ident_span },
|
||||
);
|
||||
}
|
||||
|
||||
let unused_imports = visitor.unused_imports;
|
||||
let mut check_redundant_imports = FxIndexSet::default();
|
||||
for module in self.arenas.local_modules().iter() {
|
||||
|
@ -1336,9 +1336,7 @@ pub(crate) fn check_for_redundant_imports(&mut self, import: Import<'a>) {
|
||||
}
|
||||
|
||||
let mut is_redundant = true;
|
||||
|
||||
let mut redundant_span = PerNS { value_ns: None, type_ns: None, macro_ns: None };
|
||||
|
||||
self.per_ns(|this, ns| {
|
||||
if is_redundant && let Ok(binding) = source_bindings[ns].get() {
|
||||
if binding.res() == Res::Err {
|
||||
|
1
tests/ui/imports/auxiliary/aux-issue-121915.rs
Normal file
1
tests/ui/imports/auxiliary/aux-issue-121915.rs
Normal file
@ -0,0 +1 @@
|
||||
pub fn item() {}
|
11
tests/ui/imports/redundant-import-issue-121915-2015.rs
Normal file
11
tests/ui/imports/redundant-import-issue-121915-2015.rs
Normal file
@ -0,0 +1,11 @@
|
||||
//@ compile-flags: --extern aux_issue_121915 --edition 2015
|
||||
//@ aux-build: aux-issue-121915.rs
|
||||
|
||||
extern crate aux_issue_121915;
|
||||
|
||||
#[deny(unused_imports)]
|
||||
fn main() {
|
||||
use aux_issue_121915;
|
||||
//~^ ERROR the item `aux_issue_121915` is imported redundantly
|
||||
aux_issue_121915::item();
|
||||
}
|
17
tests/ui/imports/redundant-import-issue-121915-2015.stderr
Normal file
17
tests/ui/imports/redundant-import-issue-121915-2015.stderr
Normal file
@ -0,0 +1,17 @@
|
||||
error: the item `aux_issue_121915` is imported redundantly
|
||||
--> $DIR/redundant-import-issue-121915-2015.rs:8:9
|
||||
|
|
||||
LL | extern crate aux_issue_121915;
|
||||
| ------------------------------ the item `aux_issue_121915` is already imported here
|
||||
...
|
||||
LL | use aux_issue_121915;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/redundant-import-issue-121915-2015.rs:6:8
|
||||
|
|
||||
LL | #[deny(unused_imports)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
9
tests/ui/imports/redundant-import-issue-121915.rs
Normal file
9
tests/ui/imports/redundant-import-issue-121915.rs
Normal file
@ -0,0 +1,9 @@
|
||||
//@ compile-flags: --extern aux_issue_121915 --edition 2018
|
||||
//@ aux-build: aux-issue-121915.rs
|
||||
|
||||
#[deny(unused_imports)]
|
||||
fn main() {
|
||||
use aux_issue_121915;
|
||||
//~^ ERROR the item `aux_issue_121915` is imported redundantly
|
||||
aux_issue_121915::item();
|
||||
}
|
14
tests/ui/imports/redundant-import-issue-121915.stderr
Normal file
14
tests/ui/imports/redundant-import-issue-121915.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error: the item `aux_issue_121915` is imported redundantly
|
||||
--> $DIR/redundant-import-issue-121915.rs:6:9
|
||||
|
|
||||
LL | use aux_issue_121915;
|
||||
| ^^^^^^^^^^^^^^^^ the item `aux_issue_121915` is already defined by prelude
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/redundant-import-issue-121915.rs:4:8
|
||||
|
|
||||
LL | #[deny(unused_imports)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
40
tests/ui/imports/suggest-remove-issue-121315.rs
Normal file
40
tests/ui/imports/suggest-remove-issue-121315.rs
Normal file
@ -0,0 +1,40 @@
|
||||
//@ compile-flags: --edition 2021
|
||||
#![deny(unused_imports)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
fn test0() {
|
||||
// Test remove FlatUnused
|
||||
use std::convert::TryFrom;
|
||||
//~^ ERROR the item `TryFrom` is imported redundantly
|
||||
let _ = u32::try_from(5i32);
|
||||
}
|
||||
|
||||
fn test1() {
|
||||
// FIXME(yukang) Test remove NestedFullUnused
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
//~^ ERROR the item `TryFrom` is imported redundantly
|
||||
//~| ERROR the item `TryInto` is imported redundantly
|
||||
|
||||
let _ = u32::try_from(5i32);
|
||||
let _a: i32 = u32::try_into(5u32).unwrap();
|
||||
}
|
||||
|
||||
fn test2() {
|
||||
// FIXME(yukang): Test remove both redundant and unused
|
||||
use std::convert::{AsMut, Into};
|
||||
//~^ ERROR unused import: `AsMut`
|
||||
//~| ERROR the item `Into` is imported redundantly
|
||||
|
||||
let _a: u32 = (5u8).into();
|
||||
}
|
||||
|
||||
fn test3() {
|
||||
// Test remove NestedPartialUnused
|
||||
use std::convert::{From, Infallible};
|
||||
//~^ ERROR unused import: `From`
|
||||
|
||||
trait MyTrait {}
|
||||
impl MyTrait for fn() -> Infallible {}
|
||||
}
|
||||
|
||||
fn main() {}
|
56
tests/ui/imports/suggest-remove-issue-121315.stderr
Normal file
56
tests/ui/imports/suggest-remove-issue-121315.stderr
Normal file
@ -0,0 +1,56 @@
|
||||
error: the item `TryFrom` is imported redundantly
|
||||
--> $DIR/suggest-remove-issue-121315.rs:7:9
|
||||
|
|
||||
LL | use std::convert::TryFrom;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
--> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
|
||||
|
|
||||
= note: the item `TryFrom` is already defined here
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/suggest-remove-issue-121315.rs:2:9
|
||||
|
|
||||
LL | #![deny(unused_imports)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: the item `TryFrom` is imported redundantly
|
||||
--> $DIR/suggest-remove-issue-121315.rs:14:24
|
||||
|
|
||||
LL | use std::convert::{TryFrom, TryInto};
|
||||
| ^^^^^^^
|
||||
--> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
|
||||
|
|
||||
= note: the item `TryFrom` is already defined here
|
||||
|
||||
error: the item `TryInto` is imported redundantly
|
||||
--> $DIR/suggest-remove-issue-121315.rs:14:33
|
||||
|
|
||||
LL | use std::convert::{TryFrom, TryInto};
|
||||
| ^^^^^^^
|
||||
--> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
|
||||
|
|
||||
= note: the item `TryInto` is already defined here
|
||||
|
||||
error: unused import: `AsMut`
|
||||
--> $DIR/suggest-remove-issue-121315.rs:24:24
|
||||
|
|
||||
LL | use std::convert::{AsMut, Into};
|
||||
| ^^^^^
|
||||
|
||||
error: the item `Into` is imported redundantly
|
||||
--> $DIR/suggest-remove-issue-121315.rs:24:31
|
||||
|
|
||||
LL | use std::convert::{AsMut, Into};
|
||||
| ^^^^
|
||||
--> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
|
||||
|
|
||||
= note: the item `Into` is already defined here
|
||||
|
||||
error: unused import: `From`
|
||||
--> $DIR/suggest-remove-issue-121315.rs:33:24
|
||||
|
|
||||
LL | use std::convert::{From, Infallible};
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user