@@ -332,15 +332,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
332
332
pub ( crate ) fn smart_resolve_partial_mod_path_errors (
333
333
& mut self ,
334
334
prefix_path : & [ Segment ] ,
335
- path : & [ Segment ] ,
335
+ following_seg : Option < & Segment > ,
336
336
) -> 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
- } ;
342
337
if let Some ( segment) = prefix_path. last ( ) &&
343
- let Some ( next_seg) = next_seg {
338
+ let Some ( following_seg) = following_seg
339
+ {
344
340
let candidates = self . r . lookup_import_candidates (
345
341
segment. ident ,
346
342
Namespace :: TypeNS ,
@@ -353,9 +349,10 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
353
349
. filter ( |candidate| {
354
350
if let Some ( def_id) = candidate. did &&
355
351
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
+ } )
359
356
} else {
360
357
false
361
358
}
@@ -371,7 +368,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
371
368
pub ( crate ) fn smart_resolve_report_errors (
372
369
& mut self ,
373
370
path : & [ Segment ] ,
374
- full_path : & [ Segment ] ,
371
+ following_seg : Option < & Segment > ,
375
372
span : Span ,
376
373
source : PathSource < ' _ > ,
377
374
res : Option < Res > ,
@@ -412,8 +409,15 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
412
409
return ( err, Vec :: new ( ) ) ;
413
410
}
414
411
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
+ ) ;
417
421
if found {
418
422
return ( err, candidates) ;
419
423
}
@@ -422,7 +426,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
422
426
423
427
// if we have suggested using pattern matching, then don't add needless suggestions
424
428
// 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) ;
426
430
427
431
if fallback {
428
432
// Fallback label.
@@ -519,7 +523,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
519
523
err : & mut Diagnostic ,
520
524
source : PathSource < ' _ > ,
521
525
path : & [ Segment ] ,
522
- full_path : & [ Segment ] ,
526
+ following_seg : Option < & Segment > ,
523
527
span : Span ,
524
528
res : Option < Res > ,
525
529
base_error : & BaseError ,
@@ -590,8 +594,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
590
594
}
591
595
592
596
// 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 ( ) ;
595
600
if path. len ( ) == 1 && self . self_type_is_available ( ) {
596
601
if let Some ( candidate) =
597
602
self . lookup_assoc_candidate ( ident, ns, is_expected, source. is_call ( ) )
@@ -690,7 +695,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
690
695
}
691
696
692
697
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 ) ;
694
699
}
695
700
696
701
return ( false , candidates) ;
@@ -776,12 +781,14 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
776
781
err : & mut Diagnostic ,
777
782
source : PathSource < ' _ > ,
778
783
path : & [ Segment ] ,
784
+ following_seg : Option < & Segment > ,
779
785
span : Span ,
780
786
base_error : & BaseError ,
781
787
) -> bool {
782
788
let is_expected = & |res| source. is_expected ( res) ;
783
789
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) ;
785
792
let is_in_same_file = & |sp1, sp2| {
786
793
let source_map = self . r . tcx . sess . source_map ( ) ;
787
794
let file1 = source_map. span_to_filename ( sp1) ;
@@ -1715,6 +1722,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
1715
1722
fn lookup_typo_candidate (
1716
1723
& mut self ,
1717
1724
path : & [ Segment ] ,
1725
+ following_seg : Option < & Segment > ,
1718
1726
ns : Namespace ,
1719
1727
filter_fn : & impl Fn ( Res ) -> bool ,
1720
1728
) -> TypoCandidate {
@@ -1793,6 +1801,26 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
1793
1801
}
1794
1802
}
1795
1803
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
+ }
1796
1824
let name = path[ path. len ( ) - 1 ] . ident . name ;
1797
1825
// Make sure error reporting is deterministic.
1798
1826
names. sort_by ( |a, b| a. candidate . as_str ( ) . cmp ( b. candidate . as_str ( ) ) ) ;
0 commit comments