Closed enjhnsn2 closed 2 weeks ago
Sadly no :(
The only way now is to refine Ordering
by an int
.
use std::cmp::Ordering;
#[flux_rs::extern_spec]
#[flux_rs::refined_by(val: int)]
#[flux_rs::invariant(val == -1 || val == 0 || val == 1)]
enum Ordering {
#[flux::variant(Ordering[-1])]
Less,
#[flux::variant(Ordering[0])]
Equal,
#[flux::variant(Ordering[1])]
Greater,
}
#[flux_rs::opaque]
#[flux_rs::refined_by(n: int)]
struct Wrapper {
x: *mut u8
}
#[flux_rs::trusted]
impl Wrapper {
#[flux_rs::sig(
fn(self: &Wrapper[@lhs], other: &Wrapper[@rhs]) -> Ordering{val: val == -1 => lhs < rhs &&
val == 0 => lhs == rhs &&
val == 1 => lhs > rhs}
)]
fn cmp(&self, other: &Wrapper) -> Ordering {
todo!()
}
}
My idea for stuff like this is to implement a feature that let you mark an enum (without payload for now) with #[flux::reflect]
such that it becomes something in the logic you can use.
Is this something I could do on an extern_spec of Ordering? Otherwise I'd have to rewrite every pointer comparison in flux.
@enjhnsn2 I'am looking at the mir produced by your example and calling <
and >=
uses PartialOrd::lt
and PartialOrd::ge
so you should refine those and it's not necessary to refine Ord::cmp
cool, I'll try that and let you know how it works
Cool, both the extern_spec on Ordering and refining le,lt,ge,gt
works.
I'll post my implementation before closing:
#[flux_rs::trusted]
impl PartialOrd for FluxPtr {
fn partial_cmp(&self, other: &Self) -> Option<Ordering>{todo!()}
#[flux_rs::sig(fn(self: &Self[@lhs], other: &Self[@rhs]) -> bool[lhs < rhs])]
fn lt(&self, other: &Self) -> bool { todo!() }
#[flux_rs::sig(fn(self: &Self[@lhs], other: &Self[@rhs]) -> bool[lhs <= rhs])]
fn le(&self, other: &Self) -> bool { todo!() }
#[flux_rs::sig(fn(self: &Self[@lhs], other: &Self[@rhs]) -> bool[lhs > rhs])]
fn gt(&self, other: &Self) -> bool { todo!() }
#[flux_rs::sig(fn(self: &Self[@lhs], other: &Self[@rhs]) -> bool[lhs >= rhs])]
fn ge(&self, other: &Self) -> bool { todo!() }
}
I have an opaque wrapper struct used to represent pointers in Tock:
However, comparisons do not work when using this wrapper. The following code:
fails with:
This is because
FluxPtr
is opaque and Flux has no way to know that for the comparisonself: &FluxPtr[@self_index] < other: &FluxPtr[@other_index]
thatself < other => self_index < other_index
I tried to fix this by implementing the
cmp
function myself instead of deriving it:However this fails with:
Is it possible to match on enum variants within a flux signature? Alternately, do you have any suggestions about handling comparisons on opaque structs?