]> git.proxmox.com Git - rustc.git/blobdiff - src/librustc/middle/cstore.rs
New upstream version 1.41.1+dfsg1
[rustc.git] / src / librustc / middle / cstore.rs
index 960d616cd4ca232ae6c6178b816cba55d7972f0e..324b01316fa4a63216b153ef005240e9e332cc24 100644 (file)
@@ -1,71 +1,47 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// the rustc crate store interface. This also includes types that
-// are *mostly* used as a part of that interface, but these should
-// probably get a better home if someone can find one.
-
-use hir::def;
-use hir::def_id::{CrateNum, DefId, DefIndex};
-use hir::map as hir_map;
-use hir::map::definitions::{Definitions, DefKey, DisambiguatedDefPathData,
-                            DefPathTable};
-use hir::svh::Svh;
-use ich;
-use middle::lang_items;
-use ty::{self, TyCtxt};
-use session::Session;
-use session::search_paths::PathKind;
-use util::nodemap::{NodeSet, DefIdMap};
+//! the rustc crate store interface. This also includes types that
+//! are *mostly* used as a part of that interface, but these should
+//! probably get a better home if someone can find one.
+
+use crate::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
+use crate::hir::map as hir_map;
+use crate::hir::map::definitions::{DefKey, DefPathTable};
+use rustc_data_structures::svh::Svh;
+use crate::ty::{self, TyCtxt};
+use crate::session::{Session, CrateDisambiguator};
+use crate::session::search_paths::PathKind;
 
 use std::any::Any;
 use std::path::{Path, PathBuf};
-use std::rc::Rc;
-use owning_ref::ErasedBoxRef;
 use syntax::ast;
-use syntax::ext::base::SyntaxExtension;
 use syntax::symbol::Symbol;
 use syntax_pos::Span;
-use rustc_back::target::Target;
-use hir;
-use rustc_back::PanicStrategy;
+use syntax::expand::allocator::AllocatorKind;
+use rustc_target::spec::Target;
+use rustc_data_structures::sync::{self, MetadataRef};
+use rustc_macros::HashStable;
 
+pub use rustc_session::utils::NativeLibraryKind;
 pub use self::NativeLibraryKind::*;
 
 // lonely orphan structs and enums looking for a better home
 
-#[derive(Clone, Debug)]
-pub struct LinkMeta {
-    pub crate_hash: Svh,
-}
-
-// Where a crate came from on the local filesystem. One of these three options
-// must be non-None.
-#[derive(PartialEq, Clone, Debug)]
+/// Where a crate came from on the local filesystem. One of these three options
+/// must be non-None.
+#[derive(PartialEq, Clone, Debug, HashStable)]
 pub struct CrateSource {
     pub dylib: Option<(PathBuf, PathKind)>,
     pub rlib: Option<(PathBuf, PathKind)>,
     pub rmeta: Option<(PathBuf, PathKind)>,
 }
 
-#[derive(RustcEncodable, RustcDecodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
+impl CrateSource {
+    pub fn paths(&self) -> impl Iterator<Item = &PathBuf> {
+        self.dylib.iter().chain(self.rlib.iter()).chain(self.rmeta.iter()).map(|p| &p.0)
+    }
+}
+
+#[derive(RustcEncodable, RustcDecodable, Copy, Clone,
+         Ord, PartialOrd, Eq, PartialEq, Debug, HashStable)]
 pub enum DepKind {
     /// A dependency that is only used for its macros, none of which are visible from other crates.
     /// These are included in the metadata only as placeholders and are ignored when decoding.
@@ -73,7 +49,7 @@ pub enum DepKind {
     /// A dependency that is only used for its macros.
     MacrosOnly,
     /// A dependency that is always injected into the dependency list and so
-    /// doesn't need to be linked to an rlib, e.g. the injected allocator.
+    /// doesn't need to be linked to an rlib, e.g., the injected allocator.
     Implicit,
     /// A dependency that is required by an rlib version of this crate.
     /// Ordinary `extern crate`s result in `Explicit` dependencies.
@@ -113,90 +89,79 @@ impl LibSource {
     }
 }
 
-#[derive(Copy, Debug, PartialEq, Clone, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Debug, PartialEq, Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub enum LinkagePreference {
     RequireDynamic,
     RequireStatic,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
-pub enum NativeLibraryKind {
-    NativeStatic,    // native static library (.a archive)
-    NativeStaticNobundle, // native static library, which doesn't get bundled into .rlibs
-    NativeFramework, // macOS-specific
-    NativeUnknown,   // default way to specify a dynamic library
-}
-
-#[derive(Clone, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct NativeLibrary {
     pub kind: NativeLibraryKind,
-    pub name: Symbol,
+    pub name: Option<Symbol>,
     pub cfg: Option<ast::MetaItem>,
-    pub foreign_items: Vec<DefIndex>,
+    pub foreign_module: Option<DefId>,
+    pub wasm_import_module: Option<Symbol>,
 }
 
