@@ -654,7 +654,22 @@ impl<'a> CrateLocator<'a> {
654
654
continue ;
655
655
}
656
656
}
657
- * slot = Some ( ( hash, metadata, lib. clone ( ) ) ) ;
657
+
658
+ // Question: maybe we shouldn't error eagerly here, because it is possible that
659
+ // e.g. a rlib only contains a stub, but a (later-resolved) dylib contains the full
660
+ // metadata?
661
+ if metadata. get_header ( ) . is_stub {
662
+ // `is_stub` should never be true for .rmeta files.
663
+ assert_ne ! ( flavor, CrateFlavor :: Rmeta ) ;
664
+
665
+ // Because rmeta files are resolved before rlib/dylib files, if this is a stub and
666
+ // we haven't found a slot already, it means that the full metadata is missing.
667
+ if slot. is_none ( ) {
668
+ return Err ( CrateError :: FullMetadataNotFound ( self . crate_name , flavor) ) ;
669
+ }
670
+ } else {
671
+ * slot = Some ( ( hash, metadata, lib. clone ( ) ) ) ;
672
+ }
658
673
ret = Some ( ( lib, kind) ) ;
659
674
}
660
675
@@ -916,6 +931,7 @@ pub(crate) enum CrateError {
916
931
ExternLocationNotExist ( Symbol , PathBuf ) ,
917
932
ExternLocationNotFile ( Symbol , PathBuf ) ,
918
933
MultipleCandidates ( Symbol , CrateFlavor , Vec < PathBuf > ) ,
934
+ FullMetadataNotFound ( Symbol , CrateFlavor ) ,
919
935
SymbolConflictsCurrent ( Symbol ) ,
920
936
StableCrateIdCollision ( Symbol , Symbol ) ,
921
937
DlOpen ( String , String ) ,
@@ -966,6 +982,9 @@ impl CrateError {
966
982
CrateError :: MultipleCandidates ( crate_name, flavor, candidates) => {
967
983
dcx. emit_err ( errors:: MultipleCandidates { span, crate_name, flavor, candidates } ) ;
968
984
}
985
+ CrateError :: FullMetadataNotFound ( crate_name, flavor) => {
986
+ dcx. emit_err ( errors:: FullMetadataNotFound { span, crate_name, flavor } ) ;
987
+ }
969
988
CrateError :: SymbolConflictsCurrent ( root_name) => {
970
989
dcx. emit_err ( errors:: SymbolConflictsCurrent { span, crate_name : root_name } ) ;
971
990
}
0 commit comments