1010
1111//! Calculation and management of a Strict Version Hash for crates
1212//!
13- //! # Today's ABI problem
14- //!
15- //! In today's implementation of rustc, it is incredibly difficult to achieve
16- //! forward binary compatibility without resorting to C-like interfaces. Within
17- //! rust code itself, abi details such as symbol names suffer from a variety of
18- //! unrelated factors to code changing such as the "def id drift" problem. This
19- //! ends up yielding confusing error messages about metadata mismatches and
20- //! such.
21- //!
22- //! The core of this problem is when an upstream dependency changes and
23- //! downstream dependents are not recompiled. This causes compile errors because
24- //! the upstream crate's metadata has changed but the downstream crates are
25- //! still referencing the older crate's metadata.
26- //!
27- //! This problem exists for many reasons, the primary of which is that rust does
28- //! not currently support forwards ABI compatibility (in place upgrades of a
29- //! crate).
30- //!
31- //! # SVH and how it alleviates the problem
32- //!
33- //! With all of this knowledge on hand, this module contains the implementation
34- //! of a notion of a "Strict Version Hash" for a crate. This is essentially a
35- //! hash of all contents of a crate which can somehow be exposed to downstream
36- //! crates.
37- //!
38- //! This hash is currently calculated by just hashing the AST, but this is
39- //! obviously wrong (doc changes should not result in an incompatible ABI).
40- //! Implementation-wise, this is required at this moment in time.
41- //!
42- //! By encoding this strict version hash into all crate's metadata, stale crates
43- //! can be detected immediately and error'd about by rustc itself.
44- //!
45- //! # Relevant links
46- //!
47- //! Original issue: https://github.com/rust-lang/rust/issues/10207
13+ //! The SVH is used for incremental compilation to track when HIR
14+ //! nodes have changed between compilations, and also to detect
15+ //! mismatches where we have two versions of the same crate that were
16+ //! compiled from distinct sources.
4817
4918use std:: fmt;
19+ use std:: hash:: { Hash , Hasher } ;
5020
51- #[ derive( Clone , Eq , Hash , PartialEq , Debug ) ]
21+ #[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
5222pub struct Svh {
53- hash : String ,
23+ hash : u64 ,
5424}
5525
5626impl Svh {
5727 /// Create a new `Svh` given the hash. If you actually want to
5828 /// compute the SVH from some HIR, you want the `calculate_svh`
59- /// function found in `librustc_trans`.
60- pub fn new ( hash : String ) -> Svh {
61- assert ! ( hash. len( ) == 16 ) ;
29+ /// function found in `librustc_incremental`.
30+ pub fn new ( hash : u64 ) -> Svh {
6231 Svh { hash : hash }
6332 }
6433
65- pub fn from_hash ( hash : u64 ) -> Svh {
66- return Svh :: new ( ( 0 ..64 ) . step_by ( 4 ) . map ( |i| hex ( hash >> i) ) . collect ( ) ) ;
34+ pub fn as_u64 ( & self ) -> u64 {
35+ self . hash
36+ }
37+
38+ pub fn to_string ( & self ) -> String {
39+ let hash = self . hash ;
40+ return ( 0 ..64 ) . step_by ( 4 ) . map ( |i| hex ( hash >> i) ) . collect ( ) ;
6741
6842 fn hex ( b : u64 ) -> char {
6943 let b = ( b & 0xf ) as u8 ;
@@ -74,14 +48,16 @@ impl Svh {
7448 b as char
7549 }
7650 }
51+ }
7752
78- pub fn as_str < ' a > ( & ' a self ) -> & ' a str {
79- & self . hash
53+ impl Hash for Svh {
54+ fn hash < H > ( & self , state : & mut H ) where H : Hasher {
55+ self . hash . to_le ( ) . hash ( state) ;
8056 }
8157}
8258
8359impl fmt:: Display for Svh {
8460 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
85- f. pad ( self . as_str ( ) )
61+ f. pad ( & self . to_string ( ) )
8662 }
8763}
0 commit comments