mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 00:34:06 +00:00
Rollup merge of #64054 - estebank:unused-import-is-to-eager, r=petrochenkov
Always emit unresolved import errors and hide unused import lint Fix https://github.com/rust-lang/rust/issues/63724. r? @petrochenkov
This commit is contained in:
commit
8926301d11
@ -71,7 +71,7 @@ pub enum ImportDirectiveSubclass<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// One import directive.
|
/// One import directive.
|
||||||
#[derive(Debug,Clone)]
|
#[derive(Debug, Clone)]
|
||||||
crate struct ImportDirective<'a> {
|
crate struct ImportDirective<'a> {
|
||||||
/// The ID of the `extern crate`, `UseTree` etc that imported this `ImportDirective`.
|
/// The ID of the `extern crate`, `UseTree` etc that imported this `ImportDirective`.
|
||||||
///
|
///
|
||||||
@ -447,12 +447,13 @@ impl<'a> Resolver<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Define the name or return the existing binding if there is a collision.
|
// Define the name or return the existing binding if there is a collision.
|
||||||
pub fn try_define(&mut self,
|
pub fn try_define(
|
||||||
|
&mut self,
|
||||||
module: Module<'a>,
|
module: Module<'a>,
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
ns: Namespace,
|
ns: Namespace,
|
||||||
binding: &'a NameBinding<'a>)
|
binding: &'a NameBinding<'a>,
|
||||||
-> Result<(), &'a NameBinding<'a>> {
|
) -> Result<(), &'a NameBinding<'a>> {
|
||||||
let res = binding.res();
|
let res = binding.res();
|
||||||
self.check_reserved_macro_name(ident, res);
|
self.check_reserved_macro_name(ident, res);
|
||||||
self.set_binding_parent_module(binding, module);
|
self.set_binding_parent_module(binding, module);
|
||||||
@ -480,8 +481,11 @@ impl<'a> Resolver<'a> {
|
|||||||
};
|
};
|
||||||
if glob_binding.res() != nonglob_binding.res() &&
|
if glob_binding.res() != nonglob_binding.res() &&
|
||||||
ns == MacroNS && nonglob_binding.expansion != ExpnId::root() {
|
ns == MacroNS && nonglob_binding.expansion != ExpnId::root() {
|
||||||
resolution.binding = Some(this.ambiguity(AmbiguityKind::GlobVsExpanded,
|
resolution.binding = Some(this.ambiguity(
|
||||||
nonglob_binding, glob_binding));
|
AmbiguityKind::GlobVsExpanded,
|
||||||
|
nonglob_binding,
|
||||||
|
glob_binding,
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
resolution.binding = Some(nonglob_binding);
|
resolution.binding = Some(nonglob_binding);
|
||||||
}
|
}
|
||||||
@ -513,9 +517,11 @@ impl<'a> Resolver<'a> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ambiguity(&self, kind: AmbiguityKind,
|
fn ambiguity(
|
||||||
primary_binding: &'a NameBinding<'a>, secondary_binding: &'a NameBinding<'a>)
|
&self, kind: AmbiguityKind,
|
||||||
-> &'a NameBinding<'a> {
|
primary_binding: &'a NameBinding<'a>,
|
||||||
|
secondary_binding: &'a NameBinding<'a>,
|
||||||
|
) -> &'a NameBinding<'a> {
|
||||||
self.arenas.alloc_name_binding(NameBinding {
|
self.arenas.alloc_name_binding(NameBinding {
|
||||||
ambiguity: Some((secondary_binding, kind)),
|
ambiguity: Some((secondary_binding, kind)),
|
||||||
..primary_binding.clone()
|
..primary_binding.clone()
|
||||||
@ -524,8 +530,12 @@ impl<'a> Resolver<'a> {
|
|||||||
|
|
||||||
// Use `f` to mutate the resolution of the name in the module.
|
// Use `f` to mutate the resolution of the name in the module.
|
||||||
// If the resolution becomes a success, define it in the module's glob importers.
|
// If the resolution becomes a success, define it in the module's glob importers.
|
||||||
fn update_resolution<T, F>(&mut self, module: Module<'a>, ident: Ident, ns: Namespace, f: F)
|
fn update_resolution<T, F>(
|
||||||
-> T
|
&mut self, module: Module<'a>,
|
||||||
|
ident: Ident,
|
||||||
|
ns: Namespace,
|
||||||
|
f: F,
|
||||||
|
) -> T
|
||||||
where F: FnOnce(&mut Resolver<'a>, &mut NameResolution<'a>) -> T
|
where F: FnOnce(&mut Resolver<'a>, &mut NameResolution<'a>) -> T
|
||||||
{
|
{
|
||||||
// Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
|
// Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
|
||||||
@ -627,14 +637,18 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
|||||||
self.finalize_resolutions_in(module);
|
self.finalize_resolutions_in(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut has_errors = false;
|
|
||||||
let mut seen_spans = FxHashSet::default();
|
let mut seen_spans = FxHashSet::default();
|
||||||
let mut errors = vec![];
|
let mut errors = vec![];
|
||||||
let mut prev_root_id: NodeId = NodeId::from_u32(0);
|
let mut prev_root_id: NodeId = NodeId::from_u32(0);
|
||||||
for i in 0 .. self.r.determined_imports.len() {
|
let determined_imports = mem::take(&mut self.r.determined_imports);
|
||||||
let import = self.r.determined_imports[i];
|
let indeterminate_imports = mem::take(&mut self.r.indeterminate_imports);
|
||||||
|
|
||||||
|
for (is_indeterminate, import) in determined_imports
|
||||||
|
.into_iter()
|
||||||
|
.map(|i| (false, i))
|
||||||
|
.chain(indeterminate_imports.into_iter().map(|i| (true, i)))
|
||||||
|
{
|
||||||
if let Some(err) = self.finalize_import(import) {
|
if let Some(err) = self.finalize_import(import) {
|
||||||
has_errors = true;
|
|
||||||
|
|
||||||
if let SingleImport { source, ref source_bindings, .. } = import.subclass {
|
if let SingleImport { source, ref source_bindings, .. } = import.subclass {
|
||||||
if source.name == kw::SelfLower {
|
if source.name == kw::SelfLower {
|
||||||
@ -666,25 +680,27 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
|||||||
errors.push((path, err));
|
errors.push((path, err));
|
||||||
prev_root_id = import.root_id;
|
prev_root_id = import.root_id;
|
||||||
}
|
}
|
||||||
|
} else if is_indeterminate {
|
||||||
|
// Consider erroneous imports used to avoid duplicate diagnostics.
|
||||||
|
self.r.used_imports.insert((import.id, TypeNS));
|
||||||
|
let path = import_path_to_string(
|
||||||
|
&import.module_path.iter().map(|seg| seg.ident).collect::<Vec<_>>(),
|
||||||
|
&import.subclass,
|
||||||
|
import.span,
|
||||||
|
);
|
||||||
|
let err = UnresolvedImportError {
|
||||||
|
span: import.span,
|
||||||
|
label: None,
|
||||||
|
note: Vec::new(),
|
||||||
|
suggestion: None,
|
||||||
|
};
|
||||||
|
errors.push((path, err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !errors.is_empty() {
|
if !errors.is_empty() {
|
||||||
self.throw_unresolved_import_error(errors.clone(), None);
|
self.throw_unresolved_import_error(errors.clone(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
for import in &self.r.indeterminate_imports {
|
|
||||||
// Consider erroneous imports used to avoid duplicate diagnostics.
|
|
||||||
self.r.used_imports.insert((import.id, TypeNS));
|
|
||||||
}
|
|
||||||
// Report unresolved imports only if no hard error was already reported
|
|
||||||
// to avoid generating multiple errors on the same import.
|
|
||||||
if !has_errors {
|
|
||||||
for import in &self.r.indeterminate_imports {
|
|
||||||
self.throw_unresolved_import_error(errors, Some(MultiSpan::from(import.span)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn throw_unresolved_import_error(
|
fn throw_unresolved_import_error(
|
||||||
@ -839,8 +855,14 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
|||||||
) -> Option<UnresolvedImportError> {
|
) -> Option<UnresolvedImportError> {
|
||||||
let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
|
let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
|
||||||
let prev_ambiguity_errors_len = self.r.ambiguity_errors.len();
|
let prev_ambiguity_errors_len = self.r.ambiguity_errors.len();
|
||||||
let path_res = self.r.resolve_path(&directive.module_path, None, &directive.parent_scope,
|
let path_res = self.r.resolve_path(
|
||||||
true, directive.span, directive.crate_lint());
|
&directive.module_path,
|
||||||
|
None,
|
||||||
|
&directive.parent_scope,
|
||||||
|
true,
|
||||||
|
directive.span,
|
||||||
|
directive.crate_lint(),
|
||||||
|
);
|
||||||
let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len;
|
let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len;
|
||||||
directive.vis.set(orig_vis);
|
directive.vis.set(orig_vis);
|
||||||
if let PathResult::Failed { .. } | PathResult::NonModule(..) = path_res {
|
if let PathResult::Failed { .. } | PathResult::NonModule(..) = path_res {
|
||||||
@ -903,7 +925,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return Some(err);
|
return Some(err);
|
||||||
}
|
}
|
||||||
return None;
|
return None;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use prelude::*; //~ ERROR unresolved import `prelude`
|
use prelude::*; //~ ERROR unresolved import `prelude`
|
||||||
|
|
||||||
mod unresolved_env {
|
mod unresolved_env {
|
||||||
use env;
|
use env; //~ ERROR unresolved import `env`
|
||||||
|
|
||||||
include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
|
include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
|
||||||
//~^ ERROR cannot determine resolution for the macro `env`
|
//~^ ERROR cannot determine resolution for the macro `env`
|
||||||
|
@ -19,6 +19,12 @@ LL | use prelude::*;
|
|||||||
| unresolved import
|
| unresolved import
|
||||||
| help: a similar path exists: `std::prelude`
|
| help: a similar path exists: `std::prelude`
|
||||||
|
|
||||||
|
error[E0432]: unresolved import `env`
|
||||||
|
--> $DIR/issue-55897.rs:4:9
|
||||||
|
|
|
||||||
|
LL | use env;
|
||||||
|
| ^^^ no `env` in the root
|
||||||
|
|
||||||
error: cannot determine resolution for the macro `env`
|
error: cannot determine resolution for the macro `env`
|
||||||
--> $DIR/issue-55897.rs:6:22
|
--> $DIR/issue-55897.rs:6:22
|
||||||
|
|
|
|
||||||
@ -27,6 +33,6 @@ LL | include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
|
|||||||
|
|
|
|
||||||
= note: import resolution is stuck, try simplifying macro imports
|
= note: import resolution is stuck, try simplifying macro imports
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0432`.
|
For more information about this error, try `rustc --explain E0432`.
|
||||||
|
@ -8,11 +8,11 @@ mod qux {
|
|||||||
|
|
||||||
use qux::quz; //~ ERROR function `quz` is private
|
use qux::quz; //~ ERROR function `quz` is private
|
||||||
use qux::bar; //~ ERROR unresolved import `qux::bar`
|
use qux::bar; //~ ERROR unresolved import `qux::bar`
|
||||||
use foo::bar;
|
use foo::bar; //~ ERROR unresolved import `foo`
|
||||||
use baz::*;
|
use baz::*; //~ ERROR unresolved import `baz`
|
||||||
use qux::bar2; //~ ERROR unresolved import `qux::bar2`
|
use qux::bar2; //~ ERROR unresolved import `qux::bar2`
|
||||||
use foo2::bar2;
|
use foo2::bar2;//~ ERROR unresolved import `foo2`
|
||||||
use baz2::*;
|
use baz2::*; //~ ERROR unresolved import `baz2`
|
||||||
use qux::quy; //~ ERROR unused import
|
use qux::quy; //~ ERROR unused import
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -10,6 +10,30 @@ error[E0432]: unresolved import `qux::bar2`
|
|||||||
LL | use qux::bar2;
|
LL | use qux::bar2;
|
||||||
| ^^^^^^^^^ no `bar2` in `qux`
|
| ^^^^^^^^^ no `bar2` in `qux`
|
||||||
|
|
||||||
|
error[E0432]: unresolved import `foo`
|
||||||
|
--> $DIR/unresolved-imports-used.rs:11:5
|
||||||
|
|
|
||||||
|
LL | use foo::bar;
|
||||||
|
| ^^^ maybe a missing crate `foo`?
|
||||||
|
|
||||||
|
error[E0432]: unresolved import `baz`
|
||||||
|
--> $DIR/unresolved-imports-used.rs:12:5
|
||||||
|
|
|
||||||
|
LL | use baz::*;
|
||||||
|
| ^^^ maybe a missing crate `baz`?
|
||||||
|
|
||||||
|
error[E0432]: unresolved import `foo2`
|
||||||
|
--> $DIR/unresolved-imports-used.rs:14:5
|
||||||
|
|
|
||||||
|
LL | use foo2::bar2;
|
||||||
|
| ^^^^ maybe a missing crate `foo2`?
|
||||||
|
|
||||||
|
error[E0432]: unresolved import `baz2`
|
||||||
|
--> $DIR/unresolved-imports-used.rs:15:5
|
||||||
|
|
|
||||||
|
LL | use baz2::*;
|
||||||
|
| ^^^^ maybe a missing crate `baz2`?
|
||||||
|
|
||||||
error[E0603]: function `quz` is private
|
error[E0603]: function `quz` is private
|
||||||
--> $DIR/unresolved-imports-used.rs:9:10
|
--> $DIR/unresolved-imports-used.rs:9:10
|
||||||
|
|
|
|
||||||
@ -28,7 +52,7 @@ note: lint level defined here
|
|||||||
LL | #![deny(unused_imports)]
|
LL | #![deny(unused_imports)]
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0432, E0603.
|
Some errors have detailed explanations: E0432, E0603.
|
||||||
For more information about an error, try `rustc --explain E0432`.
|
For more information about an error, try `rustc --explain E0432`.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// edition:2018
|
// edition:2018
|
||||||
// compile-flags:--extern foo --extern bar
|
// compile-flags:--extern foo --extern bar
|
||||||
|
|
||||||
use foo::bar; //~ ERROR unresolved import
|
use foo::bar; //~ ERROR can't find crate for `foo`
|
||||||
use bar::foo;
|
use bar::foo;
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
error[E0432]: unresolved import
|
error[E0463]: can't find crate for `foo`
|
||||||
--> $DIR/deadlock.rs:4:5
|
--> $DIR/deadlock.rs:4:5
|
||||||
|
|
|
|
||||||
LL | use foo::bar;
|
LL | use foo::bar;
|
||||||
| ^^^^^^^^
|
| ^^^ can't find crate
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0432`.
|
For more information about this error, try `rustc --explain E0463`.
|
||||||
|
Loading…
Reference in New Issue
Block a user