From 1225c3f6b8976b96eff4444cd7416a5d14eb3cd4 Mon Sep 17 00:00:00 2001 From: yukang Date: Mon, 17 Oct 2022 05:54:13 +0800 Subject: [PATCH 1/2] fix #103112, add diagnostic for calling a function with the same name when a Macro is not found --- compiler/rustc_resolve/src/macros.rs | 22 +++++++++++++++++++-- src/test/ui/suggestions/issue-103112.rs | 4 ++++ src/test/ui/suggestions/issue-103112.stderr | 14 +++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/suggestions/issue-103112.rs create mode 100644 src/test/ui/suggestions/issue-103112.stderr diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index f6f0b3c11391b..71264ffc877de 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -12,7 +12,7 @@ use rustc_attr::StabilityLevel; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::intern::Interned; use rustc_data_structures::sync::Lrc; -use rustc_errors::struct_span_err; +use rustc_errors::{struct_span_err, Applicability}; use rustc_expand::base::{Annotatable, DeriveResolutions, Indeterminate, ResolverExpand}; use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::compile_declarative_macro; @@ -694,7 +694,25 @@ impl<'a> Resolver<'a> { check_consistency(self, &path, path_span, kind, initial_res, res) } path_res @ PathResult::NonModule(..) | path_res @ PathResult::Failed { .. } => { + let mut suggestion = None; let (span, label) = if let PathResult::Failed { span, label, .. } = path_res { + // try to suggest if it's not a macro, maybe a function + if let PathResult::NonModule(partial_res) = self.resolve_path( + &path, + Some(ValueNS), + &parent_scope, + Some(Finalize::new(ast::CRATE_NODE_ID, path_span)), + None, + ) && partial_res.unresolved_segments() == 0 { + let sm = self.session.source_map(); + let span = sm.span_extend_while(span, |c| c == '!').unwrap_or(span); + let code = sm.span_to_snippet(span).unwrap(); + suggestion = Some( + (vec![(span, code.trim_end_matches('!').to_string())], + format!("{} is not a macro, but a {}, try to remove `!`", Segment::names_to_string(&path), partial_res.base_res().descr()), + Applicability::MaybeIncorrect) + ); + } (span, label) } else { ( @@ -708,7 +726,7 @@ impl<'a> Resolver<'a> { }; self.report_error( span, - ResolutionError::FailedToResolve { label, suggestion: None }, + ResolutionError::FailedToResolve { label, suggestion }, ); } PathResult::Module(..) | PathResult::Indeterminate => unreachable!(), diff --git a/src/test/ui/suggestions/issue-103112.rs b/src/test/ui/suggestions/issue-103112.rs new file mode 100644 index 0000000000000..111ae7c73080d --- /dev/null +++ b/src/test/ui/suggestions/issue-103112.rs @@ -0,0 +1,4 @@ +fn main() { + std::process::abort!(); + //~^ ERROR: failed to resolve +} diff --git a/src/test/ui/suggestions/issue-103112.stderr b/src/test/ui/suggestions/issue-103112.stderr new file mode 100644 index 0000000000000..3518ef4c65271 --- /dev/null +++ b/src/test/ui/suggestions/issue-103112.stderr @@ -0,0 +1,14 @@ +error[E0433]: failed to resolve: could not find `abort` in `process` + --> $DIR/issue-103112.rs:2:19 + | +LL | std::process::abort!(); + | ^^^^^ could not find `abort` in `process` + | +help: std::process::abort is not a macro, but a function, try to remove `!` + | +LL | std::process::abort(); + | ~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0433`. From f90bf50d475eb9240c5bdeef3102c235335180c4 Mon Sep 17 00:00:00 2001 From: yukang Date: Tue, 18 Oct 2022 01:58:22 +0800 Subject: [PATCH 2/2] fix span for suggestion --- compiler/rustc_resolve/src/macros.rs | 20 +++++++------------- src/test/ui/suggestions/issue-103112.stderr | 5 +++-- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 71264ffc877de..9526296f95115 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -697,21 +697,15 @@ impl<'a> Resolver<'a> { let mut suggestion = None; let (span, label) = if let PathResult::Failed { span, label, .. } = path_res { // try to suggest if it's not a macro, maybe a function - if let PathResult::NonModule(partial_res) = self.resolve_path( - &path, - Some(ValueNS), - &parent_scope, - Some(Finalize::new(ast::CRATE_NODE_ID, path_span)), - None, - ) && partial_res.unresolved_segments() == 0 { + if let PathResult::NonModule(partial_res) = self.maybe_resolve_path(&path, Some(ValueNS), &parent_scope) + && partial_res.unresolved_segments() == 0 { let sm = self.session.source_map(); - let span = sm.span_extend_while(span, |c| c == '!').unwrap_or(span); - let code = sm.span_to_snippet(span).unwrap(); - suggestion = Some( - (vec![(span, code.trim_end_matches('!').to_string())], + let exclamation_span = sm.next_point(span); + suggestion = Some(( + vec![(exclamation_span, "".to_string())], format!("{} is not a macro, but a {}, try to remove `!`", Segment::names_to_string(&path), partial_res.base_res().descr()), - Applicability::MaybeIncorrect) - ); + Applicability::MaybeIncorrect + )); } (span, label) } else { diff --git a/src/test/ui/suggestions/issue-103112.stderr b/src/test/ui/suggestions/issue-103112.stderr index 3518ef4c65271..4ca7fdf9b5a2a 100644 --- a/src/test/ui/suggestions/issue-103112.stderr +++ b/src/test/ui/suggestions/issue-103112.stderr @@ -6,8 +6,9 @@ LL | std::process::abort!(); | help: std::process::abort is not a macro, but a function, try to remove `!` | -LL | std::process::abort(); - | ~~~~~ +LL - std::process::abort!(); +LL + std::process::abort(); + | error: aborting due to previous error