Extending external_trait_specification with spec functions #1618
Chris-Hawblitzel
started this conversation in
Language design
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
@ziqiaozhou @tjhance @utaal This is a follow-up to #1527 and discussions that we've had in meetings. It is relevant to #1465 and #1569 .
We often write Verus traits with a mixture of
execandspecfunctions:However, if the trait is an external trait, such as an std library trait like
PartialOrdorAdd, then the trait will not have anyspecfunctions in it, making it harder to declarerequiresandensuresfor theexecfunctions in the trait. To overcome this limitation, we've previously discussed approaches to extend existing traits with additional ghost functions. Here, I will detail a proposal to implement such an approach. I'll only considerspecfunctions, leavingprooffunctions for future work.Suppose we have an external trait
Twith anexecfunctione:Suppose we allow the
external_trait_specificationto extendTwith additionalspecfunctions as follows:The syntax macro could generate the following additional traits and trait impls from the
ExTdeclaration:TSpec::ris an uninterpreted function that represents all implementations ofT::r. There would be two ways to defineTSpec::rfor various types that implementT: (1) a verified way based on trait implementations, and (2) an unverified way based on user-supplied axioms. When Rust's trait coherence rules can be satisfied, (1) is better, but in case Rust's trait coherence rules are an insurmountable obstacle, (2) is available as a backup strategy.For (1), a user simply implements
TImplSpecalong withT:Verus would emit an axiom saying that
TSpecalways agrees withTImplSpec. It would be equivalent to the following broadcast (although it would be an internal axiom, not a named broadcast function):User functions can then use
TandTSpec:Although
T,TSpec, andTImplSpecappear as separate traits to Rust's type system, Verus would group them together internally in VIR. By doing this, Verus would prohibit circular definitions such as the following:Here,
<u32 as TSpec>would depend onimpl<A: T + ?Sized> TSpec for AwithA = u32, which would in turn depend onu32: T. If, for example, we set up an internal dependency ofu32: Tonu32: TImplSpec, we can catch the circular definition.Beta Was this translation helpful? Give feedback.
All reactions