Repository: verus-lang/verus

Issue #1235: Definitions of functions mentioned in trait requires/ensures are not always visible to implementations of that trait
Created: 2024-07-25T16:38:51Z
In this recording, introducing IntegerMarshalling_v.rs:63 causes proofs of a different obligation deepv_is_as_int to fail in the trait implementations (lines 146, 207). Commenting out line 63 (replacing it with 62: assume(false)) hides the problem. This is weird, because the line causing the problem is a call to the function whose impl proofs break. I conjecture this is some strange interaction with how trait defaults are encoded?
2024-07-25-09-35-43.zip

Duplicate issue #1239: Generated SMT axioms about trait implementations with associated type projections have triggers that aren't general enough
Created: 2024-08-08T17:08:54Z
In this example, this definition that appears as a trait default
    open spec fn loyalty_test(&self) -> int
    {
        7
    }
isn't visible to complete this proof:
    exec fn try_get(&self)
    {
        assert( self.bdyf.loyalty_test() == 7 );
    }
Verus gives:
verus --time open-trait-default-spec-fn.rs --crate-type=lib
error: assertion failed
  --> open-trait-default-spec-fn.rs:82:17
   |
82 |         assert( self.bdyf.loyalty_test() == 7 );
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assertion failed

Some degree of trait hierarchy is required to reproduce this. This is a distilling of the failure I have in my real code. I tried a simpler example and it didn't fail.
For some reason github is refusing my .tgz upload, so I'll paste the entire failed code example here.
use builtin::*;
use builtin_macros::*;
use vstd::prelude::*;

verus!{

pub trait Marshal {
    type DV;
    type U: Deepview<Self::DV>;
}

pub trait UniformSized {
}

pub trait IntFormattable : Deepview<int> {
}

pub trait Deepview<U> { }

impl<DVE, Elt: Deepview<DVE>> Deepview<Seq<DVE>> for Vec<Elt> {
}

pub struct IntFormat<T> {
    t: T,
}

impl<T: IntFormattable> UniformSized for IntFormat<T> {
}

impl<T: IntFormattable> Marshal for IntFormat<T> {
    type DV = int;
    type U = T;
}

pub trait SeqMarshal<DVElt, Elt: Deepview<DVElt>> {
    open spec fn loyalty_test(&self) -> int
    {
        7
    }
}

pub struct ResizableUniformSizedElementSeqFormat
    <EltFormat: Marshal + UniformSized, LenType: IntFormattable>
{
    e: EltFormat,
    l: LenType,
}

impl<EltFormat: Marshal + UniformSized, LenType: IntFormattable>
    SeqMarshal< EltFormat::DV, EltFormat::U >
    for ResizableUniformSizedElementSeqFormat<EltFormat, LenType>
{
}

impl<EltFormat: Marshal + UniformSized, LenType: IntFormattable>
    Marshal
    for ResizableUniformSizedElementSeqFormat<EltFormat, LenType>
{
    type DV = Seq<EltFormat::DV>;
    type U = Vec<EltFormat::U>;
}

pub struct VariableSizedElementSeqFormat <
    EltFormat: Marshal,
    BdyType: IntFormattable,
    LenType: IntFormattable,
> {
    e: EltFormat,
    pub bdyf: ResizableUniformSizedElementSeqFormat<IntFormat<BdyType>, LenType>,
}


impl<
    EltFormat: Marshal,
    BdyType: IntFormattable,
    LenType: IntFormattable,
>
    VariableSizedElementSeqFormat<EltFormat, BdyType, LenType>
{
    exec fn try_get(&self)
    {
        assert( self.bdyf.loyalty_test() == 7 );
    }
    
}

}

Closing comment (2024-08-08T17:09:44Z): Perhaps related to #1235
...exvidently not, as branch trait-req-ens-call-graph fixes #1235 but not this example.