@@ -459,7 +459,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
459459 return ( err, Vec :: new ( ) ) ;
460460 }
461461
462- let ( found, mut candidates) = self . try_lookup_name_relaxed (
462+ let ( found, suggested_candidates , mut candidates) = self . try_lookup_name_relaxed (
463463 & mut err,
464464 source,
465465 path,
@@ -478,7 +478,15 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
478478 }
479479
480480 let mut fallback = self . suggest_trait_and_bounds ( & mut err, source, res, span, & base_error) ;
481- fallback |= self . suggest_typo ( & mut err, source, path, following_seg, span, & base_error) ;
481+ fallback |= self . suggest_typo (
482+ & mut err,
483+ source,
484+ path,
485+ following_seg,
486+ span,
487+ & base_error,
488+ suggested_candidates,
489+ ) ;
482490
483491 if fallback {
484492 // Fallback label.
@@ -589,7 +597,16 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
589597 span : Span ,
590598 res : Option < Res > ,
591599 base_error : & BaseError ,
592- ) -> ( bool , Vec < ImportSuggestion > ) {
600+ ) -> ( bool , FxHashSet < String > , Vec < ImportSuggestion > ) {
601+ let span = match following_seg {
602+ Some ( _) if path[ 0 ] . ident . span . eq_ctxt ( path[ path. len ( ) - 1 ] . ident . span ) => {
603+ // The path `span` that comes in includes any following segments, which we don't
604+ // want to replace in the suggestions.
605+ path[ 0 ] . ident . span . to ( path[ path. len ( ) - 1 ] . ident . span )
606+ }
607+ _ => span,
608+ } ;
609+ let mut suggested_candidates = FxHashSet :: default ( ) ;
593610 // Try to lookup name in more relaxed fashion for better error reporting.
594611 let ident = path. last ( ) . unwrap ( ) . ident ;
595612 let is_expected = & |res| source. is_expected ( res) ;
@@ -646,6 +663,11 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
646663 } ;
647664 let msg = format ! ( "{preamble}try using the variant's enum" ) ;
648665
666+ suggested_candidates. extend (
667+ enum_candidates
668+ . iter ( )
669+ . map ( |( _variant_path, enum_ty_path) | enum_ty_path. clone ( ) ) ,
670+ ) ;
649671 err. span_suggestions (
650672 span,
651673 msg,
@@ -658,7 +680,8 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
658680 // Try finding a suitable replacement.
659681 let typo_sugg = self
660682 . lookup_typo_candidate ( path, following_seg, source. namespace ( ) , is_expected)
661- . to_opt_suggestion ( ) ;
683+ . to_opt_suggestion ( )
684+ . filter ( |sugg| !suggested_candidates. contains ( sugg. candidate . as_str ( ) ) ) ;
662685 if let [ segment] = path
663686 && !matches ! ( source, PathSource :: Delegation )
664687 && self . self_type_is_available ( )
@@ -719,7 +742,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
719742 }
720743 }
721744 self . r . add_typo_suggestion ( err, typo_sugg, ident_span) ;
722- return ( true , candidates) ;
745+ return ( true , suggested_candidates , candidates) ;
723746 }
724747
725748 // If the first argument in call is `self` suggest calling a method.
@@ -737,7 +760,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
737760 format ! ( "self.{path_str}({args_snippet})" ) ,
738761 Applicability :: MachineApplicable ,
739762 ) ;
740- return ( true , candidates) ;
763+ return ( true , suggested_candidates , candidates) ;
741764 }
742765 }
743766
@@ -754,7 +777,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
754777 ) {
755778 // We do this to avoid losing a secondary span when we override the main error span.
756779 self . r . add_typo_suggestion ( err, typo_sugg, ident_span) ;
757- return ( true , candidates) ;
780+ return ( true , suggested_candidates , candidates) ;
758781 }
759782 }
760783
@@ -772,7 +795,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
772795 ident. span ,
773796 format ! ( "the binding `{path_str}` is available in a different scope in the same function" ) ,
774797 ) ;
775- return ( true , candidates) ;
798+ return ( true , suggested_candidates , candidates) ;
776799 }
777800 }
778801 }
@@ -781,7 +804,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
781804 candidates = self . smart_resolve_partial_mod_path_errors ( path, following_seg) ;
782805 }
783806
784- ( false , candidates)
807+ ( false , suggested_candidates , candidates)
785808 }
786809
787810 fn suggest_trait_and_bounds (
@@ -869,13 +892,16 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
869892 following_seg : Option < & Segment > ,
870893 span : Span ,
871894 base_error : & BaseError ,
895+ suggested_candidates : FxHashSet < String > ,
872896 ) -> bool {
873897 let is_expected = & |res| source. is_expected ( res) ;
874898 let ident_span = path. last ( ) . map_or ( span, |ident| ident. ident . span ) ;
875899 let typo_sugg =
876900 self . lookup_typo_candidate ( path, following_seg, source. namespace ( ) , is_expected) ;
877901 let mut fallback = false ;
878- let typo_sugg = typo_sugg. to_opt_suggestion ( ) ;
902+ let typo_sugg = typo_sugg
903+ . to_opt_suggestion ( )
904+ . filter ( |sugg| !suggested_candidates. contains ( sugg. candidate . as_str ( ) ) ) ;
879905 if !self . r . add_typo_suggestion ( err, typo_sugg, ident_span) {
880906 fallback = true ;
881907 match self . diag_metadata . current_let_binding {
0 commit comments