52
52
//! than finding a number of solutions (there are normally quite a few).
53
53
54
54
use 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 ;
56
57
use rustc_middle:: bug;
57
58
use rustc_middle:: middle:: dependency_format:: { Dependencies , DependencyList , Linkage } ;
58
59
use rustc_middle:: ty:: TyCtxt ;
@@ -84,7 +85,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
84
85
let sess = & tcx. sess ;
85
86
86
87
if !sess. opts . output_types . should_codegen ( ) {
87
- return Vec :: new ( ) ;
88
+ return IndexVec :: new ( ) ;
88
89
}
89
90
90
91
let preferred_linkage = match ty {
@@ -131,7 +132,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
131
132
132
133
match preferred_linkage {
133
134
// If the crate is not linked, there are no link-time dependencies.
134
- Linkage :: NotLinked => return Vec :: new ( ) ,
135
+ Linkage :: NotLinked => return IndexVec :: new ( ) ,
135
136
Linkage :: Static => {
136
137
// Attempt static linkage first. For dylibs and executables, we may be
137
138
// able to retry below with dynamic linkage.
@@ -156,7 +157,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
156
157
}
157
158
sess. dcx ( ) . emit_err ( RlibRequired { crate_name : tcx. crate_name ( cnum) } ) ;
158
159
}
159
- return Vec :: new ( ) ;
160
+ return IndexVec :: new ( ) ;
160
161
}
161
162
}
162
163
Linkage :: Dynamic | Linkage :: IncludedFromDylib => { }
@@ -210,13 +211,19 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
210
211
211
212
// Collect what we've got so far in the return vector.
212
213
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
+ }
220
227
221
228
// Run through the dependency list again, and add any missing libraries as
222
229
// static libraries.
@@ -232,7 +239,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
232
239
assert ! ( src. rlib. is_some( ) || src. rmeta. is_some( ) ) ;
233
240
info ! ( "adding staticlib: {}" , tcx. crate_name( cnum) ) ;
234
241
add_library ( tcx, cnum, RequireStatic , & mut formats, & mut unavailable_as_static) ;
235
- ret[ cnum. as_usize ( ) - 1 ] = Linkage :: Static ;
242
+ ret[ cnum] = Linkage :: Static ;
236
243
}
237
244
}
238
245
@@ -252,8 +259,10 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
252
259
//
253
260
// For situations like this, we perform one last pass over the dependencies,
254
261
// 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
+ }
257
266
let src = tcx. used_crate_source ( cnum) ;
258
267
match * kind {
259
268
Linkage :: NotLinked | Linkage :: IncludedFromDylib => { }
@@ -334,14 +343,17 @@ fn attempt_static(tcx: TyCtxt<'_>, unavailable: &mut Vec<CrateNum>) -> Option<De
334
343
335
344
// All crates are available in an rlib format, so we're just going to link
336
345
// 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
+ }
345
357
346
358
// Our allocator/panic runtime may not have been linked above if it wasn't
347
359
// explicitly linked, which is the case for any injected dependency. Handle
@@ -367,8 +379,7 @@ fn activate_injected_dep(
367
379
list : & mut DependencyList ,
368
380
replaces_injected : & dyn Fn ( CrateNum ) -> bool ,
369
381
) {
370
- for ( i, slot) in list. iter ( ) . enumerate ( ) {
371
- let cnum = CrateNum :: new ( i + 1 ) ;
382
+ for ( cnum, slot) in list. iter_enumerated ( ) {
372
383
if !replaces_injected ( cnum) {
373
384
continue ;
374
385
}
@@ -377,25 +388,23 @@ fn activate_injected_dep(
377
388
}
378
389
}
379
390
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 ;
383
393
}
384
394
}
385
395
386
396
// After the linkage for a crate has been determined we need to verify that
387
397
// 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 ) {
389
399
let sess = & tcx. sess ;
390
400
if list. is_empty ( ) {
391
401
return ;
392
402
}
393
403
let mut panic_runtime = None ;
394
- for ( i , linkage) in list. iter ( ) . enumerate ( ) {
404
+ for ( cnum , linkage) in list. iter_enumerated ( ) {
395
405
if let Linkage :: NotLinked = * linkage {
396
406
continue ;
397
407
}
398
- let cnum = CrateNum :: new ( i + 1 ) ;
399
408
400
409
if tcx. is_panic_runtime ( cnum) {
401
410
if let Some ( ( prev, _) ) = panic_runtime {
@@ -431,11 +440,10 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) {
431
440
// strategy. If the dep isn't linked, we ignore it, and if our strategy
432
441
// is abort then it's compatible with everything. Otherwise all crates'
433
442
// panic strategy must match our own.
434
- for ( i , linkage) in list. iter ( ) . enumerate ( ) {
443
+ for ( cnum , linkage) in list. iter_enumerated ( ) {
435
444
if let Linkage :: NotLinked = * linkage {
436
445
continue ;
437
446
}
438
- let cnum = CrateNum :: new ( i + 1 ) ;
439
447
if cnum == runtime_cnum || tcx. is_compiler_builtins ( cnum) {
440
448
continue ;
441
449
}
@@ -450,13 +458,16 @@ fn verify_ok(tcx: TyCtxt<'_>, list: &[Linkage]) {
450
458
} ) ;
451
459
}
452
460
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
+ }
460
471
}
461
472
}
462
473
}
0 commit comments