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::*;
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)]
```
*/
+use std::mem;
pub use stable_deref_trait::{StableDeref as StableAddress, CloneStableDeref as CloneStableAddress};
/// An owning reference.
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> {
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.
}
}
+ /// 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.
}
}
-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 {
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()
}}
}
}
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]
ptr: ArchiveRef,
}
+unsafe impl Send for ArchiveRO {}
+
pub struct Iter<'a> {
archive: &'a ArchiveRO,
ptr: ::ArchiveIteratorRef,
pub llof: ObjectFileRef,
}
+unsafe impl Send for ObjectFile {}
+
impl ObjectFile {
// This will take ownership of llmb
pub fn new(llmb: MemoryBufferRef) -> Option<ObjectFile> {
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;
// 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.
#[macro_use]
extern crate rustc;
extern crate rustc_back;
+#[macro_use]
extern crate rustc_data_structures;
mod diagnostics;
//! 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,
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)?;
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()));
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);
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;
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.
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());
.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))
}
}
}
#[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;
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;
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) {}
&self,
_target: &Target,
_filename: &Path
- ) -> Result<ErasedBoxRef<[u8]>, String> {
+ ) -> Result<MetadataRef, String> {
bug!("DummyMetadataLoader::get_rlib_metadata");
}
&self,
_target: &Target,
_filename: &Path
- ) -> Result<ErasedBoxRef<[u8]>, String> {
+ ) -> Result<MetadataRef, String> {
bug!("DummyMetadataLoader::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);
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()));
}
}
&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)
}