Skip to content

Commit

Permalink
Fix unecessarily gapingly large soundness hole.
Browse files Browse the repository at this point in the history
  • Loading branch information
purpleposeidon committed Feb 4, 2021
1 parent 1a734ef commit 18847c5
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "v9"
version = "0.1.42"
version = "0.1.43"
authors = ["neptunepink <purpleposeidon@gmail.com>"]
edition = "2018"
license = "MIT/Apache-2.0"
Expand Down
12 changes: 11 additions & 1 deletion src/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,27 @@ use std::cmp::Ordering;

type Run<M> = (Id<M>, Id<M>);

pub trait Raw: 'static + Copy + fmt::Debug + Ord + Send + Sync + hash::Hash + serde::Serialize + serde::de::DeserializeOwned + Add<Output=Self> + Sub<Output=Self> {
pub trait Raw
where
Self: 'static + Send + Sync,
Self: Ord + Copy + fmt::Debug + hash::Hash,
Self: serde::Serialize + serde::de::DeserializeOwned,
Self: Add<Output=Self> + Sub<Output=Self>,
Self: self::raw_impl::Sealed,
{
fn to_usize(self) -> usize;
fn from_usize(x: usize) -> Self;
fn offset(self, d: i8) -> Self;
const ZERO: Self;
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 }
Expand Down
29 changes: 22 additions & 7 deletions src/util.rs
Original file line number Diff line number Diff line change
@@ -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<T> {
val: RefCell<T>,
}
impl<T> SyncRef<T> {
pub fn new(val: T) -> Self {
impl<T: TableMarker> SyncRef<RunList<T>> {
pub fn new(val: RunList<T>) -> Self {
SyncRef {
val: RefCell::new(val),
}
}
pub fn get_mut(&mut self) -> &mut T {
pub fn get_mut(&mut self) -> &mut RunList<T> {
self.val.get_mut()
}
pub fn as_cell(&mut self) -> &RefCell<T> {
pub fn as_cell(&mut self) -> &RefCell<RunList<T>> {
&self.val
}
pub unsafe fn as_cell_unsafe(&self) -> &RefCell<T> {
pub unsafe fn as_cell_unsafe(&self) -> &RefCell<RunList<T>> {
&self.val
}
}
// Trying to impl Deref/DerefMut provokes odd curiosities.
unsafe impl<T: Send> Send for SyncRef<T> {}
unsafe impl<T> Sync for SyncRef<T> {}
unsafe impl<T: TableMarker> Send for SyncRef<RunList<T>> {}
unsafe impl<T: TableMarker> Sync for SyncRef<RunList<T>> {}
// 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: Send + Sync>(_: 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> {
Expand Down

0 comments on commit 18847c5

Please sign in to comment.