@@ -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 ;
@@ -632,6 +632,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
632632
633633 let mut errors = false ;
634634 let mut seen_spans = FxHashSet ( ) ;
635+ let mut error_vec = Vec :: new ( ) ;
636+ let mut prev_root_id: NodeId = NodeId :: new ( 0 ) ;
635637 for i in 0 .. self . determined_imports . len ( ) {
636638 let import = self . determined_imports [ i] ;
637639 let error = self . finalize_import ( import) ;
@@ -694,13 +696,22 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
694696 // If the error is a single failed import then create a "fake" import
695697 // resolution for it so that later resolve stages won't complain.
696698 self . import_dummy_binding ( import) ;
699+ if prev_root_id. as_u32 ( ) != 0 &&
700+ prev_root_id. as_u32 ( ) != import. root_id . as_u32 ( ) &&
701+ !error_vec. is_empty ( ) {
702+ // in case of new import line, throw diagnostic message
703+ // for previous line.
704+ let mut empty_vec = vec ! [ ] ;
705+ mem:: swap ( & mut empty_vec, & mut error_vec) ;
706+ self . throw_unresolved_import_error ( empty_vec, None ) ;
707+ }
697708 if !seen_spans. contains ( & span) {
698709 let path = import_path_to_string ( & import. module_path [ ..] ,
699710 & import. subclass ,
700711 span) ;
701- let error = ResolutionError :: UnresolvedImport ( Some ( ( span, & path, & err) ) ) ;
702- resolve_error ( self . resolver , span, error) ;
712+ error_vec. push ( ( span, path, err) ) ;
703713 seen_spans. insert ( span) ;
714+ prev_root_id = import. root_id ;
704715 }
705716 }
706717 }
@@ -749,21 +760,48 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
749760 } ) ;
750761 }
751762
763+ if !error_vec. is_empty ( ) {
764+ self . throw_unresolved_import_error ( error_vec. clone ( ) , None ) ;
765+ }
766+
752767 // Report unresolved imports only if no hard error was already reported
753768 // to avoid generating multiple errors on the same import.
754769 if !errors {
755770 for import in & self . indeterminate_imports {
756771 if import. is_uniform_paths_canary {
757772 continue ;
758773 }
759-
760- let error = ResolutionError :: UnresolvedImport ( None ) ;
761- resolve_error ( self . resolver , import. span , error) ;
774+ self . throw_unresolved_import_error ( error_vec, Some ( MultiSpan :: from ( import. span ) ) ) ;
762775 break ;
763776 }
764777 }
765778 }
766779
780+ fn throw_unresolved_import_error ( & self , error_vec : Vec < ( Span , String , String ) > ,
781+ span : Option < MultiSpan > ) {
782+ let max_span_label_msg_count = 10 ; // upper limit on number of span_label message.
783+ let ( span, msg) = match error_vec. is_empty ( ) {
784+ true => ( span. unwrap ( ) , "unresolved import" . to_string ( ) ) ,
785+ false => {
786+ let span = MultiSpan :: from_spans ( error_vec. clone ( ) . into_iter ( )
787+ . map ( |elem : ( Span , String , String ) | { elem. 0 }
788+ ) . collect ( ) ) ;
789+ let path_vec: Vec < String > = error_vec. clone ( ) . into_iter ( )
790+ . map ( |elem : ( Span , String , String ) | { format ! ( "`{}`" , elem. 1 ) }
791+ ) . collect ( ) ;
792+ let path = path_vec. join ( ", " ) ;
793+ let msg = format ! ( "unresolved import{} {}" ,
794+ if path_vec. len( ) > 1 { "s" } else { "" } , path) ;
795+ ( span, msg)
796+ }
797+ } ;
798+ let mut err = struct_span_err ! ( self . resolver. session, span, E0432 , "{}" , & msg) ;
799+ for span_error in error_vec. into_iter ( ) . take ( max_span_label_msg_count) {
800+ err. span_label ( span_error. 0 , span_error. 2 ) ;
801+ }
802+ err. emit ( ) ;
803+ }
804+
767805 /// Attempts to resolve the given import, returning true if its resolution is determined.
768806 /// If successful, the resolved bindings are written into the module.
769807 fn resolve_import ( & mut self , directive : & ' b ImportDirective < ' b > ) -> bool {
0 commit comments