about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_resolve/src/imports.rs55
-rw-r--r--compiler/rustc_resolve/src/lib.rs13
-rw-r--r--tests/ui/cfg/diagnostics-same-crate.rs15
-rw-r--r--tests/ui/cfg/diagnostics-same-crate.stderr40
4 files changed, 98 insertions, 25 deletions
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 9bf3e9ccabd..48711f43518 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -19,6 +19,7 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::intern::Interned;
 use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, MultiSpan};
 use rustc_hir::def::{self, DefKind, PartialRes};
+use rustc_hir::def_id::DefId;
 use rustc_middle::metadata::ModChild;
 use rustc_middle::metadata::Reexport;
 use rustc_middle::span_bug;
@@ -250,6 +251,9 @@ struct UnresolvedImportError {
     note: Option<String>,
     suggestion: Option<Suggestion>,
     candidates: Option<Vec<ImportSuggestion>>,
+    segment: Option<Symbol>,
+    /// comes from `PathRes::Failed { module }`
+    module: Option<DefId>,
 }
 
 // Reexports of the form `pub use foo as bar;` where `foo` is `extern crate foo;`
@@ -579,16 +583,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 &import.kind,
                 import.span,
             );
-            let err = UnresolvedImportError {
-                span: import.span,
-                label: None,
-                note: None,
-                suggestion: None,
-                candidates: None,
-            };
             // FIXME: there should be a better way of doing this than
             // formatting this as a string then checking for `::`
             if path.contains("::") {
+                let err = UnresolvedImportError {
+                    span: import.span,
+                    label: None,
+                    note: None,
+                    suggestion: None,
+                    candidates: None,
+                    segment: None,
+                    module: None,
+                };
                 errors.push((*import, err))
             }
         }
@@ -738,15 +744,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 }
             }
 
-            match &import.kind {
-                ImportKind::Single { source, .. } => {
-                    if let Some(ModuleOrUniformRoot::Module(module)) = import.imported_module.get()
-                        && let Some(module) = module.opt_def_id()
-                    {
-                        self.find_cfg_stripped(&mut diag, &source.name, module)
-                    }
-                }
-                _ => {}
+            if matches!(import.kind, ImportKind::Single { .. })
+                && let Some(segment) = err.segment
+                && let Some(module) = err.module
+            {
+                self.find_cfg_stripped(&mut diag, &segment, module)
             }
         }
 
@@ -916,10 +918,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 span,
                 label,
                 suggestion,
+                module,
+                segment_name,
                 ..
             } => {
                 if no_ambiguity {
                     assert!(import.imported_module.get().is_none());
+                    let module = if let Some(ModuleOrUniformRoot::Module(m)) = module {
+                        m.opt_def_id()
+                    } else {
+                        None
+                    };
                     let err = match self.make_path_suggestion(
                         span,
                         import.module_path.clone(),
@@ -935,6 +944,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 Applicability::MaybeIncorrect,
                             )),
                             candidates: None,
+                            segment: Some(segment_name),
+                            module,
                         },
                         None => UnresolvedImportError {
                             span,
@@ -942,6 +953,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             note: None,
                             suggestion,
                             candidates: None,
+                            segment: Some(segment_name),
+                            module,
                         },
                     };
                     return Some(err);
@@ -990,6 +1003,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 note: None,
                                 suggestion: None,
                                 candidates: None,
+                                segment: None,
+                                module: None,
                             });
                         }
                     }
@@ -1199,6 +1214,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     } else {
                         None
                     },
