@@ -332,15 +332,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
332332 pub ( crate ) fn smart_resolve_partial_mod_path_errors (
333333 & mut self ,
334334 prefix_path : & [ Segment ] ,
335- path : & [ Segment ] ,
335+ following_seg : Option < & Segment > ,
336336 ) -> Vec < ImportSuggestion > {
337- let next_seg = if path. len ( ) >= prefix_path. len ( ) + 1 && prefix_path. len ( ) == 1 {
338- path. get ( prefix_path. len ( ) )
339- } else {
340- None
341- } ;
342337 if let Some ( segment) = prefix_path. last ( ) &&
343- let Some ( next_seg) = next_seg {
338+ let Some ( following_seg) = following_seg
339+ {
344340 let candidates = self . r . lookup_import_candidates (
345341 segment. ident ,
346342 Namespace :: TypeNS ,
@@ -353,9 +349,10 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
353349 . filter ( |candidate| {
354350 if let Some ( def_id) = candidate. did &&
355351 let Some ( module) = self . r . get_module ( def_id) {
356- self . r . resolutions ( module) . borrow ( ) . iter ( ) . any ( |( key, _r) | {
357- key. ident . name == next_seg. ident . name
358- } )
352+ Some ( def_id) != self . parent_scope . module . opt_def_id ( ) &&
353+ self . r . resolutions ( module) . borrow ( ) . iter ( ) . any ( |( key, _r) | {
354+ key. ident . name == following_seg. ident . name
355+ } )
359356 } else {
360357 false
361358 }
@@ -371,7 +368,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
371368 pub ( crate ) fn smart_resolve_report_errors (
372369 & mut self ,
373370 path : & [ Segment ] ,
374- full_path : & [ Segment ] ,
371+ following_seg : Option < & Segment > ,
375372 span : Span ,
376373 source : PathSource < ' _ > ,
377374 res : Option < Res > ,
@@ -412,8 +409,15 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
412409 return ( err, Vec :: new ( ) ) ;
413410 }
414411
415- let ( found, candidates) =
416- self . try_lookup_name_relaxed ( & mut err, source, path, full_path, span, res, & base_error) ;
412+ let ( found, candidates) = self . try_lookup_name_relaxed (
413+ & mut err,
414+ source,
415+ path,
416+ following_seg,
417+ span,
418+ res,
419+ & base_error,
420+ ) ;
417421 if found {
418422 return ( err, candidates) ;
419423 }
@@ -422,7 +426,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
422426
423427 // if we have suggested using pattern matching, then don't add needless suggestions
424428 // for typos.
425- fallback |= self . suggest_typo ( & mut err, source, path, span, & base_error) ;
429+ fallback |= self . suggest_typo ( & mut err, source, path, following_seg , span, & base_error) ;
426430
427431 if fallback {
428432 // Fallback label.
@@ -519,7 +523,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
519523 err : & mut Diagnostic ,
520524 source : PathSource < ' _ > ,
521525 path : & [ Segment ] ,
522- full_path : & [ Segment ] ,
526+ following_seg : Option < & Segment > ,
523527 span : Span ,
524528 res : Option < Res > ,
525529 base_error : & BaseError ,
@@ -590,8 +594,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
590594 }
591595
592596 // Try finding a suitable replacement.
593- let typo_sugg =
594- self . lookup_typo_candidate ( path, source. namespace ( ) , is_expected) . to_opt_suggestion ( ) ;
597+ let typo_sugg = self
598+ . lookup_typo_candidate ( path, following_seg, source. namespace ( ) , is_expected)
599+ . to_opt_suggestion ( ) ;
595600 if path. len ( ) == 1 && self . self_type_is_available ( ) {
596601 if let Some ( candidate) =
597602 self . lookup_assoc_candidate ( ident, ns, is_expected, source. is_call ( ) )
@@ -690,7 +695,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
690695 }
691696
692697 if candidates. is_empty ( ) {
693- candidates = self . smart_resolve_partial_mod_path_errors ( path, full_path ) ;
698+ candidates = self . smart_resolve_partial_mod_path_errors ( path, following_seg ) ;
694699 }
695700
696701 return ( false , candidates) ;
@@ -776,12 +781,14 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
776781 err : & mut Diagnostic ,
777782 source : PathSource < ' _ > ,
778783 path : & [ Segment ] ,
784+ following_seg : Option < & Segment > ,
779785 span : Span ,
780786 base_error : & BaseError ,
781787 ) -> bool {
782788 let is_expected = & |res| source. is_expected ( res) ;
783789 let ident_span = path. last ( ) . map_or ( span, |ident| ident. ident . span ) ;
784- let typo_sugg = self . lookup_typo_candidate ( path, source. namespace ( ) , is_expected) ;
790+ let typo_sugg =
791+ self . lookup_typo_candidate ( path, following_seg, source. namespace ( ) , is_expected) ;
785792 let is_in_same_file = & |sp1, sp2| {
786793 let source_map = self . r . tcx . sess . source_map ( ) ;
787794 let file1 = source_map. span_to_filename ( sp1) ;
@@ -1715,6 +1722,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
17151722 fn lookup_typo_candidate (
17161723 & mut self ,
17171724 path : & [ Segment ] ,
1725+ following_seg : Option < & Segment > ,
17181726 ns : Namespace ,
17191727 filter_fn : & impl Fn ( Res ) -> bool ,
17201728 ) -> TypoCandidate {
@@ -1793,6 +1801,26 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
17931801 }
17941802 }
17951803
1804+ // if next_seg is present, let's filter everything that does not continue the path
1805+ if let Some ( following_seg) = following_seg {
1806+ names. retain ( |suggestion| match suggestion. res {
1807+ Res :: Def ( DefKind :: Struct | DefKind :: Enum | DefKind :: Union , _) => {
1808+ // FIXME: this is not totally accurate, but mostly works
1809+ suggestion. candidate != following_seg. ident . name
1810+ }
1811+ Res :: Def ( DefKind :: Mod , def_id) => self . r . get_module ( def_id) . map_or_else (
1812+ || false ,
1813+ |module| {
1814+ self . r
1815+ . resolutions ( module)
1816+ . borrow ( )
1817+ . iter ( )
1818+ . any ( |( key, _) | key. ident . name == following_seg. ident . name )
1819+ } ,
1820+ ) ,
1821+ _ => true ,
1822+ } ) ;
1823+ }
17961824 let name = path[ path. len ( ) - 1 ] . ident . name ;
17971825 // Make sure error reporting is deterministic.
17981826 names. sort_by ( |a, b| a. candidate . as_str ( ) . cmp ( b. candidate . as_str ( ) ) ) ;
0 commit comments