Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,15 @@ impl<'ra> ImportData<'ra> {
}
}

/// Returns the first meaningful path segment of this import,
/// skipping synthetic segments like `{{root}}` and `$crate`.
pub(crate) fn first_non_root_segment(&self) -> Option<Symbol> {
self.module_path
.iter()
.find(|seg| seg.ident.name != kw::PathRoot && seg.ident.name != kw::DollarCrate)
.map(|seg| seg.ident.name)
}

pub(crate) fn id(&self) -> Option<NodeId> {
match self.kind {
ImportKind::Single { id, .. }
Expand Down Expand Up @@ -653,6 +662,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {

glob_error |= import.is_glob();

if let Some(name) = import.first_non_root_segment() {
self.failed_import_prefixes.insert(name);
}

if let ImportKind::Single { source, ref decls, .. } = import.kind
&& source.name == kw::SelfLower
// Silence `unresolved import` error if E0429 is already emitted
Expand Down Expand Up @@ -1051,6 +1064,22 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
if !self.issue_145575_hack_applied {
assert!(import.imported_module.get().is_none());
}
if import.is_nested() {
let module = if let Some(ModuleOrUniformRoot::Module(m)) = module {
m.opt_def_id()
} else {
None
};
return Some(UnresolvedImportError {
span,
label: Some(label),
note: None,
suggestion,
candidates: None,
segment: Some(segment_name),
module,
});
}
self.report_error(
span,
ResolutionError::FailedToResolve {
Expand Down
22 changes: 19 additions & 3 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4462,7 +4462,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {

let Finalize { node_id, path_span, .. } = finalize;
let report_errors = |this: &mut Self, res: Option<Res>| {
if this.should_report_errs() {
if this.should_report_errs_for_path(path) {
let (mut err, candidates) = this.smart_resolve_report_errors(
path,
None,
Expand Down Expand Up @@ -4605,7 +4605,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {

let def_id = this.parent_scope.module.nearest_parent_mod();

if this.should_report_errs() {
if this.should_report_errs_for_path(path) {
if candidates.is_empty() {
if path.len() == 2
&& let [segment] = prefix_path
Expand Down Expand Up @@ -4715,7 +4715,9 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {

Err(err) => {
if let Some(err) = report_errors_for_call(self, err) {
self.report_error(err.span, err.node);
if self.should_report_errs_for_path(path) {
self.r.report_error(err.span, err.node);
}
}

PartialRes::new(Res::Err)
Expand Down Expand Up @@ -4764,6 +4766,20 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
&& !self.r.glob_error.is_some()
}

/// Like `should_report_errs`, but also suppresses errors for paths whose
/// first segment matches a known-failed import prefix.
fn should_report_errs_for_path(&self, path: &[Segment]) -> bool {
if !self.should_report_errs() {
return false;
}
if let Some(first) = path.first() {
if self.r.failed_import_prefixes.contains(&first.ident.name) {
return false;
}
}
true
}

// Resolve in alternative namespaces if resolution in the primary namespace fails.
fn resolve_qpath_anywhere(
&mut self,
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1267,6 +1267,10 @@ pub struct Resolver<'ra, 'tcx> {
glob_error: Option<ErrorGuaranteed> = None,
visibilities_for_hashing: Vec<(LocalDefId, Visibility)> = Vec::new(),
used_imports: FxHashSet<NodeId> = default::fx_hash_set(),
/// First segments of import paths that failed to resolve.
/// Used to suppress redundant resolution errors in late resolver
/// for paths sharing the same unresolved prefix.
failed_import_prefixes: FxHashSet<Symbol>,
maybe_unused_trait_imports: FxIndexSet<LocalDefId>,

/// Privacy errors are delayed until the end in order to deduplicate them.
Expand Down Expand Up @@ -1682,6 +1686,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
extern_module_map: Default::default(),

glob_map: Default::default(),
failed_import_prefixes: FxHashSet::default(),
maybe_unused_trait_imports: Default::default(),

arenas,
Expand Down
6 changes: 1 addition & 5 deletions tests/ui/imports/absolute-paths-in-nested-use-groups.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
#![allow(unused_imports)]

mod foo {}

use foo::{
//~^ ERROR: unresolved import `foo`
::bar,
//~^ ERROR: crate root in paths can only be used in start position
super::bar,
//~^ ERROR: `super` in paths can only be used in start position
self::bar,
//~^ ERROR: `self` in paths can only be used in start position
};

fn main() {}
25 changes: 9 additions & 16 deletions tests/ui/imports/absolute-paths-in-nested-use-groups.stderr
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
error[E0433]: the crate root in paths can only be used in start position
--> $DIR/absolute-paths-in-nested-use-groups.rs:6:5
error[E0432]: unresolved import `foo`
--> $DIR/absolute-paths-in-nested-use-groups.rs:3:5
|
LL | ::bar,
| ^ can only be used in path start position

error[E0433]: `super` in paths can only be used in start position
--> $DIR/absolute-paths-in-nested-use-groups.rs:8:5
LL | use foo::{
| ^^^ use of unresolved module or unlinked crate `foo`
|
LL | super::bar,
| ^^^^^ can only be used in path start position

error[E0433]: `self` in paths can only be used in start position
--> $DIR/absolute-paths-in-nested-use-groups.rs:10:5
help: you might be missing a crate named `foo`, add it to your project and import it in your code
|
LL + extern crate foo;
|
LL | self::bar,
| ^^^^ can only be used in path start position

error: aborting due to 3 previous errors
error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0433`.
For more information about this error, try `rustc --explain E0432`.
4 changes: 2 additions & 2 deletions tests/ui/imports/nested-import-root-symbol-150103.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
// caused by `{{root}}` appearing in diagnostic suggestions

mod A {
use Iuse::{ ::Fish }; //~ ERROR cannot find module or crate `Iuse` in the crate root
use Iuse::{ ::Fish }; //~ ERROR unresolved import `Iuse`
}

mod B {
use A::{::Fish}; //~ ERROR the crate root in paths can only be used in start position
use A::{::Fish}; //~ ERROR unresolved import `A::Fish`
}

fn main() {}
6 changes: 3 additions & 3 deletions tests/ui/imports/nested-import-root-symbol-150103.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0433]: cannot find module or crate `Iuse` in the crate root
error[E0432]: unresolved import `Iuse`
--> $DIR/nested-import-root-symbol-150103.rs:6:9
|
LL | use Iuse::{ ::Fish };
Expand All @@ -9,12 +9,12 @@ help: you might be missing a crate named `Iuse`, add it to your project and impo
LL + extern crate Iuse;
|

error[E0433]: the crate root in paths can only be used in start position
error[E0432]: unresolved import `A::Fish`
--> $DIR/nested-import-root-symbol-150103.rs:10:13
|
LL | use A::{::Fish};
| ^ can only be used in path start position

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0433`.
For more information about this error, try `rustc --explain E0432`.
8 changes: 8 additions & 0 deletions tests/ui/imports/redundant-import-errors-nested.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Issue #153156: Too many errors for missing crate for nested imports and later uses

use foo::{bar, baz::bat};
//~^ ERROR unresolved import `foo`

pub fn main() {
foo::qux();
}
14 changes: 14 additions & 0 deletions tests/ui/imports/redundant-import-errors-nested.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0432]: unresolved import `foo`
--> $DIR/redundant-import-errors-nested.rs:3:5
|
LL | use foo::{bar, baz::bat};
| ^^^ use of unresolved module or unlinked crate `foo`
|
help: you might be missing a crate named `foo`, add it to your project and import it in your code
|
LL + extern crate foo;
|

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0432`.
2 changes: 0 additions & 2 deletions tests/ui/resolve/open-ns-1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ fn main() {
let _ = root_function();
let _ = my_api::root_function();
let _ = my_api::utils::utils_helper();
//~^ ERROR cannot find `utils` in `my_api` [E0433]
let _ = util::util_mod_helper();
let _ = my_api::core::core_fn();
//~^ ERROR cannot find `core` in `my_api` [E0433]
}
17 changes: 2 additions & 15 deletions tests/ui/resolve/open-ns-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,6 @@ error[E0432]: unresolved import `my_api::utils`
LL | use my_api::utils::util;
| ^^^^^ could not find `utils` in `my_api`

error[E0433]: cannot find `utils` in `my_api`
--> $DIR/open-ns-1.rs:14:21
|
LL | let _ = my_api::utils::utils_helper();
| ^^^^^ could not find `utils` in `my_api`

error[E0433]: cannot find `core` in `my_api`
--> $DIR/open-ns-1.rs:17:21
|
LL | let _ = my_api::core::core_fn();
| ^^^^ could not find `core` in `my_api`

error: aborting due to 3 previous errors
error: aborting due to 1 previous error

Some errors have detailed explanations: E0432, E0433.
For more information about an error, try `rustc --explain E0432`.
For more information about this error, try `rustc --explain E0432`.
1 change: 0 additions & 1 deletion tests/ui/resolve/open-ns-7.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,4 @@ use my_api::utils::utils_helper;

fn main() {
let _ = my_api::utils::utils_helper();
//~^ ERROR cannot find `utils` in `my_api` [E0433]
}
11 changes: 2 additions & 9 deletions tests/ui/resolve/open-ns-7.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,6 @@ error[E0432]: unresolved import `my_api::utils`
LL | use my_api::utils::utils_helper;
| ^^^^^ could not find `utils` in `my_api`

error[E0433]: cannot find `utils` in `my_api`
--> $DIR/open-ns-7.rs:12:21
|
LL | let _ = my_api::utils::utils_helper();
| ^^^^^ could not find `utils` in `my_api`

error: aborting due to 2 previous errors
error: aborting due to 1 previous error

Some errors have detailed explanations: E0432, E0433.
For more information about an error, try `rustc --explain E0432`.
For more information about this error, try `rustc --explain E0432`.
1 change: 0 additions & 1 deletion tests/ui/traits/const-traits/issue-102156.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

use core::convert::{From, TryFrom};
//~^ ERROR
//~| ERROR

use std::pin::Pin;
use std::alloc::Allocator;
Expand Down
19 changes: 3 additions & 16 deletions tests/ui/traits/const-traits/issue-102156.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0433]: cannot find `core` in the crate root
error[E0432]: unresolved import `core`
--> $DIR/issue-102156.rs:5:5
|
LL | use core::convert::{From, TryFrom};
Expand All @@ -10,19 +10,6 @@ LL - use core::convert::{From, TryFrom};
LL + use std::convert::{From, TryFrom};
|

error[E0433]: cannot find `core` in the crate root
--> $DIR/issue-102156.rs:5:5
|
LL | use core::convert::{From, TryFrom};
| ^^^^ you might be missing crate `core`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: try using `std` instead of `core`
|
LL - use core::convert::{From, TryFrom};
LL + use std::convert::{From, TryFrom};
|

error: aborting due to 2 previous errors
error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0433`.
For more information about this error, try `rustc --explain E0432`.
31 changes: 1 addition & 30 deletions tests/ui/use/use-path-segment-kw.e2015.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -1027,17 +1027,6 @@ LL | macro_dollar_crate!();
|
= note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0433]: `$crate` in paths can only be used in start position
--> $DIR/use-path-segment-kw.rs:20:27
|
LL | type A3 = foobar::$crate;
| ^^^^^^ can only be used in path start position
...
LL | macro_dollar_crate!();
| --------------------- in this macro invocation
|
= note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0433]: `$crate` in paths can only be used in start position
--> $DIR/use-path-segment-kw.rs:26:26
|
Expand Down Expand Up @@ -1121,12 +1110,6 @@ error[E0433]: global paths cannot start with `crate`
LL | type B2 = ::crate;
| ^^^^^ cannot start with this

error[E0433]: `crate` in paths can only be used in start position
--> $DIR/use-path-segment-kw.rs:106:27
|
LL | type B3 = foobar::crate;
| ^^^^^ can only be used in path start position

error[E0433]: `crate` in paths can only be used in start position
--> $DIR/use-path-segment-kw.rs:112:26
|
Expand All @@ -1151,12 +1134,6 @@ error[E0433]: global paths cannot start with `super`
LL | type C2 = ::super;
| ^^^^^ cannot start with this

error[E0433]: `super` in paths can only be used in start position
--> $DIR/use-path-segment-kw.rs:144:27
|
LL | type C3 = foobar::super;
| ^^^^^ can only be used in path start position

error[E0433]: `super` in paths can only be used in start position
--> $DIR/use-path-segment-kw.rs:150:26
|
Expand All @@ -1169,12 +1146,6 @@ error[E0433]: global paths cannot start with `self`
LL | type D2 = ::self;
| ^^^^ cannot start with this

error[E0433]: `self` in paths can only be used in start position
--> $DIR/use-path-segment-kw.rs:186:27
|
LL | type D3 = foobar::self;
| ^^^^ can only be used in path start position

error[E0433]: `self` in paths can only be used in start position
--> $DIR/use-path-segment-kw.rs:194:26
|
Expand All @@ -1193,7 +1164,7 @@ error[E0433]: `self` in paths can only be used in start position
LL | type D6 = self::self;
| ^^^^ can only be used in path start position

error: aborting due to 129 previous errors
error: aborting due to 125 previous errors

Some errors have detailed explanations: E0429, E0432, E0433, E0573.
For more information about an error, try `rustc --explain E0429`.
Loading
Loading