verus-lang / verus

Verified Rust for low-level systems code

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Lifetime-generate has additional trait bound restrictions (?)

utaal-b opened this issue · comments

use vstd::prelude::*;
use vstd::seq_lib::*;

verus! {

trait VerusClone: View + Sized {
    fn verus_clone(&self) -> (r: Self)
        ensures self@ == r@;
}

fn vec_filter<V: VerusClone>(v: Vec<V>, f: impl Fn(&V)->bool, f_spec: FnSpec(V)->bool) -> (r: Vec<V>)
    requires forall|v: V| #[trigger] f.requires((&v,)), forall |v:V,r:bool| f.ensures((&v,), r) ==> f_spec(v) == r,
    ensures r@.to_multiset() =~= v@.to_multiset().filter(f_spec)
{
    let mut r = Vec::new();
    let mut i = 0;
    proof { lemma_seq_properties::<V>(); }
    while i < v.len()
        invariant
            forall|v: V| #[trigger] f.requires((&v,)),
            i <= v.len(),
            r@.to_multiset() =~= v@.subrange(0, i as int).to_multiset().filter(f_spec),
            forall |v:V,r:bool| f.ensures((&v,), r) ==> f_spec(v) == r,
    {
        proof { lemma_seq_properties::<V>(); }
        let ghost pre_r = r@.to_multiset();
        assert(
            v@.subrange(0, i as int + 1)
            =~=
            v@.subrange(0, i as int).push(v@[i as int]));
        if f(&v[i]) {
            r.push(v[i].verus_clone());
        }
        
        i += 1;
    }
    r
}

}

fails with

error: the trait bound `A27_V: T28_View` is not satisfied
  --> vec.rs:32:20
   |
32 |               r.push(v[i].verus_clone());
   |  ____________________^^^^_^
33 | |         }
   | |______^

and

fn vec_filter<V: VerusClone>

needs to be

fn vec_filter<V: VerusClone + View + Sized>

I believe this is because we ignore VerusClone because it doesn't have any associated types, but the type checker uses it to constrain V to be View + Sized too.