|
1 | 1 | //! A bunch of methods and structures more or less related to resolving imports.
|
2 | 2 |
|
3 |
| -use crate::diagnostics::Suggestion; |
| 3 | +use crate::diagnostics::{import_candidates, Suggestion}; |
4 | 4 | use crate::Determinacy::{self, *};
|
5 | 5 | use crate::Namespace::{self, *};
|
6 |
| -use crate::{module_to_string, names_to_string}; |
| 6 | +use crate::{module_to_string, names_to_string, ImportSuggestion}; |
7 | 7 | use crate::{AmbiguityKind, BindingKey, ModuleKind, ResolutionError, Resolver, Segment};
|
8 | 8 | use crate::{Finalize, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet};
|
9 | 9 | use crate::{NameBinding, NameBindingKind, PathResult};
|
@@ -406,6 +406,7 @@ struct UnresolvedImportError {
|
406 | 406 | label: Option<String>,
|
407 | 407 | note: Option<String>,
|
408 | 408 | suggestion: Option<Suggestion>,
|
| 409 | + candidate: Option<Vec<ImportSuggestion>>, |
409 | 410 | }
|
410 | 411 |
|
411 | 412 | pub struct ImportResolver<'a, 'b> {
|
@@ -497,6 +498,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
497 | 498 | label: None,
|
498 | 499 | note: None,
|
499 | 500 | suggestion: None,
|
| 501 | + candidate: None, |
500 | 502 | };
|
501 | 503 | if path.contains("::") {
|
502 | 504 | errors.push((path, err))
|
@@ -547,6 +549,16 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
547 | 549 | }
|
548 | 550 | diag.multipart_suggestion(&msg, suggestions, applicability);
|
549 | 551 | }
|
| 552 | + |
| 553 | + if let Some(candidate) = &err.candidate { |
| 554 | + import_candidates( |
| 555 | + self.r.session, |
| 556 | + &self.r.source_span, |
| 557 | + &mut diag, |
| 558 | + Some(err.span), |
| 559 | + &candidate, |
| 560 | + ) |
| 561 | + } |
550 | 562 | }
|
551 | 563 |
|
552 | 564 | diag.emit();
|
@@ -664,6 +676,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
664 | 676 | Some(finalize),
|
665 | 677 | ignore_binding,
|
666 | 678 | );
|
| 679 | + |
667 | 680 | let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len;
|
668 | 681 | import.vis.set(orig_vis);
|
669 | 682 | let module = match path_res {
|
@@ -706,12 +719,14 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
706 | 719 | String::from("a similar path exists"),
|
707 | 720 | Applicability::MaybeIncorrect,
|
708 | 721 | )),
|
| 722 | + candidate: None, |
709 | 723 | },
|
710 | 724 | None => UnresolvedImportError {
|
711 | 725 | span,
|
712 | 726 | label: Some(label),
|
713 | 727 | note: None,
|
714 | 728 | suggestion,
|
| 729 | + candidate: None, |
715 | 730 | },
|
716 | 731 | };
|
717 | 732 | return Some(err);
|
@@ -754,6 +769,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
754 | 769 | label: Some(String::from("cannot glob-import a module into itself")),
|
755 | 770 | note: None,
|
756 | 771 | suggestion: None,
|
| 772 | + candidate: None, |
757 | 773 | });
|
758 | 774 | }
|
759 | 775 | }
|
@@ -919,11 +935,19 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
919 | 935 | }
|
920 | 936 | };
|
921 | 937 |
|
| 938 | + let parent_suggestion = |
| 939 | + self.r.lookup_import_candidates(ident, TypeNS, &import.parent_scope, |_| true); |
| 940 | + |
922 | 941 | Some(UnresolvedImportError {
|
923 | 942 | span: import.span,
|
924 | 943 | label: Some(label),
|
925 | 944 | note,
|
926 | 945 | suggestion,
|
| 946 | + candidate: if !parent_suggestion.is_empty() { |
| 947 | + Some(parent_suggestion) |
| 948 | + } else { |
| 949 | + None |
| 950 | + }, |
927 | 951 | })
|
928 | 952 | } else {
|
929 | 953 | // `resolve_ident_in_module` reported a privacy error.
|
|
0 commit comments