Compare commits

...

3 commits

8 changed files with 66 additions and 62 deletions

View file

@ -38,7 +38,7 @@ jobs:
z3 \ z3 \
zlib1g-dev zlib1g-dev
- run: | - run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain 1.82.0 curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain 1.89.0
source "$HOME/.cargo/env" source "$HOME/.cargo/env"
echo "$PATH" >> "$GITHUB_PATH" echo "$PATH" >> "$GITHUB_PATH"
- uses: https://git.libre-chip.org/mirrors/cache/restore@v3 - uses: https://git.libre-chip.org/mirrors/cache/restore@v3

View file

@ -7,11 +7,11 @@ members = ["crates/*"]
[workspace.package] [workspace.package]
version = "0.3.0" version = "0.3.0"
license = "LGPL-3.0-or-later" license = "LGPL-3.0-or-later"
edition = "2021" edition = "2024"
repository = "https://git.libre-chip.org/libre-chip/fayalite" repository = "https://git.libre-chip.org/libre-chip/fayalite"
keywords = ["hdl", "hardware", "semiconductors", "firrtl", "fpga"] keywords = ["hdl", "hardware", "semiconductors", "firrtl", "fpga"]
categories = ["simulation", "development-tools", "compilers"] categories = ["simulation", "development-tools", "compilers"]
rust-version = "1.82.0" rust-version = "1.89.0"
[workspace.dependencies] [workspace.dependencies]
fayalite-proc-macros = { version = "=0.3.0", path = "crates/fayalite-proc-macros" } fayalite-proc-macros = { version = "=0.3.0", path = "crates/fayalite-proc-macros" }

View file

