]> git.lizzy.rs Git - rust.git/commitdiff
Make metadata references Send + Sync
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>
Sat, 3 Mar 2018 05:17:06 +0000 (06:17 +0100)
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>
Wed, 7 Mar 2018 00:56:59 +0000 (01:56 +0100)
12 files changed:
src/librustc/middle/cstore.rs
src/librustc_data_structures/owning_ref/mod.rs
src/librustc_data_structures/sync.rs
src/librustc_llvm/archive_ro.rs
src/librustc_llvm/lib.rs
src/librustc_metadata/cstore.rs
src/librustc_metadata/lib.rs
src/librustc_metadata/locator.rs
src/librustc_trans/lib.rs
src/librustc_trans/metadata.rs
src/librustc_trans_utils/lib.rs
src/librustc_trans_utils/trans_crate.rs

index 7f068e8f71b4bbbaf9167d1e475ded059a1d7d0b..ea11930ae89d411ec19b61e3f928cd3c1d76013e 100644 (file)
 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)]
index 23e0733748b4acbfa1490144305c6761b238bf10..c466b8f8ad1b5acb716db8b2720dd2cadb25c08f 100644 (file)
@@ -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 @@ pub fn erase_owner<'a>(self) -> OwningRef<O::Erased, 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 @@ fn into_erased(self) -> Self::Erased {
     }
 }
 
-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 {
index b1ab4eaa069246d9c0a602a6b3a44673ef0dd855..69fc9ef785eb791e645c5767f31870983f9b4a3b 100644 (file)
@@ -177,7 +177,7 @@ pub fn take(&self) -> Option<T> {
         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 @@ fn clone(&self) -> Self {
 }
 
 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]
index 6c3626cd880b2f8cedd1d6c9ed05823a46f25a7c..9d8690072709b8670adbe10321b963da977edff3 100644 (file)
@@ -22,6 +22,8 @@ pub struct ArchiveRO {
     ptr: ArchiveRef,
 }
 
+unsafe impl Send for ArchiveRO {}
+
 pub struct Iter<'a> {
     archive: &'a ArchiveRO,
     ptr: ::ArchiveIteratorRef,
index 8dcf7444dd18f919c59026bf1179d2a94f5e869b..16bee5b987e2d0a6b333745e0289f20597cf9685 100644 (file)
@@ -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> {
index 8b59eec0190508017e99b0b0381b7a7bc19bf79c..d5a1771d5353e070797f84a53fee8da2909e8c67 100644 (file)
@@ -24,7 +24,6 @@
 
 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 @@
 // 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.
index 2d015fa81f92548dd45e3855995f6c60541f9427..da0da622d521424a661ac527921bcc5bded126c4 100644 (file)
@@ -39,6 +39,7 @@
 #[macro_use]
 extern crate rustc;
 extern crate rustc_back;
+#[macro_use]
 extern crate rustc_data_structures;
 
 mod diagnostics;
index e0fb924f1aa3e41a38a122e691449c9e19c74386..c56674bd6c5a9b959b0f121f52742fe80fa7bc48 100644 (file)
 //! 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};
 
 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);
index 6cb9d2027c74796f08d13d01cee24f4e39bd4096..960e2ed629a13ad8781b8fdaaded0eab7279e69f 100644 (file)
@@ -51,7 +51,7 @@
 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;
index d57624da0c68df76c053593855bce55843fb9347..9483420f2f0e79f670f0b4251a18f97fd8dce77f 100644 (file)
 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 @@ fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<ErasedBoxRef<
                                 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 @@ fn get_dylib_metadata(&self,
                 .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))
         }
     }
 }
index bfecb2019836656db67549a56e04bd032d638f37..e87ab3abdf8ed42ae4eba5a9ab3441e66bacf406 100644 (file)
@@ -40,7 +40,7 @@
 #[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;
 
index 419371ba3e339b8f148ed3f8d638f79dc255e15b..1e896f261c03e5435d398ad4a835c508696ac6b4 100644 (file)
@@ -28,7 +28,7 @@
 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_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 @@ fn get_rlib_metadata(
         &self,
         _target: &Target,
         _filename: &Path
-    ) -> Result<ErasedBoxRef<[u8]>, String> {
+    ) -> Result<MetadataRef, String> {
         bug!("DummyMetadataLoader::get_rlib_metadata");
     }
 
@@ -127,7 +129,7 @@ fn get_dylib_metadata(
         &self,
         _target: &Target,
         _filename: &Path
-    ) -> Result<ErasedBoxRef<[u8]>, String> {
+    ) -> Result<MetadataRef, String> {
         bug!("DummyMetadataLoader::get_dylib_metadata");
     }
 }
@@ -135,7 +137,7 @@ fn get_dylib_metadata(
 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 @@ fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<ErasedBoxRef<
                 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 @@ fn get_dylib_metadata(
         &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)
     }