From fe5b433f7889c0c95953605aad7e3b97741067f5 Mon Sep 17 00:00:00 2001 From: amatgil Date: Thu, 18 Sep 2025 17:24:53 +0200 Subject: [PATCH 1/9] rand -> rand_xoshiro for better reproducibility across archs --- Cargo.lock | 23 +++++++++++++++++++---- Cargo.toml | 4 ++-- site/Cargo.toml | 2 +- src/algorithm/dyadic/mod.rs | 20 ++++++++++++++++---- src/algorithm/monadic/sort.rs | 3 ++- src/constant.rs | 5 +++-- src/run_prim.rs | 15 ++++++++++----- 7 files changed, 53 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b0cde85ed..bbd58fd09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5066,7 +5066,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -5076,7 +5076,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -5088,6 +5088,21 @@ dependencies = [ "getrandom 0.2.15", ] +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" + +[[package]] +name = "rand_xoshiro" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41" +dependencies = [ + "rand_core 0.9.3", +] + [[package]] name = "rangemap" version = "1.5.1" @@ -5821,7 +5836,7 @@ dependencies = [ "leptos", "leptos_meta", "leptos_router", - "rand", + "rand_xoshiro", "serde", "serde_json", "uiua", @@ -6585,7 +6600,7 @@ dependencies = [ "paste", "pathdiff", "png", - "rand", + "rand_xoshiro", "rawrrr", "rayon", "regex", diff --git a/Cargo.toml b/Cargo.toml index 2f137e8f1..bd71ee1be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ js-sys = "0.3.69" leptos = "0.6.11" leptos_meta = {version = "0.6.11", features = ["csr"]} leptos_router = {version = "0.6.11", features = ["csr"]} -rand = {version = "0.8.5", features = ["small_rng"]} +rand_xoshiro = "0.7.0" serde = {version = "1", features = ["derive"]} serde_json = "1.0.115" unicode-segmentation = "1.10" @@ -106,7 +106,6 @@ open = {version = "5", optional = true} parking_lot = "0.12.1" paste = "1.0.14" pathdiff = "0.2.1" -rand.workspace = true rawrrr = {version = "0.2.1", optional = true} rayon = "1.9.0" regex = "1.10.3" @@ -183,6 +182,7 @@ web-sys = {version = "0.3.60", optional = true} # Window dependencies eframe = {version = "0.29.1", optional = true, features = ["persistence"]} native-dialog = {version = "0.7.0", optional = true} +rand_xoshiro = "0.7.0" rmp-serde = {version = "1.3.0", optional = true} [features] diff --git a/site/Cargo.toml b/site/Cargo.toml index fcb7ac74b..059a6109a 100644 --- a/site/Cargo.toml +++ b/site/Cargo.toml @@ -23,7 +23,7 @@ js-sys.workspace = true leptos.workspace = true leptos_meta.workspace = true leptos_router.workspace = true -rand.workspace = true +rand_xoshiro.workspace = true serde.workspace = true serde_json.workspace = true uiua = {path = "..", default-features = false, features = ["batteries", "web"]} diff --git a/src/algorithm/dyadic/mod.rs b/src/algorithm/dyadic/mod.rs index 1d18f1474..9fea3c15c 100644 --- a/src/algorithm/dyadic/mod.rs +++ b/src/algorithm/dyadic/mod.rs @@ -15,7 +15,11 @@ use std::{ use bytemuck::allocation::cast_vec; use ecow::{eco_vec, EcoVec}; -use rand::prelude::*; +use rand_xoshiro::{ + rand_core::{RngCore, SeedableRng}, + Xoshiro256Plus, +}; + #[cfg(not(target_arch = "wasm32"))] use rayon::prelude::*; use smallvec::SmallVec; @@ -2112,7 +2116,7 @@ impl Value { let mut hasher = DefaultHasher::new(); seed.hash(&mut hasher); let seed = hasher.finish(); - let mut rng = SmallRng::seed_from_u64(seed); + let mut rng = Xoshiro256Plus::seed_from_u64(seed); const SHAPE_REQ: &str = "Shape must be an array of natural \ numbers with at most rank 2"; @@ -2122,7 +2126,7 @@ impl Value { let elem_count = validate_size::(shape.iter().copied(), env)?; let mut data = eco_vec![0.0; elem_count]; for x in data.make_mut() { - *x = rng.gen(); + *x = f64::from_bits(rng.next_u64()); } Ok(Array::new(shape, data)) }; @@ -2168,7 +2172,15 @@ impl Value { 0 => Err(env.error("Cannot pick random row of an empty array").fill()), 1 => Ok(self.row(0)), len => { - let i = RNG.with_borrow_mut(|rng| rng.gen_range(0..len)); + let i = RNG.with_borrow_mut(|rng| { + let upper = len.next_power_of_two(); + loop { + let r = rng.next_u64() as usize; + if r % upper < len { + break len; + } + } + }); Ok(self.row(i)) } } diff --git a/src/algorithm/monadic/sort.rs b/src/algorithm/monadic/sort.rs index 22e93b540..607089e9a 100644 --- a/src/algorithm/monadic/sort.rs +++ b/src/algorithm/monadic/sort.rs @@ -1,7 +1,8 @@ use std::{cmp::Ordering, ptr}; use ecow::EcoVec; -use rand::Rng; +use rand_xoshiro::rand_core::SeedableRng; +use rand_xoshiro::Xoshiro256Plus; use rayon::prelude::*; use crate::{algorithm::ArrayCmpSlice, random_with, val_as_arr, Array, ArrayValue, Value}; diff --git a/src/constant.rs b/src/constant.rs index 714144cb0..854c8d2b0 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -5,7 +5,8 @@ use std::{ }; use ecow::EcoVec; -use rand::prelude::*; +use rand_xoshiro::rand_core::SeedableRng; +use rand_xoshiro::Xoshiro256Plus; use crate::{ parse_doc_line_fragments, Array, Boxed, PrimDocFragment, SysBackend, Value, WILDCARD_NAN, @@ -485,7 +486,7 @@ fn music_constant(backend: &dyn SysBackend) -> Value { hat_mask.push((hat_bits & 1) as f64); hat_bits >>= 1; } - let mut rng = SmallRng::seed_from_u64(0); + let mut rng = Xoshiro256Plus::seed_from_u64(0); let sr = backend.audio_sample_rate(); (0..(BEAT * 2.0 * 16.0 * sr as f64) as usize) .map(|s| { diff --git a/src/run_prim.rs b/src/run_prim.rs index 400f8d98e..ff355dabf 100644 --- a/src/run_prim.rs +++ b/src/run_prim.rs @@ -14,13 +14,18 @@ use std::{ collections::HashMap, f64::consts::{PI, TAU}, iter::repeat_n, + mem::transmute, sync::{ atomic::{self, AtomicUsize}, OnceLock, }, + time::{SystemTime, UNIX_EPOCH}, }; -use rand::prelude::*; +use rand_xoshiro::{ + rand_core::{RngCore, SeedableRng}, + Xoshiro256Plus, +}; use crate::{ algorithm::{self, ga::GaOp, loops, reduce, table, zip, *}, @@ -1783,22 +1788,22 @@ fn undo_regex(env: &mut Uiua) -> UiuaResult { } thread_local! { - pub(crate) static RNG: RefCell = RefCell::new(SmallRng::from_entropy()); + pub(crate) static RNG: RefCell = RefCell::new(Xoshiro256Plus::from_seed(transmute(SystemTime::now().saturating_duration_since(UNIX_EPOCH).as_micros()))); } /// Generate a random number, equivalent to [`Primitive::Rand`] pub fn random() -> f64 { - random_with(|rng| rng.gen()) + random_with(|rng| f64::from_bits(rng.next_u64())) } /// Access the interpreter's random number generator for the thread -pub fn random_with(f: impl FnOnce(&mut SmallRng) -> T) -> T { +pub fn random_with(f: impl FnOnce(&mut Xoshiro256Plus) -> T) -> T { RNG.with(|rng| f(&mut rng.borrow_mut())) } /// Seed the random number generator pub fn seed_random(seed: u64) { - random_with(|rng| *rng = SmallRng::seed_from_u64(seed)); + random_with(|rng| *rng = Xoshiro256Plus::seed_from_u64(seed)); } fn stack_n(env: &mut Uiua, n: usize, inverse: bool) -> UiuaResult { From c78633a6b9eaf56d278b672ed5cadcbe9f31eb52 Mon Sep 17 00:00:00 2001 From: amatgil Date: Thu, 18 Sep 2025 17:34:34 +0200 Subject: [PATCH 2/9] Remember to return the generated value, not the upper bound :P --- src/algorithm/dyadic/mod.rs | 6 +++--- src/algorithm/monadic/sort.rs | 10 +++++++++- src/run_prim.rs | 3 ++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/algorithm/dyadic/mod.rs b/src/algorithm/dyadic/mod.rs index 9fea3c15c..d1a463e53 100644 --- a/src/algorithm/dyadic/mod.rs +++ b/src/algorithm/dyadic/mod.rs @@ -2175,9 +2175,9 @@ impl Value { let i = RNG.with_borrow_mut(|rng| { let upper = len.next_power_of_two(); loop { - let r = rng.next_u64() as usize; - if r % upper < len { - break len; + let r = rng.next_u64() as usize % upper; + if r < len { + break r; } } }); diff --git a/src/algorithm/monadic/sort.rs b/src/algorithm/monadic/sort.rs index 607089e9a..356257fa6 100644 --- a/src/algorithm/monadic/sort.rs +++ b/src/algorithm/monadic/sort.rs @@ -233,7 +233,15 @@ impl Array { let row_len = self.row_len(); let slice = self.data.as_mut_slice(); for i in (1..row_count).rev() { - let j = rng.gen_range(0..=i); + let j = { + let upper = i.next_power_of_two(); + loop { + let r = rng.next_u64() as usize % upper; + if r <= i { + break r; + } + } + }; if i == j { continue; } diff --git a/src/run_prim.rs b/src/run_prim.rs index ff355dabf..9465ca8cb 100644 --- a/src/run_prim.rs +++ b/src/run_prim.rs @@ -1788,7 +1788,8 @@ fn undo_regex(env: &mut Uiua) -> UiuaResult { } thread_local! { - pub(crate) static RNG: RefCell = RefCell::new(Xoshiro256Plus::from_seed(transmute(SystemTime::now().saturating_duration_since(UNIX_EPOCH).as_micros()))); + pub(crate) static RNG: RefCell = RefCell::new(Xoshiro256Plus::seed_from_u64( + SystemTime::now().duration_since(UNIX_EPOCH).map(|t|t.as_micros()).unwrap_or(42) as u64)); } /// Generate a random number, equivalent to [`Primitive::Rand`] From 1a8ab148d39c12bf7d8d40309b108f4b054efa2f Mon Sep 17 00:00:00 2001 From: amatgil Date: Thu, 18 Sep 2025 21:23:25 +0200 Subject: [PATCH 3/9] Implement gen_range(-1..=1), seems to be more uniform than the previous way --- src/algorithm/monadic/sort.rs | 7 +++++-- src/constant.rs | 12 ++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/algorithm/monadic/sort.rs b/src/algorithm/monadic/sort.rs index 356257fa6..ad2b32117 100644 --- a/src/algorithm/monadic/sort.rs +++ b/src/algorithm/monadic/sort.rs @@ -1,8 +1,10 @@ use std::{cmp::Ordering, ptr}; use ecow::EcoVec; -use rand_xoshiro::rand_core::SeedableRng; -use rand_xoshiro::Xoshiro256Plus; +use rand_xoshiro::{ + rand_core::{RngCore, SeedableRng}, + Xoshiro256Plus, +}; use rayon::prelude::*; use crate::{algorithm::ArrayCmpSlice, random_with, val_as_arr, Array, ArrayValue, Value}; @@ -242,6 +244,7 @@ impl Array { } } }; + if i == j { continue; } diff --git a/src/constant.rs b/src/constant.rs index 854c8d2b0..6a3690973 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -5,8 +5,10 @@ use std::{ }; use ecow::EcoVec; -use rand_xoshiro::rand_core::SeedableRng; -use rand_xoshiro::Xoshiro256Plus; +use rand_xoshiro::{ + rand_core::{RngCore, SeedableRng}, + Xoshiro256Plus, +}; use crate::{ parse_doc_line_fragments, Array, Boxed, PrimDocFragment, SysBackend, Value, WILDCARD_NAN, @@ -487,6 +489,8 @@ fn music_constant(backend: &dyn SysBackend) -> Value { hat_bits >>= 1; } let mut rng = Xoshiro256Plus::seed_from_u64(0); + let mut rand_wrench = + || 2.0 * f64::from_bits(rng.next_u64() >> 12 | 0x3FF0_0000_0000_0000) - 3.0; // gen_range(-1..=1) let sr = backend.audio_sample_rate(); (0..(BEAT * 2.0 * 16.0 * sr as f64) as usize) .map(|s| { @@ -500,11 +504,11 @@ fn music_constant(backend: &dyn SysBackend) -> Value { let h = if (h * secs % 1.0) < 0.5 { 1.0 } else { -1.0 } / 3.0; // Square wave let kick = ((secs % BEAT).powf(0.4) * 40.0 * TAU).sin(); let hat = 0.3 - * rng.gen_range(-1.0..=1.0) + * rand_wrench() * hat_mask[(4.0 * beat) as usize % 32] * (0.0..=0.1).contains(&(secs % (BEAT / 4.0) / (BEAT / 4.0))) as u8 as f64; let snare = 0.5 - * rng.gen_range(-1.0..=1.0) + * rand_wrench() * ((0.5..=0.6).contains(&(secs % (2.0 * BEAT) / (2.0 * BEAT))) as u8 as f64); 0.5 * (m + h + kick + hat + snare) From c18f4f7c925116348a8d15ce6dc84171690f4118 Mon Sep 17 00:00:00 2001 From: amatgil Date: Thu, 18 Sep 2025 22:07:40 +0200 Subject: [PATCH 4/9] Make sure the random numbers are in the correct range --- src/algorithm/dyadic/mod.rs | 2 +- src/algorithm/monadic/sort.rs | 5 +---- src/run_prim.rs | 3 +-- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/algorithm/dyadic/mod.rs b/src/algorithm/dyadic/mod.rs index d1a463e53..35d8f94e5 100644 --- a/src/algorithm/dyadic/mod.rs +++ b/src/algorithm/dyadic/mod.rs @@ -2126,7 +2126,7 @@ impl Value { let elem_count = validate_size::(shape.iter().copied(), env)?; let mut data = eco_vec![0.0; elem_count]; for x in data.make_mut() { - *x = f64::from_bits(rng.next_u64()); + *x = f64::from_bits(rng.next_u64() >> 12 | 0x3FF0_0000_0000_0000) - 1.0; } Ok(Array::new(shape, data)) }; diff --git a/src/algorithm/monadic/sort.rs b/src/algorithm/monadic/sort.rs index ad2b32117..c3b49f8f2 100644 --- a/src/algorithm/monadic/sort.rs +++ b/src/algorithm/monadic/sort.rs @@ -1,10 +1,7 @@ use std::{cmp::Ordering, ptr}; use ecow::EcoVec; -use rand_xoshiro::{ - rand_core::{RngCore, SeedableRng}, - Xoshiro256Plus, -}; +use rand_xoshiro::rand_core::RngCore; use rayon::prelude::*; use crate::{algorithm::ArrayCmpSlice, random_with, val_as_arr, Array, ArrayValue, Value}; diff --git a/src/run_prim.rs b/src/run_prim.rs index 9465ca8cb..9177bbb96 100644 --- a/src/run_prim.rs +++ b/src/run_prim.rs @@ -14,7 +14,6 @@ use std::{ collections::HashMap, f64::consts::{PI, TAU}, iter::repeat_n, - mem::transmute, sync::{ atomic::{self, AtomicUsize}, OnceLock, @@ -1794,7 +1793,7 @@ thread_local! { /// Generate a random number, equivalent to [`Primitive::Rand`] pub fn random() -> f64 { - random_with(|rng| f64::from_bits(rng.next_u64())) + random_with(|rng| f64::from_bits(rng.next_u64() >> 12 | 0x3FF0_0000_0000_0000) - 1.0) } /// Access the interpreter's random number generator for the thread From 0015f2baacd94ea6beff9d6d4a779c4ddd877607 Mon Sep 17 00:00:00 2001 From: amatgil Date: Thu, 18 Sep 2025 22:07:59 +0200 Subject: [PATCH 5/9] Make site's `shuffle` call functional --- site/src/main.rs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/site/src/main.rs b/site/src/main.rs index 8c2a58b21..2730d6454 100644 --- a/site/src/main.rs +++ b/site/src/main.rs @@ -19,7 +19,10 @@ use js_sys::Date; use leptos::*; use leptos_meta::*; use leptos_router::*; -use rand::prelude::*; +use rand_xoshiro::{ + rand_core::{RngCore, SeedableRng}, + Xoshiro256Plus, +}; use uiua::{now, ConstantDef, Primitive, SysOp}; use uiua_editor::{ binding_name_class, lang, @@ -261,9 +264,23 @@ pub fn MainPage() -> impl IntoView { let indices = if visits < 4 { vec![0, rich_prims.len() - 3, rich_prims.len() - 1] } else { - let mut rng = SmallRng::seed_from_u64(visits as u64); let mut indices: Vec = (0..rich_prims.len()).collect(); - indices.shuffle(&mut rng); + { + // Shuffle indices + let l = indices.len(); + let upper = l.next_power_of_two(); + let mut rng = Xoshiro256Plus::seed_from_u64(visits as u64); + + for i in 0..indices.len() { + let index = loop { + let r = rng.next_u64() as usize % upper; + if r < l { + break r; + } + }; + indices.swap(i, index); + } + } indices.truncate(3); indices.sort_unstable(); indices From 6a205358395af961fbd75217a8b4d9ee6a20c0f9 Mon Sep 17 00:00:00 2001 From: amatgil Date: Thu, 18 Sep 2025 22:26:16 +0200 Subject: [PATCH 6/9] Seed from time properly --- src/run_prim.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/run_prim.rs b/src/run_prim.rs index 9177bbb96..bcb8a0775 100644 --- a/src/run_prim.rs +++ b/src/run_prim.rs @@ -1787,8 +1787,7 @@ fn undo_regex(env: &mut Uiua) -> UiuaResult { } thread_local! { - pub(crate) static RNG: RefCell = RefCell::new(Xoshiro256Plus::seed_from_u64( - SystemTime::now().duration_since(UNIX_EPOCH).map(|t|t.as_micros()).unwrap_or(42) as u64)); + pub(crate) static RNG: RefCell = RefCell::new(Xoshiro256Plus::seed_from_u64(f64::to_bits(crate::now()))) } /// Generate a random number, equivalent to [`Primitive::Rand`] From 5f75eaa600c9c98abebb644ec661762cacb98f6d Mon Sep 17 00:00:00 2001 From: amatgil Date: Thu, 18 Sep 2025 22:43:09 +0200 Subject: [PATCH 7/9] Add two simple tests --- tests/monadic.ua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/monadic.ua b/tests/monadic.ua index bc2a1956a..1ac297290 100644 --- a/tests/monadic.ua +++ b/tests/monadic.ua @@ -267,3 +267,7 @@ ReprTest! ←^ ˙$"\"_\" repr _" °□⊢ ⍤⤙≍ ⟜⍜binary∘ ⇡257 ⍤⤙≍ ⟜⍜binary∘ ÷⟜⇡256 ⍤⤙≍ ⟜⍜binary∘ ×π ⇡256 + +# Rand/Gen +/×♭×⊃≥₀≤₁ gen1000_1000 0 +/×♭×⊃≥₀≤₁⍥₁₀₀₀₀⚂ \ No newline at end of file From 5bc84dd95cc96436e7a8285ef984fe5a3989e191 Mon Sep 17 00:00:00 2001 From: amatgil Date: Thu, 18 Sep 2025 22:53:45 +0200 Subject: [PATCH 8/9] Tweak tests, use ahasher --- Cargo.lock | 1 + Cargo.toml | 1 + src/algorithm/dyadic/mod.rs | 5 +++-- src/run_prim.rs | 1 - tests/monadic.ua | 5 +++-- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bbd58fd09..212289384 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6564,6 +6564,7 @@ dependencies = [ name = "uiua" version = "0.18.0-dev.1" dependencies = [ + "ahash", "arboard", "bitflags 2.9.1", "bytemuck", diff --git a/Cargo.toml b/Cargo.toml index bd71ee1be..ba4511160 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -180,6 +180,7 @@ wasm-bindgen = {workspace = true, optional = true} web-sys = {version = "0.3.60", optional = true} # Window dependencies +ahash = "0.8.12" eframe = {version = "0.29.1", optional = true, features = ["persistence"]} native-dialog = {version = "0.7.0", optional = true} rand_xoshiro = "0.7.0" diff --git a/src/algorithm/dyadic/mod.rs b/src/algorithm/dyadic/mod.rs index 35d8f94e5..d8597439f 100644 --- a/src/algorithm/dyadic/mod.rs +++ b/src/algorithm/dyadic/mod.rs @@ -8,11 +8,12 @@ use core::f64; use std::{ borrow::Cow, cmp::Ordering, - hash::{DefaultHasher, Hash, Hasher}, + hash::{Hash, Hasher}, iter::{once, repeat_n}, mem::{replace, swap, take}, }; +use ahash::AHasher; use bytemuck::allocation::cast_vec; use ecow::{eco_vec, EcoVec}; use rand_xoshiro::{ @@ -2113,7 +2114,7 @@ impl Value { } /// Generate randomly seeded arrays pub fn gen(&self, seed: &Self, env: &Uiua) -> UiuaResult { - let mut hasher = DefaultHasher::new(); + let mut hasher = AHasher::default(); seed.hash(&mut hasher); let seed = hasher.finish(); let mut rng = Xoshiro256Plus::seed_from_u64(seed); diff --git a/src/run_prim.rs b/src/run_prim.rs index bcb8a0775..d45b936b3 100644 --- a/src/run_prim.rs +++ b/src/run_prim.rs @@ -18,7 +18,6 @@ use std::{ atomic::{self, AtomicUsize}, OnceLock, }, - time::{SystemTime, UNIX_EPOCH}, }; use rand_xoshiro::{ diff --git a/tests/monadic.ua b/tests/monadic.ua index 1ac297290..fc473b8f3 100644 --- a/tests/monadic.ua +++ b/tests/monadic.ua @@ -269,5 +269,6 @@ ReprTest! ←^ ˙$"\"_\" repr _" °□⊢ ⍤⤙≍ ⟜⍜binary∘ ×π ⇡256 # Rand/Gen -/×♭×⊃≥₀≤₁ gen1000_1000 0 -/×♭×⊃≥₀≤₁⍥₁₀₀₀₀⚂ \ No newline at end of file +⍤⤙≍1 /×♭×⊃≥₀≤₁ gen1000_1000 0 +⍤⤙≍1 /×♭×⊃≥₀≤₁⍥₁₀₀₀₀⚂ +⍤⤙≍ 1000_1000 △gen1000_1000 0 \ No newline at end of file From 132b4b2f95b4f3aad1adf1127791ece616ec9744 Mon Sep 17 00:00:00 2001 From: Kai Schmidt Date: Thu, 23 Oct 2025 16:38:05 -0700 Subject: [PATCH 9/9] fix a clippy lint --- .clippy.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/.clippy.toml b/.clippy.toml index bdd96d81d..9d2eb6849 100644 --- a/.clippy.toml +++ b/.clippy.toml @@ -11,6 +11,7 @@ allowed-duplicate-crates = [ "objc2-foundation", "proc-macro-utils", # TODO: can be resolved by updating leptos crates to 0.7.0 "serde_qs", # TODO: can be resolved by updating leptos crates to 0.7.0 + "rand_core", "rustix", "linux-raw-sys", # needed by rustix@0.38 "thiserror",