From 7f45f53204d9f3ec030b4a20afb479170f9a37d0 Mon Sep 17 00:00:00 2001 From: bohan Date: Wed, 20 Mar 2024 17:06:58 +0800 Subject: [PATCH] store segment and module in `UnresolvedImportError` --- compiler/rustc_resolve/src/imports.rs | 55 +++++++++++++++------- compiler/rustc_resolve/src/lib.rs | 13 +++++ tests/ui/cfg/diagnostics-same-crate.rs | 15 +++++- tests/ui/cfg/diagnostics-same-crate.stderr | 40 ++++++++++++---- 4 files changed, 98 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 9bf3e9ccabdf1..48711f435186d 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, suggestion: Option, candidates: Option>, + segment: Option, + /// comes from `PathRes::Failed { module }` + module: Option, } // 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 dfc2d029d4cfd..aa03adb7097e4 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, 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>, /// 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 2d0907c6dfb8c..d9ff8d61e9243 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 62a9d132de09d..83a44587238a5 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`.