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.
This commit is contained in:
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user