about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_resolve/src/late.rs6
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs30
-rw-r--r--tests/ui/feature-gates/feature-gate-extern_absolute_paths.stderr9
-rw-r--r--tests/ui/hygiene/extern-prelude-from-opaque-fail.stderr12
-rw-r--r--tests/ui/macros/builtin-prelude-no-accidents.stderr32
-rw-r--r--tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr20
-rw-r--r--tests/ui/resolve/export-fully-qualified.stderr5
-rw-r--r--tests/ui/suggestions/crate-or-module-typo.stderr26
8 files changed, 120 insertions, 20 deletions
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 9f4573ea025..9e05d1e14a4 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -3556,9 +3556,13 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 _ => return Some(parent_err),
             };
 
-            let (mut err, candidates) =
+            let (mut err, mut candidates) =
                 this.smart_resolve_report_errors(prefix_path, path_span, PathSource::Type, None);
 
+            if candidates.is_empty() {
+                candidates = this.smart_resolve_partial_mod_path_errors(prefix_path, path);
+            }
+
             // There are two different error messages user might receive at
             // this point:
             // - E0412 cannot find type `{}` in this scope
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 7284b33f09d..b859e8d4c2e 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -4,6 +4,7 @@ use crate::late::{LifetimeBinderKind, LifetimeRes, LifetimeRibKind, LifetimeUseS
 use crate::{errors, path_names_to_string};
 use crate::{Module, ModuleKind, ModuleOrUniformRoot};
 use crate::{PathResult, PathSource, Segment};
+use rustc_hir::def::Namespace::{self, *};
 
 use rustc_ast::visit::{FnCtxt, FnKind, LifetimeCtxt};
 use rustc_ast::{
@@ -17,7 +18,6 @@ use rustc_errors::{
     MultiSpan,
 };
 use rustc_hir as hir;
-use rustc_hir::def::Namespace::{self, *};
 use rustc_hir::def::{self, CtorKind, CtorOf, DefKind};
 use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
 use rustc_hir::PrimTy;
@@ -221,10 +221,14 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                 let suggestion = if self.current_trait_ref.is_none()
                     && let Some((fn_kind, _)) = self.diagnostic_metadata.current_function
                     && let Some(FnCtxt::Assoc(_)) = fn_kind.ctxt()
+                    && let FnKind::Fn(_, _, sig, ..) = fn_kind
                     && let Some(items) = self.diagnostic_metadata.current_impl_items
                     && let Some(item) = items.iter().find(|i| {
                         if let AssocItemKind::Fn(..) | AssocItemKind::Const(..) = &i.kind
                             && i.ident.name == item_str.name
+                            // don't suggest if the item is in Fn signature arguments
+                            // issue #112590
+                            && !sig.span.contains(item_span)
                         {
                             debug!(?item_str.name);
                             return true
@@ -318,6 +322,30 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
         }
     }
 
+    /// Try to suggest for a module path that cannot be resolved.
+    /// Such as `fmt::Debug` where `fmt` is not resolved without importing,
+    /// here we search with `lookup_import_candidates` for a module named `fmt`
+    /// with `TypeNS` as namespace.
+    ///
+    /// We need a separate function here because we won't suggest for a path with single segment
+    /// and we won't change `SourcePath` api `is_expected` to match `Type` with `DefKind::Mod`
+    pub(crate) fn smart_resolve_partial_mod_path_errors(
+        &mut self,
+        prefix_path: &[Segment],
+        path: &[Segment],
+    ) -> Vec<ImportSuggestion> {
+        if path.len() <= 1 {
+            return Vec::new();
+        }
+        let ident = prefix_path.last().unwrap().ident;
+        self.r.lookup_import_candidates(
+            ident,
+            Namespace::TypeNS,
+            &self.parent_scope,
+            &|res: Res| matches!(res, Res::Def(DefKind::Mod, _)),
+        )
+    }
+
     /// Handles error reporting for `smart_resolve_path_fragment` function.
     /// Creates base error and amends it with one short label and possibly some longer helps/notes.
     pub(crate) fn smart_resolve_report_errors(
diff --git a/tests/ui/feature-gates/feature-gate-extern_absolute_paths.stderr b/tests/ui/feature-gates/feature-gate-extern_absolute_paths.stderr
index 3bae23a4aaa..7de67da9b5d 100644
--- a/tests/ui/feature-gates/feature-gate-extern_absolute_paths.stderr
+++ b/tests/ui/feature-gates/feature-gate-extern_absolute_paths.stderr
@@ -13,6 +13,15 @@ LL |     let _: u8 = ::core::default::Default();
    |                   ^^^^ maybe a missing crate `core`?
    |
    = help: consider adding `extern crate core` to use the `core` crate
+help: consider importing this module
+   |
+LL + use std::default;
+   |
+help: if you import `default`, refer to it directly
+   |
+LL -     let _: u8 = ::core::default::Default();
+LL +     let _: u8 = default::Default();
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/hygiene/extern-prelude-from-opaque-fail.stderr b/tests/ui/hygiene/extern-prelude-from-opaque-fail.stderr
index f1f4caee361..1f7df7a2e79 100644
--- a/tests/ui/hygiene/extern-prelude-from-opaque-fail.stderr
+++ b/tests/ui/hygiene/extern-prelude-from-opaque-fail.stderr
@@ -24,6 +24,8 @@ LL |         fn f() { my_core::mem::drop(0); }
 LL | a!();
    | ---- in this macro invocation
    |
+   = help: consider importing this module:
+           my_core::mem
    = note: this error originates in the macro `a` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0433]: failed to resolve: use of undeclared crate or module `my_core`
@@ -31,6 +33,16 @@ error[E0433]: failed to resolve: use of undeclared crate or module `my_core`
    |
 LL |     fn f() { my_core::mem::drop(0); }
    |              ^^^^^^^ use of undeclared crate or module `my_core`
+   |
+help: consider importing this module
+   |
+LL +     use my_core::mem;
+   |
+help: if you import `mem`, refer to it directly
+   |
+LL -     fn f() { my_core::mem::drop(0); }
+LL +     fn f() { mem::drop(0); }
+   |
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/macros/builtin-prelude-no-accidents.stderr b/tests/ui/macros/builtin-prelude-no-accidents.stderr
index 8cd9a63b808..b726e186241 100644
--- a/tests/ui/macros/builtin-prelude-no-accidents.stderr
+++ b/tests/ui/macros/builtin-prelude-no-accidents.stderr
@@ -3,21 +3,37 @@ error[E0433]: failed to resolve: use of undeclared crate or module `env`
    |
 LL |     env::current_dir;
    |     ^^^ use of undeclared crate or module `env`
-
-error[E0433]: failed to resolve: use of undeclared crate or module `vec`
-  --> $DIR/builtin-prelude-no-accidents.rs:7:14
    |
-LL |     type B = vec::Vec<u8>;
-   |              ^^^
-   |              |
-   |              use of undeclared crate or module `vec`
-   |              help: a struct with a similar name exists (notice the capitalization): `Vec`
+help: consider importing this module
+   |
+LL + use std::env;
+   |
 
 error[E0433]: failed to resolve: use of undeclared crate or module `panic`
   --> $DIR/builtin-prelude-no-accidents.rs:6:14
    |
 LL |     type A = panic::PanicInfo;
    |              ^^^^^ use of undeclared crate or module `panic`
+   |
+help: consider importing this module
+   |
+LL + use std::panic;
+   |
+
+error[E0433]: failed to resolve: use of undeclared crate or module `vec`
+  --> $DIR/builtin-prelude-no-accidents.rs:7:14
+   |
+LL |     type B = vec::Vec<u8>;
+   |              ^^^ use of undeclared crate or module `vec`
+   |
+help: a struct with a similar name exists
+   |
+LL |     type B = Vec::Vec<u8>;
+   |              ~~~
+help: consider importing this module
+   |
+LL + use std::vec;
+   |
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr b/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr
index 96885d11ee0..ce95633d114 100644
--- a/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr
+++ b/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr
@@ -21,17 +21,27 @@ error: unexpected `const` parameter declaration
 LL |     path::path::Struct::<const N: usize>()
    |                          ^^^^^^^^^^^^^^ expected a `const` expression, not a parameter declaration
 
+error[E0412]: cannot find type `T` in this scope
+  --> $DIR/const-param-decl-on-type-instead-of-impl.rs:8:15
+   |
+LL | fn banana(a: <T<const N: usize>>::BAR) {}
+   |               ^ not found in this scope
+
 error[E0433]: failed to resolve: use of undeclared crate or module `path`
   --> $DIR/const-param-decl-on-type-instead-of-impl.rs:12:5
    |
 LL |     path::path::Struct::<const N: usize>()
    |     ^^^^ use of undeclared crate or module `path`
-
-error[E0412]: cannot find type `T` in this scope
-  --> $DIR/const-param-decl-on-type-instead-of-impl.rs:8:15
    |
-LL | fn banana(a: <T<const N: usize>>::BAR) {}
-   |               ^ not found in this scope
+help: consider importing this module
+   |
+LL + use std::path;
+   |
+help: if you import `path`, refer to it directly
+   |
+LL -     path::path::Struct::<const N: usize>()
+LL +     path::Struct::<const N: usize>()
+   |
 
 error[E0308]: mismatched types
   --> $DIR/const-param-decl-on-type-instead-of-impl.rs:5:17
diff --git a/tests/ui/resolve/export-fully-qualified.stderr b/tests/ui/resolve/export-fully-qualified.stderr
index 7ee352e1232..04d62477062 100644
--- a/tests/ui/resolve/export-fully-qualified.stderr
+++ b/tests/ui/resolve/export-fully-qualified.stderr
@@ -3,6 +3,11 @@ error[E0433]: failed to resolve: use of undeclared crate or module `foo`
    |
 LL |     pub fn bar() { foo::baz(); }
    |                    ^^^ use of undeclared crate or module `foo`
+   |
+help: consider importing this module
+   |
+LL +     use foo;
+   |
 
 error: aborting due to previous error
 
diff --git a/tests/ui/suggestions/crate-or-module-typo.stderr b/tests/ui/suggestions/crate-or-module-typo.stderr
index 98b88b4fb92..8b988beb5c2 100644
--- a/tests/ui/suggestions/crate-or-module-typo.stderr
+++ b/tests/ui/suggestions/crate-or-module-typo.stderr
@@ -20,6 +20,17 @@ help: there is a crate or module with a similar name
 LL | use bar::bar;
    |     ~~~
 
+error[E0433]: failed to resolve: use of undeclared crate or module `bar`
+  --> $DIR/crate-or-module-typo.rs:6:20
+   |
+LL |     pub fn bar() { bar::baz(); }
+   |                    ^^^ use of undeclared crate or module `bar`
+   |
+help: consider importing this module
+   |
+LL +     use crate::bar;
+   |
+
 error[E0433]: failed to resolve: use of undeclared crate or module `st`
   --> $DIR/crate-or-module-typo.rs:14:10
    |
@@ -30,12 +41,17 @@ help: there is a crate or module with a similar name
    |
 LL |     bar: std::cell::Cell<bool>
    |          ~~~
-
-error[E0433]: failed to resolve: use of undeclared crate or module `bar`
-  --> $DIR/crate-or-module-typo.rs:6:20
+help: consider importing one of these items
+   |
+LL + use core::cell;
+   |
+LL + use std::cell;
+   |
+help: if you import `cell`, refer to it directly
+   |
+LL -     bar: st::cell::Cell<bool>
+LL +     bar: cell::Cell<bool>
    |
-LL |     pub fn bar() { bar::baz(); }
-   |                    ^^^ use of undeclared crate or module `bar`
 
 error: aborting due to 4 previous errors