diff --git a/compiler/rustc_resolve/src/diagnostics/impls.rs b/compiler/rustc_resolve/src/diagnostics/impls.rs index f1400c83e4295..18a02666cfc4a 100644 --- a/compiler/rustc_resolve/src/diagnostics/impls.rs +++ b/compiler/rustc_resolve/src/diagnostics/impls.rs @@ -206,21 +206,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .iter() .map(|(import, import_error)| { if let Some(ModuleOrUniformRoot::Module(module_data)) = import.imported_module.get() - && let ModuleKind::Def(DefKind::Mod, def_id, _, name) = module_data.kind + && let ModuleKind::Def(DefKind::Mod, def_id, ..) = module_data.kind { - let Some(directive) = self.on_unknown_data(def_id) else { + let Some((this, directive)) = self.on_unknown_data(def_id) else { return CustomDiagnostic::default(); }; - let this = if let Some(name) = name { - name.to_string() - } else if let Some(crate_name) = &self.tcx.sess.opts.crate_name { - crate_name.to_string() - } else { - "".to_string() - }; let unresolved = import_error.segment.map(|s| s.name).unwrap_or(kw::Underscore); - let args = FormatArgs { this, unresolved: unresolved.to_string(), .. }; + let args = FormatArgs { + this: this.to_string(), + unresolved: unresolved.to_string(), + .. + }; directive.eval(None, &args) } else { @@ -3867,12 +3864,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } - /// Gets the `#[diagnostic::on_unknown]` attribute data associated with this `DefId`. - pub(crate) fn on_unknown_data(&self, def_id: DefId) -> Option<&Directive> { - match def_id.as_local() { + /// Gets the name and `#[diagnostic::on_unknown]` attribute data associated with this `DefId`. + pub(crate) fn on_unknown_data(&self, def_id: DefId) -> Option<(Symbol, &Directive)> { + let directive = match def_id.as_local() { Some(local) => Some(self.on_unknown_data.get(&local)?.directive.as_ref()), - None => find_attr!(self.tcx, def_id, OnUnknown{ directive } => directive)?.as_deref(), - } + None => find_attr!(self.tcx, def_id, OnUnknown { directive } => directive)?.as_deref(), + }?; + + let name = + self.expect_module(def_id).name().unwrap_or_else(|| self.tcx.crate_name(def_id.krate)); + + Some((name, directive)) } } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 821c16ceee3e5..83e5fbef9bcb9 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -558,9 +558,10 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { }; let mut notes = Vec::new(); if let Some(module_def_id) = module - && let Some(directive) = self.r.on_unknown_data(module_def_id) + && let Some((this, directive)) = self.r.on_unknown_data(module_def_id) { - let args = FormatArgs { unresolved: item_ident.to_string(), this: mod_str, .. }; + let args = + FormatArgs { unresolved: item_ident.to_string(), this: this.to_string(), .. }; let CustomDiagnostic { message, label, diff --git a/tests/ui/diagnostic_namespace/on_unknown/auxiliary/foreign.rs b/tests/ui/diagnostic_namespace/on_unknown/auxiliary/foreign.rs new file mode 100644 index 0000000000000..c9269fcb84ca2 --- /dev/null +++ b/tests/ui/diagnostic_namespace/on_unknown/auxiliary/foreign.rs @@ -0,0 +1,12 @@ +#![feature(diagnostic_on_unknown)] + +mod a { + #[diagnostic::on_unknown( + message = "this={this}, unresolved={unresolved}", + )] + pub mod b {} +} + +pub mod c { + pub use super::a::b as d; +} diff --git a/tests/ui/diagnostic_namespace/on_unknown/expressions_and_paths_correct_mod_name.rs b/tests/ui/diagnostic_namespace/on_unknown/expressions_and_paths_correct_mod_name.rs new file mode 100644 index 0000000000000..d8bf14ccc54c3 --- /dev/null +++ b/tests/ui/diagnostic_namespace/on_unknown/expressions_and_paths_correct_mod_name.rs @@ -0,0 +1,20 @@ +#![feature(diagnostic_on_unknown)] + +mod a { + #[diagnostic::on_unknown( + message = "this={this}, unresolved={unresolved}", + )] + pub mod b {} +} + +mod c { + pub use super::a::b as d; +} + +use c::d::x; //~ ERROR this=b, unresolved=x + +fn main() { + let _ = c::d::X(); //~ ERROR this=b, unresolved=X + + let _: c::d::X; //~ ERROR this=b, unresolved=X +} diff --git a/tests/ui/diagnostic_namespace/on_unknown/expressions_and_paths_correct_mod_name.stderr b/tests/ui/diagnostic_namespace/on_unknown/expressions_and_paths_correct_mod_name.stderr new file mode 100644 index 0000000000000..a269acdf42b17 --- /dev/null +++ b/tests/ui/diagnostic_namespace/on_unknown/expressions_and_paths_correct_mod_name.stderr @@ -0,0 +1,30 @@ +error[E0432]: this=b, unresolved=x + --> $DIR/expressions_and_paths_correct_mod_name.rs:14:5 + | +LL | use c::d::x; + | ^^^^^^- + | | + | no `x` in `a::b` + | + = note: unresolved import `c::d::x` + +error[E0425]: this=b, unresolved=X + --> $DIR/expressions_and_paths_correct_mod_name.rs:17:19 + | +LL | let _ = c::d::X(); + | ^ not found in `c::d` + | + = note: cannot find function, tuple struct or tuple variant `X` in module `c::d` + +error[E0425]: this=b, unresolved=X + --> $DIR/expressions_and_paths_correct_mod_name.rs:19:18 + | +LL | let _: c::d::X; + | ^ not found in `c::d` + | + = note: cannot find type `X` in module `c::d` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0425, E0432. +For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/diagnostic_namespace/on_unknown/expressions_and_paths_correct_mod_name_foreign.rs b/tests/ui/diagnostic_namespace/on_unknown/expressions_and_paths_correct_mod_name_foreign.rs new file mode 100644 index 0000000000000..6cb8872984b36 --- /dev/null +++ b/tests/ui/diagnostic_namespace/on_unknown/expressions_and_paths_correct_mod_name_foreign.rs @@ -0,0 +1,11 @@ +//@ aux-crate:foreign=foreign.rs + +extern crate foreign; + +use foreign::c::d::x; //~ ERROR this=b, unresolved=x + +fn main() { + let _ = foreign::c::d::X(); //~ ERROR this=b, unresolved=X + + let _: foreign::c::d::X; //~ ERROR this=b, unresolved=X +} diff --git a/tests/ui/diagnostic_namespace/on_unknown/expressions_and_paths_correct_mod_name_foreign.stderr b/tests/ui/diagnostic_namespace/on_unknown/expressions_and_paths_correct_mod_name_foreign.stderr new file mode 100644 index 0000000000000..ee1765828718f --- /dev/null +++ b/tests/ui/diagnostic_namespace/on_unknown/expressions_and_paths_correct_mod_name_foreign.stderr @@ -0,0 +1,30 @@ +error[E0432]: this=b, unresolved=x + --> $DIR/expressions_and_paths_correct_mod_name_foreign.rs:5:5 + | +LL | use foreign::c::d::x; + | ^^^^^^^^^^^^^^^- + | | + | no `x` in `a::b` + | + = note: unresolved import `foreign::c::d::x` + +error[E0425]: this=b, unresolved=X + --> $DIR/expressions_and_paths_correct_mod_name_foreign.rs:8:28 + | +LL | let _ = foreign::c::d::X(); + | ^ not found in `foreign::c::d` + | + = note: cannot find function, tuple struct or tuple variant `X` in module `foreign::c::d` + +error[E0425]: this=b, unresolved=X + --> $DIR/expressions_and_paths_correct_mod_name_foreign.rs:10:27 + | +LL | let _: foreign::c::d::X; + | ^ not found in `foreign::c::d` + | + = note: cannot find type `X` in module `foreign::c::d` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0425, E0432. +For more information about an error, try `rustc --explain E0425`.