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

feat: Allow more assumptions in library backend #4545

Conversation

robin-aws
Copy link
Member

@robin-aws robin-aws commented Sep 13, 2023

The "library backend" which is selected using --target:lib and produces .doo files is currently more restrictive than the other backends. The common SinglePassCompiler logic rejects features that cannot be compiled such as assume statements without {:axiom}, but the library backend doesn't actually use that base class. It instead leverages the Declaration.Assumptions() method that the auditor uses to identify assumptions. AssumptionDescriptions have a allowedInLibraries flag to indicate whether they should cause build errors when trying to build a .doo file, and the initial version was intentionally very conservative.

This PR switches the value of this flag for a few cases that are very likely to appear in useful libraries and where the risk of misuse is zero or very low:

  • assume {:axiom} ... - already allowed by other backends.
  • decreases * - not really an assumption, more of a sound specification limitation, and we may even remove this from the auditor as well in the future.
  • {:extern} declarations with requires or ensures - now allowed only if the declaration also has {:axiom}, and this case now creates auditor warnings as well.
  • {:termination false} - allowed because there is no mitigation and traits are highly valuable to share in libraries. This is worth discussing, and the better alternative may be to support an assumption attribute on the class extending a trait instead, so that the assumption appears in the consumer instead of the library code. (Update: I reverted the change to allow this attribute in libraries and will implement the alternative instead in a separate PR)

Also corrected a typo in mitigation text suggesting modifies * when it should be modifies {} - modifies * doesn't even parse. :)

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

issue: "Declaration with [{:extern}] has a ensures clause.",
mitigation: "Test external callee (maybe with [/testContracts]).",
mitigationIETF: "MUST test external callee.",
mitigation: "Turn into a [method] with [modifies {}] or test thoroughly for lack of side effects.",
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
mitigation: "Turn into a [method] with [modifies {}] or test thoroughly for lack of side effects.",
mitigation: "Turn into a [method] with [modifies {}] and test thoroughly for lack of side effects.",

Copy link
Member

Choose a reason for hiding this comment

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

Turning it into a method allows for non-determinism that may occur, but if we have modifies {} then we'll really want to know that it has no side effects.

isExplicit: false,
allowedInLibraries: false);

public static AssumptionDescription ExternWithPrecondition(bool hasAxiomAttribute) {
Copy link
Member

Choose a reason for hiding this comment

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

I know I originally suggested this design, but now I'm thinking this should be treated as such:

  • If an extern does not have {:axiom}, have the auditor flag any pre- or post-conditions. Don't allow it in libraries.
  • If an extern does have {:axiom}, have the auditor flag it as an explicit (intentional) assumption, and allow it in libraries. Don't say anything about pre- or post-conditions.
    This is more consistent with treatments elsewhere. Having {:axiom} on an enclosing scope (e.g., a declaration) silences mention of other assumptions associated with it (e.g., the contract of a declaration).

Copy link
Member

@atomb atomb 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!

@robin-aws robin-aws enabled auto-merge (squash) September 15, 2023 18:03
@robin-aws robin-aws merged commit 2e14590 into dafny-lang:master Sep 15, 2023
18 checks passed
@robin-aws robin-aws deleted the allow-more-assumptions-in-library-backend branch September 15, 2023 18:43
TaBo2410 added a commit that referenced this pull request Sep 20, 2023
…iment-trsplitexpr

* commit '86840e6b14386c1e88480854dd8ce64ad17cb2ff':
  Map eq range (#4567)
  Fix: Declarations with {:only} ensure that other declarations aren't displayed as verified in the gutter icons (#4433)
  Fix caching of export declarations (#4556)
  Do not return exceptions when doing hover in a program with parse errors (#4557)
  Proof dependency warnings (#4542)
  [Test Generation] Reduce memory footprint by reusing the same Boogie program for multiple test generation queries (#4530)
  Fix a variety of bugs in Rust backend based on ESDK testing (#4538)
  Checker for .Values and .Items on maps (#4551)
  feat: Allow more assumptions in library backend (#4545)
  feat: Attributes on reads clauses (#4554)
  Fix gutter icons fields (#4549)
  Report errors that occur in the project file, in the IDE as well (#4539)
  Switch to ubuntu-20.04 for the refman build (#4555)
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.

2 participants