-pub enum LoadedMacro {
-    MacroDef(ast::Item),
-    ProcMacro(Rc<SyntaxExtension>),
+#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
+pub struct ForeignModule {
+    pub foreign_items: Vec<DefId>,
+    pub def_id: DefId,
 }
 
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone, Debug, HashStable)]
 pub struct ExternCrate {
-    /// def_id of an `extern crate` in the current crate that caused
-    /// this crate to be loaded; note that there could be multiple
-    /// such ids
-    pub def_id: DefId,
+    pub src: ExternCrateSource,
 
     /// span of the extern crate that caused this to be loaded
     pub span: Span,
 
+    /// Number of links to reach the extern;
+    /// used to select the extern with the shortest path
+    pub path_len: usize,
+
+    /// Crate that depends on this crate
+    pub dependency_of: CrateNum,
+}
+
+impl ExternCrate {
     /// If true, then this crate is the crate named by the extern
     /// crate referenced above. If false, then this crate is a dep
     /// of the crate.
-    pub direct: bool,
+    pub fn is_direct(&self) -> bool {
+        self.dependency_of == LOCAL_CRATE
+    }
 
-    /// Number of links to reach the extern crate `def_id`
-    /// declaration; used to select the extern crate with the shortest
-    /// path
-    pub path_len: usize,
+    pub fn rank(&self) -> impl PartialOrd {
+        // Prefer:
+        // - direct extern crate to indirect
+        // - shorter paths to longer
+        (self.is_direct(), !self.path_len)
+    }
+}
+
+#[derive(Copy, Clone, Debug, HashStable)]
+pub enum ExternCrateSource {
+    /// Crate is loaded by `extern crate`.
+    Extern(
+        /// def_id of the item in the current crate that caused
+        /// this crate to be loaded; note that there could be multiple
+        /// such ids
+        DefId,
+    ),
+    /// Crate is implicitly loaded by a path resolving through extern prelude.
+    Path,
 }
 
 pub struct EncodedMetadata {
-    pub raw_data: Vec<u8>,
-    pub hashes: EncodedMetadataHashes,
+    pub raw_data: Vec<u8>
 }
 
 impl EncodedMetadata {
     pub fn new() -> EncodedMetadata {
         EncodedMetadata {
             raw_data: Vec::new(),
-            hashes: EncodedMetadataHashes::new(),
-        }
-    }
-}
-
-/// The hash for some metadata that (when saving) will be exported
-/// from this crate, or which (when importing) was exported by an
-/// upstream crate.
-#[derive(Debug, RustcEncodable, RustcDecodable, Copy, Clone)]
-pub struct EncodedMetadataHash {
-    pub def_index: DefIndex,
-    pub hash: ich::Fingerprint,
-}
-
-/// The hash for some metadata that (when saving) will be exported
-/// from this crate, or which (when importing) was exported by an
-/// upstream crate.
-#[derive(Debug, RustcEncodable, RustcDecodable, Clone)]
-pub struct EncodedMetadataHashes {
-    // Stable content hashes for things in crate metadata, indexed by DefIndex.
-    pub hashes: Vec<EncodedMetadataHash>,
-}
-
-impl EncodedMetadataHashes {
-    pub fn new() -> EncodedMetadataHashes {
-        EncodedMetadataHashes {
-            hashes: Vec::new(),
         }
     }
 }
@@ -213,239 +178,91 @@ pub trait MetadataLoader {
     fn get_rlib_metadata(&self,
                          target: &Target,
                          filename: &Path)
-                         -> Result<ErasedBoxRef<[u8]>, String>;
+                         -> Result<MetadataRef, String>;
     fn get_dylib_metadata(&self,
                           target: &Target,
                           filename: &Path)
-                          -> Result<ErasedBoxRef<[u8]>, String>;
+                          -> Result<MetadataRef, String>;
 }
 
