@@ -31,7 +31,7 @@ use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
3131use syntax:: ext:: hygiene:: Mark ;
3232use syntax:: symbol:: keywords;
3333use syntax:: util:: lev_distance:: find_best_match_for_name;
34- use syntax_pos:: Span ;
34+ use syntax_pos:: { MultiSpan , Span } ;
3535
3636use std:: cell:: { Cell , RefCell } ;
3737use std:: collections:: BTreeMap ;
@@ -635,6 +635,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
635635
636636 let mut errors = false ;
637637 let mut seen_spans = FxHashSet ( ) ;
638+ let mut error_vec = Vec :: new ( ) ;
639+ let mut prev_root_id: NodeId = NodeId :: new ( 0 ) ;
638640 for i in 0 .. self . determined_imports . len ( ) {
639641 let import = self . determined_imports [ i] ;
640642 let error = self . finalize_import ( import) ;
@@ -689,13 +691,22 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
689691 // If the error is a single failed import then create a "fake" import
690692 // resolution for it so that later resolve stages won't complain.
691693 self . import_dummy_binding ( import) ;
694+ if prev_root_id. as_u32 ( ) != 0 &&
695+ prev_root_id. as_u32 ( ) != import. root_id . as_u32 ( ) &&
696+ !error_vec. is_empty ( ) {
697+ // in case of new import line, throw diagnostic message
698+ // for previous line.
699+ let mut empty_vec = vec ! [ ] ;
700+ mem:: swap ( & mut empty_vec, & mut error_vec) ;
701+ self . throw_unresolved_import_error ( empty_vec, None ) ;
702+ }
692703 if !seen_spans. contains ( & span) {
693704 let path = import_path_to_string ( & import. module_path [ ..] ,
694705 & import. subclass ,
695706 span) ;
696- let error = ResolutionError :: UnresolvedImport ( Some ( ( span, & path, & err) ) ) ;
697- resolve_error ( self . resolver , span, error) ;
707+ error_vec. push ( ( span, path, err) ) ;
698708 seen_spans. insert ( span) ;
709+ prev_root_id = import. root_id ;
699710 }
700711 }
701712 }
@@ -760,21 +771,48 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
760771 } ) ;
761772 }
762773
774+ if !error_vec. is_empty ( ) {
775+ self . throw_unresolved_import_error ( error_vec. clone ( ) , None ) ;
776+ }
777+
763778 // Report unresolved imports only if no hard error was already reported
764779 // to avoid generating multiple errors on the same import.
765780 if !errors {
766781 for import in & self . indeterminate_imports {
767782 if import. is_uniform_paths_canary {
768783 continue ;
769784 }
770-
771- let error = ResolutionError :: UnresolvedImport ( None ) ;
772- resolve_error ( self . resolver , import. span , error) ;
785+ self . throw_unresolved_import_error ( error_vec, Some ( MultiSpan :: from ( import. span ) ) ) ;
773786 break ;
774787 }
775788 }
776789 }
777790
791+ fn throw_unresolved_import_error ( & self , error_vec : Vec < ( Span , String , String ) > ,
792+ span : Option < MultiSpan > ) {
793+ let max_span_label_msg_count = 10 ; // upper limit on number of span_label message.
794+ let ( span, msg) = match error_vec. is_empty ( ) {
795+ true => ( span. unwrap ( ) , "unresolved import" . to_string ( ) ) ,
796+ false => {
797+ let span = MultiSpan :: from_spans ( error_vec. clone ( ) . into_iter ( )
798+ . map ( |elem : ( Span , String , String ) | { elem. 0 }
799+ ) . collect ( ) ) ;
800+ let path_vec: Vec < String > = error_vec. clone ( ) . into_iter ( )
801+ . map ( |elem : ( Span , String , String ) | { format ! ( "`{}`" , elem. 1 ) }
802+ ) . collect ( ) ;
803+ let path = path_vec. join ( ", " ) ;
804+ let msg = format ! ( "unresolved import{} {}" ,
805+ if path_vec. len( ) > 1 { "s" } else { "" } , path) ;
806+ ( span, msg)
807+ }
808+ } ;
809+ let mut err = struct_span_err ! ( self . resolver. session, span, E0432 , "{}" , & msg) ;
810+ for span_error in error_vec. into_iter ( ) . take ( max_span_label_msg_count) {
811+ err. span_label ( span_error. 0 , span_error. 2 ) ;
812+ }
813+ err. emit ( ) ;
814+ }
815+
778816 /// Attempts to resolve the given import, returning true if its resolution is determined.
779817 /// If successful, the resolved bindings are written into the module.
780818 fn resolve_import ( & mut self , directive : & ' b ImportDirective < ' b > ) -> bool {
0 commit comments