From: Skgland Date: Thu, 27 Nov 2025 19:07:13 +0000 (+0100) Subject: fix `function_casts_as_integer` warning X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=797a8f86110b846c4c5201c7888774132143ec62;p=scryer-prolog.git fix `function_casts_as_integer` warning Comparing addresses of function pointers is brittle. Functions may be duplicated resulting in function pointers to the same function to compare !=. Functions may be merged/de-duplicated resulting in function pointers to different function to compare ==. The later shouldn't be relevant here as the function differ in behavior, but mentioning it for completeness. --- diff --git a/src/machine/dispatch.rs b/src/machine/dispatch.rs index 8306c6e8..88191b0d 100644 --- a/src/machine/dispatch.rs +++ b/src/machine/dispatch.rs @@ -1104,7 +1104,7 @@ impl MachineState { } _ => { push_cell!(self, heap_loc_as_cell!(h), return); - (self.bind_fn)(self, Ref::heap_cell(h), value); + self.occurs_check.bind(self, Ref::heap_cell(h), value); } ); } @@ -1152,7 +1152,7 @@ impl MachineState { push_cell!(self, heap_loc_as_cell!(h), return); let addr = self.store(self[r]); - (self.bind_fn)(self, Ref::heap_cell(h), addr); + self.occurs_check.bind(self, Ref::heap_cell(h), addr); // the former code of this match arm was: @@ -1235,7 +1235,7 @@ impl MachineState { let h = self.heap.cell_len(); push_cell!(self, heap_loc_as_cell!(h), return); - (self.bind_fn)(self, Ref::heap_cell(h), addr); + self.occurs_check.bind(self, Ref::heap_cell(h), addr); self.registers[arg] = heap_loc_as_cell!(h); } @@ -1281,7 +1281,7 @@ impl MachineState { if stored_v.is_stack_var() { let h = self.heap.cell_len(); push_cell!(self, heap_loc_as_cell!(h), return); - (self.bind_fn)(self, Ref::heap_cell(h), stored_v); + self.occurs_check.bind(self, Ref::heap_cell(h), stored_v); } else { push_cell!(self, stored_v, return); } diff --git a/src/machine/machine_state.rs b/src/machine/machine_state.rs index 452debb2..968dc2e1 100644 --- a/src/machine/machine_state.rs +++ b/src/machine/machine_state.rs @@ -57,6 +57,62 @@ pub enum OnEOF { Return, Continue, } +pub(crate) trait OccursCheckImpl { + fn flag_value(&self) -> Atom; + fn unify(&self, state: &mut MachineState); + fn bind(&self, state: &mut MachineState, r: Ref, h: HeapCellValue); +} + +/// Not subject to occurs-check +pub(crate) struct Nsto; + +impl OccursCheckImpl for Nsto { + fn flag_value(&self) -> Atom { + atom!("false") + } + + fn unify(&self, state: &mut MachineState) { + state.unify(); + } + + fn bind(&self, state: &mut MachineState, r: Ref, h: HeapCellValue) { + state.bind(r, h); + } +} + +/// Subject to occurs-check +pub(crate) struct Sto; + +impl OccursCheckImpl for Sto { + fn flag_value(&self) -> Atom { + atom!("true") + } + + fn unify(&self, state: &mut MachineState) { + state.unify_with_occurs_check(); + } + + fn bind(&self, state: &mut MachineState, r: Ref, h: HeapCellValue) { + state.bind_with_occurs_check_wrapper(r, h); + } +} + +/// Subject to occurs-check -> error +pub(crate) struct StoError; + +impl OccursCheckImpl for StoError { + fn flag_value(&self) -> Atom { + atom!("error") + } + + fn unify(&self, state: &mut MachineState) { + state.unify_with_occurs_check_with_error(); + } + + fn bind(&self, state: &mut MachineState, r: Ref, h: HeapCellValue) { + state.bind_with_occurs_check_with_error_wrapper(r, h); + } +} pub struct MachineState { pub atom_tbl: Arc, @@ -93,8 +149,7 @@ pub struct MachineState { pub(crate) cc: usize, pub(crate) global_clock: usize, pub(crate) dynamic_mode: FirstOrNext, - pub(crate) unify_fn: fn(&mut MachineState), - pub(crate) bind_fn: fn(&mut MachineState, Ref, HeapCellValue), + pub(crate) occurs_check: &'static dyn OccursCheckImpl, pub(crate) run_cleaners_fn: fn(&mut Machine) -> bool, } @@ -128,28 +183,8 @@ impl fmt::Debug for MachineState { .field("cc", &self.cc) .field("global_clock", &self.global_clock) .field("dynamic_mode", &self.dynamic_mode) - .field( - "unify_fn", - if self.unify_fn as usize == MachineState::unify as usize { - &"MachineState::unify" - } else if self.unify_fn as usize == MachineState::unify_with_occurs_check as usize { - &"MachineState::unify_with_occurs_check" - } else { - &"MachineState::unify_with_occurs_check_with_error" - }, - ) - .field( - "bind_fn", - if self.bind_fn as usize == MachineState::bind as usize { - &"MachineState::bind" - } else if self.bind_fn as usize - == MachineState::bind_with_occurs_check_wrapper as usize - { - &"MachineState::bind_with_occurs_check" - } else { - &"MachineState::bind_with_occurs_check_with_error_wrapper" - }, - ) + .field("unify_fn", &&*self.occurs_check.flag_value().as_str()) + .field("bind_fn", &&*self.occurs_check.flag_value().as_str()) .finish() } } diff --git a/src/machine/machine_state_impl.rs b/src/machine/machine_state_impl.rs index ee8a130b..dc9d7c9a 100644 --- a/src/machine/machine_state_impl.rs +++ b/src/machine/machine_state_impl.rs @@ -64,8 +64,7 @@ impl MachineState { cc: 0, global_clock: 0, dynamic_mode: FirstOrNext::First, - unify_fn: MachineState::unify, - bind_fn: MachineState::bind, + occurs_check: &Nsto, run_cleaners_fn: |_| false, } } @@ -951,7 +950,7 @@ impl MachineState { } }; - (self.bind_fn)(self, r, f_a); + self.occurs_check.bind(self, r, f_a); Ok(()) } diff --git a/src/machine/partial_string.rs b/src/machine/partial_string.rs index 80c3c9af..0749667b 100644 --- a/src/machine/partial_string.rs +++ b/src/machine/partial_string.rs @@ -5,13 +5,42 @@ use crate::machine::machine_errors::CycleSearchResult; use crate::machine::system_calls::BrentAlgState; use crate::types::*; +trait StepperImpl { + fn step<'a>(&self, iter: &mut HeapPStrIter<'a>) -> Option; + fn is_cyclic(&self) -> bool; +} + +struct PreCycleDiscoverStepper; + +impl StepperImpl for PreCycleDiscoverStepper { + fn step<'a>(&self, iter: &mut HeapPStrIter<'a>) -> Option { + iter.pre_cycle_discovery_stepper() + } + + fn is_cyclic(&self) -> bool { + false + } +} + +struct PostCycleDiscoverStepper; + +impl StepperImpl for PostCycleDiscoverStepper { + fn step<'a>(&self, iter: &mut HeapPStrIter<'a>) -> Option { + iter.post_cycle_discovery_stepper() + } + + fn is_cyclic(&self) -> bool { + true + } +} + #[derive(Clone, Copy)] pub struct HeapPStrIter<'a> { pub heap: &'a Heap, // pub focus: HeapCellValue, orig_focus: usize, brent_st: BrentAlgState, - stepper: fn(&mut HeapPStrIter<'a>) -> Option, + stepper: &'static dyn StepperImpl, } struct PStrIterStep { @@ -33,7 +62,7 @@ impl<'a> HeapPStrIter<'a> { heap, orig_focus, brent_st: BrentAlgState::new(orig_focus), - stepper: HeapPStrIter::pre_cycle_discovery_stepper, + stepper: &PreCycleDiscoverStepper, } } @@ -161,7 +190,7 @@ impl<'a> HeapPStrIter<'a> { debug_assert!(matches!(cycle_result, CycleSearchResult::Cyclic { .. })); self.walk_hare_to_cycle_end(); - self.stepper = HeapPStrIter::post_cycle_discovery_stepper; + self.stepper = &PostCycleDiscoverStepper; } None => { // self.focus = self.heap[next_hare]; @@ -194,7 +223,7 @@ impl<'a> HeapPStrIter<'a> { } pub(crate) fn is_cyclic(&self) -> bool { - self.stepper as usize == Self::post_cycle_discovery_stepper as usize + self.stepper.is_cyclic() } } @@ -203,7 +232,7 @@ impl<'a> Iterator for HeapPStrIter<'a> { #[inline(always)] fn next(&mut self) -> Option { - (self.stepper)(self) + self.stepper.step(self) } } diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index b7a63aad..7ab919f0 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -9213,36 +9213,25 @@ impl Machine { #[inline(always)] pub(crate) fn is_sto_enabled(&mut self) { - if self.machine_st.unify_fn as usize == MachineState::unify_with_occurs_check as usize { - self.machine_st - .unify_atom(atom!("true"), self.machine_st.registers[1]); - } else if self.machine_st.unify_fn as usize - == MachineState::unify_with_occurs_check_with_error as usize - { - self.machine_st - .unify_atom(atom!("error"), self.machine_st.registers[1]); - } else { - self.machine_st - .unify_atom(atom!("false"), self.machine_st.registers[1]); - } + self.machine_st.unify_atom( + self.machine_st.occurs_check.flag_value(), + self.machine_st.registers[1], + ); } #[inline(always)] pub(crate) fn set_sto_as_unify(&mut self) { - self.machine_st.unify_fn = MachineState::unify_with_occurs_check; - self.machine_st.bind_fn = MachineState::bind_with_occurs_check_wrapper; + self.machine_st.occurs_check = &Sto; } #[inline(always)] pub(crate) fn set_nsto_as_unify(&mut self) { - self.machine_st.unify_fn = MachineState::unify; - self.machine_st.bind_fn = MachineState::bind; + self.machine_st.occurs_check = &Nsto; } #[inline(always)] pub(crate) fn set_sto_with_error_as_unify(&mut self) { - self.machine_st.unify_fn = MachineState::unify_with_occurs_check_with_error; - self.machine_st.bind_fn = MachineState::bind_with_occurs_check_with_error_wrapper; + self.machine_st.occurs_check = &StoError; } #[inline(always)] diff --git a/src/macros.rs b/src/macros.rs index f977b882..b48ae942 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -415,7 +415,7 @@ macro_rules! unify { macro_rules! unify_fn { ($machine_st:expr, $($value:expr),*) => {{ $($machine_st.pdl.push($value);)* - ($machine_st.unify_fn)(&mut $machine_st) + $machine_st.occurs_check.unify(&mut $machine_st) }}; }