From b60100c806ead152cf2598f58e521d04dec3f78f Mon Sep 17 00:00:00 2001 From: Peter McEvoy Date: Fri, 10 Mar 2023 12:18:40 -0500 Subject: [PATCH 01/11] Apply lints suggested by cargo clippy --- rust/ares/benches/cue_pill.rs | 3 +- rust/ares/src/hamt.rs | 40 ++++++------ rust/ares/src/interpreter.rs | 14 ++-- rust/ares/src/jets/math.rs | 114 +++++++++++++-------------------- rust/ares/src/main.rs | 2 +- rust/ares/src/mem.rs | 10 +-- rust/ares/src/newt.rs | 5 +- rust/ares/src/noun.rs | 18 +++--- rust/ares/src/serf.rs | 30 +++------ rust/ares/src/serialization.rs | 6 +- rust/ares/src/snapshot.rs | 2 +- 11 files changed, 104 insertions(+), 140 deletions(-) diff --git a/rust/ares/benches/cue_pill.rs b/rust/ares/benches/cue_pill.rs index cf61943..f7e9834 100644 --- a/rust/ares/benches/cue_pill.rs +++ b/rust/ares/benches/cue_pill.rs @@ -1,7 +1,6 @@ use ares::mem::NockStack; use ares::noun::{DirectAtom, IndirectAtom}; use ares::serialization::{cue, jam}; -use memmap; use std::env; use std::fs::{File, OpenOptions}; use std::io; @@ -11,7 +10,7 @@ use std::time::SystemTime; fn main() -> io::Result<()> { let filename = env::args().nth(1).expect("Must provide input filename"); - let output_filename = format!("{}.out", filename.clone()); + let output_filename = format!("{}.out", filename); let f = File::open(filename)?; let in_len = f.metadata()?.len(); let mut stack = NockStack::new(1 << 10 << 10 << 10, 0); diff --git a/rust/ares/src/hamt.rs b/rust/ares/src/hamt.rs index 0bed472..be088bc 100644 --- a/rust/ares/src/hamt.rs +++ b/rust/ares/src/hamt.rs @@ -69,7 +69,7 @@ impl MutHamt { unsafe { 'lookup: loop { let chunk = mug & 0x1f; - mug = mug >> 5; + mug >>= 5; match (*stem).entry(chunk) { None => { break None; @@ -79,8 +79,8 @@ impl MutHamt { } Some(Right(leaf)) => { for pair in leaf.to_mut_slice().iter_mut() { - if unifying_equality(stack, n, &mut (*pair).0) { - break 'lookup Some((*pair).1); + if unifying_equality(stack, n, &mut pair.0) { + break 'lookup Some(pair.1); } } break None; @@ -97,13 +97,13 @@ impl MutHamt { unsafe { 'insert: loop { let chunk = mug & 0x1f; - mug = mug >> 5; + mug >>= 5; match (*stem).entry(chunk) { None => { let new_leaf_buffer = stack.struct_alloc(1); *new_leaf_buffer = (*n, t); - (*stem).bitmap = (*stem).bitmap | chunk_to_bit(chunk); - (*stem).typemap = (*stem).typemap & !chunk_to_bit(chunk); + (*stem).bitmap |= chunk_to_bit(chunk); + (*stem).typemap &= !chunk_to_bit(chunk); (*stem).buffer[chunk as usize] = MutEntry { leaf: Leaf { len: 1, @@ -119,8 +119,8 @@ impl MutHamt { } Some(Right(leaf)) => { for pair in leaf.to_mut_slice().iter_mut() { - if unifying_equality(stack, n, &mut (*pair).0) { - (*pair).1 = t; + if unifying_equality(stack, n, &mut pair.0) { + pair.1 = t; break 'insert; } } @@ -142,9 +142,9 @@ impl MutHamt { let leaf_chunk = (leaf_mug >> ((depth + 1) * 5)) & 0x1f; (*new_stem).bitmap = chunk_to_bit(leaf_chunk); (*new_stem).typemap = 0; - (*new_stem).buffer[leaf_chunk as usize] = MutEntry { leaf: leaf }; + (*new_stem).buffer[leaf_chunk as usize] = MutEntry { leaf }; (*stem).buffer[chunk as usize] = MutEntry { stem: new_stem }; - (*stem).typemap = (*stem).typemap | chunk_to_bit(chunk); + (*stem).typemap |= chunk_to_bit(chunk); stem = new_stem; depth += 1; continue; @@ -281,7 +281,7 @@ impl Hamt { let mut mug = mug_u32(stack, *n); 'lookup: loop { let chunk = mug & 0x1F; // 5 bits - mug = mug >> 5; + mug >>= 5; match stem.entry(chunk) { None => { break None; @@ -314,7 +314,7 @@ impl Hamt { unsafe { 'insert: loop { let chunk = mug & 0x1F; // 5 bits - mug = mug >> 5; + mug >>= 5; match stem.entry(chunk) { None => { let new_leaf_buffer = stack.struct_alloc(1); @@ -399,7 +399,7 @@ impl Hamt { // next time around assert!(leaf.len == 1); let fake_buffer = stack.struct_alloc(1); - *fake_buffer = Entry { leaf: leaf }; + *fake_buffer = Entry { leaf }; // get the mug chunk for the noun at *the next level* so // we can build a fake stem for it let fake_mug = mug_u32(stack, (*leaf.buffer).0); @@ -430,13 +430,13 @@ impl Hamt { impl Preserve for Hamt { unsafe fn preserve(&mut self, stack: &mut NockStack) { - if stack.in_frame((*self).0.buffer) { - let dest_buffer = stack.struct_alloc_in_previous_frame((*self).0.size()); - copy_nonoverlapping((*self).0.buffer, dest_buffer, (*self).0.size()); - (*self).0.buffer = dest_buffer; + if stack.in_frame(self.0.buffer) { + let dest_buffer = stack.struct_alloc_in_previous_frame(self.0.size()); + copy_nonoverlapping(self.0.buffer, dest_buffer, self.0.size()); + self.0.buffer = dest_buffer; let traversal_stack = stack.struct_alloc::<(Stem, u32)>(6); let mut traversal_depth = 1; - *traversal_stack = ((*self).0, 0); + *traversal_stack = (self.0, 0); 'preserve: loop { if traversal_depth == 0 { break; @@ -487,8 +487,8 @@ impl Preserve for Hamt { buffer: dest_buffer, }; for pair in new_leaf.to_mut_slice().iter_mut() { - (*pair).0.preserve(stack); - (*pair).1.preserve(stack); + pair.0.preserve(stack); + pair.1.preserve(stack); } *(stem.buffer.add(idx) as *mut Entry) = Entry { leaf: new_leaf }; } diff --git a/rust/ares/src/interpreter.rs b/rust/ares/src/interpreter.rs index 1d59dce..eb818d7 100644 --- a/rust/ares/src/interpreter.rs +++ b/rust/ares/src/interpreter.rs @@ -653,20 +653,20 @@ fn match_pre_hint( return Err(()); } } - return Ok(jet_res); + Ok(jet_res) } else { // Print jet errors and punt to Nock eprintln!("\rJet {} failed", jet_name); - return Err(()); + Err(()) } } tas!(b"memo") => { let formula = unsafe { *stack.local_noun_pointer(2) }; let mut key = Cell::new(stack, subject, formula).as_noun(); if let Some(res) = cache.lookup(stack, &mut key) { - return Ok(res); + Ok(res) } else { - return Err(()); + Err(()) } } _ => Err(()), @@ -711,10 +711,8 @@ fn match_post_hinted( let formula = unsafe { *stack.local_noun_pointer(2) }; let mut key = Cell::new(stack, subject, formula).as_noun(); *cache = cache.insert(stack, &mut key, res); - return Ok(()); - } - _ => { - return Err(()); + Ok(()) } + _ => Err(()), } } diff --git a/rust/ares/src/jets/math.rs b/rust/ares/src/jets/math.rs index 92ff336..222d7da 100644 --- a/rust/ares/src/jets/math.rs +++ b/rust/ares/src/jets/math.rs @@ -21,7 +21,7 @@ use bitvec::prelude::{BitSlice, Lsb0}; use either::Either::*; use ibig::ops::DivRem; use ibig::UBig; -use std::cmp; +use std::{cmp, convert::TryFrom}; crate::gdb!(); @@ -136,15 +136,13 @@ pub fn jet_div(stack: &mut NockStack, subject: Noun) -> Result { if unsafe { b.as_noun().raw_equals(D(0)) } { Err(Deterministic) + } else if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) { + Ok(unsafe { DirectAtom::new_unchecked(a.data() / b.data()) }.as_noun()) } else { - if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) { - Ok(unsafe { DirectAtom::new_unchecked(a.data() / b.data()) }.as_noun()) - } else { - let a_big = a.as_ubig(stack); - let b_big = b.as_ubig(stack); - let res = UBig::div_stack(stack, a_big, b_big); - Ok(Atom::from_ubig(stack, &res).as_noun()) - } + let a_big = a.as_ubig(stack); + let b_big = b.as_ubig(stack); + let res = UBig::div_stack(stack, a_big, b_big); + Ok(Atom::from_ubig(stack, &res).as_noun()) } } @@ -155,13 +153,11 @@ pub fn jet_mod(stack: &mut NockStack, subject: Noun) -> Result { if unsafe { b.as_noun().raw_equals(D(0)) } { Err(Deterministic) + } else if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) { + Ok(unsafe { DirectAtom::new_unchecked(a.data() % b.data()) }.as_noun()) } else { - if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) { - Ok(unsafe { DirectAtom::new_unchecked(a.data() % b.data()) }.as_noun()) - } else { - let res = a.as_ubig(stack) % b.as_ubig(stack); - Ok(Atom::from_ubig(stack, &res).as_noun()) - } + let res = a.as_ubig(stack) % b.as_ubig(stack); + Ok(Atom::from_ubig(stack, &res).as_noun()) } } @@ -204,18 +200,14 @@ pub fn jet_lth(stack: &mut NockStack, subject: Noun) -> Result { } else { NO } + } else if a.bit_size() < b.bit_size() { + YES + } else if a.bit_size() > b.bit_size() { + NO + } else if a.as_ubig(stack) < b.as_ubig(stack) { + YES } else { - if a.bit_size() < b.bit_size() { - YES - } else if a.bit_size() > b.bit_size() { - NO - } else { - if a.as_ubig(stack) < b.as_ubig(stack) { - YES - } else { - NO - } - } + NO }) } @@ -230,18 +222,14 @@ pub fn jet_lte(stack: &mut NockStack, subject: Noun) -> Result { } else { NO } + } else if a.bit_size() < b.bit_size() { + YES + } else if a.bit_size() > b.bit_size() { + NO + } else if a.as_ubig(stack) <= b.as_ubig(stack) { + YES } else { - if a.bit_size() < b.bit_size() { - YES - } else if a.bit_size() > b.bit_size() { - NO - } else { - if a.as_ubig(stack) <= b.as_ubig(stack) { - YES - } else { - NO - } - } + NO }) } @@ -256,18 +244,14 @@ pub fn jet_gth(stack: &mut NockStack, subject: Noun) -> Result { } else { NO } + } else if a.bit_size() > b.bit_size() { + YES + } else if a.bit_size() < b.bit_size() { + NO + } else if a.as_ubig(stack) > b.as_ubig(stack) { + YES } else { - if a.bit_size() > b.bit_size() { - YES - } else if a.bit_size() < b.bit_size() { - NO - } else { - if a.as_ubig(stack) > b.as_ubig(stack) { - YES - } else { - NO - } - } + NO }) } @@ -282,18 +266,14 @@ pub fn jet_gte(stack: &mut NockStack, subject: Noun) -> Result { } else { NO } + } else if a.bit_size() > b.bit_size() { + YES + } else if a.bit_size() < b.bit_size() { + NO + } else if a.as_ubig(stack) >= b.as_ubig(stack) { + YES } else { - if a.bit_size() > b.bit_size() { - YES - } else if a.bit_size() < b.bit_size() { - NO - } else { - if a.as_ubig(stack) >= b.as_ubig(stack) { - YES - } else { - NO - } - } + NO }) } @@ -468,7 +448,7 @@ pub fn jet_can(stack: &mut NockStack, subject: Noun) -> Result { } let original_list = raw_slot(arg, 3); - let mut len = 0 as usize; + let mut len = 0usize; let mut list = original_list; loop { if unsafe { list.raw_equals(D(0)) } { @@ -477,7 +457,7 @@ pub fn jet_can(stack: &mut NockStack, subject: Noun) -> Result { let cell = list.as_cell()?; let item = cell.head().as_cell()?; - let step = item.head().as_direct()?.data() as usize; + let step = usize::try_from(item.head().as_direct()?.data()).unwrap(); len = len.checked_add(step).ok_or(NonDeterministic)?; list = cell.tail(); @@ -515,7 +495,7 @@ pub fn jet_rep(stack: &mut NockStack, subject: Noun) -> Result { let (bloq, step) = bite(raw_slot(arg, 2))?; let original_list = raw_slot(arg, 3); - let mut len = 0 as usize; + let mut len = 0usize; let mut list = original_list; loop { if unsafe { list.raw_equals(D(0)) } { @@ -663,13 +643,11 @@ unsafe fn chop( pub fn met(bloq: usize, a: Atom) -> usize { if unsafe { a.as_noun().raw_equals(D(0)) } { 0 + } else if bloq < 6 { + (a.bit_size() + ((1 << bloq) - 1)) >> bloq } else { - if bloq < 6 { - (a.bit_size() + ((1 << bloq) - 1)) >> bloq - } else { - let bloq_word = bloq - 6; - (a.size() + ((1 << bloq_word) - 1)) >> bloq_word - } + let bloq_word = bloq - 6; + (a.size() + ((1 << bloq_word) - 1)) >> bloq_word } } diff --git a/rust/ares/src/main.rs b/rust/ares/src/main.rs index bace6be..772f9c6 100644 --- a/rust/ares/src/main.rs +++ b/rust/ares/src/main.rs @@ -33,7 +33,7 @@ fn main() -> io::Result<()> { return serf(); } - let output_filename = format!("{}.out", filename.clone()); + let output_filename = format!("{}.out", filename); let f = File::open(filename)?; let in_len = f.metadata()?.len(); let mut stack = NockStack::new(8 << 10 << 10, 0); diff --git a/rust/ares/src/mem.rs b/rust/ares/src/mem.rs index cc97c70..f8daa61 100644 --- a/rust/ares/src/mem.rs +++ b/rust/ares/src/mem.rs @@ -98,12 +98,12 @@ impl NockStack { *frame_pointer.add(1) = ptr::null::() as u64; }; NockStack { - start: start, - size: size, + start, + size, polarity: Polarity::West, - stack_pointer: stack_pointer, - frame_pointer: frame_pointer, - memory: memory, + stack_pointer, + frame_pointer, + memory, } } diff --git a/rust/ares/src/newt.rs b/rust/ares/src/newt.rs index 5231c94..dbba09f 100644 --- a/rust/ares/src/newt.rs +++ b/rust/ares/src/newt.rs @@ -82,7 +82,7 @@ impl Newt { fn write_noun(&mut self, stack: &mut NockStack, noun: Noun) { let atom = jam(stack, noun); let size = atom.size() << 3; - let mut buf = vec![0 as u8; size + 5]; + let mut buf = vec![0u8; size + 5]; buf[1] = size as u8; buf[2] = (size >> 8) as u8; buf[3] = (size >> 16) as u8; @@ -192,8 +192,7 @@ impl Newt { /** Fetch next message. */ pub fn next(&mut self, stack: &mut NockStack) -> Option { - let mut header: Vec = Vec::with_capacity(5); - header.resize(5, 0); + let mut header: Vec = vec![0; 5]; if let Err(err) = self.input.read_exact(&mut header) { if err.kind() == std::io::ErrorKind::UnexpectedEof { return None; diff --git a/rust/ares/src/noun.rs b/rust/ares/src/noun.rs index 380bc0a..ade5270 100644 --- a/rust/ares/src/noun.rs +++ b/rust/ares/src/noun.rs @@ -63,7 +63,7 @@ fn acyclic_noun_go(noun: Noun, seen: &mut IntMap<()>) -> bool { match noun.as_either_atom_cell() { Either::Left(_atom) => true, Either::Right(cell) => { - if let Some(_) = seen.get(cell.0) { + if seen.get(cell.0).is_some() { false } else { seen.insert(cell.0, ()); @@ -155,8 +155,8 @@ impl DirectAtom { self.0 } - pub fn as_bitslice<'a>(&'a self) -> &'a BitSlice { - &(BitSlice::from_element(&self.0)) + pub fn as_bitslice(&self) -> &BitSlice { + BitSlice::from_element(&self.0) } } @@ -345,16 +345,16 @@ impl IndirectAtom { unsafe { self.to_raw_pointer().add(2) as *const u64 } } - pub fn as_slice<'a>(&'a self) -> &'a [u64] { + pub fn as_slice(&self) -> &[u64] { unsafe { from_raw_parts(self.data_pointer(), self.size()) } } - pub fn as_bytes<'a>(&'a self) -> &'a [u8] { + pub fn as_bytes(&self) -> &[u8] { unsafe { from_raw_parts(self.data_pointer() as *const u8, self.size() << 3) } } /** BitSlice view on an indirect atom, with lifetime tied to reference to indirect atom. */ - pub fn as_bitslice<'a>(&'a self) -> &'a BitSlice { + pub fn as_bitslice(&self) -> &BitSlice { BitSlice::from_slice(self.as_slice()) } @@ -617,11 +617,11 @@ impl Atom { } } - pub fn as_bitslice<'a>(&'a self) -> &'a BitSlice { + pub fn as_bitslice(&self) -> &BitSlice { if self.is_indirect() { unsafe { self.indirect.as_bitslice() } } else { - unsafe { &(self.direct.as_bitslice()) } + unsafe { self.direct.as_bitslice() } } } @@ -843,7 +843,7 @@ impl Noun { } pub unsafe fn from_raw(raw: u64) -> Noun { - Noun { raw: raw } + Noun { raw } } /** Produce the total size of a noun, in words diff --git a/rust/ares/src/serf.rs b/rust/ares/src/serf.rs index a19a0c3..6df6767 100644 --- a/rust/ares/src/serf.rs +++ b/rust/ares/src/serf.rs @@ -31,8 +31,8 @@ pub fn serf() -> io::Result<()> { snap_path.push("chk"); create_dir_all(&snap_path)?; - let ref mut stack = NockStack::new(96 << 10 << 10, 0); - let ref mut newt = Newt::new(); + let stack = &mut NockStack::new(96 << 10 << 10, 0); + let newt = &mut Newt::new(); let mut event_number; let mut arvo; @@ -42,13 +42,7 @@ pub fn serf() -> io::Result<()> { newt.ripe(stack, event_number, mug as u64); // Can't use for loop because it borrows newt - loop { - let writ = if let Some(writ) = newt.next(stack) { - writ - } else { - break; - }; - + while let Some(writ) = newt.next(stack) { let tag = raw_slot(writ, 2).as_direct().unwrap(); match tag.data() { tas!(b"live") => { @@ -89,18 +83,14 @@ pub fn serf() -> io::Result<()> { // event_number = raw_slot(writ, 6).as_direct().unwrap().data(); let mut lit = raw_slot(writ, 7); - loop { - if let Ok(cell) = lit.as_cell() { - if run { - let ovo = cell.head(); - let res = slam(stack, newt, arvo, POKE_AXIS, ovo).as_cell().unwrap(); - arvo = res.tail(); - } - event_number += 1; - lit = cell.tail(); - } else { - break; + while let Ok(cell) = lit.as_cell() { + if run { + let ovo = cell.head(); + let res = slam(stack, newt, arvo, POKE_AXIS, ovo).as_cell().unwrap(); + arvo = res.tail(); } + event_number += 1; + lit = cell.tail(); } newt.play_done(stack, 0); } diff --git a/rust/ares/src/serialization.rs b/rust/ares/src/serialization.rs index 2d85d13..d7f6270 100644 --- a/rust/ares/src/serialization.rs +++ b/rust/ares/src/serialization.rs @@ -168,9 +168,9 @@ pub fn jam(stack: &mut NockStack, noun: Noun) -> Atom { let (atom, slice) = unsafe { IndirectAtom::new_raw_mut_bitslice(stack, size) }; let mut state = JamState { cursor: 0, - size: size, - atom: atom, - slice: slice, + size, + atom, + slice, }; stack.push(1); unsafe { diff --git a/rust/ares/src/snapshot.rs b/rust/ares/src/snapshot.rs index 58ce27c..966b88d 100644 --- a/rust/ares/src/snapshot.rs +++ b/rust/ares/src/snapshot.rs @@ -97,7 +97,7 @@ fn latest_snapshot( snap_path: PathBuf, ) -> io::Result<(u8, u64, IndirectAtom)> { let res0 = load_snapshot(stack, snap_path.clone(), 0); - let res1 = load_snapshot(stack, snap_path.clone(), 1); + let res1 = load_snapshot(stack, snap_path, 1); match (res0, res1) { (Ok((event_number_0, state_0)), Ok((event_number_1, state_1))) => { From a7807fd50fa909a61930a466e7d257fa54a3bfb2 Mon Sep 17 00:00:00 2001 From: Peter McEvoy Date: Tue, 14 Mar 2023 11:37:12 -0400 Subject: [PATCH 02/11] Add cargo clippy step to CI --- .github/workflows/ares-shared.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ares-shared.yml b/.github/workflows/ares-shared.yml index 4f079ef..714c676 100644 --- a/.github/workflows/ares-shared.yml +++ b/.github/workflows/ares-shared.yml @@ -20,6 +20,9 @@ jobs: - name: Format run: cargo fmt --check + - name: Lint + run: cargo clippy -- --deny warnings + - name: Build run: cargo build --verbose From 290b964d110f73b66209c547fcaab6310b452c34 Mon Sep 17 00:00:00 2001 From: Peter McEvoy Date: Tue, 14 Mar 2023 11:40:07 -0400 Subject: [PATCH 03/11] Apply additional lints suggested by cargo clippy --- rust/ares/src/hamt.rs | 6 ++++++ rust/ares/src/newt.rs | 6 ++++++ rust/ares/src/noun.rs | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/rust/ares/src/hamt.rs b/rust/ares/src/hamt.rs index be088bc..6caa889 100644 --- a/rust/ares/src/hamt.rs +++ b/rust/ares/src/hamt.rs @@ -428,6 +428,12 @@ impl Hamt { } } +impl Default for Hamt { + fn default() -> Self { + Self::new() + } +} + impl Preserve for Hamt { unsafe fn preserve(&mut self, stack: &mut NockStack) { if stack.in_frame(self.0.buffer) { diff --git a/rust/ares/src/newt.rs b/rust/ares/src/newt.rs index dbba09f..f9443ed 100644 --- a/rust/ares/src/newt.rs +++ b/rust/ares/src/newt.rs @@ -218,3 +218,9 @@ impl Newt { Some(cue(stack, atom)) } } + +impl Default for Newt { + fn default() -> Self { + Self::new() + } +} diff --git a/rust/ares/src/noun.rs b/rust/ares/src/noun.rs index ade5270..03578b6 100644 --- a/rust/ares/src/noun.rs +++ b/rust/ares/src/noun.rs @@ -370,7 +370,7 @@ impl IndirectAtom { if index == 0 || *(data.add(index)) != 0 { break; } - index = index - 1; + index -= 1; } *(self.to_raw_pointer_mut().add(1)) = (index + 1) as u64; self From fff84ada171c1cc66c68b1e7d75354e0e7b74fbe Mon Sep 17 00:00:00 2001 From: Peter McEvoy Date: Tue, 14 Mar 2023 12:07:47 -0400 Subject: [PATCH 04/11] Add noun::Error and noun::Result --- rust/ares/src/jets.rs | 8 ++++++- rust/ares/src/noun.rs | 56 ++++++++++++++++++++++++++++++------------- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/rust/ares/src/jets.rs b/rust/ares/src/jets.rs index 5225f03..293d907 100644 --- a/rust/ares/src/jets.rs +++ b/rust/ares/src/jets.rs @@ -2,7 +2,7 @@ pub mod math; use crate::jets::math::*; use crate::mem::NockStack; -use crate::noun::Noun; +use crate::noun::{self, Noun}; use ares_macros::tas; crate::gdb!(); @@ -24,6 +24,12 @@ impl From<()> for JetErr { } } +impl From for JetErr { + fn from(_err: noun::Error) -> Self { + Self::NonDeterministic + } +} + impl From for () { fn from(_: JetErr) -> Self {} } diff --git a/rust/ares/src/noun.rs b/rust/ares/src/noun.rs index 03578b6..061e9d5 100644 --- a/rust/ares/src/noun.rs +++ b/rust/ares/src/noun.rs @@ -97,6 +97,30 @@ fn is_cell(noun: u64) -> bool { noun & CELL_MASK == CELL_TAG } +/** A noun-related error. */ +#[derive(Debug, PartialEq)] +pub enum Error { + /** Expected type [`Allocated`]. */ + NotAllocated, + /** Expected type [`Atom`]. */ + NotAtom, + /** Expected type [`Cell`]. */ + NotCell, + /** Expected type [`DirectAtom`]. */ + NotDirectAtom, + /** Expected type [`IndirectAtom`]. */ + NotIndirectAtom, + /** The value can't be represented by the given type. */ + NotRepresentable, +} + +impl From for () { + fn from(_: Error) -> Self {} +} + +/** A [`Result`] that returns an [`Error`] on error. */ +pub type Result = std::result::Result; + /** A direct atom. * * Direct atoms represent an atom up to and including DIRECT_MAX as a machine word. @@ -117,9 +141,9 @@ impl DirectAtom { } /** Create a new direct atom, or return Err if the value is greater than DIRECT_MAX */ - pub const fn new(value: u64) -> Result { + pub const fn new(value: u64) -> Result { if value > DIRECT_MAX { - Err(()) + Err(Error::NotRepresentable) } else { Ok(DirectAtom(value)) } @@ -593,19 +617,19 @@ impl Atom { unsafe { is_indirect_atom(self.raw) } } - pub fn as_direct(&self) -> Result { + pub fn as_direct(&self) -> Result { if self.is_direct() { unsafe { Ok(self.direct) } } else { - Err(()) + Err(Error::NotDirectAtom) } } - pub fn as_indirect(&self) -> Result { + pub fn as_indirect(&self) -> Result { if self.is_indirect() { unsafe { Ok(self.indirect) } } else { - Err(()) + Err(Error::NotIndirectAtom) } } @@ -781,43 +805,43 @@ impl Noun { unsafe { is_cell(self.raw) } } - pub fn as_direct(&self) -> Result { + pub fn as_direct(&self) -> Result { if self.is_direct() { unsafe { Ok(self.direct) } } else { - Err(()) + Err(Error::NotDirectAtom) } } - pub fn as_indirect(&self) -> Result { + pub fn as_indirect(&self) -> Result { if self.is_indirect() { unsafe { Ok(self.indirect) } } else { - Err(()) + Err(Error::NotIndirectAtom) } } - pub fn as_cell(&self) -> Result { + pub fn as_cell(&self) -> Result { if self.is_cell() { unsafe { Ok(self.cell) } } else { - Err(()) + Err(Error::NotCell) } } - pub fn as_atom(&self) -> Result { + pub fn as_atom(&self) -> Result { if self.is_atom() { unsafe { Ok(self.atom) } } else { - Err(()) + Err(Error::NotAtom) } } - pub fn as_allocated(&self) -> Result { + pub fn as_allocated(&self) -> Result { if self.is_allocated() { unsafe { Ok(self.allocated) } } else { - Err(()) + Err(Error::NotAllocated) } } From 38d3c124ce96e99418823eaf2a72fc24e40c1ee4 Mon Sep 17 00:00:00 2001 From: Peter McEvoy Date: Tue, 14 Mar 2023 12:18:00 -0400 Subject: [PATCH 05/11] Return Option instead of Result from jets::get_jet() --- rust/ares/src/interpreter.rs | 2 +- rust/ares/src/jets.rs | 56 ++++++++++++++++++------------------ 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/rust/ares/src/interpreter.rs b/rust/ares/src/interpreter.rs index eb818d7..6e6195a 100644 --- a/rust/ares/src/interpreter.rs +++ b/rust/ares/src/interpreter.rs @@ -640,7 +640,7 @@ fn match_pre_hint( let jet_formula = cell.tail().as_cell()?; let jet_name = jet_formula.tail(); - let jet = jets::get_jet(jet_name)?; + let jet = jets::get_jet(jet_name).ok_or(())?; if let Ok(mut jet_res) = jet(stack, subject) { // if in test mode, check that the jet returns the same result as the raw nock if jets::get_jet_test_mode(jet_name) { diff --git a/rust/ares/src/jets.rs b/rust/ares/src/jets.rs index 293d907..3b86405 100644 --- a/rust/ares/src/jets.rs +++ b/rust/ares/src/jets.rs @@ -34,36 +34,36 @@ impl From for () { fn from(_: JetErr) -> Self {} } -pub fn get_jet(jet_name: Noun) -> Result { - match jet_name.as_direct()?.data() { - tas!(b"dec") => Ok(jet_dec), - tas!(b"add") => Ok(jet_add), - tas!(b"sub") => Ok(jet_sub), - tas!(b"mul") => Ok(jet_mul), - tas!(b"div") => Ok(jet_div), - tas!(b"mod") => Ok(jet_mod), - tas!(b"dvr") => Ok(jet_dvr), - tas!(b"lth") => Ok(jet_lth), - tas!(b"lte") => Ok(jet_lte), - tas!(b"gth") => Ok(jet_gth), - tas!(b"gte") => Ok(jet_gte), - tas!(b"bex") => Ok(jet_bex), - tas!(b"lsh") => Ok(jet_lsh), - tas!(b"rsh") => Ok(jet_rsh), - tas!(b"con") => Ok(jet_con), - tas!(b"dis") => Ok(jet_dis), - tas!(b"mix") => Ok(jet_mix), - tas!(b"end") => Ok(jet_end), - tas!(b"cat") => Ok(jet_cat), - tas!(b"cut") => Ok(jet_cut), - tas!(b"can") => Ok(jet_can), - tas!(b"rep") => Ok(jet_rep), - tas!(b"rip") => Ok(jet_rip), - tas!(b"met") => Ok(jet_met), - tas!(b"mug") => Ok(jet_mug), +pub fn get_jet(jet_name: Noun) -> Option { + match jet_name.as_direct().ok()?.data() { + tas!(b"dec") => Some(jet_dec), + tas!(b"add") => Some(jet_add), + tas!(b"sub") => Some(jet_sub), + tas!(b"mul") => Some(jet_mul), + tas!(b"div") => Some(jet_div), + tas!(b"mod") => Some(jet_mod), + tas!(b"dvr") => Some(jet_dvr), + tas!(b"lth") => Some(jet_lth), + tas!(b"lte") => Some(jet_lte), + tas!(b"gth") => Some(jet_gth), + tas!(b"gte") => Some(jet_gte), + tas!(b"bex") => Some(jet_bex), + tas!(b"lsh") => Some(jet_lsh), + tas!(b"rsh") => Some(jet_rsh), + tas!(b"con") => Some(jet_con), + tas!(b"dis") => Some(jet_dis), + tas!(b"mix") => Some(jet_mix), + tas!(b"end") => Some(jet_end), + tas!(b"cat") => Some(jet_cat), + tas!(b"cut") => Some(jet_cut), + tas!(b"can") => Some(jet_can), + tas!(b"rep") => Some(jet_rep), + tas!(b"rip") => Some(jet_rip), + tas!(b"met") => Some(jet_met), + tas!(b"mug") => Some(jet_mug), _ => { // eprintln!("Unknown jet: {:?}", jet_name); - Err(()) + None } } } From 4ceb48b5cf756dc99870291f21821c582566d7b8 Mon Sep 17 00:00:00 2001 From: Peter McEvoy Date: Tue, 14 Mar 2023 12:19:12 -0400 Subject: [PATCH 06/11] Add local type aliases for HAMT stem entries --- rust/ares/src/hamt.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rust/ares/src/hamt.rs b/rust/ares/src/hamt.rs index 6caa889..a8b1531 100644 --- a/rust/ares/src/hamt.rs +++ b/rust/ares/src/hamt.rs @@ -5,6 +5,10 @@ use either::Either::{self, *}; use std::ptr::{copy_nonoverlapping, null}; use std::slice; +type MutStemEntry = Either<*mut MutStem, Leaf>; + +type StemEntry = Either, Leaf>; + #[inline] fn chunk_to_bit(chunk: u32) -> u32 { 1u32 << chunk @@ -37,7 +41,7 @@ impl MutStem { } #[inline] - fn entry(&self, chunk: u32) -> Option, Leaf>> { + fn entry(&self, chunk: u32) -> Option> { if self.has_index(chunk) { if self.typemap & chunk_to_bit(chunk) != 0 { unsafe { Some(Left(self.buffer[chunk as usize].stem)) } @@ -201,7 +205,7 @@ impl Stem { } #[inline] - fn entry(self, chunk: u32) -> Option<(Either, Leaf>, usize)> { + fn entry(self, chunk: u32) -> Option<(StemEntry, usize)> { self.index(chunk).map(|idx| { ( unsafe { From 36b591f3c8d00f87a2c1e31bf387354b33af1d93 Mon Sep 17 00:00:00 2001 From: Peter McEvoy Date: Tue, 14 Mar 2023 12:21:38 -0400 Subject: [PATCH 07/11] Comment out partial implementation of get_jet_test_mode() --- rust/ares/src/jets.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rust/ares/src/jets.rs b/rust/ares/src/jets.rs index 3b86405..03bb4a5 100644 --- a/rust/ares/src/jets.rs +++ b/rust/ares/src/jets.rs @@ -69,8 +69,11 @@ pub fn get_jet(jet_name: Noun) -> Option { } pub fn get_jet_test_mode(jet_name: Noun) -> bool { + /* match jet_name.as_direct().unwrap().data() { - // tas!(b"cut") => true, + tas!(b"cut") => true, _ => false, } + */ + false } From 38462557e56fa9a7c3cd3b41cb64c0f3b9448936 Mon Sep 17 00:00:00 2001 From: Peter McEvoy Date: Tue, 14 Mar 2023 18:24:51 -0400 Subject: [PATCH 08/11] Add clippy to Nix shell --- rust/shell.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/shell.nix b/rust/shell.nix index 821ba53..ac90189 100644 --- a/rust/shell.nix +++ b/rust/shell.nix @@ -7,6 +7,7 @@ pkgs.mkShell { packages = with pkgs; [ (fenix.stable.withComponents [ "cargo" + "clippy" "rustc" "rustfmt" "rust-src" From be2af4423172db35b6e4bfc363f9d65a7db19914 Mon Sep 17 00:00:00 2001 From: Peter McEvoy Date: Tue, 14 Mar 2023 18:26:10 -0400 Subject: [PATCH 09/11] Remove unused lifetime from Cell::tail_as_mut() --- rust/ares/src/noun.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ares/src/noun.rs b/rust/ares/src/noun.rs index 061e9d5..1190094 100644 --- a/rust/ares/src/noun.rs +++ b/rust/ares/src/noun.rs @@ -469,7 +469,7 @@ impl Cell { &mut (*self.to_raw_pointer_mut()).head as *mut Noun } - pub unsafe fn tail_as_mut<'a>(mut self) -> *mut Noun { + pub unsafe fn tail_as_mut(mut self) -> *mut Noun { &mut (*self.to_raw_pointer_mut()).tail as *mut Noun } From f8b05fc53b345287c79a84860322c1f452b44bcf Mon Sep 17 00:00:00 2001 From: Peter McEvoy Date: Tue, 14 Mar 2023 18:27:03 -0400 Subject: [PATCH 10/11] Add leading _ to jet_name parameter --- rust/ares/src/jets.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ares/src/jets.rs b/rust/ares/src/jets.rs index 03bb4a5..354b8ad 100644 --- a/rust/ares/src/jets.rs +++ b/rust/ares/src/jets.rs @@ -68,7 +68,7 @@ pub fn get_jet(jet_name: Noun) -> Option { } } -pub fn get_jet_test_mode(jet_name: Noun) -> bool { +pub fn get_jet_test_mode(_jet_name: Noun) -> bool { /* match jet_name.as_direct().unwrap().data() { tas!(b"cut") => true, From 997c4d2b20cb6140e47169a2fe08cc29e9d64703 Mon Sep 17 00:00:00 2001 From: Peter McEvoy Date: Tue, 14 Mar 2023 18:27:28 -0400 Subject: [PATCH 11/11] Disable missing_safety_doc lint --- .github/workflows/ares-shared.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ares-shared.yml b/.github/workflows/ares-shared.yml index 714c676..78e032b 100644 --- a/.github/workflows/ares-shared.yml +++ b/.github/workflows/ares-shared.yml @@ -21,7 +21,7 @@ jobs: run: cargo fmt --check - name: Lint - run: cargo clippy -- --deny warnings + run: cargo clippy -- --deny warnings --allow clippy::missing_safety_doc - name: Build run: cargo build --verbose