11//! A bunch of methods and structures more or less related to resolving imports.
22
3- use crate :: diagnostics:: { import_candidates, Suggestion } ;
3+ use crate :: diagnostics:: { import_candidates, DiagnosticMode , Suggestion } ;
44use crate :: Determinacy :: { self , * } ;
55use crate :: Namespace :: * ;
66use crate :: { module_to_string, names_to_string, ImportSuggestion } ;
@@ -402,7 +402,7 @@ struct UnresolvedImportError {
402402 label : Option < String > ,
403403 note : Option < String > ,
404404 suggestion : Option < Suggestion > ,
405- candidate : Option < Vec < ImportSuggestion > > ,
405+ candidates : Option < Vec < ImportSuggestion > > ,
406406}
407407
408408pub struct ImportResolver < ' a , ' b > {
@@ -475,12 +475,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
475475 errors = vec ! [ ] ;
476476 }
477477 if seen_spans. insert ( err. span ) {
478- let path = import_path_to_string (
479- & import. module_path . iter ( ) . map ( |seg| seg. ident ) . collect :: < Vec < _ > > ( ) ,
480- & import. kind ,
481- err. span ,
482- ) ;
483- errors. push ( ( path, err) ) ;
478+ errors. push ( ( import, err) ) ;
484479 prev_root_id = import. root_id ;
485480 }
486481 } else if is_indeterminate {
@@ -494,10 +489,12 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
494489 label : None ,
495490 note : None ,
496491 suggestion : None ,
497- candidate : None ,
492+ candidates : None ,
498493 } ;
494+ // FIXME: there should be a better way of doing this than
495+ // formatting this as a string then checking for `::`
499496 if path. contains ( "::" ) {
500- errors. push ( ( path , err) )
497+ errors. push ( ( import , err) )
501498 }
502499 }
503500 }
@@ -507,7 +504,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
507504 }
508505 }
509506
510- fn throw_unresolved_import_error ( & self , errors : Vec < ( String , UnresolvedImportError ) > ) {
507+ fn throw_unresolved_import_error ( & self , errors : Vec < ( & Import < ' _ > , UnresolvedImportError ) > ) {
511508 if errors. is_empty ( ) {
512509 return ;
513510 }
@@ -516,7 +513,17 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
516513 const MAX_LABEL_COUNT : usize = 10 ;
517514
518515 let span = MultiSpan :: from_spans ( errors. iter ( ) . map ( |( _, err) | err. span ) . collect ( ) ) ;
519- let paths = errors. iter ( ) . map ( |( path, _) | format ! ( "`{}`" , path) ) . collect :: < Vec < _ > > ( ) ;
516+ let paths = errors
517+ . iter ( )
518+ . map ( |( import, err) | {
519+ let path = import_path_to_string (
520+ & import. module_path . iter ( ) . map ( |seg| seg. ident ) . collect :: < Vec < _ > > ( ) ,
521+ & import. kind ,
522+ err. span ,
523+ ) ;
524+ format ! ( "`{path}`" )
525+ } )
526+ . collect :: < Vec < _ > > ( ) ;
520527 let msg = format ! ( "unresolved import{} {}" , pluralize!( paths. len( ) ) , paths. join( ", " ) , ) ;
521528
522529 let mut diag = struct_span_err ! ( self . r. session, span, E0432 , "{}" , & msg) ;
@@ -525,7 +532,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
525532 diag. note ( note) ;
526533 }
527534
528- for ( _ , err) in errors. into_iter ( ) . take ( MAX_LABEL_COUNT ) {
535+ for ( import , err) in errors. into_iter ( ) . take ( MAX_LABEL_COUNT ) {
529536 if let Some ( label) = err. label {
530537 diag. span_label ( err. span , label) ;
531538 }
@@ -538,14 +545,36 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
538545 diag. multipart_suggestion ( & msg, suggestions, applicability) ;
539546 }
540547
541- if let Some ( candidate) = & err. candidate {
542- import_candidates (
543- self . r . session ,
544- & self . r . untracked . source_span ,
545- & mut diag,
546- Some ( err. span ) ,
547- & candidate,
548- )
548+ if let Some ( candidates) = & err. candidates {
549+ match & import. kind {
550+ ImportKind :: Single { nested : false , source, target, .. } => import_candidates (
551+ self . r . session ,
552+ & self . r . untracked . source_span ,
553+ & mut diag,
554+ Some ( err. span ) ,
555+ & candidates,
556+ DiagnosticMode :: Import ,
557+ ( source != target)
558+ . then ( || format ! ( " as {target}" ) )
559+ . as_deref ( )
560+ . unwrap_or ( "" ) ,
561+ ) ,
562+ ImportKind :: Single { nested : true , source, target, .. } => {
563+ import_candidates (
564+ self . r . session ,
565+ & self . r . untracked . source_span ,
566+ & mut diag,
567+ None ,
568+ & candidates,
569+ DiagnosticMode :: Normal ,
570+ ( source != target)
571+ . then ( || format ! ( " as {target}" ) )
572+ . as_deref ( )
573+ . unwrap_or ( "" ) ,
574+ ) ;
575+ }
576+ _ => { }
577+ }
549578 }
550579 }
551580
@@ -707,14 +736,14 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
707736 String :: from ( "a similar path exists" ) ,
708737 Applicability :: MaybeIncorrect ,
709738 ) ) ,
710- candidate : None ,
739+ candidates : None ,
711740 } ,
712741 None => UnresolvedImportError {
713742 span,
714743 label : Some ( label) ,
715744 note : None ,
716745 suggestion,
717- candidate : None ,
746+ candidates : None ,
718747 } ,
719748 } ;
720749 return Some ( err) ;
@@ -761,7 +790,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
761790 ) ) ,
762791 note : None ,
763792 suggestion : None ,
764- candidate : None ,
793+ candidates : None ,
765794 } ) ;
766795 }
767796 }
@@ -873,7 +902,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
873902 let resolutions = resolutions. as_ref ( ) . into_iter ( ) . flat_map ( |r| r. iter ( ) ) ;
874903 let names = resolutions
875904 . filter_map ( |( BindingKey { ident : i, .. } , resolution) | {
876- if * i == ident {
905+ if i . name == ident. name {
877906 return None ;
878907 } // Never suggest the same name
879908 match * resolution. borrow ( ) {
@@ -943,7 +972,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
943972 label : Some ( label) ,
944973 note,
945974 suggestion,
946- candidate : if !parent_suggestion. is_empty ( ) {
975+ candidates : if !parent_suggestion. is_empty ( ) {
947976 Some ( parent_suggestion)
948977 } else {
949978 None
0 commit comments