]> git.lizzy.rs Git - rust.git/blob - src/librustc/hir/svh.rs
Auto merge of #33030 - nagisa:mir-unrequire-end-block, r=nikomatsakis
[rust.git] / src / librustc / hir / svh.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Calculation and management of a Strict Version Hash for crates
12 //!
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
48
49 use std::fmt;
50
51 #[derive(Clone, Eq, Hash, PartialEq, Debug)]
52 pub struct Svh {
53     hash: String,
54 }
55
56 impl Svh {
57     /// Create a new `Svh` given the hash. If you actually want to
58     /// 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);
62         Svh { hash: hash }
63     }
64
65     pub fn from_hash(hash: u64) -> Svh {
66         return Svh::new((0..64).step_by(4).map(|i| hex(hash >> i)).collect());
67
68         fn hex(b: u64) -> char {
69             let b = (b & 0xf) as u8;
70             let b = match b {
71                 0 ... 9 => '0' as u8 + b,
72                 _ => 'a' as u8 + b - 10,
73             };
74             b as char
75         }
76     }
77
78     pub fn as_str<'a>(&'a self) -> &'a str {
79         &self.hash
80     }
81 }
82
83 impl fmt::Display for Svh {
84     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
85         f.pad(self.as_str())
86     }
87 }