about summary refs log tree commit diff
diff options
context:
space:
mode:
authoryukang <moorekang@gmail.com>2023-06-22 11:19:05 +0800
committeryukang <moorekang@gmail.com>2023-07-02 15:35:18 +0800
commitb26701ea7964d444f32a43710a763eb0989d9d7e (patch)
tree45600c58c50bc4d54272770f2a66b9c3d8daf372
parente7e1a39fa0ff1da2f408af3fac253839cbd74848 (diff)
downloadrust-b26701ea7964d444f32a43710a763eb0989d9d7e.tar.gz
rust-b26701ea7964d444f32a43710a763eb0989d9d7e.zip
add testcase for 112590
-rw-r--r--compiler/rustc_resolve/src/late.rs15
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs46
-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/parser/const-param-decl-on-type-instead-of-impl.stderr20
-rw-r--r--tests/ui/resolve/export-fully-qualified-2018.rs13
-rw-r--r--tests/ui/resolve/export-fully-qualified-2018.stderr14
-rw-r--r--tests/ui/resolve/export-fully-qualified.rs2
-rw-r--r--tests/ui/resolve/export-fully-qualified.stderr2
-rw-r--r--tests/ui/suggestions/crate-or-module-typo.stderr25
-rw-r--r--tests/ui/suggestions/issue-112590-suggest-import.rs10
-rw-r--r--tests/ui/suggestions/issue-112590-suggest-import.stderr36
12 files changed, 132 insertions, 72 deletions
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 9e05d1e14a4..386be405a92 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -3499,7 +3499,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         let report_errors = |this: &mut Self, res: Option<Res>| {
             if this.should_report_errs() {
                 let (err, candidates) =
-                    this.smart_resolve_report_errors(path, path_span, source, res);
+                    this.smart_resolve_report_errors(path, path, path_span, source, res);
 
                 let def_id = this.parent_scope.module.nearest_parent_mod();
                 let instead = res.is_some();
@@ -3556,12 +3556,13 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 _ => return Some(parent_err),
             };
 
-            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);
-            }
+            let (mut err, candidates) = this.smart_resolve_report_errors(
+                prefix_path,
+                path,
+                path_span,
+                PathSource::Type,
+                None,
+            );
 
             // There are two different error messages user might receive at
             // this point:
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index b859e8d4c2e..a551f681d5c 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -334,16 +334,36 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
         prefix_path: &[Segment],
         path: &[Segment],
     ) -> Vec<ImportSuggestion> {
-        if path.len() <= 1 {
-            return Vec::new();
+        let next_seg = if path.len() >= prefix_path.len() + 1 && prefix_path.len() == 1 {
+            path.get(prefix_path.len())
+        } else {
+            None
+        };
+        if let Some(segment) = prefix_path.last() &&
+            let Some(next_seg) = next_seg {
+            let candidates = self.r.lookup_import_candidates(
+                segment.ident,
+                Namespace::TypeNS,
+                &self.parent_scope,
+                &|res: Res| matches!(res, Res::Def(DefKind::Mod, _)),
+            );
+            // double check next seg is valid
+            candidates
+                .into_iter()
+                .filter(|candidate| {
+                    if let Some(def_id) = candidate.did &&
+                        let Some(module) = self.r.get_module(def_id) {
+                            self.r.resolutions(module).borrow().iter().any(|(key, _r)| {
+                                key.ident.name == next_seg.ident.name
+                            })
+                    } else {
+                        false
+                    }
+                })
+                .collect::<Vec<_>>()
+        } else {
+            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.
@@ -351,6 +371,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
     pub(crate) fn smart_resolve_report_errors(
         &mut self,
         path: &[Segment],
+        full_path: &[Segment],
         span: Span,
         source: PathSource<'_>,
         res: Option<Res>,
@@ -392,7 +413,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
         }
 
         let (found, candidates) =
-            self.try_lookup_name_relaxed(&mut err, source, path, span, res, &base_error);
+            self.try_lookup_name_relaxed(&mut err, source, path, full_path, span, res, &base_error);
         if found {
             return (err, candidates);
         }
@@ -498,6 +519,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
         err: &mut Diagnostic,
         source: PathSource<'_>,
         path: &[Segment],
+        full_path: &[Segment],
         span: Span,
         res: Option<Res>,
         base_error: &BaseError,
@@ -667,6 +689,10 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
             }
         }
 
+        if candidates.is_empty() {
+            candidates = self.smart_resolve_partial_mod_path_errors(path, full_path);
+        }
+
         return (false, candidates);
     }
 
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 7de67da9b5d..3bae23a4aaa 100644
--- a/tests/ui/feature-gates/feature-gate-extern_absolute_paths.stderr
+++ b/tests/ui/feature-gates/feature-gate-extern_absolute_paths.stderr
@@ -13,15 +13,6 @@ 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 1f7df7a2e79..f1f4caee361 100644
--- a/tests/ui/hygiene/extern-prelude-from-opaque-fail.stderr
+++ b/tests/ui/hygiene/extern-prelude-from-opaque-fail.stderr
@@ -24,8 +24,6 @@ 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`
@@ -33,16 +31,6 @@ 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/parser/const-param-decl-on-type-instead-of-impl.stderr b/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr
index ce95633d114..96885d11ee0 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,27 +21,17 @@ 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
    |
-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>()
-   |
+LL | fn banana(a: <T<const N: usize>>::BAR) {}
+   |               ^ not found in this scope
 
 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-2018.rs b/tests/ui/resolve/export-fully-qualified-2018.rs
new file mode 100644
index 00000000000..afd48acb6bb
--- /dev/null
+++ b/tests/ui/resolve/export-fully-qualified-2018.rs
@@ -0,0 +1,13 @@
+// edition:2018
+
+// In this test baz isn't resolved when called as foo.baz even though
+// it's called from inside foo. This is somewhat surprising and may
+// want to change eventually.
+
+mod foo {
+    pub fn bar() { foo::baz(); } //~ ERROR failed to resolve: use of undeclared crate or module `foo`
+
+    fn baz() { }
+}
+
+fn main() { }
diff --git a/tests/ui/resolve/export-fully-qualified-2018.stderr b/tests/ui/resolve/export-fully-qualified-2018.stderr
new file mode 100644
index 00000000000..366ffd9bb2b
--- /dev/null
+++ b/tests/ui/resolve/export-fully-qualified-2018.stderr
@@ -0,0 +1,14 @@
+error[E0433]: failed to resolve: use of undeclared crate or module `foo`
+  --> $DIR/export-fully-qualified-2018.rs:8:20
+   |
+LL |     pub fn bar() { foo::baz(); }
+   |                    ^^^ use of undeclared crate or module `foo`
+   |
+help: consider importing this module
+   |
+LL +     use crate::foo;
+   |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/tests/ui/resolve/export-fully-qualified.rs b/tests/ui/resolve/export-fully-qualified.rs
index 4e73a2c5488..9d4daf4cd79 100644
--- a/tests/ui/resolve/export-fully-qualified.rs
+++ b/tests/ui/resolve/export-fully-qualified.rs
@@ -1,3 +1,5 @@
+// edition:2015
+
 // In this test baz isn't resolved when called as foo.baz even though
 // it's called from inside foo. This is somewhat surprising and may
 // want to change eventually.
diff --git a/tests/ui/resolve/export-fully-qualified.stderr b/tests/ui/resolve/export-fully-qualified.stderr
index 04d62477062..0cd516ee1b1 100644
--- a/tests/ui/resolve/export-fully-qualified.stderr
+++ b/tests/ui/resolve/export-fully-qualified.stderr
@@ -1,5 +1,5 @@
 error[E0433]: failed to resolve: use of undeclared crate or module `foo`
-  --> $DIR/export-fully-qualified.rs:6:20
+  --> $DIR/export-fully-qualified.rs:8:20
    |
 LL |     pub fn bar() { foo::baz(); }
    |                    ^^^ use of undeclared crate or module `foo`
diff --git a/tests/ui/suggestions/crate-or-module-typo.stderr b/tests/ui/suggestions/crate-or-module-typo.stderr
index 8b988beb5c2..5e7a7685ab0 100644
--- a/tests/ui/suggestions/crate-or-module-typo.stderr
+++ b/tests/ui/suggestions/crate-or-module-typo.stderr
@@ -20,17 +20,6 @@ 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
    |
@@ -41,16 +30,16 @@ help: there is a crate or module with a similar name
    |
 LL |     bar: std::cell::Cell<bool>
    |          ~~~
-help: consider importing one of these items
-   |
-LL + use core::cell;
+
+error[E0433]: failed to resolve: use of undeclared crate or module `bar`
+  --> $DIR/crate-or-module-typo.rs:6:20
    |
-LL + use std::cell;
+LL |     pub fn bar() { bar::baz(); }
+   |                    ^^^ use of undeclared crate or module `bar`
    |
-help: if you import `cell`, refer to it directly
+help: consider importing this module
    |
-LL -     bar: st::cell::Cell<bool>
-LL +     bar: cell::Cell<bool>
+LL +     use crate::bar;
    |
 
 error: aborting due to 4 previous errors
diff --git a/tests/ui/suggestions/issue-112590-suggest-import.rs b/tests/ui/suggestions/issue-112590-suggest-import.rs
new file mode 100644
index 00000000000..0938814c559
--- /dev/null
+++ b/tests/ui/suggestions/issue-112590-suggest-import.rs
@@ -0,0 +1,10 @@
+pub struct S;
+
+impl fmt::Debug for S { //~ ERROR failed to resolve: use of undeclared crate or module `fmt`
+    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { //~ ERROR failed to resolve: use of undeclared crate or module `fmt`
+        //~^ ERROR failed to resolve: use of undeclared crate or module `fmt`
+        Ok(())
+    }
+}
+
+fn main() { }
diff --git a/tests/ui/suggestions/issue-112590-suggest-import.stderr b/tests/ui/suggestions/issue-112590-suggest-import.stderr
new file mode 100644
index 00000000000..aeac18c16f0
--- /dev/null
+++ b/tests/ui/suggestions/issue-112590-suggest-import.stderr
@@ -0,0 +1,36 @@
+error[E0433]: failed to resolve: use of undeclared crate or module `fmt`
+  --> $DIR/issue-112590-suggest-import.rs:3:6
+   |
+LL | impl fmt::Debug for S {
+   |      ^^^ use of undeclared crate or module `fmt`
+   |
+help: consider importing this module
+   |
+LL + use std::fmt;
+   |
+
+error[E0433]: failed to resolve: use of undeclared crate or module `fmt`
+  --> $DIR/issue-112590-suggest-import.rs:4:28
+   |
+LL |     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
+   |                            ^^^ use of undeclared crate or module `fmt`
+   |
+help: consider importing this module
+   |
+LL + use std::fmt;
+   |
+
+error[E0433]: failed to resolve: use of undeclared crate or module `fmt`
+  --> $DIR/issue-112590-suggest-import.rs:4:51
+   |
+LL |     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
+   |                                                   ^^^ use of undeclared crate or module `fmt`
+   |
+help: consider importing this module
+   |
+LL + use std::fmt;
+   |
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0433`.