-/// A store of Rust crates, through with their metadata
-/// can be accessed.
+pub type MetadataLoaderDyn = dyn MetadataLoader + Sync;
+
+/// A store of Rust crates, through which their metadata can be accessed.
+///
+/// Note that this trait should probably not be expanding today. All new
+/// functionality should be driven through queries instead!
+///
+/// If you find a method on this trait named `{name}_untracked` it signifies
+/// that it's *not* tracked for dependency information throughout compilation
+/// (it'd break incremental compilation) and should only be called pre-HIR (e.g.
+/// during resolve)
 pub trait CrateStore {
-    fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc<Any>;
-
-    // access to the metadata loader
-    fn metadata_loader(&self) -> &MetadataLoader;
-
-    // item info
-    fn visibility(&self, def: DefId) -> ty::Visibility;
-    fn visible_parent_map<'a>(&'a self, sess: &Session) -> ::std::cell::Ref<'a, DefIdMap<DefId>>;
-    fn item_generics_cloned(&self, def: DefId) -> ty::Generics;
-
-    // trait info
-    fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>;
-
-    // impl info
-    fn impl_defaultness(&self, def: DefId) -> hir::Defaultness;
-
-    // trait/impl-item info
-    fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem;
-
-    // flags
-    fn is_dllimport_foreign_item(&self, def: DefId) -> bool;
-    fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool;
-
-    // crate metadata
-    fn dep_kind(&self, cnum: CrateNum) -> DepKind;
-    fn export_macros(&self, cnum: CrateNum);
-    fn lang_items(&self, cnum: CrateNum) -> Vec<(DefIndex, usize)>;
-    fn missing_lang_items(&self, cnum: CrateNum) -> Vec<lang_items::LangItem>;
-    fn is_compiler_builtins(&self, cnum: CrateNum) -> bool;
-    fn is_sanitizer_runtime(&self, cnum: CrateNum) -> bool;
-    fn is_profiler_runtime(&self, cnum: CrateNum) -> bool;
-    fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy;
-    /// The name of the crate as it is referred to in source code of the current
-    /// crate.
-    fn crate_name(&self, cnum: CrateNum) -> Symbol;
-    /// The name of the crate as it is stored in the crate's metadata.
-    fn original_crate_name(&self, cnum: CrateNum) -> Symbol;
-    fn crate_hash(&self, cnum: CrateNum) -> Svh;
-    fn crate_disambiguator(&self, cnum: CrateNum) -> Symbol;
-    fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option<DefId>;
-    fn derive_registrar_fn(&self, cnum: CrateNum) -> Option<DefId>;
-    fn native_libraries(&self, cnum: CrateNum) -> Vec<NativeLibrary>;
-    fn exported_symbols(&self, cnum: CrateNum) -> Vec<DefId>;
-    fn is_no_builtins(&self, cnum: CrateNum) -> bool;
+    fn as_any(&self) -> &dyn Any;
 
     // resolve
-    fn retrace_path(&self,
-                    cnum: CrateNum,
-                    path_data: &[DisambiguatedDefPathData])
-                    -> Option<DefId>;
     fn def_key(&self, def: DefId) -> DefKey;
     fn def_path(&self, def: DefId) -> hir_map::DefPath;
     fn def_path_hash(&self, def: DefId) -> hir_map::DefPathHash;
-    fn def_path_table(&self, cnum: CrateNum) -> Rc<DefPathTable>;
-    fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>;
-    fn item_children(&self, did: DefId, sess: &Session) -> Vec<def::Export>;
-    fn load_macro(&self, did: DefId, sess: &Session) -> LoadedMacro;
+    fn def_path_table(&self, cnum: CrateNum) -> &DefPathTable;
 
-    // misc. metadata
-    fn item_body<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-                           -> &'tcx hir::Body;
+    // "queries" used in resolve that aren't tracked for incremental compilation
+    fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol;
+    fn crate_is_private_dep_untracked(&self, cnum: CrateNum) -> bool;
+    fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> CrateDisambiguator;
+    fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh;
+    fn item_generics_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::Generics;
 
     // This is basically a 1-based range of ints, which is a little
     // silly - I may fix that.
