Skip to content

Commit f168d97

Browse files
committed
Elide unused import errors for failed use statements
1 parent c32171b commit f168d97

File tree

5 files changed

+67
-5
lines changed

5 files changed

+67
-5
lines changed

src/librustc_resolve/check_unused.rs

+24-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
use std::ops::{Deref, DerefMut};
2727

2828
use crate::Resolver;
29-
use crate::resolve_imports::ImportDirectiveSubclass;
29+
use crate::resolve_imports::{ImportDirective, ImportDirectiveSubclass};
3030

3131
use rustc::util::nodemap::NodeMap;
3232
use rustc::{lint, ty};
@@ -283,7 +283,15 @@ pub fn check_crate(resolver: &mut Resolver<'_>, krate: &ast::Crate) {
283283
};
284284
visit::walk_crate(&mut visitor, krate);
285285

286-
for unused in visitor.unused_imports.values() {
286+
let mut silencing_spans: Vec<Span> = visitor.privacy_errors
287+
.iter()
288+
.map(|crate::PrivacyError(span, _, _)| span)
289+
.chain(visitor.indeterminate_imports.iter().map(|ImportDirective { span, .. }| span))
290+
.chain(visitor.unresolved_imports.iter())
291+
.map(|sp| *sp)
292+
.collect();
293+
294+
'unused_imports: for unused in visitor.unused_imports.values() {
287295
let mut fixes = Vec::new();
288296
let mut spans = match calc_unused_spans(unused, unused.use_tree, unused.use_tree_id) {
289297
UnusedSpanResult::Used => continue,
@@ -305,6 +313,20 @@ pub fn check_crate(resolver: &mut Resolver<'_>, krate: &ast::Crate) {
305313

306314
let len = spans.len();
307315
spans.sort();
316+
for sp in &spans {
317+
// Do not emit unused warnings about failed use statements (#48244)
318+
let mut idx = None;
319+
for (i, span) in silencing_spans.iter().enumerate() {
320+
if sp.overlaps(*span) {
321+
idx = Some(i);
322+
break;
323+
}
324+
}
325+
if let Some(idx) = idx {
326+
silencing_spans.remove(idx); // we won't be seeing this again
327+
continue 'unused_imports;
328+
}
329+
}
308330
let ms = MultiSpan::from_spans(spans.clone());
309331
let mut span_snippets = spans.iter()
310332
.filter_map(|s| {

src/librustc_resolve/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1555,6 +1555,7 @@ pub struct Resolver<'a> {
15551555

15561556
/// All non-determined imports.
15571557
indeterminate_imports: Vec<&'a ImportDirective<'a>>,
1558+
unresolved_imports: Vec<Span>,
15581559

15591560
/// The module that represents the current item scope.
15601561
current_module: Module<'a>,
@@ -1924,6 +1925,7 @@ impl<'a> Resolver<'a> {
19241925

19251926
determined_imports: Vec::new(),
19261927
indeterminate_imports: Vec::new(),
1928+
unresolved_imports: Vec::new(),
19271929

19281930
current_module: graph_root,
19291931
ribs: PerNS {

src/librustc_resolve/resolve_imports.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ impl<'a> Resolver<'a> {
635635
/// An error that may be transformed into a diagnostic later. Used to combine multiple unresolved
636636
/// import errors within the same use tree into a single diagnostic.
637637
#[derive(Debug, Clone)]
638-
struct UnresolvedImportError {
638+
pub struct UnresolvedImportError {
639639
span: Span,
640640
label: Option<String>,
641641
note: Vec<String>,
@@ -744,19 +744,23 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
744744
// to avoid generating multiple errors on the same import.
745745
if !has_errors {
746746
for import in &self.indeterminate_imports {
747-
self.throw_unresolved_import_error(errors, Some(MultiSpan::from(import.span)));
747+
let sp = Some(MultiSpan::from(import.span));
748+
self.throw_unresolved_import_error(errors, sp);
748749
break;
749750
}
750751
}
751752
}
752753

753754
fn throw_unresolved_import_error(
754-
&self,
755+
&mut self,
755756
errors: Vec<(String, UnresolvedImportError)>,
756757
span: Option<MultiSpan>,
757758
) {
758759
/// Upper limit on the number of `span_label` messages.
759760
const MAX_LABEL_COUNT: usize = 10;
761+
for (_, error) in &errors {
762+
self.unresolved_imports.push(error.span);
763+
}
760764

761765
let (span, msg) = if errors.is_empty() {
762766
(span.unwrap(), "unresolved import".to_string())

src/test/ui/imports/failed-imports.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![deny(unused_imports)]
2+
// there should be *no* unused import errors
3+
4+
mod qux {
5+
pub(in crate::qux) fn quz() {}
6+
}
7+
8+
use qux::quz;//~ ERROR function `quz` is private
9+
use qux::bar;//~ ERROR unresolved import `qux::bar`
10+
use foo::bar; //~ ERROR unresolved import `foo`
11+
12+
fn main() {}
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error[E0432]: unresolved import `qux::bar`
2+
--> $DIR/failed-imports.rs:9:5
3+
|
4+
LL | use qux::bar;
5+
| ^^^^^^^^ no `bar` in `qux`
6+
7+
error[E0432]: unresolved import `foo`
8+
--> $DIR/failed-imports.rs:10:5
9+
|
10+
LL | use foo::bar;
11+
| ^^^ maybe a missing `extern crate foo;`?
12+
13+
error[E0603]: function `quz` is private
14+
--> $DIR/failed-imports.rs:8:10
15+
|
16+
LL | use qux::quz;
17+
| ^^^
18+
19+
error: aborting due to 3 previous errors
20+
21+
Some errors have detailed explanations: E0432, E0603.
22+
For more information about an error, try `rustc --explain E0432`.

0 commit comments

Comments
 (0)