]> Repositorios git - scryer-prolog.git/commitdiff
fix `function_casts_as_integer` warning
authorSkgland <[email protected]>
Thu, 27 Nov 2025 19:07:13 +0000 (20:07 +0100)
committerBennet Bleßmann <[email protected]>
Thu, 4 Dec 2025 22:35:23 +0000 (23:35 +0100)
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.

src/machine/dispatch.rs
src/machine/machine_state.rs
src/machine/machine_state_impl.rs
src/machine/partial_string.rs
src/machine/system_calls.rs
src/macros.rs

index 8306c6e825109db5580b3aa93d1dfa44bcc392f3..88191b0d38dbb3f29d458a2748867c2b7cc300d5 100644 (file)
@@ -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);
         }
index 452debb2ed5b0fa85398df007efe8e7fb2fee97d..968dc2e13b2b80060c244491ed17fee08377ca8e 100644 (file)
@@ -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<AtomTable>,
@@ -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()
     }
 }
index ee8a130b98825818deb1111024a3c0ce2c26f666..dc9d7c9a8559911bf630664e0738ab522b5a8112 100644 (file)
@@ -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(())
     }
 
index 80c3c9af8a51c2ab2722a8bf47fcf1c7ffde3c7a..0749667b6bd875583ab3de03e915668bcf699596 100644 (file)
@@ -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<PStrIteratee>;
+    fn is_cyclic(&self) -> bool;
+}
+
+struct PreCycleDiscoverStepper;
+
+impl StepperImpl for PreCycleDiscoverStepper {
+    fn step<'a>(&self, iter: &mut HeapPStrIter<'a>) -> Option<PStrIteratee> {
+        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<PStrIteratee> {
+        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<PStrIteratee>,
+    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::Item> {
-        (self.stepper)(self)
+        self.stepper.step(self)
     }
 }
 
index b7a63aad5f0d62fd8459fbfd0d258e6fecdaa694..7ab919f0cf0a297062f50b03f256586b55a1c02f 100644 (file)
@@ -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)]
index f977b88259c6e47637edc17e00489f3ef6a3ff7a..b48ae9421fd8e05699b62674555da93f66964083 100644 (file)
@@ -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)
     }};
 }