5252//! than finding a number of solutions (there are normally quite a few).
5353
5454use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
55- use rustc_hir:: def_id:: CrateNum ;
55+ use rustc_hir:: def_id:: { CrateNum , LOCAL_CRATE } ;
56+ use rustc_index:: IndexVec ;
5657use rustc_middle:: bug;
5758use rustc_middle:: middle:: dependency_format:: { Dependencies , DependencyList , Linkage } ;
5859use rustc_middle:: ty:: TyCtxt ;
@@ -84,7 +85,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
8485 let sess = & tcx. sess ;
8586
8687 if !sess. opts . output_types . should_codegen ( ) {
87- return Vec :: new ( ) ;
88+ return IndexVec :: new ( ) ;
8889 }
8990
9091 let preferred_linkage = match ty {
@@ -131,7 +132,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
131132
132133 match preferred_linkage {
133134 // If the crate is not linked, there are no link-time dependencies.
134- Linkage :: NotLinked => return Vec :: new ( ) ,
135+ Linkage :: NotLinked => return IndexVec :: new ( ) ,
135136 Linkage :: Static => {
136137 // Attempt static linkage first. For dylibs and executables, we may be
137138 // able to retry below with dynamic linkage.
@@ -156,7 +157,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
156157 }
157158 sess. dcx ( ) . emit_err ( RlibRequired { crate_name : tcx. crate_name ( cnum) } ) ;
158159 }
159- return Vec :: new ( ) ;
160+ return IndexVec :: new ( ) ;
160161 }
161162 }
162163 Linkage :: Dynamic | Linkage :: IncludedFromDylib => { }
@@ -210,13 +211,19 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
210211
211212 // Collect what we've got so far in the return vector.
212213 let last_crate = tcx. crates ( ( ) ) . len ( ) ;
213- let mut ret = ( 1 ..last_crate + 1 )
214- . map ( |cnum| match formats. get ( & CrateNum :: new ( cnum) ) {
215- Some ( & RequireDynamic ) => Linkage :: Dynamic ,
216- Some ( & RequireStatic ) => Linkage :: IncludedFromDylib ,
217- None => Linkage :: NotLinked ,
218- } )
219- . collect :: < Vec < _ > > ( ) ;
214+ let mut ret = IndexVec :: new ( ) ;
215+ assert_eq ! ( ret. push( Linkage :: Static ) , LOCAL_CRATE ) ;
216+ for cnum in 1 ..last_crate + 1 {
217+ let cnum = CrateNum :: new ( cnum) ;
218+ assert_eq ! (
219+ ret. push( match formats. get( & cnum) {
220+ Some ( & RequireDynamic ) => Linkage :: Dynamic ,
221+ Some ( & RequireStatic ) => Linkage :: IncludedFromDylib ,
222+ None => Linkage :: NotLinked ,
223+ } ) ,
224+ cnum
225+ ) ;
226+ }
220227
221228 // Run through the dependency list again, and add any missing libraries as
222229 // static libraries.
@@ -232,7 +239,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
232239 assert ! ( src. rlib. is_some( ) || src. rmeta. is_some( ) ) ;
233240 info ! ( "adding staticlib: {}" , tcx. crate_name( cnum) ) ;
234241 add_library ( tcx, cnum, RequireStatic , & mut formats, & mut unavailable_as_static) ;
235- ret[ cnum. as_usize ( ) - 1 ] = Linkage :: Static ;
242+ ret[ cnum] = Linkage :: Static ;
236243 }
237244 }
238245
@@ -252,8 +259,10 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
252259 //
253260 // For situations like this, we perform one last pass over the dependencies,
254261 // making sure that everything is available in the requested format.
255- for ( cnum, kind) in ret. iter ( ) . enumerate ( ) {
256- let cnum = CrateNum :: new ( cnum + 1 ) ;
262+ for ( cnum, kind) in ret. iter_enumerated ( ) {
263+ if cnum == LOCAL_CRATE {
264+ continue ;
265+ }
257266 let src = tcx. used_crate_source ( cnum) ;
258267 match * kind {
259268 Linkage :: NotLinked | Linkage :: IncludedFromDylib => { }
@@ -334,14 +343,17 @@ fn attempt_static(tcx: TyCtxt<'_>, unavailable: &mut Vec<CrateNum>) -> Option<De
334343
335344 // All crates are available in an rlib format, so we're just going to link
336345 // everything in explicitly so long as it's actually required.
337- let mut ret = tcx
338- . crates ( ( ) )
339- . iter ( )
340- . map ( |& cnum| match tcx. dep_kind ( cnum) {
341- CrateDepKind :: Explicit => Linkage :: Static ,
342- CrateDepKind :: MacrosOnly | CrateDepKind :: Implicit => Linkage :: NotLinked ,
343- } )
344- . collect :: < Vec < _ > > ( ) ;
346+ let mut ret = IndexVec :: new ( ) ;
347+ assert_eq ! ( ret. push( Linkage :: Static ) , LOCAL_CRATE ) ;
348+ for & cnum in tcx. crates ( ( ) ) {
349+ assert_eq ! (
350+ ret. push( match tcx. dep_kind( cnum) {
351+ CrateDepKind :: Explicit => Linkage :: Static ,
352+ CrateDepKind :: MacrosOnly | CrateDepKind :: Implicit => Linkage :: NotLinked ,
353+ } ) ,
354+ cnum
355+ ) ;
356+ }
345357
346358 // Our allocator/panic runtime may not have been linked above if it wasn't
347359 // explicitly linked, which is the case for any injected dependency. Handle
@@ -367,8 +379,7 @@ fn activate_injected_dep(
367379 list : & mut DependencyList ,
368380 replaces_injected : & dyn Fn ( CrateNum ) -> bool ,
369381) {
370- for ( i, slot) in list. iter ( ) . enumerate ( ) {
371- let cnum = CrateNum :: new ( i + 1 ) ;
382+ for ( cnum, slot) in list. iter_enumerated ( ) {
372383 if !replaces_injected ( cnum) {
373384 continue ;
374385 }
@@ -377,25 +388,23 @@ fn activate_injected_dep(
377388 }
378389 }
379390 if let Some ( injected) = injected {
380- let idx = injected. as_usize ( ) - 1 ;
381- assert_eq ! ( list[ idx] , Linkage :: NotLinked ) ;
382- list[ idx] = Linkage :: Static ;
391+ assert_eq ! ( list[ injected] , Linkage :: NotLinked ) ;
392+ list[ injected] = Linkage :: Static ;
383393 }
384394}
385395
386396// After the linkage for a crate has been determined we need to verify that
387397// there's only going to be one allocator in the output.
388- fn verify_ok ( tcx : TyCtxt < ' _ > , list : & [ Linkage ] ) {
398+ fn verify_ok ( tcx : TyCtxt < ' _ > , list : & DependencyList ) {
389399 let sess = & tcx. sess ;
390400 if list. is_empty ( ) {
391401 return ;
392402 }
393403 let mut panic_runtime = None ;
394- for ( i , linkage) in list. iter ( ) . enumerate ( ) {
404+ for ( cnum , linkage) in list. iter_enumerated ( ) {
395405 if let Linkage :: NotLinked = * linkage {
396406 continue ;
397407 }
398- let cnum = CrateNum :: new ( i + 1 ) ;
399408
400409 if tcx. is_panic_runtime ( cnum) {
401410 if let Some ( ( prev, _) ) = panic_runtime {
@@ -431,11 +440,10 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) {
431440 // strategy. If the dep isn't linked, we ignore it, and if our strategy
432441 // is abort then it's compatible with everything. Otherwise all crates'
433442 // panic strategy must match our own.
434- for ( i , linkage) in list. iter ( ) . enumerate ( ) {
443+ for ( cnum , linkage) in list. iter_enumerated ( ) {
435444 if let Linkage :: NotLinked = * linkage {
436445 continue ;
437446 }
438- let cnum = CrateNum :: new ( i + 1 ) ;
439447 if cnum == runtime_cnum || tcx. is_compiler_builtins ( cnum) {
440448 continue ;
441449 }
@@ -450,13 +458,16 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) {
450458 } ) ;
451459 }
452460
453- let found_drop_strategy = tcx. panic_in_drop_strategy ( cnum) ;
454- if tcx. sess . opts . unstable_opts . panic_in_drop != found_drop_strategy {
455- sess. dcx ( ) . emit_err ( IncompatiblePanicInDropStrategy {
456- crate_name : tcx. crate_name ( cnum) ,
457- found_strategy : found_drop_strategy,
458- desired_strategy : tcx. sess . opts . unstable_opts . panic_in_drop ,
459- } ) ;
461+ // panic_in_drop_strategy isn't allowed for LOCAL_CRATE
462+ if cnum != LOCAL_CRATE {
463+ let found_drop_strategy = tcx. panic_in_drop_strategy ( cnum) ;
464+ if tcx. sess . opts . unstable_opts . panic_in_drop != found_drop_strategy {
465+ sess. dcx ( ) . emit_err ( IncompatiblePanicInDropStrategy {
466+ crate_name : tcx. crate_name ( cnum) ,
467+ found_strategy : found_drop_strategy,
468+ desired_strategy : tcx. sess . opts . unstable_opts . panic_in_drop ,
469+ } ) ;
470+ }
460471 }
461472 }
462473 }
0 commit comments