about summary refs log tree commit diff
path: root/compiler/rustc_resolve/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2021-10-13 22:51:00 +0200
committerGitHub <noreply@github.com>2021-10-13 22:51:00 +0200
commitefac68b93cfac0aa7062169f3b041661fbbdbdbd (patch)
treed91e65af7b37766a328edae3f7b009b4038d57a8 /compiler/rustc_resolve/src
parenteeb16a2a892c2a29b1da3085e29f39efa3486e1c (diff)
parentf819e6d59c41b6bb3db2810c5c8e340b2fb2a88d (diff)
downloadrust-efac68b93cfac0aa7062169f3b041661fbbdbdbd.tar.gz
rust-efac68b93cfac0aa7062169f3b041661fbbdbdbd.zip
Rollup merge of #89347 - TaKO8Ki:crate-or-module-typo, r=estebank
suggestion for typoed crate or module

Previously, the compiler didn't suggest similarly named crates or modules. This pull request adds a suggestion for typoed crates or modules.

#76208

before:

```
error[E0433]: failed to resolve: use of undeclared type or module `chono`
 --> src/main.rs:2:5
  |
2 | use chono::prelude::*;
  |     ^^^^^ use of undeclared type or module `chono`
```

after:

```
error[E0433]: failed to resolve: use of undeclared type or module `chono`
 --> src/main.rs:2:5
  |
2 | use chono::prelude::*;
  |     ^^^^^
  |     |
  |     use of undeclared crate or module `chono`
  |     help: a similar crate or module exists: `chrono`
```
Diffstat (limited to 'compiler/rustc_resolve/src')
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs28
-rw-r--r--compiler/rustc_resolve/src/lib.rs17
2 files changed, 44 insertions, 1 deletions
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index dea47c25a8e..e3970038a33 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1277,6 +1277,34 @@ impl<'a> Resolver<'a> {
 
         err.emit();
     }
+
+    crate fn find_similarly_named_module_or_crate(
+        &mut self,
+        ident: Symbol,
+        current_module: &Module<'a>,
+    ) -> Option<Symbol> {
+        let mut candidates = self
+            .extern_prelude
+            .iter()
+            .map(|(ident, _)| ident.name)
+            .chain(
+                self.module_map
+                    .iter()
+                    .filter(|(_, module)| {
+                        current_module.is_ancestor_of(module) && !ptr::eq(current_module, *module)
+                    })
+                    .map(|(_, module)| module.kind.name())
+                    .flatten(),
+            )
+            .filter(|c| !c.to_string().is_empty())
+            .collect::<Vec<_>>();
+        candidates.sort();
+        candidates.dedup();
+        match find_best_match_for_name(&candidates, ident, None) {
+            Some(sugg) if sugg == ident => None,
+            sugg => sugg,
+        }
+    }
 }
 
 impl<'a, 'b> ImportResolver<'a, 'b> {
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 3e7783033ef..9652c483686 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -2555,7 +2555,22 @@ impl<'a> Resolver<'a> {
 
                             (format!("use of undeclared type `{}`", ident), suggestion)
                         } else {
-                            (format!("use of undeclared crate or module `{}`", ident), None)
+                            (
+                                format!("use of undeclared crate or module `{}`", ident),
+                                self.find_similarly_named_module_or_crate(
+                                    ident.name,
+                                    &parent_scope.module,
+                                )
+                                .map(|sugg| {
+                                    (
+                                        vec![(ident.span, sugg.to_string())],
+                                        String::from(
+                                            "there is a crate or module with a similar name",
+                                        ),
+                                        Applicability::MaybeIncorrect,
+                                    )
+                                }),
+                            )
                         }
                     } else {
                         let parent = path[i - 1].ident.name;