@@ -332,15 +332,10 @@ 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 {
344
339
let candidates = self . r . lookup_import_candidates (
345
340
segment. ident ,
346
341
Namespace :: TypeNS ,
@@ -354,7 +349,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
354
349
if let Some ( def_id) = candidate. did &&
355
350
let Some ( module) = self . r . get_module ( def_id) {
356
351
self . r . resolutions ( module) . borrow ( ) . iter ( ) . any ( |( key, _r) | {
357
- key. ident . name == next_seg . ident . name
352
+ key. ident . name == following_seg . ident . name
358
353
} )
359
354
} else {
360
355
false
@@ -371,7 +366,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
371
366
pub ( crate ) fn smart_resolve_report_errors (
372
367
& mut self ,
373
368
path : & [ Segment ] ,
374
- full_path : & [ Segment ] ,
369
+ following_seg : Option < & Segment > ,
375
370
span : Span ,
376
371
source : PathSource < ' _ > ,
377
372
res : Option < Res > ,
@@ -412,8 +407,15 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
412
407
return ( err, Vec :: new ( ) ) ;
413
408
}
414
409
415
- let ( found, candidates) =
416
- self . try_lookup_name_relaxed ( & mut err, source, path, full_path, span, res, & base_error) ;
410
+ let ( found, candidates) = self . try_lookup_name_relaxed (
411
+ & mut err,
412
+ source,
413
+ path,
414
+ following_seg,
415
+ span,
416
+ res,
417
+ & base_error,
418
+ ) ;
417
419
if found {
418
420
return ( err, candidates) ;
419
421
}
@@ -422,7 +424,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
422
424
423
425
// if we have suggested using pattern matching, then don't add needless suggestions
424
426
// for typos.
425
- fallback |= self . suggest_typo ( & mut err, source, path, span, & base_error) ;
427
+ fallback |= self . suggest_typo ( & mut err, source, path, following_seg , span, & base_error) ;
426
428
427
429
if fallback {
428
430
// Fallback label.
@@ -519,7 +521,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
519
521
err : & mut Diagnostic ,
520
522
source : PathSource < ' _ > ,
521
523
path : & [ Segment ] ,
522
- full_path : & [ Segment ] ,
524
+ following_seg : Option < & Segment > ,
523
525
span : Span ,
524
526
res : Option < Res > ,
525
527
base_error : & BaseError ,
@@ -590,8 +592,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
590
592
}
591
593
592
594
// Try finding a suitable replacement.
593
- let typo_sugg =
594
- self . lookup_typo_candidate ( path, source. namespace ( ) , is_expected) . to_opt_suggestion ( ) ;
595
+ let typo_sugg = self
596
+ . lookup_typo_candidate ( path, following_seg, source. namespace ( ) , is_expected)
597
+ . to_opt_suggestion ( ) ;
595
598
if path. len ( ) == 1 && self . self_type_is_available ( ) {
596
599
if let Some ( candidate) =
597
600
self . lookup_assoc_candidate ( ident, ns, is_expected, source. is_call ( ) )
@@ -690,7 +693,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
690
693
}
691
694
692
695
if candidates. is_empty ( ) {
693
- candidates = self . smart_resolve_partial_mod_path_errors ( path, full_path ) ;
696
+ candidates = self . smart_resolve_partial_mod_path_errors ( path, following_seg ) ;
694
697
}
695
698
696
699
return ( false , candidates) ;
@@ -776,12 +779,14 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
776
779
err : & mut Diagnostic ,
777
780
source : PathSource < ' _ > ,
778
781
path : & [ Segment ] ,
782
+ following_seg : Option < & Segment > ,
779
783
span : Span ,
780
784
base_error : & BaseError ,
781
785
) -> bool {
782
786
let is_expected = & |res| source. is_expected ( res) ;
783
787
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) ;
788
+ let typo_sugg =
789
+ self . lookup_typo_candidate ( path, following_seg, source. namespace ( ) , is_expected) ;
785
790
let is_in_same_file = & |sp1, sp2| {
786
791
let source_map = self . r . tcx . sess . source_map ( ) ;
787
792
let file1 = source_map. span_to_filename ( sp1) ;
@@ -1715,6 +1720,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
1715
1720
fn lookup_typo_candidate (
1716
1721
& mut self ,
1717
1722
path : & [ Segment ] ,
1723
+ following_seg : Option < & Segment > ,
1718
1724
ns : Namespace ,
1719
1725
filter_fn : & impl Fn ( Res ) -> bool ,
1720
1726
) -> TypoCandidate {
@@ -1793,6 +1799,26 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
1793
1799
}
1794
1800
}
1795
1801
1802
+ // if next_seg is present, let's filter everything that does not continue the path
1803
+ if let Some ( following_seg) = following_seg {
1804
+ names. retain ( |suggestion| match suggestion. res {
1805
+ Res :: Def ( DefKind :: Struct | DefKind :: Enum | DefKind :: Union , _) => {
1806
+ // this is not totally accurate, but mostly works
1807
+ suggestion. candidate != following_seg. ident . name
1808
+ }
1809
+ Res :: Def ( DefKind :: Mod , def_id) => self . r . get_module ( def_id) . map_or_else (
1810
+ || false ,
1811
+ |module| {
1812
+ self . r
1813
+ . resolutions ( module)
1814
+ . borrow ( )
1815
+ . iter ( )
1816
+ . any ( |( key, _) | key. ident . name == following_seg. ident . name )
1817
+ } ,
1818
+ ) ,
1819
+ _ => true ,
1820
+ } ) ;
1821
+ }
1796
1822
let name = path[ path. len ( ) - 1 ] . ident . name ;
1797
1823
// Make sure error reporting is deterministic.
1798
1824
names. sort_by ( |a, b| a. candidate . as_str ( ) . cmp ( b. candidate . as_str ( ) ) ) ;
0 commit comments