Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cyclic dependency between trait definitions doesn't work well with F* #1297

Open
maximebuyse opened this issue Feb 6, 2025 · 0 comments
Open
Labels
workaround This bug has a workaround

Comments

@maximebuyse
Copy link
Contributor

#[derive(PartialEq, Eq)]
struct W(u16);

impl Ord for W {
    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
        self.0.cmp(&other.0)
    }
}

impl PartialOrd for W {
    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
        Some(self.cmp(other))
    }
}

Open this code snippet in the playground

In this example partial_cmp is defined using cmp. But PartialOrd is a trait bound of Ord so we would need to define mutually recursive type class implementations in F* which is not possible.

Maybe this is not something we want to fix, the workaround for the example would be to not define partial_cmp using cmp and repeat the definition:

impl PartialOrd for W {
    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
        Some(self.0.cmp(&other.0))
    }
}

And to avoid code duplication this can be reused in the definition of Ord:

impl Ord for W {
    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
        self.partial_cmp(other).unwrap()
    }
}

I mark this as bug because we shouldn't produce invalid F* code, we can decide to leave this as unsupported but then we should report an error.

@maximebuyse maximebuyse added the workaround This bug has a workaround label Feb 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
workaround This bug has a workaround
Projects
None yet
Development

No branches or pull requests

1 participant