@@ -25,6 +25,22 @@ use crate::util::{self, CargoResult, StableHasher};
25
25
/// use the same rustc version.
26
26
const METADATA_VERSION : u8 = 2 ;
27
27
28
+ /// Uniquely identify a [`Unit`] under specific circumstances, see [`Metadata`] for more.
29
+ #[ derive( Copy , Clone , Hash , Eq , PartialEq , Ord , PartialOrd ) ]
30
+ pub struct UnitHash ( u64 ) ;
31
+
32
+ impl fmt:: Display for UnitHash {
33
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
34
+ write ! ( f, "{:016x}" , self . 0 )
35
+ }
36
+ }
37
+
38
+ impl fmt:: Debug for UnitHash {
39
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
40
+ write ! ( f, "UnitHash({:016x})" , self . 0 )
41
+ }
42
+ }
43
+
28
44
/// The `Metadata` is a hash used to make unique file names for each unit in a
29
45
/// build. It is also used for symbol mangling.
30
46
///
@@ -68,30 +84,27 @@ const METADATA_VERSION: u8 = 2;
68
84
///
69
85
/// Note that the `Fingerprint` is in charge of tracking everything needed to determine if a
70
86
/// rebuild is needed.
71
- #[ derive( Copy , Clone , Hash , Eq , PartialEq , Ord , PartialOrd ) ]
72
- pub struct Metadata ( u64 ) ;
87
+ #[ derive( Copy , Clone , Debug ) ]
88
+ pub struct Metadata {
89
+ meta_hash : UnitHash ,
90
+ use_extra_filename : bool ,
91
+ }
73
92
74
- impl fmt:: Display for Metadata {
75
- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
76
- write ! ( f, "{:016x}" , self . 0 )
93
+ impl Metadata {
94
+ /// A hash to identify a given [`Unit`] in the build graph
95
+ pub fn unit_id ( & self ) -> UnitHash {
96
+ self . meta_hash
77
97
}
78
- }
79
98
80
- impl fmt :: Debug for Metadata {
81
- fn fmt ( & self , f : & mut fmt :: Formatter < ' _ > ) -> fmt :: Result {
82
- write ! ( f , "Metadata({:016x})" , self . 0 )
99
+ /// A hash to add to symbol naming through `-C metadata`
100
+ pub fn c_metadata ( & self ) -> UnitHash {
101
+ self . meta_hash
83
102
}
84
- }
85
103
86
- /// Information about the metadata hashes used for a `Unit`.
87
- struct MetaInfo {
88
- /// The symbol hash to use.
89
- meta_hash : Metadata ,
90
- /// Whether or not the `-C extra-filename` flag is used to generate unique
91
- /// output filenames for this `Unit`.
92
- ///
93
- /// If this is `true`, the `meta_hash` is used for the filename.
94
- use_extra_filename : bool ,
104
+ /// A hash to add to file names through `-C extra-filename`
105
+ pub fn c_extra_filename ( & self ) -> Option < UnitHash > {
106
+ self . use_extra_filename . then_some ( self . meta_hash )
107
+ }
95
108
}
96
109
97
110
/// Collection of information about the files emitted by the compiler, and the
@@ -108,7 +121,7 @@ pub struct CompilationFiles<'a, 'gctx> {
108
121
roots : Vec < Unit > ,
109
122
ws : & ' a Workspace < ' gctx > ,
110
123
/// Metadata hash to use for each unit.
111
- metas : HashMap < Unit , MetaInfo > ,
124
+ metas : HashMap < Unit , Metadata > ,
112
125
/// For each Unit, a list all files produced.
113
126
outputs : HashMap < Unit , LazyCell < Arc < Vec < OutputFile > > > > ,
114
127
}
@@ -177,13 +190,7 @@ impl<'a, 'gctx: 'a> CompilationFiles<'a, 'gctx> {
177
190
///
178
191
/// [`fingerprint`]: super::super::fingerprint#fingerprints-and-metadata
179
192
pub fn metadata ( & self , unit : & Unit ) -> Metadata {
180
- self . metas [ unit] . meta_hash
181
- }
182
-
183
- /// Returns whether or not `-C extra-filename` is used to extend the
184
- /// output filenames to make them unique.
185
- pub fn use_extra_filename ( & self , unit : & Unit ) -> bool {
186
- self . metas [ unit] . use_extra_filename
193
+ self . metas [ unit]
187
194
}
188
195
189
196
/// Gets the short hash based only on the `PackageId`.
@@ -224,9 +231,9 @@ impl<'a, 'gctx: 'a> CompilationFiles<'a, 'gctx> {
224
231
/// taken in those cases!
225
232
fn pkg_dir ( & self , unit : & Unit ) -> String {
226
233
let name = unit. pkg . package_id ( ) . name ( ) ;
227
- let meta = & self . metas [ unit] ;
228
- if meta. use_extra_filename {
229
- format ! ( "{}-{}" , name, meta . meta_hash )
234
+ let meta = self . metas [ unit] ;
235
+ if let Some ( c_extra_filename ) = meta. c_extra_filename ( ) {
236
+ format ! ( "{}-{}" , name, c_extra_filename )
230
237
} else {
231
238
format ! ( "{}-{}" , name, self . target_short_hash( unit) )
232
239
}
@@ -467,7 +474,11 @@ impl<'a, 'gctx: 'a> CompilationFiles<'a, 'gctx> {
467
474
// The file name needs to be stable across Cargo sessions.
468
475
// This originally used unit.buildkey(), but that isn't stable,
469
476
// so we use metadata instead (prefixed with name for debugging).
470
- let file_name = format ! ( "{}-{}.examples" , unit. pkg. name( ) , self . metadata( unit) ) ;
477
+ let file_name = format ! (
478
+ "{}-{}.examples" ,
479
+ unit. pkg. name( ) ,
480
+ self . metadata( unit) . unit_id( )
481
+ ) ;
471
482
let path = self . deps_dir ( unit) . join ( file_name) ;
472
483
vec ! [ OutputFile {
473
484
path,
@@ -523,8 +534,8 @@ impl<'a, 'gctx: 'a> CompilationFiles<'a, 'gctx> {
523
534
// Convert FileType to OutputFile.
524
535
let mut outputs = Vec :: new ( ) ;
525
536
for file_type in file_types {
526
- let meta = & self . metas [ unit] ;
527
- let meta_opt = meta. use_extra_filename . then ( || meta . meta_hash . to_string ( ) ) ;
537
+ let meta = self . metas [ unit] ;
538
+ let meta_opt = meta. c_extra_filename ( ) . map ( |h| h . to_string ( ) ) ;
528
539
let path = out_dir. join ( file_type. output_filename ( & unit. target , meta_opt. as_deref ( ) ) ) ;
529
540
530
541
// If, the `different_binary_name` feature is enabled, the name of the hardlink will
@@ -558,8 +569,8 @@ impl<'a, 'gctx: 'a> CompilationFiles<'a, 'gctx> {
558
569
fn metadata_of < ' a > (
559
570
unit : & Unit ,
560
571
build_runner : & BuildRunner < ' _ , ' _ > ,
561
- metas : & ' a mut HashMap < Unit , MetaInfo > ,
562
- ) -> & ' a MetaInfo {
572
+ metas : & ' a mut HashMap < Unit , Metadata > ,
573
+ ) -> & ' a Metadata {
563
574
if !metas. contains_key ( unit) {
564
575
let meta = compute_metadata ( unit, build_runner, metas) ;
565
576
metas. insert ( unit. clone ( ) , meta) ;
@@ -574,8 +585,8 @@ fn metadata_of<'a>(
574
585
fn compute_metadata (
575
586
unit : & Unit ,
576
587
build_runner : & BuildRunner < ' _ , ' _ > ,
577
- metas : & mut HashMap < Unit , MetaInfo > ,
578
- ) -> MetaInfo {
588
+ metas : & mut HashMap < Unit , Metadata > ,
589
+ ) -> Metadata {
579
590
let bcx = & build_runner. bcx ;
580
591
let mut hasher = StableHasher :: new ( ) ;
581
592
@@ -669,9 +680,9 @@ fn compute_metadata(
669
680
target_configs_are_different. hash ( & mut hasher) ;
670
681
}
671
682
672
- MetaInfo {
673
- meta_hash : Metadata ( hasher. finish ( ) ) ,
674
- use_extra_filename : should_use_metadata ( bcx, unit) ,
683
+ Metadata {
684
+ meta_hash : UnitHash ( hasher. finish ( ) ) ,
685
+ use_extra_filename : use_extra_filename ( bcx, unit) ,
675
686
}
676
687
}
677
688
@@ -717,8 +728,8 @@ fn hash_rustc_version(bcx: &BuildContext<'_, '_>, hasher: &mut StableHasher, uni
717
728
// between different backends without recompiling.
718
729
}
719
730
720
- /// Returns whether or not this unit should use a metadata hash.
721
- fn should_use_metadata ( bcx : & BuildContext < ' _ , ' _ > , unit : & Unit ) -> bool {
731
+ /// Returns whether or not this unit should use a hash in the filename to make it unique .
732
+ fn use_extra_filename ( bcx : & BuildContext < ' _ , ' _ > , unit : & Unit ) -> bool {
722
733
if unit. mode . is_doc_test ( ) || unit. mode . is_doc ( ) {
723
734
// Doc tests do not have metadata.
724
735
return false ;
0 commit comments