diff --git a/.forgejo/workflows/test.yml b/.forgejo/workflows/test.yml index b0c4a59..b2d03ba 100644 --- a/.forgejo/workflows/test.yml +++ b/.forgejo/workflows/test.yml @@ -38,7 +38,7 @@ jobs: z3 \ zlib1g-dev - run: | - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain 1.89.0 + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain 1.82.0 source "$HOME/.cargo/env" echo "$PATH" >> "$GITHUB_PATH" - uses: https://git.libre-chip.org/mirrors/cache/restore@v3 diff --git a/Cargo.toml b/Cargo.toml index 5a792c6..d681425 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,11 +7,11 @@ members = ["crates/*"] [workspace.package] version = "0.3.0" license = "LGPL-3.0-or-later" -edition = "2024" +edition = "2021" 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.82.0" [workspace.dependencies] fayalite-proc-macros = { version = "=0.3.0", path = "crates/fayalite-proc-macros" } diff --git a/crates/fayalite-proc-macros-impl/src/hdl_type_common.rs b/crates/fayalite-proc-macros-impl/src/hdl_type_common.rs index 3efa555..2da0915 100644 --- a/crates/fayalite-proc-macros-impl/src/hdl_type_common.rs +++ b/crates/fayalite-proc-macros-impl/src/hdl_type_common.rs @@ -3761,10 +3761,7 @@ pub(crate) trait AsTurbofish { } 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<'_> { TypeGenerics::as_turbofish(self) @@ -3772,8 +3769,7 @@ impl AsTurbofish for TypeGenerics<'_> { } impl AsTurbofish for ParsedGenericsTypeGenerics<'_> { - type Turbofish<'a> - = ParsedGenericsTurbofish<'a> + type Turbofish<'a> = ParsedGenericsTurbofish<'a> where Self: 'a; @@ -3824,18 +3820,15 @@ impl SplitForImpl for Generics { } impl SplitForImpl for ParsedGenerics { - type ImplGenerics<'a> - = ParsedGenericsImplGenerics<'a> + type ImplGenerics<'a> = ParsedGenericsImplGenerics<'a> where Self: 'a; - type TypeGenerics<'a> - = ParsedGenericsTypeGenerics<'a> + type TypeGenerics<'a> = ParsedGenericsTypeGenerics<'a> where Self: 'a; - type WhereClause<'a> - = ParsedGenericsWhereClause<'a> + type WhereClause<'a> = ParsedGenericsWhereClause<'a> where Self: 'a; @@ -4052,8 +4045,7 @@ impl ToTokens for MaybeParsed { } impl AsTurbofish for MaybeParsed { - type Turbofish<'a> - = MaybeParsed, U::Turbofish<'a>> + type Turbofish<'a> = MaybeParsed, U::Turbofish<'a>> where Self: 'a; @@ -4066,16 +4058,13 @@ impl AsTurbofish for MaybeParsed { } impl SplitForImpl for MaybeParsed { - type ImplGenerics<'a> - = MaybeParsed, U::ImplGenerics<'a>> + type ImplGenerics<'a> = MaybeParsed, U::ImplGenerics<'a>> where Self: 'a; - type TypeGenerics<'a> - = MaybeParsed, U::TypeGenerics<'a>> + type TypeGenerics<'a> = MaybeParsed, U::TypeGenerics<'a>> where Self: 'a; - type WhereClause<'a> - = MaybeParsed, U::WhereClause<'a>> + type WhereClause<'a> = MaybeParsed, U::WhereClause<'a>> where Self: 'a; diff --git a/crates/fayalite/src/sim.rs b/crates/fayalite/src/sim.rs index 10ae16c..6659391 100644 --- a/crates/fayalite/src/sim.rs +++ b/crates/fayalite/src/sim.rs @@ -65,7 +65,6 @@ use std::{ mem, ops::IndexMut, pin::Pin, - ptr, rc::Rc, sync::Arc, task::Poll, @@ -7737,7 +7736,7 @@ impl Eq for SimGeneratorFn {} impl PartialEq for SimGeneratorFn { fn eq(&self, other: &Self) -> bool { let Self { args, f } = self; - *args == other.args && ptr::fn_addr_eq(*f, other.f) + *args == other.args && *f == other.f } } diff --git a/crates/fayalite/src/sim/interpreter.rs b/crates/fayalite/src/sim/interpreter.rs index 35a25d0..de582f0 100644 --- a/crates/fayalite/src/sim/interpreter.rs +++ b/crates/fayalite/src/sim/interpreter.rs @@ -7,7 +7,7 @@ use crate::{ intern::{Intern, Interned, Memoize}, source_location::SourceLocation, ty::CanonicalType, - util::{HashMap, HashSet}, + util::{get_many_mut, HashMap, HashSet}, }; use bitvec::{boxed::BitBox, slice::BitSlice}; use num_bigint::BigInt; @@ -2073,21 +2073,21 @@ pub(crate) struct BorrowedStatePart<'a, K: StatePartKind> { } impl< - 'a, - K: StatePartKind< - BorrowedState<'a>: DerefMut + BorrowMut<[T]>>, - >, - T, -> BorrowedStatePart<'a, K> + 'a, + K: StatePartKind< + BorrowedState<'a>: DerefMut + BorrowMut<[T]>>, + >, + T, + > BorrowedStatePart<'a, K> { - pub(crate) fn get_disjoint_mut( + pub(crate) fn get_many_mut( &mut self, indexes: [StatePartIndex; N], ) -> [&mut T; N] { - (*self.value) - .borrow_mut() - .get_disjoint_mut(indexes.map(|v| v.value as usize)) - .expect("indexes are disjoint") + get_many_mut( + (*self.value).borrow_mut(), + indexes.map(|v| v.value as usize), + ) } } @@ -2568,7 +2568,7 @@ impl_insns! { src: StatePartIndex, } => { if dest != src { - let [dest, src] = state.big_slots.get_disjoint_mut([dest, src]); + let [dest, src] = state.big_slots.get_many_mut([dest, src]); dest.clone_from(src); } next!(); @@ -2590,7 +2590,7 @@ impl_insns! { } => { if let Some(src) = state.eval_array_indexed(src) { if dest != src { - let [dest, src] = state.big_slots.get_disjoint_mut([dest, src]); + let [dest, src] = state.big_slots.get_many_mut([dest, src]); dest.clone_from(src); } } else { @@ -2619,7 +2619,7 @@ impl_insns! { } => { if let Some(dest) = state.eval_array_indexed(dest) { if dest != src { - let [dest, src] = state.big_slots.get_disjoint_mut([dest, src]); + let [dest, src] = state.big_slots.get_many_mut([dest, src]); dest.clone_from(src); } } diff --git a/crates/fayalite/src/util.rs b/crates/fayalite/src/util.rs index 4670a1f..233867e 100644 --- a/crates/fayalite/src/util.rs +++ b/crates/fayalite/src/util.rs @@ -35,8 +35,8 @@ pub use scoped_ref::ScopedRef; #[doc(inline)] pub use misc::{ - BitSliceWriteWithBase, DebugAsDisplay, DebugAsRawString, MakeMutSlice, RcWriter, interned_bit, - iter_eq_by, + get_many_mut, interned_bit, iter_eq_by, BitSliceWriteWithBase, DebugAsDisplay, + DebugAsRawString, MakeMutSlice, RcWriter, }; pub mod job_server; diff --git a/crates/fayalite/src/util/misc.rs b/crates/fayalite/src/util/misc.rs index 99b7343..f482eaa 100644 --- a/crates/fayalite/src/util/misc.rs +++ b/crates/fayalite/src/util/misc.rs @@ -163,6 +163,22 @@ impl fmt::UpperHex for BitSliceWriteWithBase<'_> { } } +#[inline] +#[track_caller] +pub fn get_many_mut(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)] pub struct RcWriter(Rc>>); diff --git a/crates/fayalite/tests/ui/simvalue_is_not_internable.stderr b/crates/fayalite/tests/ui/simvalue_is_not_internable.stderr index 6550b5f..eb8877b 100644 --- a/crates/fayalite/tests/ui/simvalue_is_not_internable.stderr +++ b/crates/fayalite/tests/ui/simvalue_is_not_internable.stderr @@ -4,7 +4,7 @@ error[E0277]: `Cell` cannot be shared between thr 11 | fn f(v: SimValue<()>) -> Interned> { | ^^^^^^^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely | - = help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell` + = help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell`, which is required by `SimValue<()>: Sync` = 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 @@ -28,7 +28,7 @@ error[E0277]: `UnsafeCell>` cannot be shared between th 11 | fn f(v: SimValue<()>) -> Interned> { | ^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell>` cannot be shared between threads safely | - = help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>` + = help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>`, which is required by `SimValue<()>: Sync` note: required because it appears within the type `util::alternating_cell::AlternatingCell>` --> 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 | 12 | Intern::intern_sized(v) - | -------------------- ^ the trait `Hash` is not implemented for `SimValue<()>` + | -------------------- ^ the trait `Hash` is not implemented for `SimValue<()>`, which is required by `SimValue<()>: Intern` | | | 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` -help: consider dereferencing here - | -12 | Intern::intern_sized(*v) - | + error[E0277]: the trait bound `SimValue<()>: Intern` is not satisfied --> tests/ui/simvalue_is_not_internable.rs:12:26 | 12 | Intern::intern_sized(v) - | -------------------- ^ the trait `std::cmp::Eq` is not implemented for `SimValue<()>` + | -------------------- ^ the trait `std::cmp::Eq` is not implemented for `SimValue<()>`, which is required by `SimValue<()>: Intern` | | | 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` -help: consider dereferencing here - | -12 | Intern::intern_sized(*v) - | + error[E0277]: `Cell` cannot be shared between threads safely --> tests/ui/simvalue_is_not_internable.rs:12:26 @@ -81,7 +81,7 @@ error[E0277]: `Cell` cannot be shared between thr | | | required by a bound introduced by this call | - = help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell` + = help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell`, which is required by `SimValue<()>: Sync` = 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 @@ -101,10 +101,6 @@ note: required by a bound in `intern_sized` | fn intern(&self) -> Interned; | fn intern_sized(self) -> Interned | ------------ required by a bound in this associated function -help: consider dereferencing here - | -12 | Intern::intern_sized(*v) - | + error[E0277]: `UnsafeCell>` cannot be shared between threads safely --> tests/ui/simvalue_is_not_internable.rs:12:26 @@ -114,7 +110,7 @@ error[E0277]: `UnsafeCell>` cannot be shared between th | | | required by a bound introduced by this call | - = help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>` + = help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>`, which is required by `SimValue<()>: Sync` note: required because it appears within the type `util::alternating_cell::AlternatingCell>` --> src/util/alternating_cell.rs | @@ -133,10 +129,6 @@ note: required by a bound in `intern_sized` | fn intern(&self) -> Interned; | fn intern_sized(self) -> Interned | ------------ required by a bound in this associated function -help: consider dereferencing here - | -12 | Intern::intern_sized(*v) - | + error[E0277]: `Cell` cannot be shared between threads safely --> tests/ui/simvalue_is_not_internable.rs:12:5 @@ -144,7 +136,7 @@ error[E0277]: `Cell` cannot be shared between thr 12 | Intern::intern_sized(v) | ^^^^^^^^^^^^^^^^^^^^^^^ `Cell` cannot be shared between threads safely | - = help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell` + = help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell`, which is required by `SimValue<()>: Sync` = 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 @@ -168,7 +160,7 @@ error[E0277]: `UnsafeCell>` cannot be shared between th 12 | Intern::intern_sized(v) | ^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell>` cannot be shared between threads safely | - = help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>` + = help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell>`, which is required by `SimValue<()>: Sync` note: required because it appears within the type `util::alternating_cell::AlternatingCell>` --> src/util/alternating_cell.rs |