213213//! metadata::loader or metadata::creader for all the juicy details!
214214
215215use cstore:: { MetadataBlob , MetadataVec , MetadataArchive } ;
216+ use common:: { metadata_encoding_version, rustc_version} ;
216217use decoder;
217- use encoder;
218218
219219use rustc:: hir:: svh:: Svh ;
220220use rustc:: session:: Session ;
@@ -260,6 +260,7 @@ pub struct Context<'a> {
260260 pub rejected_via_hash : Vec < CrateMismatch > ,
261261 pub rejected_via_triple : Vec < CrateMismatch > ,
262262 pub rejected_via_kind : Vec < CrateMismatch > ,
263+ pub rejected_via_version : Vec < CrateMismatch > ,
263264 pub should_match_name : bool ,
264265}
265266
@@ -336,6 +337,10 @@ impl<'a> Context<'a> {
336337 struct_span_err ! ( self . sess, self . span, E0462 ,
337338 "found staticlib `{}` instead of rlib or dylib{}" ,
338339 self . ident, add)
340+ } else if !self . rejected_via_version . is_empty ( ) {
341+ struct_span_err ! ( self . sess, self . span, E0514 ,
342+ "found crate `{}` compiled by an incompatible version of rustc{}" ,
343+ self . ident, add)
339344 } else {
340345 struct_span_err ! ( self . sess, self . span, E0463 ,
341346 "can't find crate for `{}`{}" ,
@@ -350,7 +355,7 @@ impl<'a> Context<'a> {
350355 }
351356 }
352357 if !self . rejected_via_hash . is_empty ( ) {
353- err. note ( "perhaps this crate needs to be recompiled?" ) ;
358+ err. note ( "perhaps that crate needs to be recompiled?" ) ;
354359 let mismatches = self . rejected_via_hash . iter ( ) ;
355360 for ( i, & CrateMismatch { ref path, .. } ) in mismatches. enumerate ( ) {
356361 err. note ( & format ! ( "crate `{}` path #{}: {}" ,
@@ -367,13 +372,22 @@ impl<'a> Context<'a> {
367372 }
368373 }
369374 if !self . rejected_via_kind . is_empty ( ) {
370- err. help ( "please recompile this crate using --crate-type lib" ) ;
375+ err. help ( "please recompile that crate using --crate-type lib" ) ;
371376 let mismatches = self . rejected_via_kind . iter ( ) ;
372377 for ( i, & CrateMismatch { ref path, .. } ) in mismatches. enumerate ( ) {
373378 err. note ( & format ! ( "crate `{}` path #{}: {}" ,
374379 self . ident, i+1 , path. display( ) ) ) ;
375380 }
376381 }
382+ if !self . rejected_via_version . is_empty ( ) {
383+ err. help ( & format ! ( "please recompile that crate using this compiler ({})" ,
384+ rustc_version( ) ) ) ;
385+ let mismatches = self . rejected_via_version . iter ( ) ;
386+ for ( i, & CrateMismatch { ref path, ref got } ) in mismatches. enumerate ( ) {
387+ err. note ( & format ! ( "crate `{}` path #{}: {} compiled by {:?}" ,
388+ self . ident, i+1 , path. display( ) , got) ) ;
389+ }
390+ }
377391
378392 err. emit ( ) ;
379393 self . sess . abort_if_errors ( ) ;
@@ -591,6 +605,17 @@ impl<'a> Context<'a> {
591605 }
592606
593607 fn crate_matches ( & mut self , crate_data : & [ u8 ] , libpath : & Path ) -> Option < Svh > {
608+ let crate_rustc_version = decoder:: crate_rustc_version ( crate_data) ;
609+ if crate_rustc_version != Some ( rustc_version ( ) ) {
610+ let message = crate_rustc_version. unwrap_or ( format ! ( "an unknown compiler" ) ) ;
611+ info ! ( "Rejecting via version: expected {} got {}" , rustc_version( ) , message) ;
612+ self . rejected_via_version . push ( CrateMismatch {
613+ path : libpath. to_path_buf ( ) ,
614+ got : message
615+ } ) ;
616+ return None ;
617+ }
618+
594619 if self . should_match_name {
595620 match decoder:: maybe_get_crate_name ( crate_data) {
596621 Some ( ref name) if self . crate_name == * name => { }
@@ -801,12 +826,12 @@ fn get_metadata_section_imp(target: &Target, flavor: CrateFlavor, filename: &Pat
801826 let cbuf = llvm:: LLVMGetSectionContents ( si. llsi ) ;
802827 let csz = llvm:: LLVMGetSectionSize ( si. llsi ) as usize ;
803828 let cvbuf: * const u8 = cbuf as * const u8 ;
804- let vlen = encoder :: metadata_encoding_version. len ( ) ;
829+ let vlen = metadata_encoding_version. len ( ) ;
805830 debug ! ( "checking {} bytes of metadata-version stamp" ,
806831 vlen) ;
807832 let minsz = cmp:: min ( vlen, csz) ;
808833 let buf0 = slice:: from_raw_parts ( cvbuf, minsz) ;
809- let version_ok = buf0 == encoder :: metadata_encoding_version;
834+ let version_ok = buf0 == metadata_encoding_version;
810835 if !version_ok {
811836 return Err ( ( format ! ( "incompatible metadata version found: '{}'" ,
812837 filename. display( ) ) ) ) ;
0 commit comments