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

fix: Use reveal_ constant as function argument in override axiom #5111

Merged
merged 16 commits into from
Mar 1, 2024

Conversation

RustanLeino
Copy link
Collaborator

@RustanLeino RustanLeino commented Feb 20, 2024

Fixes #5017

Let verifier understand opaque function overrides, supporting both when the overridden function is opaque and non-opaque. Revealing such a function for one overriding type has the effect of revealing it for all overriding types.

Also, forbid the case where a function is opaque in a parent trait and the function override is not opaque. Previously, this had caused a crash.

By submitting this pull request, I confirm that my contribution is made under the terms of the MIT license.

MikaelMayer
MikaelMayer previously approved these changes Feb 20, 2024
Copy link
Member

@MikaelMayer MikaelMayer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solution is precise and sounds accurate! Thanks

// We can't use a bound variable $fuel, because then one of the triggers won't be mentioning this $fuel.
// Instead, we do the next best thing: use the literal false.
reveal = new Boogie.LiteralExpr(f.tok, false);
reveal = GetRevealConstant(overridingFunction);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds largely plausible to be the cause of the issue. Thanks for spotting!

@RustanLeino RustanLeino marked this pull request as ready for review February 20, 2024 23:47
@RustanLeino RustanLeino enabled auto-merge (squash) February 20, 2024 23:47
git-issue-5017b.dfy(44,14): Error: overridden predicate 'Valid' in 'M2' must be 'opaque' since the member is 'opaque' in trait 'C'
git-issue-5017b.dfy(66,14): Error: overridden predicate 'Valid' in 'Y0' must be 'opaque' since the member is 'opaque' in trait 'C'
git-issue-5017b.dfy(69,14): Error: overridden predicate 'Valid' in 'Y1' must be 'opaque' since the member is 'opaque' in trait 'C'
git-issue-5017b.dfy(94,13): Error: member 'reveal_Valid' does not exist in trait 'A'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I worried a bit about this issue. It seems that, to resolver it, one would need to implement this member, but the resolution is to actually. make Valid opaque in A. Could you detect that particular case and emit a more useful error message?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent idea. I improved many messages. However, it became more difficult for some of them. The problem is that, early on during resolution, we change reveal X(); expressions into reveal_X(); lemma calls. By the time that these attempted lemma calls go through the resolver, the name looked up is reveal_X. To improve the error message, we then have to detect that we're in a reveal-statement context and that the thing we're trying to look up has a name that starts with "reveal_" (which is not actually guaranteed to be one of the rewritten calls, since this could have been a user-defined name in the first place), and then remove the "reveal_" prefix, try to find what the name X might have referred to, and finally reconstruct the reason why no reveal_X lemma was created in the first place. It would have been much better not to have done the reveal_X-lemma surgery so early in the pipeline. Then, the symbol we'd be looking at during resolution would be X. (Btw, I've seen this mistake many times--a change is made too early in the resolution pipeline, because it seems as if that's a quick way to get a new feature into the language, but then this bites later on.)

Anyhow, I feel okay with the error messages I did improve. At some point in the future, I expect that we'll revisit reveal statements to expand their role. That would be a good time to handle reveal in a way that's less hacky than today's reveal_-lemmas.

Copy link
Member

@MikaelMayer MikaelMayer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. A minor point below too.

@@ -94,8 +94,7 @@ ExportResolve.dfy(288,39): Error: member 'u' has not been imported in this scope
ExportResolve.dfy(290,18): Error: type of corresponding source/RHS (G.Trait) does not match type of bound variable (object?)
ExportResolve.dfy(290,46): Error: type of corresponding source/RHS (G.Klass) does not match type of bound variable (object?)
ExportResolve.dfy(298,19): Error: member '_ctor' has not been imported in this scope and cannot be accessed here
ExportResolve.dfy(342,15): Error: unresolved identifier: reveal_OpaqueFunction
ExportResolve.dfy(342,29): Error: expression has no reveal lemma
ExportResolve.dfy(342,15): Error: cannot reveal 'OpaqueFunction' because no revealable constant, function, assert label, or requires label in the current scope is named 'OpaqueFunction'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not blocking, but I thought it should not be an error but a warning. Otherwise, it makes experimenting with opaque to be hard.

@RustanLeino RustanLeino merged commit 4e22bd4 into dafny-lang:master Mar 1, 2024
20 checks passed
@RustanLeino RustanLeino deleted the issue-5017 branch March 4, 2024 20:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Parent predicate can't be proven with opaque
2 participants