]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/exported_symbols.rs
Auto merge of #53444 - varkor:lib_features-conditional, r=michaelwoerister
[rust.git] / src / librustc / middle / exported_symbols.rs
1 // Copyright 2016 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 use hir::def_id::{DefId, LOCAL_CRATE};
12 use ich::StableHashingContext;
13 use rustc_data_structures::stable_hasher::{StableHasher, HashStable,
14                                            StableHasherResult};
15 use std::cmp;
16 use std::mem;
17 use ty;
18 use ty::subst::Substs;
19
20 /// The SymbolExportLevel of a symbols specifies from which kinds of crates
21 /// the symbol will be exported. `C` symbols will be exported from any
22 /// kind of crate, including cdylibs which export very few things.
23 /// `Rust` will only be exported if the crate produced is a Rust
24 /// dylib.
25 #[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable)]
26 pub enum SymbolExportLevel {
27     C,
28     Rust,
29 }
30
31 impl_stable_hash_for!(enum self::SymbolExportLevel {
32     C,
33     Rust
34 });
35
36 impl SymbolExportLevel {
37     pub fn is_below_threshold(self, threshold: SymbolExportLevel) -> bool {
38         if threshold == SymbolExportLevel::Rust {
39             // We export everything from Rust dylibs
40             true
41         } else {
42             self == SymbolExportLevel::C
43         }
44     }
45 }
46
47 #[derive(Eq, PartialEq, Debug, Copy, Clone, RustcEncodable, RustcDecodable)]
48 pub enum ExportedSymbol<'tcx> {
49     NonGeneric(DefId),
50     Generic(DefId, &'tcx Substs<'tcx>),
51     NoDefId(ty::SymbolName),
52 }
53
54 impl<'tcx> ExportedSymbol<'tcx> {
55     pub fn symbol_name(&self,
56                        tcx: ty::TyCtxt<'_, 'tcx, '_>)
57                        -> ty::SymbolName {
58         match *self {
59             ExportedSymbol::NonGeneric(def_id) => {
60                 tcx.symbol_name(ty::Instance::mono(tcx, def_id))
61             }
62             ExportedSymbol::Generic(def_id, substs) => {
63                 tcx.symbol_name(ty::Instance::new(def_id, substs))
64             }
65             ExportedSymbol::NoDefId(symbol_name) => {
66                 symbol_name
67             }
68         }
69     }
70
71     pub fn compare_stable(&self,
72                           tcx: ty::TyCtxt<'_, 'tcx, '_>,
73                           other: &ExportedSymbol<'tcx>)
74                           -> cmp::Ordering {
75         match *self {
76             ExportedSymbol::NonGeneric(self_def_id) => match *other {
77                 ExportedSymbol::NonGeneric(other_def_id) => {
78                     tcx.def_path_hash(self_def_id).cmp(&tcx.def_path_hash(other_def_id))
79                 }
80                 ExportedSymbol::Generic(..) |
81                 ExportedSymbol::NoDefId(_) => {
82                     cmp::Ordering::Less
83                 }
84             }
85             ExportedSymbol::Generic(..) => match *other {
86                 ExportedSymbol::NonGeneric(_) => {
87                     cmp::Ordering::Greater
88                 }
89                 ExportedSymbol::Generic(..) => {
90                     self.symbol_name(tcx).cmp(&other.symbol_name(tcx))
91                 }
92                 ExportedSymbol::NoDefId(_) => {
93                     cmp::Ordering::Less
94                 }
95             }
96             ExportedSymbol::NoDefId(self_symbol_name) => match *other {
97                 ExportedSymbol::NonGeneric(_) |
98                 ExportedSymbol::Generic(..) => {
99                     cmp::Ordering::Greater
100                 }
101                 ExportedSymbol::NoDefId(ref other_symbol_name) => {
102                     self_symbol_name.cmp(other_symbol_name)
103                 }
104             }
105         }
106     }
107 }
108
109 pub fn metadata_symbol_name(tcx: ty::TyCtxt) -> String {
110     format!("rust_metadata_{}_{}",
111             tcx.original_crate_name(LOCAL_CRATE),
112             tcx.crate_disambiguator(LOCAL_CRATE).to_fingerprint().to_hex())
113 }
114
115 impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ExportedSymbol<'gcx> {
116     fn hash_stable<W: StableHasherResult>(&self,
117                                           hcx: &mut StableHashingContext<'a>,
118                                           hasher: &mut StableHasher<W>) {
119         mem::discriminant(self).hash_stable(hcx, hasher);
120         match *self {
121             ExportedSymbol::NonGeneric(def_id) => {
122                 def_id.hash_stable(hcx, hasher);
123             }
124             ExportedSymbol::Generic(def_id, substs) => {
125                 def_id.hash_stable(hcx, hasher);
126                 substs.hash_stable(hcx, hasher);
127             }
128             ExportedSymbol::NoDefId(symbol_name) => {
129                 symbol_name.hash_stable(hcx, hasher);
130             }
131         }
132     }
133 }