about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2018-03-03 06:17:06 +0100
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2018-03-07 01:56:59 +0100
commit62089c335fbdbe2a04c432239dce9e6e8f9a5e8e (patch)
treef87a18a8cd044b24e782e6a5eebb21885d1569fa /src
parente8af0f4c1f121263e55da29854208db0ae1fea54 (diff)
downloadrust-62089c335fbdbe2a04c432239dce9e6e8f9a5e8e.tar.gz
rust-62089c335fbdbe2a04c432239dce9e6e8f9a5e8e.zip
Make metadata references Send + Sync
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/cstore.rs7
-rw-r--r--src/librustc_data_structures/owning_ref/mod.rs47
-rw-r--r--src/librustc_data_structures/sync.rs3
-rw-r--r--src/librustc_llvm/archive_ro.rs2
-rw-r--r--src/librustc_llvm/lib.rs2
-rw-r--r--src/librustc_metadata/cstore.rs5
-rw-r--r--src/librustc_metadata/lib.rs1
-rw-r--r--src/librustc_metadata/locator.rs10
-rw-r--r--src/librustc_trans/lib.rs2
-rw-r--r--src/librustc_trans/metadata.rs12
-rw-r--r--src/librustc_trans_utils/lib.rs2
-rw-r--r--src/librustc_trans_utils/trans_crate.rs14
12 files changed, 76 insertions, 31 deletions
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index 7f068e8f71b..ea11930ae89 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -37,13 +37,12 @@ use util::nodemap::NodeSet;
 use std::any::Any;
 use std::collections::BTreeMap;
 use std::path::{Path, PathBuf};
-use rustc_data_structures::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 rustc_data_structures::sync::Lrc;
+use rustc_data_structures::sync::{MetadataRef, Lrc};
 
 pub use self::NativeLibraryKind::*;
 
@@ -187,11 +186,11 @@ 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>;
 }
 
 #[derive(Clone)]
