@@ -349,6 +349,7 @@ impl<'a> CrateLocator<'a> {
349
349
self . crate_rejections . via_kind . clear ( ) ;
350
350
self . crate_rejections . via_version . clear ( ) ;
351
351
self . crate_rejections . via_filename . clear ( ) ;
352
+ self . crate_rejections . via_invalid . clear ( ) ;
352
353
}
353
354
354
355
crate fn maybe_load_library_crate ( & mut self ) -> Result < Option < Library > , CrateError > {
@@ -538,7 +539,16 @@ impl<'a> CrateLocator<'a> {
538
539
continue ;
539
540
}
540
541
}
541
- Err ( err) => {
542
+ Err ( MetadataError :: LoadFailure ( err) ) => {
543
+ // The file was present and created by the same compiler version, but we
544
+ // couldn't load it for some reason. Give a hard error instead of silently
545
+ // ignoring it, but only if we would have given an error anyway.
546
+ self . crate_rejections
547
+ . via_invalid
548
+ . push ( CrateMismatch { path : lib, got : err } ) ;
549
+ continue ;
550
+ }
551
+ Err ( err @ MetadataError :: NotPresent ( _) ) => {
542
552
warn ! ( "no metadata found: {}" , err) ;
543
553
continue ;
544
554
}
@@ -716,25 +726,28 @@ impl<'a> CrateLocator<'a> {
716
726
fn get_metadata_section (
717
727
target : & Target ,
718
728
flavor : CrateFlavor ,
719
- filename : & Path ,
729
+ filename : & ' p Path ,
720
730
loader : & dyn MetadataLoader ,
721
- ) -> Result < MetadataBlob , String > {
731
+ ) -> Result < MetadataBlob , MetadataError < ' p > > {
722
732
if !filename. exists ( ) {
723
- return Err ( format ! ( "no such file: '{}'" , filename . display ( ) ) ) ;
733
+ return Err ( MetadataError :: NotPresent ( filename ) ) ;
724
734
}
725
735
let raw_bytes: MetadataRef = match flavor {
726
- CrateFlavor :: Rlib => loader. get_rlib_metadata ( target, filename) ?,
736
+ CrateFlavor :: Rlib => {
737
+ loader. get_rlib_metadata ( target, filename) . map_err ( MetadataError :: LoadFailure ) ?
738
+ }
727
739
CrateFlavor :: Dylib => {
728
- let buf = loader. get_dylib_metadata ( target, filename) ?;
740
+ let buf =
741
+ loader. get_dylib_metadata ( target, filename) . map_err ( MetadataError :: LoadFailure ) ?;
729
742
// The header is uncompressed
730
743
let header_len = METADATA_HEADER . len ( ) ;
731
744
debug ! ( "checking {} bytes of metadata-version stamp" , header_len) ;
732
745
let header = & buf[ ..cmp:: min ( header_len, buf. len ( ) ) ] ;
733
746
if header != METADATA_HEADER {
734
- return Err ( format ! (
735
- "incompatible metadata version found: '{}' " ,
747
+ return Err ( MetadataError :: LoadFailure ( format ! (
748
+ "invalid metadata version found: {} " ,
736
749
filename. display( )
737
- ) ) ;
750
+ ) ) ) ;
738
751
}
739
752
740
753
// Header is okay -> inflate the actual metadata
@@ -744,17 +757,28 @@ fn get_metadata_section(
744
757
match FrameDecoder :: new ( compressed_bytes) . read_to_end ( & mut inflated) {
745
758
Ok ( _) => rustc_erase_owner ! ( OwningRef :: new( inflated) . map_owner_box( ) ) ,
746
759
Err ( _) => {
747
- return Err ( format ! ( "failed to decompress metadata: {}" , filename. display( ) ) ) ;
760
+ return Err ( MetadataError :: LoadFailure ( format ! (
761
+ "failed to decompress metadata: {}" ,
762
+ filename. display( )
763
+ ) ) ) ;
748
764
}
749
765
}
750
766
}
751
767
CrateFlavor :: Rmeta => {
752
768
// mmap the file, because only a small fraction of it is read.
753
- let file = std:: fs:: File :: open ( filename)
754
- . map_err ( |_| format ! ( "failed to open rmeta metadata: '{}'" , filename. display( ) ) ) ?;
769
+ let file = std:: fs:: File :: open ( filename) . map_err ( |_| {
770
+ MetadataError :: LoadFailure ( format ! (
771
+ "failed to open rmeta metadata: '{}'" ,
772
+ filename. display( )
773
+ ) )
774
+ } ) ?;
755
775
let mmap = unsafe { Mmap :: map ( file) } ;
756
- let mmap = mmap
757
- . map_err ( |_| format ! ( "failed to mmap rmeta metadata: '{}'" , filename. display( ) ) ) ?;
776
+ let mmap = mmap. map_err ( |_| {
777
+ MetadataError :: LoadFailure ( format ! (
778
+ "failed to mmap rmeta metadata: '{}'" ,
779
+ filename. display( )
780
+ ) )
781
+ } ) ?;
758
782
759
783
rustc_erase_owner ! ( OwningRef :: new( mmap) . map_owner_box( ) )
760
784
}
@@ -763,7 +787,10 @@ fn get_metadata_section(
763
787
if blob. is_compatible ( ) {
764
788
Ok ( blob)
765
789
} else {
766
- Err ( format ! ( "incompatible metadata version found: '{}'" , filename. display( ) ) )
790
+ Err ( MetadataError :: LoadFailure ( format ! (
791
+ "invalid metadata version found: {}" ,
792
+ filename. display( )
793
+ ) ) )
767
794
}
768
795
}
769
796
@@ -842,6 +869,7 @@ struct CrateRejections {
842
869
via_kind : Vec < CrateMismatch > ,
843
870
via_version : Vec < CrateMismatch > ,
844
871
via_filename : Vec < CrateMismatch > ,
872
+ via_invalid : Vec < CrateMismatch > ,
845
873
}
846
874
847
875
/// Candidate rejection reasons collected during crate search.
@@ -871,6 +899,24 @@ crate enum CrateError {
871
899
NonDylibPlugin ( Symbol ) ,
872
900
}
873
901
902
+ enum MetadataError < ' a > {
903
+ /// The file was missing.
904
+ NotPresent ( & ' a Path ) ,
905
+ /// The file was present and invalid.
906
+ LoadFailure ( String ) ,
907
+ }
908
+
909
+ impl fmt:: Display for MetadataError < ' _ > {
910
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
911
+ match self {
912
+ MetadataError :: NotPresent ( filename) => {
913
+ f. write_str ( & format ! ( "no such file: '{}'" , filename. display( ) ) )
914
+ }
915
+ MetadataError :: LoadFailure ( msg) => f. write_str ( msg) ,
916
+ }
917
+ }
918
+ }
919
+
874
920
impl CrateError {
875
921
crate fn report ( self , sess : & Session , span : Span , missing_core : bool ) -> ! {
876
922
let mut err = match self {
@@ -1044,6 +1090,19 @@ impl CrateError {
1044
1090
}
1045
1091
err. note ( & msg) ;
1046
1092
err
1093
+ } else if !locator. crate_rejections . via_invalid . is_empty ( ) {
1094
+ let mut err = struct_span_err ! (
1095
+ sess,
1096
+ span,
1097
+ E0786 ,
1098
+ "found invalid metadata files for crate `{}`{}" ,
1099
+ crate_name,
1100
+ add,
1101
+ ) ;
1102
+ for CrateMismatch { path : _, got } in locator. crate_rejections . via_invalid {
1103
+ err. note ( & got) ;
1104
+ }
1105
+ err
1047
1106
} else {
1048
1107
let mut err = struct_span_err ! (
1049
1108
sess,
0 commit comments