@@ -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 ;
@@ -635,6 +635,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
635
635
636
636
let mut errors = false ;
637
637
let mut seen_spans = FxHashSet ( ) ;
638
+ let mut error_vec = Vec :: new ( ) ;
639
+ let mut prev_root_id: NodeId = NodeId :: new ( 0 ) ;
638
640
for i in 0 .. self . determined_imports . len ( ) {
639
641
let import = self . determined_imports [ i] ;
640
642
let error = self . finalize_import ( import) ;
@@ -689,13 +691,22 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
689
691
// If the error is a single failed import then create a "fake" import
690
692
// resolution for it so that later resolve stages won't complain.
691
693
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
+ }
692
703
if !seen_spans. contains ( & span) {
693
704
let path = import_path_to_string ( & import. module_path [ ..] ,
694
705
& import. subclass ,
695
706
span) ;
696
- let error = ResolutionError :: UnresolvedImport ( Some ( ( span, & path, & err) ) ) ;
697
- resolve_error ( self . resolver , span, error) ;
707
+ error_vec. push ( ( span, path, err) ) ;
698
708
seen_spans. insert ( span) ;
709
+ prev_root_id = import. root_id ;
699
710
}
700
711
}
701
712
}
@@ -760,21 +771,48 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
760
771
} ) ;
761
772
}
762
773
774
+ if !error_vec. is_empty ( ) {
775
+ self . throw_unresolved_import_error ( error_vec. clone ( ) , None ) ;
776
+ }
777
+
763
778
// Report unresolved imports only if no hard error was already reported
764
779
// to avoid generating multiple errors on the same import.
765
780
if !errors {
766
781
for import in & self . indeterminate_imports {
767
782
if import. is_uniform_paths_canary {
768
783
continue ;
769
784
}
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 ) ) ) ;
773
786
break ;
774
787
}
775
788
}
776
789
}
777
790
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
+
778
816
/// Attempts to resolve the given import, returning true if its resolution is determined.
779
817
/// If successful, the resolved bindings are written into the module.
780
818
fn resolve_import ( & mut self , directive : & ' b ImportDirective < ' b > ) -> bool {
0 commit comments