@ -3761,7 +3761,10 @@ pub(crate) trait AsTurbofish {
} }
impl AsTurbofish for TypeGenerics<'_> { impl AsTurbofish for TypeGenerics<'_> {
type Turbofish<'a> = Turbofish<'a> where Self: 'a; type Turbofish<'a>
= Turbofish<'a>
where
Self: 'a;
fn as_turbofish(&self) -> Self::Turbofish<'_> { fn as_turbofish(&self) -> Self::Turbofish<'_> {
TypeGenerics::as_turbofish(self) TypeGenerics::as_turbofish(self)
@ -3769,7 +3772,8 @@ impl AsTurbofish for TypeGenerics<'_> {
} }
impl AsTurbofish for ParsedGenericsTypeGenerics<'_> { impl AsTurbofish for ParsedGenericsTypeGenerics<'_> {
type Turbofish<'a> = ParsedGenericsTurbofish<'a> type Turbofish<'a>
= ParsedGenericsTurbofish<'a>
where where
Self: 'a; Self: 'a;
@ -3820,15 +3824,18 @@ impl SplitForImpl for Generics {
} }
impl SplitForImpl for ParsedGenerics { impl SplitForImpl for ParsedGenerics {
type ImplGenerics<'a> = ParsedGenericsImplGenerics<'a> type ImplGenerics<'a>
= ParsedGenericsImplGenerics<'a>
where where
Self: 'a; Self: 'a;
type TypeGenerics<'a> = ParsedGenericsTypeGenerics<'a> type TypeGenerics<'a>
= ParsedGenericsTypeGenerics<'a>
where where
Self: 'a; Self: 'a;
type WhereClause<'a> = ParsedGenericsWhereClause<'a> type WhereClause<'a>
= ParsedGenericsWhereClause<'a>
where where
Self: 'a; Self: 'a;
@ -4045,7 +4052,8 @@ impl<P: ToTokens, U: ToTokens> ToTokens for MaybeParsed<P, U> {
} }
impl<P: AsTurbofish, U: AsTurbofish> AsTurbofish for MaybeParsed<P, U> { impl<P: AsTurbofish, U: AsTurbofish> AsTurbofish for MaybeParsed<P, U> {
type Turbofish<'a> = MaybeParsed<P::Turbofish<'a>, U::Turbofish<'a>> type Turbofish<'a>
= MaybeParsed<P::Turbofish<'a>, U::Turbofish<'a>>
where where
Self: 'a; Self: 'a;
@ -4058,13 +4066,16 @@ impl<P: AsTurbofish, U: AsTurbofish> AsTurbofish for MaybeParsed<P, U> {
} }
impl<P: SplitForImpl, U: SplitForImpl> SplitForImpl for MaybeParsed<P, U> { impl<P: SplitForImpl, U: SplitForImpl> SplitForImpl for MaybeParsed<P, U> {
type ImplGenerics<'a> = MaybeParsed<P::ImplGenerics<'a>, U::ImplGenerics<'a>> type ImplGenerics<'a>
= MaybeParsed<P::ImplGenerics<'a>, U::ImplGenerics<'a>>
where where
Self: 'a; Self: 'a;
type TypeGenerics<'a> = MaybeParsed<P::TypeGenerics<'a>, U::TypeGenerics<'a>> type TypeGenerics<'a>
= MaybeParsed<P::TypeGenerics<'a>, U::TypeGenerics<'a>>
where where
Self: 'a; Self: 'a;
type WhereClause<'a> = MaybeParsed<P::WhereClause<'a>, U::WhereClause<'a>> type WhereClause<'a>
= MaybeParsed<P::WhereClause<'a>, U::WhereClause<'a>>
where where
Self: 'a; Self: 'a;

View file

@ -65,6 +65,7 @@ use std::{
mem, mem,
ops::IndexMut, ops::IndexMut,
pin::Pin, pin::Pin,
ptr,
rc::Rc, rc::Rc,
sync::Arc, sync::Arc,
task::Poll, task::Poll,
@ -7736,7 +7737,7 @@ impl<Args: Eq, Fut> Eq for SimGeneratorFn<Args, Fut> {}
impl<Args: PartialEq, Fut> PartialEq for SimGeneratorFn<Args, Fut> { impl<Args: PartialEq, Fut> PartialEq for SimGeneratorFn<Args, Fut> {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
let Self { args, f } = self; let Self { args, f } = self;
*args == other.args && *f == other.f *args == other.args && ptr::fn_addr_eq(*f, other.f)
} }
} }

View file

@ -7,7 +7,7 @@ use crate::{
intern::{Intern, Interned, Memoize}, intern::{Intern, Interned, Memoize},
source_location::SourceLocation, source_location::SourceLocation,
ty::CanonicalType, ty::CanonicalType,
util::{get_many_mut, HashMap, HashSet}, util::{HashMap, HashSet},
}; };
use bitvec::{boxed::BitBox, slice::BitSlice}; use bitvec::{boxed::BitBox, slice::BitSlice};
use num_bigint::BigInt; use num_bigint::BigInt;
@ -2080,14 +2080,14 @@ impl<
T, T,
> BorrowedStatePart<'a, K> > BorrowedStatePart<'a, K>
{ {
pub(crate) fn get_many_mut<const N: usize>( pub(crate) fn get_disjoint_mut<const N: usize>(
&mut self, &mut self,
indexes: [StatePartIndex<K>; N], indexes: [StatePartIndex<K>; N],
) -> [&mut T; N] { ) -> [&mut T; N] {
get_many_mut( (*self.value)
(*self.value).borrow_mut(), .borrow_mut()
indexes.map(|v| v.value as usize), .get_disjoint_mut(indexes.map(|v| v.value as usize))
) .expect("indexes are disjoint")
} }
} }
@ -2568,7 +2568,7 @@ impl_insns! {
src: StatePartIndex<StatePartKindBigSlots>, src: StatePartIndex<StatePartKindBigSlots>,
} => { } => {
if dest != src { if dest != src {
let [dest, src] = state.big_slots.get_many_mut([dest, src]); let [dest, src] = state.big_slots.get_disjoint_mut([dest, src]);
dest.clone_from(src); dest.clone_from(src);
} }
next!(); next!();
@ -2590,7 +2590,7 @@ impl_insns! {
} => { } => {
if let Some(src) = state.eval_array_indexed(src) { if let Some(src) = state.eval_array_indexed(src) {
if dest != src { if dest != src {
let [dest, src] = state.big_slots.get_many_mut([dest, src]); let [dest, src] = state.big_slots.get_disjoint_mut([dest, src]);
dest.clone_from(src); dest.clone_from(src);
} }
} else { } else {
@ -2619,7 +2619,7 @@ impl_insns! {
} => { } => {
if let Some(dest) = state.eval_array_indexed(dest) { if let Some(dest) = state.eval_array_indexed(dest) {
if dest != src { if dest != src {
let [dest, src] = state.big_slots.get_many_mut([dest, src]); let [dest, src] = state.big_slots.get_disjoint_mut([dest, src]);
dest.clone_from(src); dest.clone_from(src);
} }
} }

View file

@ -35,8 +35,8 @@ pub use scoped_ref::ScopedRef;
#[doc(inline)] #[doc(inline)]
pub use misc::{ pub use misc::{
get_many_mut, interned_bit, iter_eq_by, BitSliceWriteWithBase, DebugAsDisplay, BitSliceWriteWithBase, DebugAsDisplay, DebugAsRawString, MakeMutSlice, RcWriter, interned_bit,
DebugAsRawString, MakeMutSlice, RcWriter, iter_eq_by,
}; };
pub mod job_server; pub mod job_server;

View file

@ -163,22 +163,6 @@ impl fmt::UpperHex for BitSliceWriteWithBase<'_> {
} }
} }
#[inline]
#[track_caller]
pub fn get_many_mut<T, const N: usize>(slice: &mut [T], indexes: [usize; N]) -> [&mut T; N] {
for i in 0..N {
for j in 0..i {
assert!(indexes[i] != indexes[j], "duplicate index");
}
assert!(indexes[i] < slice.len(), "index out of bounds");
}
// Safety: checked that no indexes are duplicates and no indexes are out of bounds
unsafe {
let base = slice.as_mut_ptr(); // convert to a raw pointer before loop to avoid aliasing with &mut [T]
std::array::from_fn(|i| &mut *base.add(indexes[i]))
}
}
#[derive(Clone, Default)] #[derive(Clone, Default)]
pub struct RcWriter(Rc<Cell<Vec<u8>>>); pub struct RcWriter(Rc<Cell<Vec<u8>>>);

View file

@ -4,7 +4,7 @@ error[E0277]: `Cell<util::alternating_cell::State>` cannot be shared between thr
11 | fn f(v: SimValue<()>) -> Interned<SimValue<()>> { 11 | fn f(v: SimValue<()>) -> Interned<SimValue<()>> {
| ^^^^^^^^^^^^^^^^^^^^^^ `Cell<util::alternating_cell::State>` cannot be shared between threads safely | ^^^^^^^^^^^^^^^^^^^^^^ `Cell<util::alternating_cell::State>` cannot be shared between threads safely
| |
= help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell<util::alternating_cell::State>`, which is required by `SimValue<()>: Sync` = help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell<util::alternating_cell::State>`
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` = 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<value::SimValueInner<()>>` note: required because it appears within the type `util::alternating_cell::AlternatingCell<value::SimValueInner<()>>`
--> src/util/alternating_cell.rs --> src/util/alternating_cell.rs
@ -28,7 +28,7 @@ error[E0277]: `UnsafeCell<value::SimValueInner<()>>` cannot be shared between th
11 | fn f(v: SimValue<()>) -> Interned<SimValue<()>> { 11 | fn f(v: SimValue<()>) -> Interned<SimValue<()>> {
| ^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<value::SimValueInner<()>>` cannot be shared between threads safely | ^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<value::SimValueInner<()>>` cannot be shared between threads safely
| |
= help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell<value::SimValueInner<()>>`, which is required by `SimValue<()>: Sync` = help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell<value::SimValueInner<()>>`
note: required because it appears within the type `util::alternating_cell::AlternatingCell<value::SimValueInner<()>>` note: required because it appears within the type `util::alternating_cell::AlternatingCell<value::SimValueInner<()>>`
--> src/util/alternating_cell.rs --> src/util/alternating_cell.rs
| |
@ -49,29 +49,29 @@ error[E0277]: the trait bound `SimValue<()>: Intern` is not satisfied
--> tests/ui/simvalue_is_not_internable.rs:12:26 --> tests/ui/simvalue_is_not_internable.rs:12:26
| |
12 | Intern::intern_sized(v) 12 | Intern::intern_sized(v)
| -------------------- ^ the trait `Hash` is not implemented for `SimValue<()>`, which is required by `SimValue<()>: Intern` | -------------------- ^ the trait `Hash` is not implemented for `SimValue<()>`
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |
= help: the following other types implement trait `Intern`:
BitSlice
[T]
str
= note: required for `SimValue<()>` to implement `Intern` = note: required for `SimValue<()>` to implement `Intern`
help: consider dereferencing here
|
12 | Intern::intern_sized(*v)
| +
error[E0277]: the trait bound `SimValue<()>: Intern` is not satisfied error[E0277]: the trait bound `SimValue<()>: Intern` is not satisfied
--> tests/ui/simvalue_is_not_internable.rs:12:26 --> tests/ui/simvalue_is_not_internable.rs:12:26
| |
12 | Intern::intern_sized(v) 12 | Intern::intern_sized(v)
| -------------------- ^ the trait `std::cmp::Eq` is not implemented for `SimValue<()>`, which is required by `SimValue<()>: Intern` | -------------------- ^ the trait `std::cmp::Eq` is not implemented for `SimValue<()>`
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |
= help: the following other types implement trait `Intern`:
BitSlice
[T]
str
= note: required for `SimValue<()>` to implement `Intern` = note: required for `SimValue<()>` to implement `Intern`
help: consider dereferencing here
|
12 | Intern::intern_sized(*v)
| +
error[E0277]: `Cell<util::alternating_cell::State>` cannot be shared between threads safely error[E0277]: `Cell<util::alternating_cell::State>` cannot be shared between threads safely
--> tests/ui/simvalue_is_not_internable.rs:12:26 --> tests/ui/simvalue_is_not_internable.rs:12:26
@ -81,7 +81,7 @@ error[E0277]: `Cell<util::alternating_cell::State>` cannot be shared between thr
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |
= help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell<util::alternating_cell::State>`, which is required by `SimValue<()>: Sync` = help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell<util::alternating_cell::State>`
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` = 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<value::SimValueInner<()>>` note: required because it appears within the type `util::alternating_cell::AlternatingCell<value::SimValueInner<()>>`
--> src/util/alternating_cell.rs --> src/util/alternating_cell.rs
@ -101,6 +101,10 @@ note: required by a bound in `intern_sized`
| fn intern(&self) -> Interned<Self>; | fn intern(&self) -> Interned<Self>;
| fn intern_sized(self) -> Interned<Self> | fn intern_sized(self) -> Interned<Self>
| ------------ required by a bound in this associated function | ------------ required by a bound in this associated function
help: consider dereferencing here
|
12 | Intern::intern_sized(*v)
| +
error[E0277]: `UnsafeCell<value::SimValueInner<()>>` cannot be shared between threads safely error[E0277]: `UnsafeCell<value::SimValueInner<()>>` cannot be shared between threads safely
--> tests/ui/simvalue_is_not_internable.rs:12:26 --> tests/ui/simvalue_is_not_internable.rs:12:26
@ -110,7 +114,7 @@ error[E0277]: `UnsafeCell<value::SimValueInner<()>>` cannot be shared between th
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |
= help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell<value::SimValueInner<()>>`, which is required by `SimValue<()>: Sync` = help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell<value::SimValueInner<()>>`
note: required because it appears within the type `util::alternating_cell::AlternatingCell<value::SimValueInner<()>>` note: required because it appears within the type `util::alternating_cell::AlternatingCell<value::SimValueInner<()>>`
--> src/util/alternating_cell.rs --> src/util/alternating_cell.rs
| |
@ -129,6 +133,10 @@ note: required by a bound in `intern_sized`
| fn intern(&self) -> Interned<Self>; | fn intern(&self) -> Interned<Self>;
| fn intern_sized(self) -> Interned<Self> | fn intern_sized(self) -> Interned<Self>
| ------------ required by a bound in this associated function | ------------ required by a bound in this associated function
help: consider dereferencing here
|
12 | Intern::intern_sized(*v)
| +
error[E0277]: `Cell<util::alternating_cell::State>` cannot be shared between threads safely error[E0277]: `Cell<util::alternating_cell::State>` cannot be shared between threads safely
--> tests/ui/simvalue_is_not_internable.rs:12:5 --> tests/ui/simvalue_is_not_internable.rs:12:5
@ -136,7 +144,7 @@ error[E0277]: `Cell<util::alternating_cell::State>` cannot be shared between thr
12 | Intern::intern_sized(v) 12 | Intern::intern_sized(v)
| ^^^^^^^^^^^^^^^^^^^^^^^ `Cell<util::alternating_cell::State>` cannot be shared between threads safely | ^^^^^^^^^^^^^^^^^^^^^^^ `Cell<util::alternating_cell::State>` cannot be shared between threads safely
| |
= help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell<util::alternating_cell::State>`, which is required by `SimValue<()>: Sync` = help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell<util::alternating_cell::State>`
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` = 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<value::SimValueInner<()>>` note: required because it appears within the type `util::alternating_cell::AlternatingCell<value::SimValueInner<()>>`
--> src/util/alternating_cell.rs --> src/util/alternating_cell.rs
@ -160,7 +168,7 @@ error[E0277]: `UnsafeCell<value::SimValueInner<()>>` cannot be shared between th
12 | Intern::intern_sized(v) 12 | Intern::intern_sized(v)
| ^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<value::SimValueInner<()>>` cannot be shared between threads safely | ^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<value::SimValueInner<()>>` cannot be shared between threads safely
| |
= help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell<value::SimValueInner<()>>`, which is required by `SimValue<()>: Sync` = help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell<value::SimValueInner<()>>`
note: required because it appears within the type `util::alternating_cell::AlternatingCell<value::SimValueInner<()>>` note: required because it appears within the type `util::alternating_cell::AlternatingCell<value::SimValueInner<()>>`
--> src/util/alternating_cell.rs --> src/util/alternating_cell.rs
| |