]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/middle/cstore.rs
Remove a sorting operation from used_crates
[rust.git] / compiler / rustc_middle / src / middle / cstore.rs
1 //! the rustc crate store interface. This also includes types that
2 //! are *mostly* used as a part of that interface, but these should
3 //! probably get a better home if someone can find one.
4
5 use crate::ty::TyCtxt;
6
7 use rustc_ast as ast;
8 use rustc_data_structures::svh::Svh;
9 use rustc_data_structures::sync::{self, MetadataRef};
10 use rustc_hir::def::DefKind;
11 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
12 use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
13 use rustc_macros::HashStable;
14 use rustc_session::search_paths::PathKind;
15 use rustc_session::utils::NativeLibKind;
16 use rustc_session::CrateDisambiguator;
17 use rustc_span::symbol::Symbol;
18 use rustc_span::Span;
19 use rustc_target::spec::Target;
20
21 use std::any::Any;
22 use std::path::{Path, PathBuf};
23
24 // lonely orphan structs and enums looking for a better home
25
26 /// Where a crate came from on the local filesystem. One of these three options
27 /// must be non-None.
28 #[derive(PartialEq, Clone, Debug, HashStable, Encodable, Decodable)]
29 pub struct CrateSource {
30     pub dylib: Option<(PathBuf, PathKind)>,
31     pub rlib: Option<(PathBuf, PathKind)>,
32     pub rmeta: Option<(PathBuf, PathKind)>,
33 }
34
35 impl CrateSource {
36     pub fn paths(&self) -> impl Iterator<Item = &PathBuf> {
37         self.dylib.iter().chain(self.rlib.iter()).chain(self.rmeta.iter()).map(|p| &p.0)
38     }
39 }
40
41 #[derive(Encodable, Decodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
42 #[derive(HashStable)]
43 pub enum CrateDepKind {
44     /// A dependency that is only used for its macros.
45     MacrosOnly,
46     /// A dependency that is always injected into the dependency list and so
47     /// doesn't need to be linked to an rlib, e.g., the injected allocator.
48     Implicit,
49     /// A dependency that is required by an rlib version of this crate.
50     /// Ordinary `extern crate`s result in `Explicit` dependencies.
51     Explicit,
52 }
53
54 impl CrateDepKind {
55     pub fn macros_only(self) -> bool {
56         match self {
57             CrateDepKind::MacrosOnly => true,
58             CrateDepKind::Implicit | CrateDepKind::Explicit => false,
59         }
60     }
61 }
62
63 #[derive(Copy, Debug, PartialEq, Clone, Encodable, Decodable, HashStable)]
64 pub enum LinkagePreference {
65     RequireDynamic,
66     RequireStatic,
67 }
68
69 #[derive(Clone, Debug, Encodable, Decodable, HashStable)]
70 pub struct NativeLib {
71     pub kind: NativeLibKind,
72     pub name: Option<Symbol>,
73     pub cfg: Option<ast::MetaItem>,
74     pub foreign_module: Option<DefId>,
75     pub wasm_import_module: Option<Symbol>,
76     pub verbatim: Option<bool>,
77     pub dll_imports: Vec<DllImport>,
78 }
79
80 #[derive(Clone, Debug, Encodable, Decodable, HashStable)]
81 pub struct DllImport {
82     pub name: Symbol,
83     pub ordinal: Option<u16>,
84 }
85
86 #[derive(Clone, TyEncodable, TyDecodable, HashStable, Debug)]
87 pub struct ForeignModule {
88     pub foreign_items: Vec<DefId>,
89     pub def_id: DefId,
90 }
91
92 #[derive(Copy, Clone, Debug, HashStable)]
93 pub struct ExternCrate {
94     pub src: ExternCrateSource,
95
96     /// span of the extern crate that caused this to be loaded
97     pub span: Span,
98
99     /// Number of links to reach the extern;
100     /// used to select the extern with the shortest path
101     pub path_len: usize,
102
103     /// Crate that depends on this crate
104     pub dependency_of: CrateNum,
105 }
106
107 impl ExternCrate {
108     /// If true, then this crate is the crate named by the extern
109     /// crate referenced above. If false, then this crate is a dep
110     /// of the crate.
111     pub fn is_direct(&self) -> bool {
112         self.dependency_of == LOCAL_CRATE
113     }
114
115     pub fn rank(&self) -> impl PartialOrd {
116         // Prefer:
117         // - direct extern crate to indirect
118         // - shorter paths to longer
119         (self.is_direct(), !self.path_len)
120     }
121 }
122
123 #[derive(Copy, Clone, Debug, HashStable)]
124 pub enum ExternCrateSource {
125     /// Crate is loaded by `extern crate`.
126     Extern(
127         /// def_id of the item in the current crate that caused
128         /// this crate to be loaded; note that there could be multiple
129         /// such ids
130         DefId,
131     ),
132     /// Crate is implicitly loaded by a path resolving through extern prelude.
133     Path,
134 }
135
136 #[derive(Encodable, Decodable)]
137 pub struct EncodedMetadata {
138     pub raw_data: Vec<u8>,
139 }
140
141 impl EncodedMetadata {
142     pub fn new() -> EncodedMetadata {
143         EncodedMetadata { raw_data: Vec::new() }
144     }
145 }
146
147 /// The backend's way to give the crate store access to the metadata in a library.
148 /// Note that it returns the raw metadata bytes stored in the library file, whether
149 /// it is compressed, uncompressed, some weird mix, etc.
150 /// rmeta files are backend independent and not handled here.
151 ///
152 /// At the time of this writing, there is only one backend and one way to store
153 /// metadata in library -- this trait just serves to decouple rustc_metadata from
154 /// the archive reader, which depends on LLVM.
155 pub trait MetadataLoader {
156     fn get_rlib_metadata(&self, target: &Target, filename: &Path) -> Result<MetadataRef, String>;
157     fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<MetadataRef, String>;
158 }
159
160 pub type MetadataLoaderDyn = dyn MetadataLoader + Sync;
161
162 /// A store of Rust crates, through which their metadata can be accessed.
163 ///
164 /// Note that this trait should probably not be expanding today. All new
165 /// functionality should be driven through queries instead!
166 ///
167 /// If you find a method on this trait named `{name}_untracked` it signifies
168 /// that it's *not* tracked for dependency information throughout compilation
169 /// (it'd break incremental compilation) and should only be called pre-HIR (e.g.
170 /// during resolve)
171 pub trait CrateStore {
172     fn as_any(&self) -> &dyn Any;
173
174     // resolve
175     fn def_key(&self, def: DefId) -> DefKey;
176     fn def_kind(&self, def: DefId) -> DefKind;
177     fn def_path(&self, def: DefId) -> DefPath;
178     fn def_path_hash(&self, def: DefId) -> DefPathHash;
179     fn def_path_hash_to_def_id(
180         &self,
181         cnum: CrateNum,
182         index_guess: u32,
183         hash: DefPathHash,
184     ) -> Option<DefId>;
185
186     // "queries" used in resolve that aren't tracked for incremental compilation
187     fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol;
188     fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> CrateDisambiguator;
189     fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh;
190
191     // This is basically a 1-based range of ints, which is a little
192     // silly - I may fix that.
193     fn crates_untracked(&self) -> Vec<CrateNum>;
194
195     // utility functions
196     fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata;
197 }
198
199 pub type CrateStoreDyn = dyn CrateStore + sync::Sync;