@@ -31,7 +31,7 @@ use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
31
31
use syntax:: ext:: hygiene:: Mark ;
32
32
use syntax:: symbol:: keywords;
33
33
use syntax:: util:: lev_distance:: find_best_match_for_name;
34
- use syntax_pos:: Span ;
34
+ use syntax_pos:: { MultiSpan , Span } ;
35
35
36
36
use std:: cell:: { Cell , RefCell } ;
37
37
use std:: collections:: BTreeMap ;
@@ -632,6 +632,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
632
632
633
633
let mut errors = false ;
634
634
let mut seen_spans = FxHashSet ( ) ;
635
+ let mut error_vec = Vec :: new ( ) ;
636
+ let mut prev_root_id: NodeId = NodeId :: new ( 0 ) ;
635
637
for i in 0 .. self . determined_imports . len ( ) {
636
638
let import = self . determined_imports [ i] ;
637
639
let error = self . finalize_import ( import) ;
@@ -694,13 +696,22 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
694
696
// If the error is a single failed import then create a "fake" import
695
697
// resolution for it so that later resolve stages won't complain.
696
698
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
+ }
697
708
if !seen_spans. contains ( & span) {
698
709
let path = import_path_to_string ( & import. module_path [ ..] ,
699
710
& import. subclass ,
700
711
span) ;
701
- let error = ResolutionError :: UnresolvedImport ( Some ( ( span, & path, & err) ) ) ;
702
- resolve_error ( self . resolver , span, error) ;
712
+ error_vec. push ( ( span, path, err) ) ;
703
713
seen_spans. insert ( span) ;
714
+ prev_root_id = import. root_id ;
704
715
}
705
716
}
706
717
}
@@ -749,21 +760,48 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
749
760
} ) ;
750
761
}
751
762
763
+ if !error_vec. is_empty ( ) {
764
+ self . throw_unresolved_import_error ( error_vec. clone ( ) , None ) ;
765
+ }
766
+
752
767
// Report unresolved imports only if no hard error was already reported
753
768
// to avoid generating multiple errors on the same import.
754
769
if !errors {
755
770
for import in & self . indeterminate_imports {
756
771
if import. is_uniform_paths_canary {
757
772
continue ;
758
773
}
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 ) ) ) ;
762
775
break ;
763
776
}
764
777
}
765
778
}
766
779
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
+
767
805
/// Attempts to resolve the given import, returning true if its resolution is determined.
768
806
/// If successful, the resolved bindings are written into the module.
769
807
fn resolve_import ( & mut self , directive : & ' b ImportDirective < ' b > ) -> bool {
0 commit comments