@@ -459,7 +459,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
459
459
return ( err, Vec :: new ( ) ) ;
460
460
}
461
461
462
- let ( found, mut candidates) = self . try_lookup_name_relaxed (
462
+ let ( found, suggested_candidates , mut candidates) = self . try_lookup_name_relaxed (
463
463
& mut err,
464
464
source,
465
465
path,
@@ -478,7 +478,15 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
478
478
}
479
479
480
480
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
+ ) ;
482
490
483
491
if fallback {
484
492
// Fallback label.
@@ -589,7 +597,16 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
589
597
span : Span ,
590
598
res : Option < Res > ,
591
599
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 ( ) ;
593
610
// Try to lookup name in more relaxed fashion for better error reporting.
594
611
let ident = path. last ( ) . unwrap ( ) . ident ;
595
612
let is_expected = & |res| source. is_expected ( res) ;
@@ -646,6 +663,11 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
646
663
} ;
647
664
let msg = format ! ( "{preamble}try using the variant's enum" ) ;
648
665
666
+ suggested_candidates. extend (
667
+ enum_candidates
668
+ . iter ( )
669
+ . map ( |( _variant_path, enum_ty_path) | enum_ty_path. clone ( ) ) ,
670
+ ) ;
649
671
err. span_suggestions (
650
672
span,
651
673
msg,
@@ -658,7 +680,8 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
658
680
// Try finding a suitable replacement.
659
681
let typo_sugg = self
660
682
. 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 ( ) ) ) ;
662
685
if let [ segment] = path
663
686
&& !matches ! ( source, PathSource :: Delegation )
664
687
&& self . self_type_is_available ( )
@@ -719,7 +742,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
719
742
}
720
743
}
721
744
self . r . add_typo_suggestion ( err, typo_sugg, ident_span) ;
722
- return ( true , candidates) ;
745
+ return ( true , suggested_candidates , candidates) ;
723
746
}
724
747
725
748
// 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> {
737
760
format ! ( "self.{path_str}({args_snippet})" ) ,
738
761
Applicability :: MachineApplicable ,
739
762
) ;
740
- return ( true , candidates) ;
763
+ return ( true , suggested_candidates , candidates) ;
741
764
}
742
765
}
743
766
@@ -754,7 +777,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
754
777
) {
755
778
// We do this to avoid losing a secondary span when we override the main error span.
756
779
self . r . add_typo_suggestion ( err, typo_sugg, ident_span) ;
757
- return ( true , candidates) ;
780
+ return ( true , suggested_candidates , candidates) ;
758
781
}
759
782
}
760
783
@@ -772,7 +795,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
772
795
ident. span ,
773
796
format ! ( "the binding `{path_str}` is available in a different scope in the same function" ) ,
774
797
) ;
775
- return ( true , candidates) ;
798
+ return ( true , suggested_candidates , candidates) ;
776
799
}
777
800
}
778
801
}
@@ -781,7 +804,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
781
804
candidates = self . smart_resolve_partial_mod_path_errors ( path, following_seg) ;
782
805
}
783
806
784
- ( false , candidates)
807
+ ( false , suggested_candidates , candidates)
785
808
}
786
809
787
810
fn suggest_trait_and_bounds (
@@ -869,13 +892,16 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
869
892
following_seg : Option < & Segment > ,
870
893
span : Span ,
871
894
base_error : & BaseError ,
895
+ suggested_candidates : FxHashSet < String > ,
872
896
) -> bool {
873
897
let is_expected = & |res| source. is_expected ( res) ;
874
898
let ident_span = path. last ( ) . map_or ( span, |ident| ident. ident . span ) ;
875
899
let typo_sugg =
876
900
self . lookup_typo_candidate ( path, following_seg, source. namespace ( ) , is_expected) ;
877
901
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 ( ) ) ) ;
879
905
if !self . r . add_typo_suggestion ( err, typo_sugg, ident_span) {
880
906
fallback = true ;
881
907
match self . diag_metadata . current_let_binding {
0 commit comments