diff --git a/Cargo.toml b/Cargo.toml index a6c95cc..85fadee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "v9" -version = "0.1.42" +version = "0.1.43" authors = ["neptunepink "] edition = "2018" license = "MIT/Apache-2.0" diff --git a/src/id.rs b/src/id.rs index d4f1ccf..1eb18a7 100644 --- a/src/id.rs +++ b/src/id.rs @@ -11,7 +11,14 @@ use std::cmp::Ordering; type Run = (Id, Id); -pub trait Raw: 'static + Copy + fmt::Debug + Ord + Send + Sync + hash::Hash + serde::Serialize + serde::de::DeserializeOwned + Add + Sub { +pub trait Raw +where + Self: 'static + Send + Sync, + Self: Ord + Copy + fmt::Debug + hash::Hash, + Self: serde::Serialize + serde::de::DeserializeOwned, + Self: Add + Sub, + Self: self::raw_impl::Sealed, +{ fn to_usize(self) -> usize; fn from_usize(x: usize) -> Self; fn offset(self, d: i8) -> Self; @@ -19,9 +26,12 @@ pub trait Raw: 'static + Copy + fmt::Debug + Ord + Send + Sync + hash::Hash + se const LAST: Self; } mod raw_impl { + /// Forbid non-primitives from being put into a SyncRef. + pub trait Sealed {} use super::Raw; macro_rules! imp { ($($ty:ident),*) => {$( + impl Sealed for $ty {} impl Raw for $ty { #[inline] fn to_usize(self) -> usize { self as usize } diff --git a/src/util.rs b/src/util.rs index 99500b4..b368395 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,32 +1,47 @@ use std::cell::RefCell; use std::ops::Deref; +use crate::prelude_lib::RunList; +use crate::table::TableMarker; /// A `Sync`able `RefCell`. #[derive(Default, Debug, Clone)] pub struct SyncRef { val: RefCell, } -impl SyncRef { - pub fn new(val: T) -> Self { +impl SyncRef> { + pub fn new(val: RunList) -> Self { SyncRef { val: RefCell::new(val), } } - pub fn get_mut(&mut self) -> &mut T { + pub fn get_mut(&mut self) -> &mut RunList { self.val.get_mut() } - pub fn as_cell(&mut self) -> &RefCell { + pub fn as_cell(&mut self) -> &RefCell> { &self.val } - pub unsafe fn as_cell_unsafe(&self) -> &RefCell { + pub unsafe fn as_cell_unsafe(&self) -> &RefCell> { &self.val } } // Trying to impl Deref/DerefMut provokes odd curiosities. -unsafe impl Send for SyncRef {} -unsafe impl Sync for SyncRef {} +unsafe impl Send for SyncRef> {} +unsafe impl Sync for SyncRef> {} // FIXME: Ugh, this is probably unsound. +/// ```compile_fail +/// use std::cell::Cell; +/// use v9::util::SyncRef; +/// +/// fn main() { +/// let sync_ref = SyncRef::new(Cell::new(0)); +/// fn check(_: T) {} +/// check(sync_ref); +/// } +/// ``` +#[cfg(doctest)] +struct SyncRefSyncless; + /// A `&mut T` that pretends it's a `&T`. pub struct MutButRef<'a, T>(&'a mut T); impl<'a, T> MutButRef<'a, T> {