diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 00eb768ad18d4..6d2ee25df320d 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -32,7 +32,7 @@ use smallvec::{smallvec, SmallVec}; use rustc_span::source_map::{respan, Spanned}; use std::assert_matches::debug_assert_matches; use std::collections::{hash_map::Entry, BTreeSet}; -use std::mem::{replace, take}; +use std::mem::{replace, swap, take}; mod diagnostics; @@ -3369,11 +3369,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { let (mut err, candidates) = this.smart_resolve_report_errors(path, path_span, PathSource::Type, None); - if candidates.is_empty() { - err.cancel(); - return Some(parent_err); - } - // There are two different error messages user might receive at // this point: // - E0412 cannot find type `{}` in this scope @@ -3383,37 +3378,62 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // latter one - for paths in expression-position. // // Thus (since we're in expression-position at this point), not to - // confuse the user, we want to keep the *message* from E0432 (so + // confuse the user, we want to keep the *message* from E0433 (so // `parent_err`), but we want *hints* from E0412 (so `err`). // // And that's what happens below - we're just mixing both messages // into a single one. let mut parent_err = this.r.into_struct_error(parent_err.span, parent_err.node); + // overwrite all properties with the parent's error message err.message = take(&mut parent_err.message); err.code = take(&mut parent_err.code); + swap(&mut err.span, &mut parent_err.span); err.children = take(&mut parent_err.children); + err.sort_span = parent_err.sort_span; + err.is_lint = parent_err.is_lint; + + // merge the parent's suggestions with the typo suggestions + fn append_result(res1: &mut Result, E>, res2: Result, E>) { + match res1 { + Ok(vec1) => match res2 { + Ok(mut vec2) => vec1.append(&mut vec2), + Err(e) => *res1 = Err(e), + }, + Err(_) => (), + }; + } + append_result(&mut err.suggestions, parent_err.suggestions.clone()); parent_err.cancel(); let def_id = this.parent_scope.module.nearest_parent_mod(); if this.should_report_errs() { - this.r.use_injections.push(UseError { - err, - candidates, - def_id, - instead: false, - suggestion: None, - path: path.into(), - is_call: source.is_call(), - }); + if candidates.is_empty() { + // When there is no suggested imports, we can just emit the error + // and suggestions immediately. Note that we bypass the usually error + // reporting routine (ie via `self.r.report_error`) because we need + // to post-process the `ResolutionError` above. + err.emit(); + } else { + // If there are suggested imports, the error reporting is delayed + this.r.use_injections.push(UseError { + err, + candidates, + def_id, + instead: false, + suggestion: None, + path: path.into(), + is_call: source.is_call(), + }); + } } else { err.cancel(); } // We don't return `Some(parent_err)` here, because the error will - // be already printed as part of the `use` injections + // be already printed either immediately or as part of the `use` injections None }; diff --git a/src/test/ui/const-generics/issues/issue-82956.stderr b/src/test/ui/const-generics/issues/issue-82956.stderr index c8b999da98104..d2320293e857e 100644 --- a/src/test/ui/const-generics/issues/issue-82956.stderr +++ b/src/test/ui/const-generics/issues/issue-82956.stderr @@ -2,7 +2,7 @@ error[E0433]: failed to resolve: use of undeclared type `IntoIter` --> $DIR/issue-82956.rs:25:24 | LL | let mut iter = IntoIter::new(self); - | ^^^^^^^^ not found in this scope + | ^^^^^^^^ use of undeclared type `IntoIter` | help: consider importing one of these items | diff --git a/src/test/ui/derived-errors/issue-31997-1.stderr b/src/test/ui/derived-errors/issue-31997-1.stderr index 6d177666ed0fa..2f4aabf845311 100644 --- a/src/test/ui/derived-errors/issue-31997-1.stderr +++ b/src/test/ui/derived-errors/issue-31997-1.stderr @@ -2,7 +2,7 @@ error[E0433]: failed to resolve: use of undeclared type `HashMap` --> $DIR/issue-31997-1.rs:20:19 | LL | let mut map = HashMap::new(); - | ^^^^^^^ not found in this scope + | ^^^^^^^ use of undeclared type `HashMap` | help: consider importing this struct | diff --git a/src/test/ui/hygiene/no_implicit_prelude.stderr b/src/test/ui/hygiene/no_implicit_prelude.stderr index 0f2ff96b5edb6..c48c840352fa0 100644 --- a/src/test/ui/hygiene/no_implicit_prelude.stderr +++ b/src/test/ui/hygiene/no_implicit_prelude.stderr @@ -5,7 +5,7 @@ LL | fn f() { ::bar::m!(); } | ----------- in this macro invocation ... LL | Vec::new(); - | ^^^ not found in this scope + | ^^^ use of undeclared type `Vec` | = note: this error originates in the macro `::bar::m` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider importing this struct diff --git a/src/test/ui/proc-macro/amputate-span.stderr b/src/test/ui/proc-macro/amputate-span.stderr index 9553ba3da5428..ab46704114460 100644 --- a/src/test/ui/proc-macro/amputate-span.stderr +++ b/src/test/ui/proc-macro/amputate-span.stderr @@ -2,7 +2,7 @@ error[E0433]: failed to resolve: use of undeclared type `Command` --> $DIR/amputate-span.rs:49:5 | LL | Command::new("git"); - | ^^^^^^^ not found in this scope + | ^^^^^^^ use of undeclared type `Command` | help: consider importing this struct | @@ -13,7 +13,7 @@ error[E0433]: failed to resolve: use of undeclared type `Command` --> $DIR/amputate-span.rs:63:9 | LL | Command::new("git"); - | ^^^^^^^ not found in this scope + | ^^^^^^^ use of undeclared type `Command` | help: consider importing this struct | diff --git a/src/test/ui/resolve/missing-in-namespace.stderr b/src/test/ui/resolve/missing-in-namespace.stderr index 3d49b2e5dfcd8..fc925ba3b6a8f 100644 --- a/src/test/ui/resolve/missing-in-namespace.stderr +++ b/src/test/ui/resolve/missing-in-namespace.stderr @@ -1,8 +1,8 @@ error[E0433]: failed to resolve: could not find `hahmap` in `std` - --> $DIR/missing-in-namespace.rs:2:29 + --> $DIR/missing-in-namespace.rs:2:21 | LL | let _map = std::hahmap::HashMap::new(); - | ^^^^^^^ not found in `std::hahmap` + | ^^^^^^ could not find `hahmap` in `std` | help: consider importing this struct | diff --git a/src/test/ui/resolve/typo-suggestion-mistyped-in-path.rs b/src/test/ui/resolve/typo-suggestion-mistyped-in-path.rs new file mode 100644 index 0000000000000..3ce17a14f146b --- /dev/null +++ b/src/test/ui/resolve/typo-suggestion-mistyped-in-path.rs @@ -0,0 +1,42 @@ +struct Struct; +//~^ NOTE function or associated item `fob` not found for this struct + +impl Struct { + fn foo() { } +} + +mod module { + fn foo() { } + + struct Struct; + + impl Struct { + fn foo() { } + } +} + +trait Trait { + fn foo(); +} + +fn main() { + Struct::fob(); + //~^ ERROR no function or associated item named `fob` found for struct `Struct` in the current scope + //~| NOTE function or associated item not found in `Struct` + + Struc::foo(); + //~^ ERROR failed to resolve: use of undeclared type `Struc` + //~| NOTE use of undeclared type `Struc` + + modul::foo(); + //~^ ERROR failed to resolve: use of undeclared crate or module `modul` + //~| NOTE use of undeclared crate or module `modul` + + module::Struc::foo(); + //~^ ERROR failed to resolve: could not find `Struc` in `module` + //~| NOTE could not find `Struc` in `module` + + Trai::foo(); + //~^ ERROR failed to resolve: use of undeclared type `Trai` + //~| NOTE use of undeclared type `Trai` +} diff --git a/src/test/ui/resolve/typo-suggestion-mistyped-in-path.stderr b/src/test/ui/resolve/typo-suggestion-mistyped-in-path.stderr new file mode 100644 index 0000000000000..ff7cf531c06dd --- /dev/null +++ b/src/test/ui/resolve/typo-suggestion-mistyped-in-path.stderr @@ -0,0 +1,54 @@ +error[E0433]: failed to resolve: use of undeclared type `Struc` + --> $DIR/typo-suggestion-mistyped-in-path.rs:27:5 + | +LL | Struc::foo(); + | ^^^^^ + | | + | use of undeclared type `Struc` + | help: a struct with a similar name exists: `Struct` + +error[E0433]: failed to resolve: use of undeclared crate or module `modul` + --> $DIR/typo-suggestion-mistyped-in-path.rs:31:5 + | +LL | modul::foo(); + | ^^^^^ use of undeclared crate or module `modul` + | +help: there is a crate or module with a similar name + | +LL | module::foo(); + | ~~~~~~ + +error[E0433]: failed to resolve: could not find `Struc` in `module` + --> $DIR/typo-suggestion-mistyped-in-path.rs:35:13 + | +LL | module::Struc::foo(); + | ^^^^^ + | | + | could not find `Struc` in `module` + | help: a struct with a similar name exists: `Struct` + +error[E0433]: failed to resolve: use of undeclared type `Trai` + --> $DIR/typo-suggestion-mistyped-in-path.rs:39:5 + | +LL | Trai::foo(); + | ^^^^ + | | + | use of undeclared type `Trai` + | help: a trait with a similar name exists: `Trait` + +error[E0599]: no function or associated item named `fob` found for struct `Struct` in the current scope + --> $DIR/typo-suggestion-mistyped-in-path.rs:23:13 + | +LL | struct Struct; + | ------------- function or associated item `fob` not found for this struct +... +LL | Struct::fob(); + | ^^^ + | | + | function or associated item not found in `Struct` + | help: there is an associated function with a similar name: `foo` + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0433, E0599. +For more information about an error, try `rustc --explain E0433`. diff --git a/src/test/ui/resolve/use_suggestion.stderr b/src/test/ui/resolve/use_suggestion.stderr index 4fff179b1fecc..58cb659e82203 100644 --- a/src/test/ui/resolve/use_suggestion.stderr +++ b/src/test/ui/resolve/use_suggestion.stderr @@ -8,7 +8,7 @@ error[E0433]: failed to resolve: use of undeclared type `HashMap` --> $DIR/use_suggestion.rs:2:14 | LL | let x1 = HashMap::new(); - | ^^^^^^^ not found in this scope + | ^^^^^^^ use of undeclared type `HashMap` | help: consider importing this struct | diff --git a/src/test/ui/suggestions/core-std-import-order-issue-83564.stderr b/src/test/ui/suggestions/core-std-import-order-issue-83564.stderr index ce85d93b96ca8..e4e1fc591c476 100644 --- a/src/test/ui/suggestions/core-std-import-order-issue-83564.stderr +++ b/src/test/ui/suggestions/core-std-import-order-issue-83564.stderr @@ -2,7 +2,7 @@ error[E0433]: failed to resolve: use of undeclared type `NonZeroU32` --> $DIR/core-std-import-order-issue-83564.rs:8:14 | LL | let _x = NonZeroU32::new(5).unwrap(); - | ^^^^^^^^^^ not found in this scope + | ^^^^^^^^^^ use of undeclared type `NonZeroU32` | help: consider importing one of these items | diff --git a/src/test/ui/suggestions/suggest-tryinto-edition-change.rs b/src/test/ui/suggestions/suggest-tryinto-edition-change.rs index f03b42bbe4751..70c4b210d3a7b 100644 --- a/src/test/ui/suggestions/suggest-tryinto-edition-change.rs +++ b/src/test/ui/suggestions/suggest-tryinto-edition-change.rs @@ -10,18 +10,19 @@ fn test() { let _i: i16 = TryFrom::try_from(0_i32).unwrap(); //~^ ERROR failed to resolve: use of undeclared type - //~| NOTE not found in this scope + //~| NOTE use of undeclared type //~| NOTE 'std::convert::TryFrom' is included in the prelude starting in Edition 2021 //~| NOTE 'core::convert::TryFrom' is included in the prelude starting in Edition 2021 let _i: i16 = TryInto::try_into(0_i32).unwrap(); //~^ ERROR failed to resolve: use of undeclared type - //~| NOTE not found in this scope + //~| NOTE use of undeclared type //~| NOTE 'std::convert::TryInto' is included in the prelude starting in Edition 2021 //~| NOTE 'core::convert::TryInto' is included in the prelude starting in Edition 2021 let _v: Vec<_> = FromIterator::from_iter(&[1]); //~^ ERROR failed to resolve: use of undeclared type + //~| NOTE use of undeclared type //~| NOTE 'std::iter::FromIterator' is included in the prelude starting in Edition 2021 //~| NOTE 'core::iter::FromIterator' is included in the prelude starting in Edition 2021 } diff --git a/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr b/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr index 86f48716b16b5..3d1f2492360bf 100644 --- a/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr +++ b/src/test/ui/suggestions/suggest-tryinto-edition-change.stderr @@ -2,7 +2,7 @@ error[E0433]: failed to resolve: use of undeclared type `TryFrom` --> $DIR/suggest-tryinto-edition-change.rs:11:19 | LL | let _i: i16 = TryFrom::try_from(0_i32).unwrap(); - | ^^^^^^^ not found in this scope + | ^^^^^^^ use of undeclared type `TryFrom` | = note: 'std::convert::TryFrom' is included in the prelude starting in Edition 2021 = note: 'core::convert::TryFrom' is included in the prelude starting in Edition 2021 @@ -17,7 +17,7 @@ error[E0433]: failed to resolve: use of undeclared type `TryInto` --> $DIR/suggest-tryinto-edition-change.rs:17:19 | LL | let _i: i16 = TryInto::try_into(0_i32).unwrap(); - | ^^^^^^^ not found in this scope + | ^^^^^^^ use of undeclared type `TryInto` | = note: 'std::convert::TryInto' is included in the prelude starting in Edition 2021 = note: 'core::convert::TryInto' is included in the prelude starting in Edition 2021 @@ -32,12 +32,7 @@ error[E0433]: failed to resolve: use of undeclared type `FromIterator` --> $DIR/suggest-tryinto-edition-change.rs:23:22 | LL | let _v: Vec<_> = FromIterator::from_iter(&[1]); - | ^^^^^^^^^^^^ - | - ::: $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL - | -LL | pub trait IntoIterator { - | ---------------------- similarly named trait `IntoIterator` defined here + | ^^^^^^^^^^^^ use of undeclared type `FromIterator` | = note: 'std::iter::FromIterator' is included in the prelude starting in Edition 2021 = note: 'core::iter::FromIterator' is included in the prelude starting in Edition 2021