+                    module: import.imported_module.get().and_then(|module| {
+                        if let ModuleOrUniformRoot::Module(m) = module {
+                            m.opt_def_id()
+                        } else {
+                            None
+                        }
+                    }),
+                    segment: Some(ident.name),
                 })
             } else {
                 // `resolve_ident_in_module` reported a privacy error.
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index dfc2d029d4c..aa03adb7097 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -415,6 +415,19 @@ enum PathResult<'a> {
         label: String,
         suggestion: Option<Suggestion>,
         is_error_from_last_segment: bool,
+        /// The final module being resolved, for instance:
+        ///
+        /// ```compile_fail
+        /// mod a {
+        ///     mod b {
+        ///         mod c {}
+        ///     }
+        /// }
+        ///
+        /// use a::not_exist::c;
+        /// ```
+        ///
+        /// In this case, `module` will point to `a`.
         module: Option<ModuleOrUniformRoot<'a>>,
         /// The segment name of target
         segment_name: Symbol,
diff --git a/tests/ui/cfg/diagnostics-same-crate.rs b/tests/ui/cfg/diagnostics-same-crate.rs
index 2d0907c6dfb..d9ff8d61e92 100644
--- a/tests/ui/cfg/diagnostics-same-crate.rs
+++ b/tests/ui/cfg/diagnostics-same-crate.rs
@@ -4,8 +4,12 @@ pub mod inner {
     //~^ NOTE found an item that was configured out
 
     #[cfg(FALSE)]
-    pub mod doesnt_exist { //~ NOTE found an item that was configured out
+    pub mod doesnt_exist {
+        //~^ NOTE found an item that was configured out
+        //~| NOTE found an item that was configured out
+        //~| NOTE found an item that was configured out
         pub fn hello() {}
+        pub mod hi {}
     }
 
     pub mod wrong {
@@ -20,6 +24,15 @@ pub mod inner {
     }
 }
 
+mod placeholder {
+    use super::inner::doesnt_exist;
+    //~^ ERROR unresolved import `super::inner::doesnt_exist`
+    //~| NOTE no `doesnt_exist` in `inner`
+    use super::inner::doesnt_exist::hi;
+    //~^ ERROR unresolved import `super::inner::doesnt_exist`
+    //~| NOTE could not find `doesnt_exist` in `inner`
+}
+
 #[cfg(i_dont_exist_and_you_can_do_nothing_about_it)]
 pub fn vanished() {}
 
diff --git a/tests/ui/cfg/diagnostics-same-crate.stderr b/tests/ui/cfg/diagnostics-same-crate.stderr
index 62a9d132de0..83a44587238 100644
--- a/tests/ui/cfg/diagnostics-same-crate.stderr
+++ b/tests/ui/cfg/diagnostics-same-crate.stderr
@@ -1,5 +1,29 @@
+error[E0432]: unresolved import `super::inner::doesnt_exist`
+  --> $DIR/diagnostics-same-crate.rs:28:9
+   |
+LL |     use super::inner::doesnt_exist;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ no `doesnt_exist` in `inner`
+   |
+note: found an item that was configured out
+  --> $DIR/diagnostics-same-crate.rs:7:13
+   |
+LL |     pub mod doesnt_exist {
+   |             ^^^^^^^^^^^^
+
+error[E0432]: unresolved import `super::inner::doesnt_exist`
+  --> $DIR/diagnostics-same-crate.rs:31:23
+   |
+LL |     use super::inner::doesnt_exist::hi;
+   |                       ^^^^^^^^^^^^ could not find `doesnt_exist` in `inner`
+   |
+note: found an item that was configured out
+  --> $DIR/diagnostics-same-crate.rs:7:13
+   |
+LL |     pub mod doesnt_exist {
+   |             ^^^^^^^^^^^^
+
 error[E0433]: failed to resolve: could not find `doesnt_exist` in `inner`
-  --> $DIR/diagnostics-same-crate.rs:37:12
+  --> $DIR/diagnostics-same-crate.rs:50:12
    |
 LL |     inner::doesnt_exist::hello();
    |            ^^^^^^^^^^^^ could not find `doesnt_exist` in `inner`
@@ -11,7 +35,7 @@ LL |     pub mod doesnt_exist {
    |             ^^^^^^^^^^^^
 
 error[E0425]: cannot find function `uwu` in module `inner`
-  --> $DIR/diagnostics-same-crate.rs:32:12
+  --> $DIR/diagnostics-same-crate.rs:45:12
    |
 LL |     inner::uwu();
    |            ^^^ not found in `inner`
@@ -23,31 +47,31 @@ LL |     pub fn uwu() {}
    |            ^^^
 
 error[E0425]: cannot find function `meow` in module `inner::right`
-  --> $DIR/diagnostics-same-crate.rs:41:19
+  --> $DIR/diagnostics-same-crate.rs:54:19
    |
 LL |     inner::right::meow();
    |                   ^^^^ not found in `inner::right`
    |
 note: found an item that was configured out
-  --> $DIR/diagnostics-same-crate.rs:18:16
+  --> $DIR/diagnostics-same-crate.rs:22:16
    |
 LL |         pub fn meow() {}
    |                ^^^^
    = note: the item is gated behind the `what-a-cool-feature` feature
 
 error[E0425]: cannot find function `uwu` in this scope
-  --> $DIR/diagnostics-same-crate.rs:28:5
+  --> $DIR/diagnostics-same-crate.rs:41:5
    |
 LL |     uwu();
    |     ^^^ not found in this scope
 
 error[E0425]: cannot find function `vanished` in this scope
-  --> $DIR/diagnostics-same-crate.rs:48:5
+  --> $DIR/diagnostics-same-crate.rs:61:5
    |
 LL |     vanished();
    |     ^^^^^^^^ not found in this scope
 
-error: aborting due to 5 previous errors
+error: aborting due to 7 previous errors
 
-Some errors have detailed explanations: E0425, E0433.
+Some errors have detailed explanations: E0425, E0432, E0433.
 For more information about an error, try `rustc --explain E0425`.