about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs13
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs25
-rw-r--r--src/test/ui/hygiene/globs.stderr18
-rw-r--r--src/test/ui/hygiene/rustc-macro-transparency.stderr8
-rw-r--r--src/test/ui/macros/macro-context.stderr2
-rw-r--r--src/test/ui/proc-macro/gen-macro-rules-hygiene.stderr4
-rw-r--r--src/test/ui/proc-macro/mixed-site-span.stderr4
7 files changed, 51 insertions, 23 deletions
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index c4644d4f076..5d868ebec94 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -24,7 +24,7 @@ use rustc_span::hygiene::MacroKind;
 use rustc_span::lev_distance::find_best_match_for_name;
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::{BytePos, Span};
+use rustc_span::{BytePos, Span, SyntaxContext};
 
 use crate::imports::{Import, ImportKind, ImportResolver};
 use crate::late::{PatternSource, Rib};
@@ -47,6 +47,7 @@ pub(crate) type Suggestion = (Vec<(Span, String)>, String, Applicability);
 /// similarly named label and whether or not it is reachable.
 pub(crate) type LabelSuggestion = (Ident, bool);
 
+#[derive(Debug)]
 pub(crate) enum SuggestionTarget {
     /// The target has a similar name as the name used by the programmer (probably a typo)
     SimilarlyNamed,
@@ -54,6 +55,7 @@ pub(crate) enum SuggestionTarget {
     SingleItem,
 }
 
+#[derive(Debug)]
 pub(crate) struct TypoSuggestion {
     pub candidate: Symbol,
     pub res: Res,
@@ -482,11 +484,12 @@ impl<'a> Resolver<'a> {
         module: Module<'a>,
         names: &mut Vec<TypoSuggestion>,
         filter_fn: &impl Fn(Res) -> bool,
+        ctxt: Option<SyntaxContext>,
     ) {
         for (key, resolution) in self.resolutions(module).borrow().iter() {
             if let Some(binding) = resolution.borrow().binding {
                 let res = binding.res();
-                if filter_fn(res) {
+                if filter_fn(res) && ctxt.map_or(true, |ctxt| ctxt == key.ident.span.ctxt()) {
                     names.push(TypoSuggestion::typo_from_res(key.ident.name, res));
                 }
             }
@@ -1181,10 +1184,10 @@ impl<'a> Resolver<'a> {
                 Scope::CrateRoot => {
                     let root_ident = Ident::new(kw::PathRoot, ident.span);
                     let root_module = this.resolve_crate_root(root_ident);
-                    this.add_module_candidates(root_module, &mut suggestions, filter_fn);
+                    this.add_module_candidates(root_module, &mut suggestions, filter_fn, None);
                 }
                 Scope::Module(module, _) => {
-                    this.add_module_candidates(module, &mut suggestions, filter_fn);
+                    this.add_module_candidates(module, &mut suggestions, filter_fn, None);
                 }
                 Scope::MacroUsePrelude => {
                     suggestions.extend(this.macro_use_prelude.iter().filter_map(
@@ -1221,7 +1224,7 @@ impl<'a> Resolver<'a> {
                 Scope::StdLibPrelude => {
                     if let Some(prelude) = this.prelude {
                         let mut tmp_suggestions = Vec::new();
-                        this.add_module_candidates(prelude, &mut tmp_suggestions, filter_fn);
+                        this.add_module_candidates(prelude, &mut tmp_suggestions, filter_fn, None);
                         suggestions.extend(
                             tmp_suggestions
                                 .into_iter()
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 13cd7987e92..3c82c760ed7 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -131,6 +131,7 @@ pub(super) enum LifetimeElisionCandidate {
 }
 
 /// Only used for diagnostics.
+#[derive(Debug)]
 struct BaseError {
     msg: String,
     fallback_label: String,
@@ -1584,19 +1585,35 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
     ) -> Option<TypoSuggestion> {
         let mut names = Vec::new();
         if path.len() == 1 {
+            let mut ctxt = path.last().unwrap().ident.span.ctxt();
+
             // Search in lexical scope.
             // Walk backwards up the ribs in scope and collect candidates.
             for rib in self.ribs[ns].iter().rev() {
+                let rib_ctxt = if rib.kind.contains_params() {
+                    ctxt.normalize_to_macros_2_0()
+                } else {
+                    ctxt.normalize_to_macro_rules()
+                };
+
                 // Locals and type parameters
                 for (ident, &res) in &rib.bindings {
-                    if filter_fn(res) {
+                    if filter_fn(res) && ident.span.ctxt() == rib_ctxt {
                         names.push(TypoSuggestion::typo_from_res(ident.name, res));
                     }
                 }
+
+                if let RibKind::MacroDefinition(def) = rib.kind && def == self.r.macro_def(ctxt) {
+                    // If an invocation of this macro created `ident`, give up on `ident`
+                    // and switch to `ident`'s source from the macro definition.
+                    ctxt.remove_mark();
+                    continue;
+                }
+
                 // Items in scope
                 if let RibKind::ModuleRibKind(module) = rib.kind {
                     // Items from this module
-                    self.r.add_module_candidates(module, &mut names, &filter_fn);
+                    self.r.add_module_candidates(module, &mut names, &filter_fn, Some(ctxt));
 
                     if let ModuleKind::Block = module.kind {
                         // We can see through blocks
@@ -1622,7 +1639,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                             }));
 
                             if let Some(prelude) = self.r.prelude {
-                                self.r.add_module_candidates(prelude, &mut names, &filter_fn);
+                                self.r.add_module_candidates(prelude, &mut names, &filter_fn, None);
                             }
                         }
                         break;
@@ -1641,7 +1658,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
             if let PathResult::Module(ModuleOrUniformRoot::Module(module)) =
                 self.resolve_path(mod_path, Some(TypeNS), None)
             {
-                self.r.add_module_candidates(module, &mut names, &filter_fn);
+                self.r.add_module_candidates(module, &mut names, &filter_fn, None);
             }
         }
 
diff --git a/src/test/ui/hygiene/globs.stderr b/src/test/ui/hygiene/globs.stderr
index bcfcc28adf7..1f2a96a4c41 100644
--- a/src/test/ui/hygiene/globs.stderr
+++ b/src/test/ui/hygiene/globs.stderr
@@ -1,9 +1,16 @@
 error[E0425]: cannot find function `f` in this scope
   --> $DIR/globs.rs:22:9
    |
+LL |     pub fn g() {}
+   |     ---------- similarly named function `g` defined here
+...
 LL |         f();
-   |         ^ not found in this scope
+   |         ^
+   |
+help: a function with a similar name exists
    |
+LL |         g();
+   |         ~
 help: consider importing this function
    |
 LL | use foo::f;
@@ -12,8 +19,11 @@ LL | use foo::f;
 error[E0425]: cannot find function `g` in this scope
   --> $DIR/globs.rs:15:5
    |
+LL |       pub fn f() {}
+   |       ---------- similarly named function `f` defined here
+...
 LL |       g();
-   |       ^ not found in this scope
+   |       ^
 ...
 LL | /     m! {
 LL | |         use bar::*;
@@ -23,6 +33,10 @@ LL | |     }
    | |_____- in this macro invocation
    |
    = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: a function with a similar name exists
+   |
+LL |     f();
+   |     ~
 help: consider importing this function
    |
 LL | use bar::g;
diff --git a/src/test/ui/hygiene/rustc-macro-transparency.stderr b/src/test/ui/hygiene/rustc-macro-transparency.stderr
index 17d05dd0963..1d2a1e12498 100644
--- a/src/test/ui/hygiene/rustc-macro-transparency.stderr
+++ b/src/test/ui/hygiene/rustc-macro-transparency.stderr
@@ -19,14 +19,8 @@ LL |     semitransparent;
 error[E0423]: expected value, found macro `opaque`
   --> $DIR/rustc-macro-transparency.rs:30:5
    |
-LL |     struct Opaque;
-   |     -------------- similarly named unit struct `Opaque` defined here
-...
 LL |     opaque;
-   |     ^^^^^^
-   |     |
-   |     not a value
-   |     help: a unit struct with a similar name exists (notice the capitalization): `Opaque`
+   |     ^^^^^^ not a value
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/macros/macro-context.stderr b/src/test/ui/macros/macro-context.stderr
index 2a2e0c6c66a..f597c398b7c 100644
--- a/src/test/ui/macros/macro-context.stderr
+++ b/src/test/ui/macros/macro-context.stderr
@@ -57,7 +57,7 @@ error[E0425]: cannot find value `i` in this scope
   --> $DIR/macro-context.rs:3:13
    |
 LL |     () => ( i ; typeof );
-   |             ^ help: a local variable with a similar name exists: `a`
+   |             ^ not found in this scope
 ...
 LL |     let i = m!();
    |             ---- in this macro invocation
diff --git a/src/test/ui/proc-macro/gen-macro-rules-hygiene.stderr b/src/test/ui/proc-macro/gen-macro-rules-hygiene.stderr
index 6060f872f22..df7c4f72eb0 100644
--- a/src/test/ui/proc-macro/gen-macro-rules-hygiene.stderr
+++ b/src/test/ui/proc-macro/gen-macro-rules-hygiene.stderr
@@ -13,7 +13,7 @@ error[E0425]: cannot find value `local_use` in this scope
   --> $DIR/gen-macro-rules-hygiene.rs:12:1
    |
 LL | gen_macro_rules!();
-   | ^^^^^^^^^^^^^^^^^^ not found in this scope
+   | ^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `local_def`
 ...
 LL |         generated!();
    |         ------------ in this macro invocation
@@ -24,7 +24,7 @@ error[E0425]: cannot find value `local_def` in this scope
   --> $DIR/gen-macro-rules-hygiene.rs:21:9
    |
 LL |         local_def;
-   |         ^^^^^^^^^ not found in this scope
+   |         ^^^^^^^^^ help: a local variable with a similar name exists: `local_use`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/proc-macro/mixed-site-span.stderr b/src/test/ui/proc-macro/mixed-site-span.stderr
index eab4317ded8..13786080124 100644
--- a/src/test/ui/proc-macro/mixed-site-span.stderr
+++ b/src/test/ui/proc-macro/mixed-site-span.stderr
@@ -10,7 +10,7 @@ error[E0425]: cannot find value `local_use` in this scope
   --> $DIR/mixed-site-span.rs:13:9
    |
 LL |         proc_macro_rules!();
-   |         ^^^^^^^^^^^^^^^^^^^ not found in this scope
+   |         ^^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `local_def`
    |
    = note: this error originates in the macro `proc_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -18,7 +18,7 @@ error[E0425]: cannot find value `local_def` in this scope
   --> $DIR/mixed-site-span.rs:17:9
    |
 LL |         local_def;
-   |         ^^^^^^^^^ not found in this scope
+   |         ^^^^^^^^^ help: a local variable with a similar name exists: `local_use`
 
 error[E0412]: cannot find type `ItemUse` in crate `$crate`
   --> $DIR/mixed-site-span.rs:24:1