5454use crate :: creader:: CStore ;
5555use crate :: errors:: {
5656 BadPanicStrategy , CrateDepMultiple , IncompatiblePanicInDropStrategy , LibRequired ,
57- RequiredPanicStrategy , RlibRequired , RustcLibRequired , TwoPanicRuntimes ,
57+ NonStaticCrateDep , RequiredPanicStrategy , RlibRequired , RustcLibRequired , TwoPanicRuntimes ,
5858} ;
5959
6060use rustc_data_structures:: fx:: FxHashMap ;
@@ -123,13 +123,15 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
123123 CrateType :: Rlib => Linkage :: NotLinked ,
124124 } ;
125125
126+ let mut unavailable_as_static = Vec :: new ( ) ;
127+
126128 match preferred_linkage {
127129 // If the crate is not linked, there are no link-time dependencies.
128130 Linkage :: NotLinked => return Vec :: new ( ) ,
129131 Linkage :: Static => {
130132 // Attempt static linkage first. For dylibs and executables, we may be
131133 // able to retry below with dynamic linkage.
132- if let Some ( v) = attempt_static ( tcx) {
134+ if let Some ( v) = attempt_static ( tcx, & mut unavailable_as_static ) {
133135 return v;
134136 }
135137
@@ -169,11 +171,11 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
169171 let src = tcx. used_crate_source ( cnum) ;
170172 if src. dylib . is_some ( ) {
171173 info ! ( "adding dylib: {}" , name) ;
172- add_library ( tcx, cnum, RequireDynamic , & mut formats) ;
174+ add_library ( tcx, cnum, RequireDynamic , & mut formats, & mut unavailable_as_static ) ;
173175 let deps = tcx. dylib_dependency_formats ( cnum) ;
174176 for & ( depnum, style) in deps. iter ( ) {
175177 info ! ( "adding {:?}: {}" , style, tcx. crate_name( depnum) ) ;
176- add_library ( tcx, depnum, style, & mut formats) ;
178+ add_library ( tcx, depnum, style, & mut formats, & mut unavailable_as_static ) ;
177179 }
178180 }
179181 }
@@ -201,7 +203,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
201203 {
202204 assert ! ( src. rlib. is_some( ) || src. rmeta. is_some( ) ) ;
203205 info ! ( "adding staticlib: {}" , tcx. crate_name( cnum) ) ;
204- add_library ( tcx, cnum, RequireStatic , & mut formats) ;
206+ add_library ( tcx, cnum, RequireStatic , & mut formats, & mut unavailable_as_static ) ;
205207 ret[ cnum. as_usize ( ) - 1 ] = Linkage :: Static ;
206208 }
207209 }
@@ -252,6 +254,7 @@ fn add_library(
252254 cnum : CrateNum ,
253255 link : LinkagePreference ,
254256 m : & mut FxHashMap < CrateNum , LinkagePreference > ,
257+ unavailable_as_static : & mut Vec < CrateNum > ,
255258) {
256259 match m. get ( & cnum) {
257260 Some ( & link2) => {
@@ -263,7 +266,13 @@ fn add_library(
263266 // This error is probably a little obscure, but I imagine that it
264267 // can be refined over time.
265268 if link2 != link || link == RequireStatic {
266- tcx. dcx ( ) . emit_err ( CrateDepMultiple { crate_name : tcx. crate_name ( cnum) } ) ;
269+ tcx. dcx ( ) . emit_err ( CrateDepMultiple {
270+ crate_name : tcx. crate_name ( cnum) ,
271+ non_static_deps : unavailable_as_static
272+ . drain ( ..)
273+ . map ( |cnum| NonStaticCrateDep { crate_name : tcx. crate_name ( cnum) } )
274+ . collect ( ) ,
275+ } ) ;
267276 }
268277 }
269278 None => {
@@ -272,7 +281,7 @@ fn add_library(
272281 }
273282}
274283
275- fn attempt_static ( tcx : TyCtxt < ' _ > ) -> Option < DependencyList > {
284+ fn attempt_static ( tcx : TyCtxt < ' _ > , unavailable : & mut Vec < CrateNum > ) -> Option < DependencyList > {
276285 let all_crates_available_as_rlib = tcx
277286 . crates ( ( ) )
278287 . iter ( )
@@ -281,7 +290,11 @@ fn attempt_static(tcx: TyCtxt<'_>) -> Option<DependencyList> {
281290 if tcx. dep_kind ( cnum) . macros_only ( ) {
282291 return None ;
283292 }
284- Some ( tcx. used_crate_source ( cnum) . rlib . is_some ( ) )
293+ let is_rlib = tcx. used_crate_source ( cnum) . rlib . is_some ( ) ;
294+ if !is_rlib {
295+ unavailable. push ( cnum) ;
296+ }
297+ Some ( is_rlib)
285298 } )
286299 . all ( |is_rlib| is_rlib) ;
287300 if !all_crates_available_as_rlib {
0 commit comments