diff --git a/.forgejo/workflows/test.yml b/.forgejo/workflows/test.yml index 001168f..7a69a7e 100644 --- a/.forgejo/workflows/test.yml +++ b/.forgejo/workflows/test.yml @@ -16,6 +16,7 @@ jobs: - uses: https://git.libre-chip.org/mirrors/rust-cache@v2 with: save-if: ${{ github.ref == 'refs/heads/master' }} + - run: rustup override set 1.93.0 - run: cargo test - run: cargo build --tests --features=unstable-doc - run: cargo test --doc --features=unstable-doc diff --git a/Cargo.toml b/Cargo.toml index 6559e2a..504d90f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ edition = "2024" repository = "https://git.libre-chip.org/libre-chip/fayalite" keywords = ["hdl", "hardware", "semiconductors", "firrtl", "fpga"] categories = ["simulation", "development-tools", "compilers"] -rust-version = "1.89.0" +rust-version = "1.93.0" [workspace.dependencies] fayalite-proc-macros = { version = "=0.3.0", path = "crates/fayalite-proc-macros" } diff --git a/crates/fayalite/src/array.rs b/crates/fayalite/src/array.rs index 4e2b223..6ca6809 100644 --- a/crates/fayalite/src/array.rs +++ b/crates/fayalite/src/array.rs @@ -109,14 +109,42 @@ impl Default for ArrayType { } } +struct MakeType(Interned); + +impl From> for Interned { + fn from(value: MakeType) -> Self { + value.0 + } +} + +impl Default for MakeType { + fn default() -> Self { + Self(T::TYPE.intern_sized()) + } +} + +struct MakeMaskType(Interned); + +impl From> for Interned { + fn from(value: MakeMaskType) -> Self { + value.0 + } +} + +impl Default for MakeMaskType { + fn default() -> Self { + Self(T::MASK_TYPE.intern_sized()) + } +} + impl StaticType for ArrayType { const TYPE: Self = Self { - element: LazyInterned::new_lazy(&|| T::TYPE.intern_sized()), + element: LazyInterned::new_const::>(), len: Len::SIZE, type_properties: Self::TYPE_PROPERTIES, }; const MASK_TYPE: Self::MaskType = ArrayType:: { - element: LazyInterned::new_lazy(&|| T::MASK_TYPE.intern_sized()), + element: LazyInterned::new_const::>(), len: Len::SIZE, type_properties: Self::MASK_TYPE_PROPERTIES, }; diff --git a/crates/fayalite/src/intern.rs b/crates/fayalite/src/intern.rs index 9ffd251..b78aa59 100644 --- a/crates/fayalite/src/intern.rs +++ b/crates/fayalite/src/intern.rs @@ -9,12 +9,12 @@ use serde::{Deserialize, Serialize}; use std::{ any::{Any, TypeId}, borrow::{Borrow, Cow}, + cell::RefCell, cmp::Ordering, ffi::{OsStr, OsString}, fmt, hash::{BuildHasher, Hash, Hasher}, iter::FusedIterator, - marker::PhantomData, ops::Deref, path::{Path, PathBuf}, sync::RwLock, @@ -23,51 +23,172 @@ use std::{ mod interner; mod type_map; -pub trait LazyInternedTrait: Send + Sync + Any { - fn get(&self) -> Interned; +/// invariant: T must be zero-sized, `type_id` is unique for every possible T value. +struct LazyInternedLazyInner { + type_id: TypeId, + value: T, } -impl Interned + Send + Sync + Any> - LazyInternedTrait for F -{ - fn get(&self) -> Interned { - self() +impl Hash for LazyInternedLazyInner { + fn hash(&self, state: &mut H) { + let Self { type_id, value: _ } = self; + type_id.hash(state); } } -#[repr(transparent)] -pub struct LazyInternedFn(pub &'static dyn LazyInternedTrait); +impl PartialEq for LazyInternedLazyInner { + fn eq(&self, other: &Self) -> bool { + let Self { type_id, value: _ } = self; + *type_id == other.type_id + } +} -impl Copy for LazyInternedFn {} +impl Eq for LazyInternedLazyInner {} -impl Clone for LazyInternedFn { +impl fmt::Debug for LazyInternedLazyInner { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("LazyInternedLazyInner") + .finish_non_exhaustive() + } +} + +impl LazyInternedLazyInner { + const fn new(value: T) -> Self + where + T: Sized, + { + const { assert!(size_of::() == 0) }; + Self { + type_id: TypeId::of::(), + value, + } + } +} + +pub struct LazyInternedLazy( + &'static LazyInternedLazyInner Interned + Send + Sync>, +); + +impl LazyInternedLazy { + pub const fn new_const>>() -> Self { + Self(&const { LazyInternedLazyInner::new(|| V::default().into()) }) + } + pub const fn new_const_default() -> Self + where + Interned: Default, + { + Self::new_const::>() + } + pub fn interned(self) -> Interned { + struct Map(hashbrown::HashTable<(TypeId, &'static (dyn Any + Send + Sync))>); + impl Map { + const EMPTY: Self = Self(hashbrown::HashTable::new()); + fn get( + &self, + lazy_interned_lazy: LazyInternedLazy, + hash: u64, + ) -> Option<&'static Interned> { + let &(_, v) = self.0.find(hash, |v| v.0 == lazy_interned_lazy.0.type_id)?; + let Some(retval) = v.downcast_ref::>() else { + unreachable!(); + }; + Some(retval) + } + fn get_or_insert( + &mut self, + lazy_interned_lazy: LazyInternedLazy, + hash: u64, + v: &'static Interned, + ) -> &'static Interned { + let entry = self + .0 + .entry( + hash, + |&(k, _)| k == lazy_interned_lazy.0.type_id, + |&(k, _)| type_map::TypeIdBuildHasher.hash_one(k), + ) + .or_insert_with(|| (lazy_interned_lazy.0.type_id, v)); + let &(_, v) = entry.get(); + let Some(retval) = v.downcast_ref::>() else { + unreachable!(); + }; + retval + } + } + static GLOBAL_CACHE: RwLock = RwLock::new(Map::EMPTY); + #[cold] + fn insert_in_thread_local_cache( + cache: &RefCell, + this: LazyInternedLazy, + hash: u64, + ) -> Interned { + let read_lock = GLOBAL_CACHE.read().unwrap(); + let v = read_lock.get(this, hash); + drop(read_lock); + let v = v.unwrap_or_else(|| { + let v = Box::leak(Box::new((this.0.value)())); + GLOBAL_CACHE.write().unwrap().get_or_insert(this, hash, v) + }); + *cache.borrow_mut().get_or_insert(this, hash, v) + } + thread_local! { + static THREAD_LOCAL_CACHE: RefCell = const { RefCell::new(Map::EMPTY) }; + } + let hash = type_map::TypeIdBuildHasher.hash_one(self.0.type_id); + THREAD_LOCAL_CACHE.with(|cache| { + let borrow = cache.borrow(); + if let Some(v) = borrow.get(self, hash) { + *v + } else { + drop(borrow); + insert_in_thread_local_cache(cache, self, hash) + } + }) + } +} + +impl Copy for LazyInternedLazy {} + +impl Clone for LazyInternedLazy { fn clone(&self) -> Self { *self } } -impl Hash for LazyInternedFn { +impl Hash for LazyInternedLazy { fn hash(&self, state: &mut H) { - self.0.get_ptr_eq_with_type_id().hash(state); + self.0.hash(state); } } -impl Eq for LazyInternedFn {} +impl Eq for LazyInternedLazy {} -impl PartialEq for LazyInternedFn { +impl PartialEq for LazyInternedLazy { fn eq(&self, other: &Self) -> bool { - self.0.get_ptr_eq_with_type_id() == other.0.get_ptr_eq_with_type_id() + self.0 == other.0 } } pub enum LazyInterned { Interned(Interned), - Lazy(LazyInternedFn), + Lazy(LazyInternedLazy), } impl LazyInterned { - pub const fn new_lazy(v: &'static dyn LazyInternedTrait) -> Self { - Self::Lazy(LazyInternedFn(v)) + pub const fn new_const>>() -> Self { + Self::Lazy(LazyInternedLazy::new_const::()) + } + pub const fn new_const_default() -> Self + where + Interned: Default, + { + Self::new_const::>() + } + pub fn interned(self) -> Interned { + match self { + Self::Interned(retval) => retval, + Self::Lazy(retval) => retval.interned(), + } } } @@ -79,7 +200,7 @@ impl Clone for LazyInterned { impl Copy for LazyInterned {} -impl Deref for LazyInterned { +impl Deref for LazyInterned { type Target = T; fn deref(&self) -> &Self::Target { @@ -87,9 +208,9 @@ impl Deref for LazyInterned { } } -impl Eq for LazyInterned where Interned: Eq {} +impl Eq for LazyInterned where Interned: Eq {} -impl PartialEq for LazyInterned +impl PartialEq for LazyInterned where Interned: PartialEq, { @@ -98,7 +219,7 @@ where } } -impl Ord for LazyInterned +impl Ord for LazyInterned where Interned: Ord, { @@ -107,7 +228,7 @@ where } } -impl PartialOrd for LazyInterned +impl PartialOrd for LazyInterned where Interned: PartialOrd, { @@ -116,7 +237,7 @@ where } } -impl Hash for LazyInterned +impl Hash for LazyInterned where Interned: Hash, { @@ -125,77 +246,6 @@ where } } -impl LazyInterned { - pub fn interned(self) -> Interned - where - T: Intern, - { - struct MemoizeInterned(PhantomData); - - impl Hash for MemoizeInterned { - fn hash(&self, _state: &mut H) {} - } - - impl PartialEq for MemoizeInterned { - fn eq(&self, _other: &Self) -> bool { - true - } - } - - impl Eq for MemoizeInterned {} - - impl Clone for MemoizeInterned { - fn clone(&self) -> Self { - *self - } - } - - impl Copy for MemoizeInterned {} - - impl MemoizeGeneric for MemoizeInterned { - type InputRef<'a> = LazyInternedFn; - - type InputOwned = LazyInternedFn; - - type InputCow<'a> = LazyInternedFn; - - type Output = Interned; - - fn input_eq(a: Self::InputRef<'_>, b: Self::InputRef<'_>) -> bool { - a == b - } - - fn input_borrow(input: &Self::InputOwned) -> Self::InputRef<'_> { - *input - } - - fn input_cow_into_owned(input: Self::InputCow<'_>) -> Self::InputOwned { - input - } - - fn input_cow_borrow<'a>(input: &'a Self::InputCow<'_>) -> Self::InputRef<'a> { - *input - } - - fn input_cow_from_owned<'a>(input: Self::InputOwned) -> Self::InputCow<'a> { - input - } - - fn input_cow_from_ref(input: Self::InputRef<'_>) -> Self::InputCow<'_> { - input - } - - fn inner(self, input: Self::InputRef<'_>) -> Self::Output { - input.0.get() - } - } - match self { - Self::Interned(retval) => retval, - Self::Lazy(retval) => MemoizeInterned(PhantomData).get(retval), - } - } -} - pub trait InternedCompare { type InternedCompareKey: Ord + Hash; fn interned_compare_key_ref(this: &Self) -> Self::InternedCompareKey; diff --git a/crates/fayalite/src/intern/type_map.rs b/crates/fayalite/src/intern/type_map.rs index 03b68e3..e31a5bf 100644 --- a/crates/fayalite/src/intern/type_map.rs +++ b/crates/fayalite/src/intern/type_map.rs @@ -6,7 +6,7 @@ use std::{ sync::RwLock, }; -struct TypeIdHasher(u64); +pub(crate) struct TypeIdHasher(u64); // assumes TypeId has at least 64 bits that is a good hash impl Hasher for TypeIdHasher { @@ -63,7 +63,7 @@ impl Hasher for TypeIdHasher { } } -struct TypeIdBuildHasher; +pub(crate) struct TypeIdBuildHasher; impl BuildHasher for TypeIdBuildHasher { type Hasher = TypeIdHasher; diff --git a/crates/fayalite/src/phantom_const.rs b/crates/fayalite/src/phantom_const.rs index 32e9d6b..fb7be6f 100644 --- a/crates/fayalite/src/phantom_const.rs +++ b/crates/fayalite/src/phantom_const.rs @@ -4,7 +4,7 @@ use crate::{ expr::{Expr, HdlPartialEqImpl, HdlPartialOrdImpl, ToExpr, ValueType}, int::Bool, - intern::{Intern, Interned, InternedCompare, LazyInterned, LazyInternedTrait, Memoize}, + intern::{Intern, Interned, InternedCompare, LazyInterned, Memoize}, sim::value::{SimValue, ToSimValue, ToSimValueWithType}, source_location::SourceLocation, ty::{ @@ -240,11 +240,17 @@ impl PhantomConst { { Self::new_interned(value.intern_deref()) } - pub const fn new_lazy(v: &'static dyn LazyInternedTrait) -> Self { + pub const fn new_const>>() -> Self { Self { - value: LazyInterned::new_lazy(v), + value: LazyInterned::new_const::(), } } + pub const fn new_const_default() -> Self + where + Interned: Default, + { + Self::new_const::>() + } pub fn get(self) -> Interned { self.value.interned() } @@ -334,9 +340,7 @@ impl StaticType for PhantomConst where Interned: Default, { - const TYPE: Self = PhantomConst { - value: LazyInterned::new_lazy(&Interned::::default), - }; + const TYPE: Self = Self::new_const_default(); const MASK_TYPE: Self::MaskType = (); const TYPE_PROPERTIES: TypeProperties = <()>::TYPE_PROPERTIES; const MASK_TYPE_PROPERTIES: TypeProperties = <()>::TYPE_PROPERTIES; diff --git a/crates/fayalite/tests/ui/simvalue_is_not_internable.stderr b/crates/fayalite/tests/ui/simvalue_is_not_internable.stderr index 7191e5e..987cfd0 100644 --- a/crates/fayalite/tests/ui/simvalue_is_not_internable.stderr +++ b/crates/fayalite/tests/ui/simvalue_is_not_internable.stderr @@ -1,107 +1,95 @@ error[E0277]: `Cell` cannot be shared between threads safely - --> tests/ui/simvalue_is_not_internable.rs:11:26 - | -11 | fn f(v: SimValue<()>) -> Interned> { - | ^^^^^^^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely - | - = help: within `fayalite::prelude::SimValue<()>`, the trait `Sync` is not implemented for `Cell` - = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` + --> tests/ui/simvalue_is_not_internable.rs:11:26 + | + 11 | fn f(v: SimValue<()>) -> Interned> { + | ^^^^^^^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely + | + = help: within `fayalite::prelude::SimValue<()>`, the trait `Sync` is not implemented for `Cell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` note: required because it appears within the type `util::alternating_cell::AlternatingCell>` - --> src/util/alternating_cell.rs - | - | pub(crate) struct AlternatingCell { - | ^^^^^^^^^^^^^^^ + --> src/util/alternating_cell.rs + | + 22 | pub(crate) struct AlternatingCell { + | ^^^^^^^^^^^^^^^ note: required because it appears within the type `fayalite::prelude::SimValue<()>` - --> src/sim/value.rs - | - | pub struct SimValue { - | ^^^^^^^^ + --> src/sim/value.rs + | + | pub struct SimValue { + | ^^^^^^^^ note: required by a bound in `fayalite::intern::Interned` - --> src/intern.rs - | - | pub struct Interned { - | ^^^^ required by this bound in `Interned` + --> src/intern.rs + | + | pub struct Interned { + | ^^^^ required by this bound in `Interned` error[E0277]: `UnsafeCell>` cannot be shared between threads safely - --> tests/ui/simvalue_is_not_internable.rs:11:26 - | -11 | fn f(v: SimValue<()>) -> Interned> { - | ^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell>` cannot be shared between threads safely - | - = help: within `fayalite::prelude::SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>` + --> tests/ui/simvalue_is_not_internable.rs:11:26 + | + 11 | fn f(v: SimValue<()>) -> Interned> { + | ^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell>` cannot be shared between threads safely + | + = help: within `fayalite::prelude::SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>` note: required because it appears within the type `util::alternating_cell::AlternatingCell>` - --> src/util/alternating_cell.rs - | - | pub(crate) struct AlternatingCell { - | ^^^^^^^^^^^^^^^ + --> src/util/alternating_cell.rs + | + 22 | pub(crate) struct AlternatingCell { + | ^^^^^^^^^^^^^^^ note: required because it appears within the type `fayalite::prelude::SimValue<()>` - --> src/sim/value.rs - | - | pub struct SimValue { - | ^^^^^^^^ + --> src/sim/value.rs + | + | pub struct SimValue { + | ^^^^^^^^ note: required by a bound in `fayalite::intern::Interned` - --> src/intern.rs - | - | pub struct Interned { - | ^^^^ required by this bound in `Interned` + --> src/intern.rs + | + | pub struct Interned { + | ^^^^ required by this bound in `Interned` error[E0277]: `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` cannot be sent between threads safely - --> tests/ui/simvalue_is_not_internable.rs:11:26 - | -11 | fn f(v: SimValue<()>) -> Interned> { - | ^^^^^^^^^^^^^^^^^^^^^^ `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` cannot be sent between threads safely - | - = help: within `fayalite::prelude::SimValue<()>`, the trait `Send` is not implemented for `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` + --> tests/ui/simvalue_is_not_internable.rs:11:26 + | + 11 | fn f(v: SimValue<()>) -> Interned> { + | ^^^^^^^^^^^^^^^^^^^^^^ `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` cannot be sent between threads safely + | + = help: within `fayalite::prelude::SimValue<()>`, the trait `Send` is not implemented for `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` note: required because it appears within the type `DynSimOnlyValue` - --> src/sim/value/sim_only_value_unsafe.rs - | - | pub struct DynSimOnlyValue(Rc); - | ^^^^^^^^^^^^^^^ + --> src/sim/value/sim_only_value_unsafe.rs + | + | pub struct DynSimOnlyValue(Rc); + | ^^^^^^^^^^^^^^^ note: required because it appears within the type `PhantomData` - --> $RUST/core/src/marker.rs - | - | pub struct PhantomData; - | ^^^^^^^^^^^ + --> $RUST/core/src/marker.rs note: required because it appears within the type `alloc::raw_vec::RawVec` - --> $RUST/alloc/src/raw_vec/mod.rs - | - | pub(crate) struct RawVec { - | ^^^^^^ + --> $RUST/alloc/src/raw_vec/mod.rs note: required because it appears within the type `Vec` - --> $RUST/alloc/src/vec/mod.rs - | - | pub struct Vec { - | ^^^ + --> $RUST/alloc/src/vec/mod.rs note: required because it appears within the type `OpaqueSimValue` - --> src/ty.rs - | - | pub struct OpaqueSimValue { - | ^^^^^^^^^^^^^^ + --> src/ty.rs + | + | pub struct OpaqueSimValue { + | ^^^^^^^^^^^^^^ note: required because it appears within the type `value::SimValueInner<()>` - --> src/sim/value.rs - | - | struct SimValueInner { - | ^^^^^^^^^^^^^ + --> src/sim/value.rs + | + 51 | struct SimValueInner { + | ^^^^^^^^^^^^^ note: required because it appears within the type `UnsafeCell>` - --> $RUST/core/src/cell.rs - | - | pub struct UnsafeCell { - | ^^^^^^^^^^ + --> $RUST/core/src/cell.rs note: required because it appears within the type `util::alternating_cell::AlternatingCell>` - --> src/util/alternating_cell.rs - | - | pub(crate) struct AlternatingCell { - | ^^^^^^^^^^^^^^^ + --> src/util/alternating_cell.rs + | + 22 | pub(crate) struct AlternatingCell { + | ^^^^^^^^^^^^^^^ note: required because it appears within the type `fayalite::prelude::SimValue<()>` - --> src/sim/value.rs - | - | pub struct SimValue { - | ^^^^^^^^ + --> src/sim/value.rs + | + | pub struct SimValue { + | ^^^^^^^^ note: required by a bound in `fayalite::intern::Interned` - --> src/intern.rs - | - | pub struct Interned { - | ^^^^ required by this bound in `Interned` + --> src/intern.rs + | + | pub struct Interned { + | ^^^^ required by this bound in `Interned` error[E0277]: the trait bound `fayalite::prelude::SimValue<()>: Intern` is not satisfied --> tests/ui/simvalue_is_not_internable.rs:12:26 @@ -118,238 +106,214 @@ help: consider dereferencing here | + error[E0277]: `Cell` cannot be shared between threads safely - --> tests/ui/simvalue_is_not_internable.rs:12:26 - | -12 | Intern::intern_sized(v) - | -------------------- ^ `Cell` cannot be shared between threads safely - | | - | required by a bound introduced by this call - | - = help: within `fayalite::prelude::SimValue<()>`, the trait `Sync` is not implemented for `Cell` - = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` + --> tests/ui/simvalue_is_not_internable.rs:12:26 + | + 12 | Intern::intern_sized(v) + | -------------------- ^ `Cell` cannot be shared between threads safely + | | + | required by a bound introduced by this call + | + = help: within `fayalite::prelude::SimValue<()>`, the trait `Sync` is not implemented for `Cell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` note: required because it appears within the type `util::alternating_cell::AlternatingCell>` - --> src/util/alternating_cell.rs - | - | pub(crate) struct AlternatingCell { - | ^^^^^^^^^^^^^^^ + --> src/util/alternating_cell.rs + | + 22 | pub(crate) struct AlternatingCell { + | ^^^^^^^^^^^^^^^ note: required because it appears within the type `fayalite::prelude::SimValue<()>` - --> src/sim/value.rs - | - | pub struct SimValue { - | ^^^^^^^^ + --> src/sim/value.rs + | + | pub struct SimValue { + | ^^^^^^^^ note: required by a bound in `intern_sized` - --> src/intern.rs - | - | pub trait Intern: Any + Send + Sync { - | ^^^^ required by this bound in `Intern::intern_sized` + --> src/intern.rs + | + | pub trait Intern: Any + Send + Sync { + | ^^^^ required by this bound in `Intern::intern_sized` ... - | fn intern_sized(self) -> Interned - | ------------ required by a bound in this associated function + | fn intern_sized(self) -> Interned + | ------------ required by a bound in this associated function help: consider dereferencing here - | -12 | Intern::intern_sized(*v) - | + + | + 12 | Intern::intern_sized(*v) + | + error[E0277]: `UnsafeCell>` cannot be shared between threads safely - --> tests/ui/simvalue_is_not_internable.rs:12:26 - | -12 | Intern::intern_sized(v) - | -------------------- ^ `UnsafeCell>` cannot be shared between threads safely - | | - | required by a bound introduced by this call - | - = help: within `fayalite::prelude::SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>` + --> tests/ui/simvalue_is_not_internable.rs:12:26 + | + 12 | Intern::intern_sized(v) + | -------------------- ^ `UnsafeCell>` cannot be shared between threads safely + | | + | required by a bound introduced by this call + | + = help: within `fayalite::prelude::SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>` note: required because it appears within the type `util::alternating_cell::AlternatingCell>` - --> src/util/alternating_cell.rs - | - | pub(crate) struct AlternatingCell { - | ^^^^^^^^^^^^^^^ + --> src/util/alternating_cell.rs + | + 22 | pub(crate) struct AlternatingCell { + | ^^^^^^^^^^^^^^^ note: required because it appears within the type `fayalite::prelude::SimValue<()>` - --> src/sim/value.rs - | - | pub struct SimValue { - | ^^^^^^^^ + --> src/sim/value.rs + | + | pub struct SimValue { + | ^^^^^^^^ note: required by a bound in `intern_sized` - --> src/intern.rs - | - | pub trait Intern: Any + Send + Sync { - | ^^^^ required by this bound in `Intern::intern_sized` + --> src/intern.rs + | + | pub trait Intern: Any + Send + Sync { + | ^^^^ required by this bound in `Intern::intern_sized` ... - | fn intern_sized(self) -> Interned - | ------------ required by a bound in this associated function + | fn intern_sized(self) -> Interned + | ------------ required by a bound in this associated function help: consider dereferencing here - | -12 | Intern::intern_sized(*v) - | + + | + 12 | Intern::intern_sized(*v) + | + error[E0277]: `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` cannot be sent between threads safely - --> tests/ui/simvalue_is_not_internable.rs:12:26 - | -12 | Intern::intern_sized(v) - | -------------------- ^ `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` cannot be sent between threads safely - | | - | required by a bound introduced by this call - | - = help: within `fayalite::prelude::SimValue<()>`, the trait `Send` is not implemented for `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` + --> tests/ui/simvalue_is_not_internable.rs:12:26 + | + 12 | Intern::intern_sized(v) + | -------------------- ^ `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` cannot be sent between threads safely + | | + | required by a bound introduced by this call + | + = help: within `fayalite::prelude::SimValue<()>`, the trait `Send` is not implemented for `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` note: required because it appears within the type `DynSimOnlyValue` - --> src/sim/value/sim_only_value_unsafe.rs - | - | pub struct DynSimOnlyValue(Rc); - | ^^^^^^^^^^^^^^^ + --> src/sim/value/sim_only_value_unsafe.rs + | + | pub struct DynSimOnlyValue(Rc); + | ^^^^^^^^^^^^^^^ note: required because it appears within the type `PhantomData` - --> $RUST/core/src/marker.rs - | - | pub struct PhantomData; - | ^^^^^^^^^^^ + --> $RUST/core/src/marker.rs note: required because it appears within the type `alloc::raw_vec::RawVec` - --> $RUST/alloc/src/raw_vec/mod.rs - | - | pub(crate) struct RawVec { - | ^^^^^^ + --> $RUST/alloc/src/raw_vec/mod.rs note: required because it appears within the type `Vec` - --> $RUST/alloc/src/vec/mod.rs - | - | pub struct Vec { - | ^^^ + --> $RUST/alloc/src/vec/mod.rs note: required because it appears within the type `OpaqueSimValue` - --> src/ty.rs - | - | pub struct OpaqueSimValue { - | ^^^^^^^^^^^^^^ + --> src/ty.rs + | + | pub struct OpaqueSimValue { + | ^^^^^^^^^^^^^^ note: required because it appears within the type `value::SimValueInner<()>` - --> src/sim/value.rs - | - | struct SimValueInner { - | ^^^^^^^^^^^^^ + --> src/sim/value.rs + | + 51 | struct SimValueInner { + | ^^^^^^^^^^^^^ note: required because it appears within the type `UnsafeCell>` - --> $RUST/core/src/cell.rs - | - | pub struct UnsafeCell { - | ^^^^^^^^^^ + --> $RUST/core/src/cell.rs note: required because it appears within the type `util::alternating_cell::AlternatingCell>` - --> src/util/alternating_cell.rs - | - | pub(crate) struct AlternatingCell { - | ^^^^^^^^^^^^^^^ + --> src/util/alternating_cell.rs + | + 22 | pub(crate) struct AlternatingCell { + | ^^^^^^^^^^^^^^^ note: required because it appears within the type `fayalite::prelude::SimValue<()>` - --> src/sim/value.rs - | - | pub struct SimValue { - | ^^^^^^^^ + --> src/sim/value.rs + | + | pub struct SimValue { + | ^^^^^^^^ note: required by a bound in `intern_sized` - --> src/intern.rs - | - | pub trait Intern: Any + Send + Sync { - | ^^^^ required by this bound in `Intern::intern_sized` + --> src/intern.rs + | + | pub trait Intern: Any + Send + Sync { + | ^^^^ required by this bound in `Intern::intern_sized` ... - | fn intern_sized(self) -> Interned - | ------------ required by a bound in this associated function + | fn intern_sized(self) -> Interned + | ------------ required by a bound in this associated function help: consider dereferencing here - | -12 | Intern::intern_sized(*v) - | + + | + 12 | Intern::intern_sized(*v) + | + error[E0277]: `Cell` cannot be shared between threads safely - --> tests/ui/simvalue_is_not_internable.rs:12:5 - | -12 | Intern::intern_sized(v) - | ^^^^^^^^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely - | - = help: within `fayalite::prelude::SimValue<()>`, the trait `Sync` is not implemented for `Cell` - = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` + --> tests/ui/simvalue_is_not_internable.rs:12:5 + | + 12 | Intern::intern_sized(v) + | ^^^^^^^^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely + | + = help: within `fayalite::prelude::SimValue<()>`, the trait `Sync` is not implemented for `Cell` + = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` note: required because it appears within the type `util::alternating_cell::AlternatingCell>` - --> src/util/alternating_cell.rs - | - | pub(crate) struct AlternatingCell { - | ^^^^^^^^^^^^^^^ + --> src/util/alternating_cell.rs + | + 22 | pub(crate) struct AlternatingCell { + | ^^^^^^^^^^^^^^^ note: required because it appears within the type `fayalite::prelude::SimValue<()>` - --> src/sim/value.rs - | - | pub struct SimValue { - | ^^^^^^^^ + --> src/sim/value.rs + | + | pub struct SimValue { + | ^^^^^^^^ note: required by a bound in `fayalite::intern::Interned` - --> src/intern.rs - | - | pub struct Interned { - | ^^^^ required by this bound in `Interned` + --> src/intern.rs + | + | pub struct Interned { + | ^^^^ required by this bound in `Interned` error[E0277]: `UnsafeCell>` cannot be shared between threads safely - --> tests/ui/simvalue_is_not_internable.rs:12:5 - | -12 | Intern::intern_sized(v) - | ^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell>` cannot be shared between threads safely - | - = help: within `fayalite::prelude::SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>` + --> tests/ui/simvalue_is_not_internable.rs:12:5 + | + 12 | Intern::intern_sized(v) + | ^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell>` cannot be shared between threads safely + | + = help: within `fayalite::prelude::SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>` note: required because it appears within the type `util::alternating_cell::AlternatingCell>` - --> src/util/alternating_cell.rs - | - | pub(crate) struct AlternatingCell { - | ^^^^^^^^^^^^^^^ + --> src/util/alternating_cell.rs + | + 22 | pub(crate) struct AlternatingCell { + | ^^^^^^^^^^^^^^^ note: required because it appears within the type `fayalite::prelude::SimValue<()>` - --> src/sim/value.rs - | - | pub struct SimValue { - | ^^^^^^^^ + --> src/sim/value.rs + | + | pub struct SimValue { + | ^^^^^^^^ note: required by a bound in `fayalite::intern::Interned` - --> src/intern.rs - | - | pub struct Interned { - | ^^^^ required by this bound in `Interned` + --> src/intern.rs + | + | pub struct Interned { + | ^^^^ required by this bound in `Interned` error[E0277]: `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` cannot be sent between threads safely - --> tests/ui/simvalue_is_not_internable.rs:12:5 - | -12 | Intern::intern_sized(v) - | ^^^^^^^^^^^^^^^^^^^^^^^ `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` cannot be sent between threads safely - | - = help: within `fayalite::prelude::SimValue<()>`, the trait `Send` is not implemented for `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` + --> tests/ui/simvalue_is_not_internable.rs:12:5 + | + 12 | Intern::intern_sized(v) + | ^^^^^^^^^^^^^^^^^^^^^^^ `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` cannot be sent between threads safely + | + = help: within `fayalite::prelude::SimValue<()>`, the trait `Send` is not implemented for `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'static)>` note: required because it appears within the type `DynSimOnlyValue` - --> src/sim/value/sim_only_value_unsafe.rs - | - | pub struct DynSimOnlyValue(Rc); - | ^^^^^^^^^^^^^^^ + --> src/sim/value/sim_only_value_unsafe.rs + | + | pub struct DynSimOnlyValue(Rc); + | ^^^^^^^^^^^^^^^ note: required because it appears within the type `PhantomData` - --> $RUST/core/src/marker.rs - | - | pub struct PhantomData; - | ^^^^^^^^^^^ + --> $RUST/core/src/marker.rs note: required because it appears within the type `alloc::raw_vec::RawVec` - --> $RUST/alloc/src/raw_vec/mod.rs - | - | pub(crate) struct RawVec { - | ^^^^^^ + --> $RUST/alloc/src/raw_vec/mod.rs note: required because it appears within the type `Vec` - --> $RUST/alloc/src/vec/mod.rs - | - | pub struct Vec { - | ^^^ + --> $RUST/alloc/src/vec/mod.rs note: required because it appears within the type `OpaqueSimValue` - --> src/ty.rs - | - | pub struct OpaqueSimValue { - | ^^^^^^^^^^^^^^ + --> src/ty.rs + | + | pub struct OpaqueSimValue { + | ^^^^^^^^^^^^^^ note: required because it appears within the type `value::SimValueInner<()>` - --> src/sim/value.rs - | - | struct SimValueInner { - | ^^^^^^^^^^^^^ + --> src/sim/value.rs + | + 51 | struct SimValueInner { + | ^^^^^^^^^^^^^ note: required because it appears within the type `UnsafeCell>` - --> $RUST/core/src/cell.rs - | - | pub struct UnsafeCell { - | ^^^^^^^^^^ + --> $RUST/core/src/cell.rs note: required because it appears within the type `util::alternating_cell::AlternatingCell>` - --> src/util/alternating_cell.rs - | - | pub(crate) struct AlternatingCell { - | ^^^^^^^^^^^^^^^ + --> src/util/alternating_cell.rs + | + 22 | pub(crate) struct AlternatingCell { + | ^^^^^^^^^^^^^^^ note: required because it appears within the type `fayalite::prelude::SimValue<()>` - --> src/sim/value.rs - | - | pub struct SimValue { - | ^^^^^^^^ + --> src/sim/value.rs + | + | pub struct SimValue { + | ^^^^^^^^ note: required by a bound in `fayalite::intern::Interned` - --> src/intern.rs - | - | pub struct Interned { - | ^^^^ required by this bound in `Interned` + --> src/intern.rs + | + | pub struct Interned { + | ^^^^ required by this bound in `Interned`