-    fn crates(&self) -> Vec<CrateNum>;
-    fn used_libraries(&self) -> Vec<NativeLibrary>;
-    fn used_link_args(&self) -> Vec<String>;
+    fn crates_untracked(&self) -> Vec<CrateNum>;
 
     // utility functions
-    fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>;
-    fn used_crate_source(&self, cnum: CrateNum) -> CrateSource;
-    fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>;
-    fn encode_metadata<'a, 'tcx>(&self,
-                                 tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                 link_meta: &LinkMeta,
-                                 reachable: &NodeSet)
-                                 -> EncodedMetadata;
+    fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata;
     fn metadata_encoding_version(&self) -> &[u8];
+    fn allocator_kind(&self) -> Option<AllocatorKind>;
 }
 
-// FIXME: find a better place for this?
-pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
-    let mut err_count = 0;
-    {
-        let mut say = |s: &str| {
-            match (sp, sess) {
-                (_, None) => bug!("{}", s),
-                (Some(sp), Some(sess)) => sess.span_err(sp, s),
-                (None, Some(sess)) => sess.err(s),
-            }
-            err_count += 1;
-        };
-        if s.is_empty() {
-            say("crate name must not be empty");
-        }
-        for c in s.chars() {
-            if c.is_alphanumeric() { continue }
-            if c == '_'  { continue }
-            say(&format!("invalid character `{}` in crate name: `{}`", c, s));
-        }
-    }
-
-    if err_count > 0 {
-        sess.unwrap().abort_if_errors();
-    }
-}
-
-/// A dummy crate store that does not support any non-local crates,
-/// for test purposes.
-pub struct DummyCrateStore;
-
-#[allow(unused_variables)]
-impl CrateStore for DummyCrateStore {
-    fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc<Any>
-        { bug!("crate_data_as_rc_any") }
-    // item info
-    fn visibility(&self, def: DefId) -> ty::Visibility { bug!("visibility") }
-    fn visible_parent_map<'a>(&'a self, session: &Session)
-        -> ::std::cell::Ref<'a, DefIdMap<DefId>>
-    {
-        bug!("visible_parent_map")
-    }
-    fn item_generics_cloned(&self, def: DefId) -> ty::Generics
-        { bug!("item_generics_cloned") }
-
-    // trait info
-    fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId> { vec![] }
-
-    // impl info
-    fn impl_defaultness(&self, def: DefId) -> hir::Defaultness { bug!("impl_defaultness") }
-
-    // trait/impl-item info
-    fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem
-        { bug!("associated_item_cloned") }
-
-    // flags
-    fn is_dllimport_foreign_item(&self, id: DefId) -> bool { false }
-    fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool { false }
-
-    // crate metadata
-    fn lang_items(&self, cnum: CrateNum) -> Vec<(DefIndex, usize)>
-        { bug!("lang_items") }
-    fn missing_lang_items(&self, cnum: CrateNum) -> Vec<lang_items::LangItem>
-        { bug!("missing_lang_items") }
-    fn dep_kind(&self, cnum: CrateNum) -> DepKind { bug!("is_explicitly_linked") }
-    fn export_macros(&self, cnum: CrateNum) { bug!("export_macros") }
-    fn is_compiler_builtins(&self, cnum: CrateNum) -> bool { bug!("is_compiler_builtins") }
-    fn is_profiler_runtime(&self, cnum: CrateNum) -> bool { bug!("is_profiler_runtime") }
-    fn is_sanitizer_runtime(&self, cnum: CrateNum) -> bool { bug!("is_sanitizer_runtime") }
-    fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy {
-        bug!("panic_strategy")
-    }
-    fn crate_name(&self, cnum: CrateNum) -> Symbol { bug!("crate_name") }
-    fn original_crate_name(&self, cnum: CrateNum) -> Symbol {
-        bug!("original_crate_name")
-    }
-    fn crate_hash(&self, cnum: CrateNum) -> Svh { bug!("crate_hash") }
-    fn crate_disambiguator(&self, cnum: CrateNum)
-                           -> Symbol { bug!("crate_disambiguator") }
-    fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option<DefId>
-        { bug!("plugin_registrar_fn") }
-    fn derive_registrar_fn(&self, cnum: CrateNum) -> Option<DefId>
-        { bug!("derive_registrar_fn") }
-    fn native_libraries(&self, cnum: CrateNum) -> Vec<NativeLibrary>
-        { bug!("native_libraries") }
-    fn exported_symbols(&self, cnum: CrateNum) -> Vec<DefId> { bug!("exported_symbols") }
-    fn is_no_builtins(&self, cnum: CrateNum) -> bool { bug!("is_no_builtins") }
-
-    // resolve
-    fn retrace_path(&self,
-                    cnum: CrateNum,
-                    path_data: &[DisambiguatedDefPathData])
-                    -> Option<DefId> {
-        None
-    }
+pub type CrateStoreDyn = dyn CrateStore + sync::Sync;
 
