|
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