-
Notifications
You must be signed in to change notification settings - Fork 107
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
Ghost Constraint Stabilization #1271
Conversation
turns out the previous implementation was flawed in that it made the function pure whether or not the constraint held
you can still introduce unsound behavior with them, but they're far from the only way to do so, and absolutely necessary for prusti std
…ng strings & comments
removed a check preventing use of this feature previously; this effectively formalizes it as working
expressions are not implicitly in parentheses, creating very strange errors when desugaring e.g. a + b to &a + b
not thoroughly tested, but let's not let perfect be the enemy of good enough
not thoroughly tested, but let's not let perfect be the enemy of good enough
testing-specific workaround is now only present when cfg(test) is active
prusti-tests/tests/verify_overflow/fail/type-cond-specs/in-non-trusted-function.rs
Outdated
Show resolved
Hide resolved
@@ -1488,11 +1488,9 @@ impl<'p, 'v: 'p, 'tcx: 'v> ProcedureEncoder<'p, 'v, 'tcx> { | |||
// The called method might be a trait method. | |||
// We try to resolve it to the concrete implementation | |||
// and type substitutions. | |||
let query = self.encoder.env().query; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this alias? It doesn't seem to be used later on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without it, the long line spilled over into a silly-looking chained function call spanning like 5 lines, lol. I considered updating the later usage, but that felt worse. Should I just accept the other formatting rather than polluting this long function's namespace?
better no information than inaccurate information!
while preserving the safety of parenthesizing incoming LHS/RHS
the latter didn't work anyway, and now that we have type-cond-specs, we know we won't need it, so we can drop the annotations entirely.
where clauses on traits
we were getting spurious failures for the core proof tests from old data
it's like they were never there! no more use crate::*;
keep the changes to a minimum
As part of my thesis under @Aurel300, I've been writing specs for the standard library (#1249), which will ship with Prusti for users to benefit from.
Ghost Constraints → Type-Conditional Spec Refinements
These specs often rely on ghost constraints, e.g. to provide a way to opt out of specs applied by default to certain trait implementations, or to specify known return values for e.g.
core::mem::size_of
. Since these specs will be active by default, they would require enabling ghost constraints to use Prusti at all (barring the option of conditionalizing specs on enabled Prusti features somehow). Hence we propose to stabilize ghost constraints, addressing some issues with them to get them to a place where this makes sense.Ghost constraints are now called type-conditional spec refinements (
TypeCondSpec
for short) and spelled as follows:The
where
draws a clear analogy to existing Rust syntax to help users understand this attribute, and it even results in correct syntax highlighting for the constraints. Note also thatpure
is now supported here (correctly—my previous implementation was broken), and that you can apply multiple bounds.Extern Spec Improvements
I also polished up & resolved some limitations with extern specs:
where
clause.#[extern_spec(core::mem)] fn swap(...)
. This argument also works on traits & modules (impl
s already allow qualifying involved type paths).Miscellaneous
As part of this PR, I enabled auto-formatting for the
prusti-specs
crate, and reformatted it in the process. This crate is one of the last few holdovers that weren't yet auto-formatted, the other big one beingprusti-viper
. It looked like this crate is not currently being majorly worked on by anyone else!Finally, I fixed a bug where lifetimes would make trait method resolution fail, by instead erasing all regions involved in the resolution process. This made some tests fail before I reworked the piece of code that encodes lifetimes for function calls. This bug made it impossible to specify e.g.
impl Add<&i32> for i32
, because Prusti could not resolve the generalAdd::add
to this specific implementation (due to the lifetimes necessarily differing between call site & declaration site).