-    fn def_key(&self, def: DefId) -> DefKey { bug!("def_key") }
-    fn def_path(&self, def: DefId) -> hir_map::DefPath {
-        bug!("relative_def_path")
-    }
-    fn def_path_hash(&self, def: DefId) -> hir_map::DefPathHash {
-        bug!("def_path_hash")
-    }
-    fn def_path_table(&self, cnum: CrateNum) -> Rc<DefPathTable> {
-        bug!("def_path_table")
-    }
-    fn struct_field_names(&self, def: DefId) -> Vec<ast::Name> { bug!("struct_field_names") }
-    fn item_children(&self, did: DefId, sess: &Session) -> Vec<def::Export> {
-        bug!("item_children")
-    }
-    fn load_macro(&self, did: DefId, sess: &Session) -> LoadedMacro { bug!("load_macro") }
-
-    // misc. metadata
-    fn item_body<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-                           -> &'tcx hir::Body {
-        bug!("item_body")
-    }
-
-    // This is basically a 1-based range of ints, which is a little
-    // silly - I may fix that.
-    fn crates(&self) -> Vec<CrateNum> { vec![] }
-    fn used_libraries(&self) -> Vec<NativeLibrary> { vec![] }
-    fn used_link_args(&self) -> Vec<String> { vec![] }
-
-    // utility functions
-    fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>
-        { vec![] }
-    fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") }
-    fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> { None }
-    fn encode_metadata<'a, 'tcx>(&self,
-                                 tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                 link_meta: &LinkMeta,
-                                 reachable: &NodeSet)
-                                 -> EncodedMetadata {
-        bug!("encode_metadata")
-    }
-    fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
-
-    // access to the metadata loader
-    fn metadata_loader(&self) -> &MetadataLoader { bug!("metadata_loader") }
-}
-
-pub trait CrateLoader {
-    fn process_item(&mut self, item: &ast::Item, defs: &Definitions);
-    fn postprocess(&mut self, krate: &ast::Crate);
+// This method is used when generating the command line to pass through to
+// system linker. The linker expects undefined symbols on the left of the
+// command line to be defined in libraries on the right, not the other way
+// around. For more info, see some comments in the add_used_library function
+// below.
+//
+// In order to get this left-to-right dependency ordering, we perform a
+// topological sort of all crates putting the leaves at the right-most
+// positions.
+pub fn used_crates(tcx: TyCtxt<'_>, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)> {
+    let mut libs = tcx.crates()
+        .iter()
+        .cloned()
+        .filter_map(|cnum| {
+            if tcx.dep_kind(cnum).macros_only() {
+                return None
+            }
+            let source = tcx.used_crate_source(cnum);
+            let path = match prefer {
+                LinkagePreference::RequireDynamic => source.dylib.clone().map(|p| p.0),
+                LinkagePreference::RequireStatic => source.rlib.clone().map(|p| p.0),
+            };
+            let path = match path {
+                Some(p) => LibSource::Some(p),
+                None => {
+                    if source.rmeta.is_some() {
+                        LibSource::MetadataOnly
+                    } else {
+                        LibSource::None
+                    }
+                }
+            };
+            Some((cnum, path))
+        })
+        .collect::<Vec<_>>();
+    let mut ordering = tcx.postorder_cnums(LOCAL_CRATE).to_owned();
+    ordering.reverse();
+    libs.sort_by_cached_key(|&(a, _)| {
+        ordering.iter().position(|x| *x == a)
+    });
+    libs
 }