diff --git a/src/librustc_data_structures/owning_ref/mod.rs b/src/librustc_data_structures/owning_ref/mod.rs
index 23e0733748b..c466b8f8ad1 100644
--- a/src/librustc_data_structures/owning_ref/mod.rs
+++ b/src/librustc_data_structures/owning_ref/mod.rs
@@ -243,6 +243,7 @@ fn main() {
 ```
 */
 
+use std::mem;
 pub use stable_deref_trait::{StableDeref as StableAddress, CloneStableDeref as CloneStableAddress};
 
 /// An owning reference.
@@ -279,7 +280,7 @@ pub struct OwningRefMut<O, T: ?Sized> {
 pub trait Erased {}
 impl<T> Erased for T {}
 
-/// Helper trait for erasing the concrete type of what an owner derferences to,
+/// Helper trait for erasing the concrete type of what an owner dereferences to,
 /// for example `Box<T> -> Box<Erased>`. This would be unneeded with
 /// higher kinded types support in the language.
 pub unsafe trait IntoErased<'a> {
@@ -289,10 +290,20 @@ pub unsafe trait IntoErased<'a> {
     fn into_erased(self) -> Self::Erased;
 }
 
-/// Helper trait for erasing the concrete type of what an owner derferences to,
+/// Helper trait for erasing the concrete type of what an owner dereferences to,
+/// for example `Box<T> -> Box<Erased + Send>`. This would be unneeded with
+/// higher kinded types support in the language.
+pub unsafe trait IntoErasedSend<'a> {
+    /// Owner with the dereference type substituted to `Erased + Send`.
+    type Erased: Send;
+    /// Perform the type erasure.
+    fn into_erased_send(self) -> Self::Erased;
+}
+
+/// Helper trait for erasing the concrete type of what an owner dereferences to,
 /// for example `Box<T> -> Box<Erased + Send + Sync>`. This would be unneeded with
 /// higher kinded types support in the language.
-pub unsafe trait IntoErasedSendSync<'a>: Send + Sync {
+pub unsafe trait IntoErasedSendSync<'a> {
     /// Owner with the dereference type substituted to `Erased + Send + Sync`.
     type Erased: Send + Sync;
     /// Perform the type erasure.
@@ -472,6 +483,18 @@ impl<O, T: ?Sized> OwningRef<O, T> {
         }
     }
 
+    /// Erases the concrete base type of the owner with a trait object which implements `Send`.
+    ///
+    /// This allows mixing of owned references with different owner base types.
+    pub fn erase_send_owner<'a>(self) -> OwningRef<O::Erased, T>
+        where O: IntoErasedSend<'a>,
+    {
+        OwningRef {
+            reference: self.reference,
+            owner: self.owner.into_erased_send(),
+        }
+    }
+
     /// Erases the concrete base type of the owner with a trait object which implements `Send` and `Sync`.
     ///
     /// This allows mixing of owned references with different owner base types.
@@ -1161,13 +1184,25 @@ unsafe impl<'a, T: 'a> IntoErased<'a> for Arc<T> {
     }
 }
 
-unsafe impl<'a, T: Send + Sync + 'a> IntoErasedSendSync<'a> for Box<T> {
-    type Erased = Box<Erased + Send + Sync + 'a>;
-    fn into_erased_send_sync(self) -> Self::Erased {
+unsafe impl<'a, T: Send + 'a> IntoErasedSend<'a> for Box<T> {
+    type Erased = Box<Erased + Send + 'a>;
+    fn into_erased_send(self) -> Self::Erased {
         self
     }
 }
 
+unsafe impl<'a, T: Send + 'a> IntoErasedSendSync<'a> for Box<T> {
+    type Erased = Box<Erased + Sync + Send + 'a>;
+    fn into_erased_send_sync(self) -> Self::Erased {
+        let result: Box<Erased + Send + 'a> = self;
+        // This is safe since Erased can always implement Sync
+        // Only the destructor is available and it takes &mut self
+        unsafe {
+            mem::transmute(result)
+        }
+    }
+}
+
 unsafe impl<'a, T: Send + Sync + 'a> IntoErasedSendSync<'a> for Arc<T> {
     type Erased = Arc<Erased + Send + Sync + 'a>;
     fn into_erased_send_sync(self) -> Self::Erased {
diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs
index b1ab4eaa069..69fc9ef785e 100644
--- a/src/librustc_data_structures/sync.rs
+++ b/src/librustc_data_structures/sync.rs
@@ -177,7 +177,7 @@ cfg_if! {
         macro_rules! rustc_erase_owner {
             ($v:expr) => {{
                 let v = $v;
-                ::rustc_data_structures::sync::assert_send_sync_val(&v);
+                ::rustc_data_structures::sync::assert_send_val(&v);
                 v.erase_send_sync_owner()
             }}
         }
@@ -262,6 +262,7 @@ cfg_if! {
 }
 
 pub fn assert_sync<T: ?Sized + Sync>() {}
+pub fn assert_send_val<T: ?Sized + Send>(_t: &T) {}
 pub fn assert_send_sync_val<T: ?Sized + Sync + Send>(_t: &T) {}
 
 #[macro_export]
diff --git a/src/librustc_llvm/archive_ro.rs b/src/librustc_llvm/archive_ro.rs
index 6c3626cd880..9d869007270 100644
--- a/src/librustc_llvm/archive_ro.rs
+++ b/src/librustc_llvm/archive_ro.rs
@@ -22,6 +22,8 @@ pub struct ArchiveRO {
     ptr: ArchiveRef,
 }
 
+unsafe impl Send for ArchiveRO {}
+
 pub struct Iter<'a> {
     archive: &'a ArchiveRO,
     ptr: ::ArchiveIteratorRef,
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index 8dcf7444dd1..16bee5b987e 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -221,6 +221,8 @@ pub struct ObjectFile {
     pub llof: ObjectFileRef,
 }
 
+unsafe impl Send for ObjectFile {}
+
 impl ObjectFile {
     // This will take ownership of llmb
     pub fn new(llmb: MemoryBufferRef) -> Option<ObjectFile> {
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index 8b59eec0190..d5a1771d535 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -24,7 +24,6 @@ use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap};
 
 use std::cell::{RefCell, Cell};
 use rustc_data_structures::sync::Lrc;
-use rustc_data_structures::owning_ref::ErasedBoxRef;
 use syntax::{ast, attr};
 use syntax::ext::base::SyntaxExtension;
 use syntax::symbol::Symbol;
@@ -42,7 +41,9 @@ pub use cstore_impl::{provide, provide_extern};
 // own crate numbers.
 pub type CrateNumMap = IndexVec<CrateNum, CrateNum>;
 
-pub struct MetadataBlob(pub ErasedBoxRef<[u8]>);
+pub use rustc_data_structures::sync::MetadataRef;
+
+pub struct MetadataBlob(pub MetadataRef);
 
 /// Holds information about a syntax_pos::FileMap imported from another crate.
 /// See `imported_filemaps()` for more information.
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index 2d015fa81f9..da0da622d52 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -39,6 +39,7 @@ extern crate proc_macro;
 #[macro_use]
 extern crate rustc;
 extern crate rustc_back;
+#[macro_use]
 extern crate rustc_data_structures;
 
 mod diagnostics;
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs
index e0fb924f1aa..c56674bd6c5 100644
--- a/src/librustc_metadata/locator.rs
+++ b/src/librustc_metadata/locator.rs
@@ -219,7 +219,7 @@
 //! no means all of the necessary details. Take a look at the rest of
 //! metadata::locator or metadata::creader for all the juicy details!
 
-use cstore::MetadataBlob;
+use cstore::{MetadataRef, MetadataBlob};
 use creader::Library;
 use schema::{METADATA_HEADER, rustc_version};
 
@@ -243,8 +243,8 @@ use std::path::{Path, PathBuf};
 use std::time::Instant;
 
 use flate2::read::DeflateDecoder;
-use rustc_data_structures::owning_ref::{ErasedBoxRef, OwningRef};
 
+use rustc_data_structures::owning_ref::OwningRef;
 pub struct CrateMismatch {
     path: PathBuf,
     got: String,
@@ -842,7 +842,7 @@ fn get_metadata_section_imp(target: &Target,
     if !filename.exists() {
         return Err(format!("no such file: '{}'", filename.display()));
     }
-    let raw_bytes: ErasedBoxRef<[u8]> = match flavor {
+    let raw_bytes: MetadataRef = match flavor {
         CrateFlavor::Rlib => loader.get_rlib_metadata(target, filename)?,
         CrateFlavor::Dylib => {
             let buf = loader.get_dylib_metadata(target, filename)?;
@@ -862,7 +862,7 @@ fn get_metadata_section_imp(target: &Target,
             match DeflateDecoder::new(compressed_bytes).read_to_end(&mut inflated) {
                 Ok(_) => {
                     let buf = unsafe { OwningRef::new_assert_stable_address(inflated) };
-                    buf.map_owner_box().erase_owner()
+                    rustc_erase_owner!(buf.map_owner_box())
                 }
                 Err(_) => {
                     return Err(format!("failed to decompress metadata: {}", filename.display()));
@@ -872,7 +872,7 @@ fn get_metadata_section_imp(target: &Target,
         CrateFlavor::Rmeta => {
             let buf = fs::read(filename).map_err(|_|
                 format!("failed to read rmeta metadata: '{}'", filename.display()))?;
-            OwningRef::new(buf).map_owner_box().erase_owner()
+            rustc_erase_owner!(OwningRef::new(buf).map_owner_box())
         }
     };
     let blob = MetadataBlob(raw_bytes);
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index 6cb9d2027c7..960e2ed629a 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -51,7 +51,7 @@ extern crate rustc_apfloat;
 extern crate rustc_back;
 extern crate rustc_binaryen;
 extern crate rustc_const_math;
-extern crate rustc_data_structures;
+#[macro_use] extern crate rustc_data_structures;
 extern crate rustc_demangle;
 extern crate rustc_incremental;
 extern crate rustc_llvm as llvm;
diff --git a/src/librustc_trans/metadata.rs b/src/librustc_trans/metadata.rs
index d57624da0c6..9483420f2f0 100644
--- a/src/librustc_trans/metadata.rs
+++ b/src/librustc_trans/metadata.rs
@@ -15,17 +15,19 @@ use llvm;
 use llvm::{False, ObjectFile, mk_section_iter};
 use llvm::archive_ro::ArchiveRO;
 
-use rustc_data_structures::owning_ref::{ErasedBoxRef, OwningRef};
+use rustc_data_structures::owning_ref::OwningRef;
 use std::path::Path;
 use std::ptr;
 use std::slice;
 
+pub use rustc_data_structures::sync::MetadataRef;
+
 pub const METADATA_FILENAME: &str = "rust.metadata.bin";
 
 pub struct LlvmMetadataLoader;
 
 impl MetadataLoader for LlvmMetadataLoader {
-    fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<ErasedBoxRef<[u8]>, String> {
+    fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<MetadataRef, String> {
         // Use ArchiveRO for speed here, it's backed by LLVM and uses mmap
         // internally to read the file. We also avoid even using a memcpy by
         // just keeping the archive along while the metadata is in use.
@@ -47,13 +49,13 @@ impl MetadataLoader for LlvmMetadataLoader {
                                 filename.display())
                     })
             })?;
-        Ok(buf.erase_owner())
+        Ok(rustc_erase_owner!(buf))
     }
 
     fn get_dylib_metadata(&self,
                           target: &Target,
                           filename: &Path)
-                          -> Result<ErasedBoxRef<[u8]>, String> {
+                          -> Result<MetadataRef, String> {
         unsafe {
             let buf = common::path2cstr(filename);
             let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr());
@@ -65,7 +67,7 @@ impl MetadataLoader for LlvmMetadataLoader {
                 .ok_or_else(|| format!("provided path not an object file: '{}'",
                                         filename.display()))?;
             let buf = of.try_map(|of| search_meta_section(of, target, filename))?;
-            Ok(buf.erase_owner())
+            Ok(rustc_erase_owner!(buf))
         }
     }
 }
diff --git a/src/librustc_trans_utils/lib.rs b/src/librustc_trans_utils/lib.rs
index bfecb201983..e87ab3abdf8 100644
--- a/src/librustc_trans_utils/lib.rs
+++ b/src/librustc_trans_utils/lib.rs
@@ -40,7 +40,7 @@ extern crate rustc_incremental;
 #[macro_use]
 extern crate syntax;
 extern crate syntax_pos;
-extern crate rustc_data_structures;
+#[macro_use] extern crate rustc_data_structures;
 
 pub extern crate rustc as __rustc;
 
diff --git a/src/librustc_trans_utils/trans_crate.rs b/src/librustc_trans_utils/trans_crate.rs
index 419371ba3e3..1e896f261c0 100644
--- a/src/librustc_trans_utils/trans_crate.rs
+++ b/src/librustc_trans_utils/trans_crate.rs
@@ -28,7 +28,7 @@ use std::fs::File;
 use std::path::Path;
 use std::sync::mpsc;
 
-use rustc_data_structures::owning_ref::{ErasedBoxRef, OwningRef};
+use rustc_data_structures::owning_ref::OwningRef;
 use rustc_data_structures::sync::Lrc;
 use ar::{Archive, Builder, Header};
 use flate2::Compression;
@@ -47,6 +47,8 @@ use rustc_back::target::Target;
 use rustc_mir::monomorphize::collector;
 use link::{build_link_meta, out_filename};
 
+pub use rustc_data_structures::sync::MetadataRef;
+
 pub trait TransCrate {
     fn init(&self, _sess: &Session) {}
     fn print(&self, _req: PrintRequest, _sess: &Session) {}
@@ -119,7 +121,7 @@ impl MetadataLoader for DummyMetadataLoader {
         &self,
         _target: &Target,
         _filename: &Path
-    ) -> Result<ErasedBoxRef<[u8]>, String> {
+    ) -> Result<MetadataRef, String> {
         bug!("DummyMetadataLoader::get_rlib_metadata");
     }
 
@@ -127,7 +129,7 @@ impl MetadataLoader for DummyMetadataLoader {
         &self,
         _target: &Target,
         _filename: &Path
-    ) -> Result<ErasedBoxRef<[u8]>, String> {
+    ) -> Result<MetadataRef, String> {
         bug!("DummyMetadataLoader::get_dylib_metadata");
     }
 }
@@ -135,7 +137,7 @@ impl MetadataLoader for DummyMetadataLoader {
 pub struct NoLlvmMetadataLoader;
 
 impl MetadataLoader for NoLlvmMetadataLoader {
-    fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<ErasedBoxRef<[u8]>, String> {
+    fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<MetadataRef, String> {
         let file = File::open(filename)
             .map_err(|e| format!("metadata file open err: {:?}", e))?;
         let mut archive = Archive::new(file);
@@ -147,7 +149,7 @@ impl MetadataLoader for NoLlvmMetadataLoader {
                 let mut buf = Vec::new();
                 io::copy(&mut entry, &mut buf).unwrap();
                 let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf).into();
-                return Ok(buf.map_owner_box().erase_owner());
+                return Ok(rustc_erase_owner!(buf.map_owner_box()));
             }
         }
 
@@ -158,7 +160,7 @@ impl MetadataLoader for NoLlvmMetadataLoader {
         &self,
         _target: &Target,
         _filename: &Path,
-    ) -> Result<ErasedBoxRef<[u8]>, String> {
+    ) -> Result<MetadataRef, String> {
         // FIXME: Support reading dylibs from llvm enabled rustc
         self.get_rlib_metadata(_target, _filename)
     }