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

Creusot rejects these generic definitions with trait constraints #1285

Open
Lysxia opened this issue Dec 3, 2024 · 6 comments
Open

Creusot rejects these generic definitions with trait constraints #1285

Lysxia opened this issue Dec 3, 2024 · 6 comments
Labels
bug Something isn't working

Comments

@Lysxia
Copy link
Collaborator

Lysxia commented Dec 3, 2024

These are definitions which compile with plain rustc, but not creusot:

use creusot_contracts::*;
pub fn min<O: PartialOrd>(a: O, b: O) -> O {
    if a < b {
        a
    } else {
        b
    }
}

Error message:

error[E0277]: the trait bound `O: creusot_contracts::DeepModel` is not satisfied
  --> src/lib.rs:11:8
   |
11 |     if a < b {
   |        ^^^^^ the trait `creusot_contracts::DeepModel` is not implemented for `O`

error[E0277]: the trait bound `<O as creusot_contracts::DeepModel>::DeepModelTy: creusot_contracts::OrdLogic` is not satisfied
  --> src/lib.rs:11:8
   |
11 |     if a < b {
   |        ^^^^^ the trait `creusot_contracts::OrdLogic` is not implemented for `<O as creusot_contracts::DeepModel>::DeepModelTy`

use creusot_contracts::*;
pub fn f<I: Iterator>(i: &mut I) {
    for _ in i {}
}

(Adding a #[invariant(true)] doesn't help)

Error message:

error[E0277]: the trait bound `<&mut I as std::iter::IntoIterator>::IntoIter: creusot_contracts::Iterator` is not satisfied
  --> src/lib.rs:12:14
   |
12 |     for _ in i {}
   |              ^ the trait `creusot_contracts::Iterator` is not implemented for `<&mut I as std::iter::IntoIterator>::IntoIter`

error[E0277]: the trait bound `&mut I: creusot_contracts::IntoIterator` is not satisfied
  --> src/lib.rs:12:14
   |
12 |     for _ in i {}
   |              ^ the trait `creusot_contracts::Iterator` is not implemented for `&mut I`, which is required by `&mut I: creusot_contracts::IntoIterator`
   |
   = help: the following other types implement trait `creusot_contracts::Iterator`:
             creusot_contracts::std::iter::MapInv<I, <I as std::iter::Iterator>::Item, F>
             std::collections::vec_deque::Iter<'a, T>
             std::iter::Cloned<I>
             std::iter::Copied<I>
             std::iter::Empty<T>
             std::iter::Enumerate<I>
             std::iter::Filter<I, F>
             std::iter::Fuse<I>
           and 14 others
   = note: required for `&mut I` to implement `creusot_contracts::IntoIterator`

error[E0277]: the trait bound `&mut I: creusot_contracts::Iterator` is not satisfied
  --> src/lib.rs:12:14
   |
12 |     for _ in i {}
   |              ^ the trait `creusot_contracts::Iterator` is not implemented for `&mut I`
   |
   = help: the following other types implement trait `creusot_contracts::Iterator`:
             creusot_contracts::std::iter::MapInv<I, <I as std::iter::Iterator>::Item, F>
             std::collections::vec_deque::Iter<'a, T>
             std::iter::Cloned<I>
             std::iter::Copied<I>
             std::iter::Empty<T>
             std::iter::Enumerate<I>
             std::iter::Filter<I, F>
             std::iter::Fuse<I>
           and 14 others
@Lysxia Lysxia added the bug Something isn't working label Dec 3, 2024
@Lysxia
Copy link
Collaborator Author

Lysxia commented Dec 4, 2024

I'm trying to define traits that gather the necessary constraints, e.g.,

// Extends std::PartialOrd with additional constraints for translation
trait MyPartialOrd where
    Self: PartialOrd + DeepModel,
    <Self as DeepModel>::DeepModelTy: OrdLogic {
}

However the constraint on the associated type doesn't seem to work

pub fn min<O: MyPartialOrd>(a: O, b: O) -> O {
    if a < b {
        a
    } else {
        b
    }
}
error[E0277]: the trait bound `<O as creusot_contracts::DeepModel>::DeepModelTy: creusot_contracts::OrdLogic` is not satisfied
  --> src/lib.rs:33:8
   |
33 |     if a < b {
   |        ^^^^^ the trait `creusot_contracts::OrdLogic` is not implemented for `<O as creusot_contracts::DeepModel>::DeepModelTy`

thread 'rustc' panicked at creusot/src/translation/pearlite/normalize.rs:35:29:
could not resolve trait instance (DefId(20:4549 ~ creusot_contracts[1d45]::logic::ord::OrdLogic::lt_log), [Alias(Projection, AliasTy { args: [O/#0], def_id: DefId(20:848 ~ creusot_contracts[1d45]::model::DeepModel::DeepModelTy) })])

UPDATE: found a variant that works

trait MyOrd
where
    Self: Ord + DeepModel<DeepModelTy: OrdLogic>,
    {}

pub fn min<A: MyOrd>(x: A) {
}

The previous variant seems to rely on an unimplemented feature of trait resolution.

@xldenis
Copy link
Collaborator

xldenis commented Dec 4, 2024

I think the issue here is that extern_spec is not doing its job, it should be re-inforcing the trait bounds when you compile with creusot.

@Lysxia
Copy link
Collaborator Author

Lysxia commented Dec 4, 2024

How does it do that? the only way I can think of is to somehow shadow traits from std but I don't see where that is happening (which is why I was trying to do it manually)?

@xldenis
Copy link
Collaborator

xldenis commented Dec 4, 2024

we have extern_spec declarations for traits which are meant to then inject the bounds automatically via ParamEnv in creusot. That second part has always been sort of buggy though.

@jhjourdan
Copy link
Collaborator

I think the issue here is that extern_spec is not doing its job, it should be re-inforcing the trait bounds when you compile with creusot.

I think it does that, but this fails, because it cannot find the bound because of rust-lang/rust#44491.

@jhjourdan
Copy link
Collaborator

trait MyOrd
where
    Self: Ord + DeepModel<DeepModelTy: OrdLogic>,
    {}

Cannot this be written:

trait MyOrd: Ord + DeepModel<DeepModelTy: OrdLogic>,
    {}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants